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 1507b7090b4SJohannes Berg static inline void drv_vif_cfg_changed(struct ieee80211_local *local, 15112375ef9SJohannes Berg struct ieee80211_sub_if_data *sdata, 1527b7090b4SJohannes Berg u64 changed) 1537b7090b4SJohannes Berg { 1547b7090b4SJohannes Berg might_sleep(); 1557b7090b4SJohannes Berg 1567b7090b4SJohannes Berg if (!check_sdata_in_driver(sdata)) 1577b7090b4SJohannes Berg return; 1587b7090b4SJohannes Berg 1597b7090b4SJohannes Berg trace_drv_vif_cfg_changed(local, sdata, changed); 1607b7090b4SJohannes Berg if (local->ops->vif_cfg_changed) 1617b7090b4SJohannes Berg local->ops->vif_cfg_changed(&local->hw, &sdata->vif, changed); 1627b7090b4SJohannes Berg else if (local->ops->bss_info_changed) 1637b7090b4SJohannes Berg local->ops->bss_info_changed(&local->hw, &sdata->vif, 1647b7090b4SJohannes Berg &sdata->vif.bss_conf, changed); 1657b7090b4SJohannes Berg trace_drv_return_void(local); 1667b7090b4SJohannes Berg } 1677b7090b4SJohannes Berg 1687b7090b4SJohannes Berg static inline void drv_link_info_changed(struct ieee80211_local *local, 1697b7090b4SJohannes Berg struct ieee80211_sub_if_data *sdata, 170*d8675a63SJohannes Berg struct ieee80211_bss_conf *info, 1717b7090b4SJohannes Berg int link_id, u64 changed) 17224487981SJohannes Berg { 173e1781ed3SKalle Valo might_sleep(); 174e1781ed3SKalle Valo 1755bbe754dSJohannes Berg if (WARN_ON_ONCE(changed & (BSS_CHANGED_BEACON | 176b8dc1a35SJohannes Berg BSS_CHANGED_BEACON_ENABLED) && 177b8dc1a35SJohannes Berg sdata->vif.type != NL80211_IFTYPE_AP && 178b8dc1a35SJohannes Berg sdata->vif.type != NL80211_IFTYPE_ADHOC && 179239281f8SRostislav Lisovy sdata->vif.type != NL80211_IFTYPE_MESH_POINT && 180239281f8SRostislav Lisovy sdata->vif.type != NL80211_IFTYPE_OCB)) 1815bbe754dSJohannes Berg return; 1825bbe754dSJohannes Berg 1835bbe754dSJohannes Berg if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE || 184708d50edSAyala Beker sdata->vif.type == NL80211_IFTYPE_NAN || 18542bd20d9SAviya Erenfeld (sdata->vif.type == NL80211_IFTYPE_MONITOR && 186d0a9123eSJohannes Berg !sdata->vif.bss_conf.mu_mimo_owner && 1873a3713ecSPeter Große !(changed & BSS_CHANGED_TXPOWER)))) 1885bbe754dSJohannes Berg return; 189b8dc1a35SJohannes Berg 190f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 191f6837ba8SJohannes Berg return; 1927b7eab6fSJohannes Berg 193*d8675a63SJohannes Berg trace_drv_link_info_changed(local, sdata, info, link_id, changed); 1947b7090b4SJohannes Berg if (local->ops->link_info_changed) 1957b7090b4SJohannes Berg local->ops->link_info_changed(&local->hw, &sdata->vif, 196*d8675a63SJohannes Berg info, link_id, changed); 1977b7090b4SJohannes Berg else if (local->ops->bss_info_changed) 1987b7090b4SJohannes Berg local->ops->bss_info_changed(&local->hw, &sdata->vif, 199*d8675a63SJohannes Berg info, changed); 2004efc76bdSJohannes Berg trace_drv_return_void(local); 20124487981SJohannes Berg } 20224487981SJohannes Berg 2033ac64beeSJohannes Berg static inline u64 drv_prepare_multicast(struct ieee80211_local *local, 20422bedad3SJiri Pirko struct netdev_hw_addr_list *mc_list) 20524487981SJohannes Berg { 2063ac64beeSJohannes Berg u64 ret = 0; 2073ac64beeSJohannes Berg 2084efc76bdSJohannes Berg trace_drv_prepare_multicast(local, mc_list->count); 2094efc76bdSJohannes Berg 2103ac64beeSJohannes Berg if (local->ops->prepare_multicast) 21122bedad3SJiri Pirko ret = local->ops->prepare_multicast(&local->hw, mc_list); 2123ac64beeSJohannes Berg 2134efc76bdSJohannes Berg trace_drv_return_u64(local, ret); 2143ac64beeSJohannes Berg 2153ac64beeSJohannes Berg return ret; 2163ac64beeSJohannes Berg } 2173ac64beeSJohannes Berg 2183ac64beeSJohannes Berg static inline void drv_configure_filter(struct ieee80211_local *local, 2193ac64beeSJohannes Berg unsigned int changed_flags, 2203ac64beeSJohannes Berg unsigned int *total_flags, 2213ac64beeSJohannes Berg u64 multicast) 2223ac64beeSJohannes Berg { 2233ac64beeSJohannes Berg might_sleep(); 2243ac64beeSJohannes Berg 2250a2b8bb2SJohannes Berg trace_drv_configure_filter(local, changed_flags, total_flags, 2263ac64beeSJohannes Berg multicast); 2274efc76bdSJohannes Berg local->ops->configure_filter(&local->hw, changed_flags, total_flags, 2284efc76bdSJohannes Berg multicast); 2294efc76bdSJohannes Berg trace_drv_return_void(local); 23024487981SJohannes Berg } 23124487981SJohannes Berg 2321b09b556SAndrei Otcheretianski static inline void drv_config_iface_filter(struct ieee80211_local *local, 2331b09b556SAndrei Otcheretianski struct ieee80211_sub_if_data *sdata, 2341b09b556SAndrei Otcheretianski unsigned int filter_flags, 2351b09b556SAndrei Otcheretianski unsigned int changed_flags) 2361b09b556SAndrei Otcheretianski { 2371b09b556SAndrei Otcheretianski might_sleep(); 2381b09b556SAndrei Otcheretianski 2391b09b556SAndrei Otcheretianski trace_drv_config_iface_filter(local, sdata, filter_flags, 2401b09b556SAndrei Otcheretianski changed_flags); 2411b09b556SAndrei Otcheretianski if (local->ops->config_iface_filter) 2421b09b556SAndrei Otcheretianski local->ops->config_iface_filter(&local->hw, &sdata->vif, 2431b09b556SAndrei Otcheretianski filter_flags, 2441b09b556SAndrei Otcheretianski changed_flags); 2451b09b556SAndrei Otcheretianski trace_drv_return_void(local); 2461b09b556SAndrei Otcheretianski } 2471b09b556SAndrei Otcheretianski 24824487981SJohannes Berg static inline int drv_set_tim(struct ieee80211_local *local, 24924487981SJohannes Berg struct ieee80211_sta *sta, bool set) 25024487981SJohannes Berg { 2510a2b8bb2SJohannes Berg int ret = 0; 2524efc76bdSJohannes Berg trace_drv_set_tim(local, sta, set); 25324487981SJohannes Berg if (local->ops->set_tim) 2540a2b8bb2SJohannes Berg ret = local->ops->set_tim(&local->hw, sta, set); 2554efc76bdSJohannes Berg trace_drv_return_int(local, ret); 2560a2b8bb2SJohannes Berg return ret; 25724487981SJohannes Berg } 25824487981SJohannes Berg 25924487981SJohannes Berg static inline int drv_set_key(struct ieee80211_local *local, 26012375ef9SJohannes Berg enum set_key_cmd cmd, 26112375ef9SJohannes Berg struct ieee80211_sub_if_data *sdata, 26224487981SJohannes Berg struct ieee80211_sta *sta, 26324487981SJohannes Berg struct ieee80211_key_conf *key) 26424487981SJohannes Berg { 265e1781ed3SKalle Valo int ret; 266e1781ed3SKalle Valo 267e1781ed3SKalle Valo might_sleep(); 268e1781ed3SKalle Valo 269077f4939SJohannes Berg sdata = get_bss_sdata(sdata); 270f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 271f6837ba8SJohannes Berg return -EIO; 2727b7eab6fSJohannes Berg 2734efc76bdSJohannes Berg trace_drv_set_key(local, cmd, sdata, sta, key); 274e1781ed3SKalle Valo ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key); 2754efc76bdSJohannes Berg trace_drv_return_int(local, ret); 2760a2b8bb2SJohannes Berg return ret; 27724487981SJohannes Berg } 27824487981SJohannes Berg 27924487981SJohannes Berg static inline void drv_update_tkip_key(struct ieee80211_local *local, 280b3fbdcf4SJohannes Berg struct ieee80211_sub_if_data *sdata, 28124487981SJohannes Berg struct ieee80211_key_conf *conf, 282b3fbdcf4SJohannes Berg struct sta_info *sta, u32 iv32, 28324487981SJohannes Berg u16 *phase1key) 28424487981SJohannes Berg { 285b3fbdcf4SJohannes Berg struct ieee80211_sta *ista = NULL; 286b3fbdcf4SJohannes Berg 287b3fbdcf4SJohannes Berg if (sta) 288b3fbdcf4SJohannes Berg ista = &sta->sta; 289b3fbdcf4SJohannes Berg 290077f4939SJohannes Berg sdata = get_bss_sdata(sdata); 291f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 292f6837ba8SJohannes Berg return; 2937b7eab6fSJohannes Berg 2944efc76bdSJohannes Berg trace_drv_update_tkip_key(local, sdata, conf, ista, iv32); 29524487981SJohannes Berg if (local->ops->update_tkip_key) 296b3fbdcf4SJohannes Berg local->ops->update_tkip_key(&local->hw, &sdata->vif, conf, 297b3fbdcf4SJohannes Berg ista, iv32, phase1key); 2984efc76bdSJohannes Berg trace_drv_return_void(local); 29924487981SJohannes Berg } 30024487981SJohannes Berg 30124487981SJohannes Berg static inline int drv_hw_scan(struct ieee80211_local *local, 302a060bbfeSJohannes Berg struct ieee80211_sub_if_data *sdata, 303c56ef672SDavid Spinadel struct ieee80211_scan_request *req) 30424487981SJohannes Berg { 305e1781ed3SKalle Valo int ret; 306e1781ed3SKalle Valo 307e1781ed3SKalle Valo might_sleep(); 308e1781ed3SKalle Valo 309f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 310f6837ba8SJohannes Berg return -EIO; 3117b7eab6fSJohannes Berg 31279f460caSLuciano Coelho trace_drv_hw_scan(local, sdata); 313a060bbfeSJohannes Berg ret = local->ops->hw_scan(&local->hw, &sdata->vif, req); 3144efc76bdSJohannes Berg trace_drv_return_int(local, ret); 3150a2b8bb2SJohannes Berg return ret; 31624487981SJohannes Berg } 31724487981SJohannes Berg 318b856439bSEliad Peller static inline void drv_cancel_hw_scan(struct ieee80211_local *local, 319b856439bSEliad Peller struct ieee80211_sub_if_data *sdata) 320b856439bSEliad Peller { 321b856439bSEliad Peller might_sleep(); 322b856439bSEliad Peller 323f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 324f6837ba8SJohannes Berg return; 3257b7eab6fSJohannes Berg 326b856439bSEliad Peller trace_drv_cancel_hw_scan(local, sdata); 327b856439bSEliad Peller local->ops->cancel_hw_scan(&local->hw, &sdata->vif); 328b856439bSEliad Peller trace_drv_return_void(local); 329b856439bSEliad Peller } 330b856439bSEliad Peller 33179f460caSLuciano Coelho static inline int 33279f460caSLuciano Coelho drv_sched_scan_start(struct ieee80211_local *local, 33379f460caSLuciano Coelho struct ieee80211_sub_if_data *sdata, 33479f460caSLuciano Coelho struct cfg80211_sched_scan_request *req, 335633e2713SDavid Spinadel struct ieee80211_scan_ies *ies) 33679f460caSLuciano Coelho { 33779f460caSLuciano Coelho int ret; 33879f460caSLuciano Coelho 33979f460caSLuciano Coelho might_sleep(); 34079f460caSLuciano Coelho 341f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 342f6837ba8SJohannes Berg return -EIO; 3437b7eab6fSJohannes Berg 34479f460caSLuciano Coelho trace_drv_sched_scan_start(local, sdata); 34579f460caSLuciano Coelho ret = local->ops->sched_scan_start(&local->hw, &sdata->vif, 34679f460caSLuciano Coelho req, ies); 34779f460caSLuciano Coelho trace_drv_return_int(local, ret); 34879f460caSLuciano Coelho return ret; 34979f460caSLuciano Coelho } 35079f460caSLuciano Coelho 35137e3308cSJohannes Berg static inline int drv_sched_scan_stop(struct ieee80211_local *local, 35279f460caSLuciano Coelho struct ieee80211_sub_if_data *sdata) 35379f460caSLuciano Coelho { 35437e3308cSJohannes Berg int ret; 35537e3308cSJohannes Berg 35679f460caSLuciano Coelho might_sleep(); 35779f460caSLuciano Coelho 358f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 359f6837ba8SJohannes Berg return -EIO; 3607b7eab6fSJohannes Berg 36179f460caSLuciano Coelho trace_drv_sched_scan_stop(local, sdata); 36237e3308cSJohannes Berg ret = local->ops->sched_scan_stop(&local->hw, &sdata->vif); 36337e3308cSJohannes Berg trace_drv_return_int(local, ret); 36437e3308cSJohannes Berg 36537e3308cSJohannes Berg return ret; 36679f460caSLuciano Coelho } 36779f460caSLuciano Coelho 368a344d677SJohannes Berg static inline void drv_sw_scan_start(struct ieee80211_local *local, 369a344d677SJohannes Berg struct ieee80211_sub_if_data *sdata, 370a344d677SJohannes Berg const u8 *mac_addr) 37124487981SJohannes Berg { 372e1781ed3SKalle Valo might_sleep(); 373e1781ed3SKalle Valo 374a344d677SJohannes Berg trace_drv_sw_scan_start(local, sdata, mac_addr); 37524487981SJohannes Berg if (local->ops->sw_scan_start) 376a344d677SJohannes Berg local->ops->sw_scan_start(&local->hw, &sdata->vif, mac_addr); 3774efc76bdSJohannes Berg trace_drv_return_void(local); 37824487981SJohannes Berg } 37924487981SJohannes Berg 380a344d677SJohannes Berg static inline void drv_sw_scan_complete(struct ieee80211_local *local, 381a344d677SJohannes Berg struct ieee80211_sub_if_data *sdata) 38224487981SJohannes Berg { 383e1781ed3SKalle Valo might_sleep(); 384e1781ed3SKalle Valo 385a344d677SJohannes Berg trace_drv_sw_scan_complete(local, sdata); 38624487981SJohannes Berg if (local->ops->sw_scan_complete) 387a344d677SJohannes Berg local->ops->sw_scan_complete(&local->hw, &sdata->vif); 3884efc76bdSJohannes Berg trace_drv_return_void(local); 38924487981SJohannes Berg } 39024487981SJohannes Berg 39124487981SJohannes Berg static inline int drv_get_stats(struct ieee80211_local *local, 39224487981SJohannes Berg struct ieee80211_low_level_stats *stats) 39324487981SJohannes Berg { 3940a2b8bb2SJohannes Berg int ret = -EOPNOTSUPP; 3950a2b8bb2SJohannes Berg 396e1781ed3SKalle Valo might_sleep(); 397e1781ed3SKalle Valo 3980a2b8bb2SJohannes Berg if (local->ops->get_stats) 3990a2b8bb2SJohannes Berg ret = local->ops->get_stats(&local->hw, stats); 4000a2b8bb2SJohannes Berg trace_drv_get_stats(local, stats, ret); 4010a2b8bb2SJohannes Berg 4020a2b8bb2SJohannes Berg return ret; 40324487981SJohannes Berg } 40424487981SJohannes Berg 4059352c19fSJohannes Berg static inline void drv_get_key_seq(struct ieee80211_local *local, 4069352c19fSJohannes Berg struct ieee80211_key *key, 4079352c19fSJohannes Berg struct ieee80211_key_seq *seq) 40824487981SJohannes Berg { 4099352c19fSJohannes Berg if (local->ops->get_key_seq) 4109352c19fSJohannes Berg local->ops->get_key_seq(&local->hw, &key->conf, seq); 4119352c19fSJohannes Berg trace_drv_get_key_seq(local, &key->conf); 41224487981SJohannes Berg } 41324487981SJohannes Berg 414f23a4780SArik Nemtsov static inline int drv_set_frag_threshold(struct ieee80211_local *local, 415f23a4780SArik Nemtsov u32 value) 416f23a4780SArik Nemtsov { 417f23a4780SArik Nemtsov int ret = 0; 418f23a4780SArik Nemtsov 419f23a4780SArik Nemtsov might_sleep(); 420f23a4780SArik Nemtsov 421f23a4780SArik Nemtsov trace_drv_set_frag_threshold(local, value); 422f23a4780SArik Nemtsov if (local->ops->set_frag_threshold) 423f23a4780SArik Nemtsov ret = local->ops->set_frag_threshold(&local->hw, value); 424f23a4780SArik Nemtsov trace_drv_return_int(local, ret); 425f23a4780SArik Nemtsov return ret; 426f23a4780SArik Nemtsov } 427f23a4780SArik Nemtsov 42824487981SJohannes Berg static inline int drv_set_rts_threshold(struct ieee80211_local *local, 42924487981SJohannes Berg u32 value) 43024487981SJohannes Berg { 4310a2b8bb2SJohannes Berg int ret = 0; 432e1781ed3SKalle Valo 433e1781ed3SKalle Valo might_sleep(); 434e1781ed3SKalle Valo 4354efc76bdSJohannes Berg trace_drv_set_rts_threshold(local, value); 43624487981SJohannes Berg if (local->ops->set_rts_threshold) 4370a2b8bb2SJohannes Berg ret = local->ops->set_rts_threshold(&local->hw, value); 4384efc76bdSJohannes Berg trace_drv_return_int(local, ret); 4390a2b8bb2SJohannes Berg return ret; 44024487981SJohannes Berg } 44124487981SJohannes Berg 442310bc676SLukáš Turek static inline int drv_set_coverage_class(struct ieee80211_local *local, 443a4bcaf55SLorenzo Bianconi s16 value) 444310bc676SLukáš Turek { 445310bc676SLukáš Turek int ret = 0; 446310bc676SLukáš Turek might_sleep(); 447310bc676SLukáš Turek 4484efc76bdSJohannes Berg trace_drv_set_coverage_class(local, value); 449310bc676SLukáš Turek if (local->ops->set_coverage_class) 450310bc676SLukáš Turek local->ops->set_coverage_class(&local->hw, value); 451310bc676SLukáš Turek else 452310bc676SLukáš Turek ret = -EOPNOTSUPP; 453310bc676SLukáš Turek 4544efc76bdSJohannes Berg trace_drv_return_int(local, ret); 455310bc676SLukáš Turek return ret; 456310bc676SLukáš Turek } 457310bc676SLukáš Turek 45824487981SJohannes Berg static inline void drv_sta_notify(struct ieee80211_local *local, 45912375ef9SJohannes Berg struct ieee80211_sub_if_data *sdata, 46024487981SJohannes Berg enum sta_notify_cmd cmd, 46124487981SJohannes Berg struct ieee80211_sta *sta) 46224487981SJohannes Berg { 463bc192f89SFelix Fietkau sdata = get_bss_sdata(sdata); 464f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 465f6837ba8SJohannes Berg return; 4667b7eab6fSJohannes Berg 4674efc76bdSJohannes Berg trace_drv_sta_notify(local, sdata, cmd, sta); 46824487981SJohannes Berg if (local->ops->sta_notify) 46912375ef9SJohannes Berg local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta); 4704efc76bdSJohannes Berg trace_drv_return_void(local); 47124487981SJohannes Berg } 47224487981SJohannes Berg 47334e89507SJohannes Berg static inline int drv_sta_add(struct ieee80211_local *local, 47434e89507SJohannes Berg struct ieee80211_sub_if_data *sdata, 47534e89507SJohannes Berg struct ieee80211_sta *sta) 47634e89507SJohannes Berg { 47734e89507SJohannes Berg int ret = 0; 47834e89507SJohannes Berg 47934e89507SJohannes Berg might_sleep(); 48034e89507SJohannes Berg 481bc192f89SFelix Fietkau sdata = get_bss_sdata(sdata); 482f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 483f6837ba8SJohannes Berg return -EIO; 4847b7eab6fSJohannes Berg 4854efc76bdSJohannes Berg trace_drv_sta_add(local, sdata, sta); 48634e89507SJohannes Berg if (local->ops->sta_add) 48734e89507SJohannes Berg ret = local->ops->sta_add(&local->hw, &sdata->vif, sta); 48834e89507SJohannes Berg 4894efc76bdSJohannes Berg trace_drv_return_int(local, ret); 49034e89507SJohannes Berg 49134e89507SJohannes Berg return ret; 49234e89507SJohannes Berg } 49334e89507SJohannes Berg 49434e89507SJohannes Berg static inline void drv_sta_remove(struct ieee80211_local *local, 49534e89507SJohannes Berg struct ieee80211_sub_if_data *sdata, 49634e89507SJohannes Berg struct ieee80211_sta *sta) 49734e89507SJohannes Berg { 49834e89507SJohannes Berg might_sleep(); 49934e89507SJohannes Berg 500bc192f89SFelix Fietkau sdata = get_bss_sdata(sdata); 501f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 502f6837ba8SJohannes Berg return; 5037b7eab6fSJohannes Berg 5044efc76bdSJohannes Berg trace_drv_sta_remove(local, sdata, sta); 50534e89507SJohannes Berg if (local->ops->sta_remove) 50634e89507SJohannes Berg local->ops->sta_remove(&local->hw, &sdata->vif, sta); 50734e89507SJohannes Berg 5084efc76bdSJohannes Berg trace_drv_return_void(local); 50934e89507SJohannes Berg } 51034e89507SJohannes Berg 51177d2ece6SSujith Manoharan #ifdef CONFIG_MAC80211_DEBUGFS 51277d2ece6SSujith Manoharan static inline void drv_sta_add_debugfs(struct ieee80211_local *local, 51377d2ece6SSujith Manoharan struct ieee80211_sub_if_data *sdata, 51477d2ece6SSujith Manoharan struct ieee80211_sta *sta, 51577d2ece6SSujith Manoharan struct dentry *dir) 51677d2ece6SSujith Manoharan { 51777d2ece6SSujith Manoharan might_sleep(); 51877d2ece6SSujith Manoharan 51977d2ece6SSujith Manoharan sdata = get_bss_sdata(sdata); 520f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 521f6837ba8SJohannes Berg return; 52277d2ece6SSujith Manoharan 52377d2ece6SSujith Manoharan if (local->ops->sta_add_debugfs) 52477d2ece6SSujith Manoharan local->ops->sta_add_debugfs(&local->hw, &sdata->vif, 52577d2ece6SSujith Manoharan sta, dir); 52677d2ece6SSujith Manoharan } 52777d2ece6SSujith Manoharan #endif 52877d2ece6SSujith Manoharan 5296a9d1b91SJohannes Berg static inline void drv_sta_pre_rcu_remove(struct ieee80211_local *local, 5306a9d1b91SJohannes Berg struct ieee80211_sub_if_data *sdata, 5316a9d1b91SJohannes Berg struct sta_info *sta) 5326a9d1b91SJohannes Berg { 5336a9d1b91SJohannes Berg might_sleep(); 5346a9d1b91SJohannes Berg 5356a9d1b91SJohannes Berg sdata = get_bss_sdata(sdata); 536f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 537f6837ba8SJohannes Berg return; 5386a9d1b91SJohannes Berg 5396a9d1b91SJohannes Berg trace_drv_sta_pre_rcu_remove(local, sdata, &sta->sta); 5406a9d1b91SJohannes Berg if (local->ops->sta_pre_rcu_remove) 5416a9d1b91SJohannes Berg local->ops->sta_pre_rcu_remove(&local->hw, &sdata->vif, 5426a9d1b91SJohannes Berg &sta->sta); 5436a9d1b91SJohannes Berg trace_drv_return_void(local); 5446a9d1b91SJohannes Berg } 5456a9d1b91SJohannes Berg 546727da60bSDenys Vlasenko __must_check 547f09603a2SJohannes Berg int drv_sta_state(struct ieee80211_local *local, 548f09603a2SJohannes Berg struct ieee80211_sub_if_data *sdata, 549f09603a2SJohannes Berg struct sta_info *sta, 550f09603a2SJohannes Berg enum ieee80211_sta_state old_state, 551727da60bSDenys Vlasenko enum ieee80211_sta_state new_state); 552f09603a2SJohannes Berg 553ba905bf4SAshok Raj Nagarajan __must_check 554ba905bf4SAshok Raj Nagarajan int drv_sta_set_txpwr(struct ieee80211_local *local, 555ba905bf4SAshok Raj Nagarajan struct ieee80211_sub_if_data *sdata, 556ba905bf4SAshok Raj Nagarajan struct sta_info *sta); 557ba905bf4SAshok Raj Nagarajan 5584fbd572cSDenys Vlasenko void drv_sta_rc_update(struct ieee80211_local *local, 5598f727ef3SJohannes Berg struct ieee80211_sub_if_data *sdata, 5604fbd572cSDenys Vlasenko struct ieee80211_sta *sta, u32 changed); 5618f727ef3SJohannes Berg 562f815e2b3SJohannes Berg static inline void drv_sta_rate_tbl_update(struct ieee80211_local *local, 563f815e2b3SJohannes Berg struct ieee80211_sub_if_data *sdata, 564f815e2b3SJohannes Berg struct ieee80211_sta *sta) 565f815e2b3SJohannes Berg { 566f815e2b3SJohannes Berg sdata = get_bss_sdata(sdata); 567f815e2b3SJohannes Berg if (!check_sdata_in_driver(sdata)) 568f815e2b3SJohannes Berg return; 569f815e2b3SJohannes Berg 570f815e2b3SJohannes Berg trace_drv_sta_rate_tbl_update(local, sdata, sta); 571f815e2b3SJohannes Berg if (local->ops->sta_rate_tbl_update) 572f815e2b3SJohannes Berg local->ops->sta_rate_tbl_update(&local->hw, &sdata->vif, sta); 573f815e2b3SJohannes Berg 574f815e2b3SJohannes Berg trace_drv_return_void(local); 575f815e2b3SJohannes Berg } 576f815e2b3SJohannes Berg 5772b9a7e1bSJohannes Berg static inline void drv_sta_statistics(struct ieee80211_local *local, 5782b9a7e1bSJohannes Berg struct ieee80211_sub_if_data *sdata, 5792b9a7e1bSJohannes Berg struct ieee80211_sta *sta, 5802b9a7e1bSJohannes Berg struct station_info *sinfo) 5812b9a7e1bSJohannes Berg { 5822b9a7e1bSJohannes Berg sdata = get_bss_sdata(sdata); 5832b9a7e1bSJohannes Berg if (!check_sdata_in_driver(sdata)) 5842b9a7e1bSJohannes Berg return; 5852b9a7e1bSJohannes Berg 5862b9a7e1bSJohannes Berg trace_drv_sta_statistics(local, sdata, sta); 5872b9a7e1bSJohannes Berg if (local->ops->sta_statistics) 5882b9a7e1bSJohannes Berg local->ops->sta_statistics(&local->hw, &sdata->vif, sta, sinfo); 5892b9a7e1bSJohannes Berg trace_drv_return_void(local); 5902b9a7e1bSJohannes Berg } 5912b9a7e1bSJohannes Berg 592b23dcd4aSDenys Vlasenko int drv_conf_tx(struct ieee80211_local *local, 593a3304b0aSJohannes Berg struct ieee80211_sub_if_data *sdata, u16 ac, 594b23dcd4aSDenys Vlasenko const struct ieee80211_tx_queue_params *params); 59524487981SJohannes Berg 596416eb9fcSDenys Vlasenko u64 drv_get_tsf(struct ieee80211_local *local, 597416eb9fcSDenys Vlasenko struct ieee80211_sub_if_data *sdata); 598416eb9fcSDenys Vlasenko void drv_set_tsf(struct ieee80211_local *local, 59937a41b4aSEliad Peller struct ieee80211_sub_if_data *sdata, 600416eb9fcSDenys Vlasenko u64 tsf); 601354d381bSPedersen, Thomas void drv_offset_tsf(struct ieee80211_local *local, 602354d381bSPedersen, Thomas struct ieee80211_sub_if_data *sdata, 603354d381bSPedersen, Thomas s64 offset); 604416eb9fcSDenys Vlasenko void drv_reset_tsf(struct ieee80211_local *local, 605416eb9fcSDenys Vlasenko struct ieee80211_sub_if_data *sdata); 60624487981SJohannes Berg 60724487981SJohannes Berg static inline int drv_tx_last_beacon(struct ieee80211_local *local) 60824487981SJohannes Berg { 60902582e9bSMasanari Iida int ret = 0; /* default unsupported op for less congestion */ 610e1781ed3SKalle Valo 611e1781ed3SKalle Valo might_sleep(); 612e1781ed3SKalle Valo 6134efc76bdSJohannes Berg trace_drv_tx_last_beacon(local); 61424487981SJohannes Berg if (local->ops->tx_last_beacon) 6150a2b8bb2SJohannes Berg ret = local->ops->tx_last_beacon(&local->hw); 6164efc76bdSJohannes Berg trace_drv_return_int(local, ret); 6170a2b8bb2SJohannes Berg return ret; 61824487981SJohannes Berg } 61924487981SJohannes Berg 6206db96838SDenys Vlasenko int drv_ampdu_action(struct ieee80211_local *local, 62112375ef9SJohannes Berg struct ieee80211_sub_if_data *sdata, 62250ea05efSSara Sharon struct ieee80211_ampdu_params *params); 6231f87f7d3SJohannes Berg 6241289723eSHolger Schurig static inline int drv_get_survey(struct ieee80211_local *local, int idx, 6251289723eSHolger Schurig struct survey_info *survey) 6261289723eSHolger Schurig { 6271289723eSHolger Schurig int ret = -EOPNOTSUPP; 628c466d4efSJohn W. Linville 629c466d4efSJohn W. Linville trace_drv_get_survey(local, idx, survey); 630c466d4efSJohn W. Linville 63135dd0509SHolger Schurig if (local->ops->get_survey) 6321289723eSHolger Schurig ret = local->ops->get_survey(&local->hw, idx, survey); 633c466d4efSJohn W. Linville 634c466d4efSJohn W. Linville trace_drv_return_int(local, ret); 635c466d4efSJohn W. Linville 6361289723eSHolger Schurig return ret; 6371289723eSHolger Schurig } 6381f87f7d3SJohannes Berg 6391f87f7d3SJohannes Berg static inline void drv_rfkill_poll(struct ieee80211_local *local) 6401f87f7d3SJohannes Berg { 641e1781ed3SKalle Valo might_sleep(); 642e1781ed3SKalle Valo 6431f87f7d3SJohannes Berg if (local->ops->rfkill_poll) 6441f87f7d3SJohannes Berg local->ops->rfkill_poll(&local->hw); 6451f87f7d3SJohannes Berg } 646a80f7c0bSJohannes Berg 64739ecc01dSJohannes Berg static inline void drv_flush(struct ieee80211_local *local, 64877be2c54SEmmanuel Grumbach struct ieee80211_sub_if_data *sdata, 64939ecc01dSJohannes Berg u32 queues, bool drop) 650a80f7c0bSJohannes Berg { 65177be2c54SEmmanuel Grumbach struct ieee80211_vif *vif = sdata ? &sdata->vif : NULL; 65277be2c54SEmmanuel Grumbach 653e1781ed3SKalle Valo might_sleep(); 654e1781ed3SKalle Valo 655f6837ba8SJohannes Berg if (sdata && !check_sdata_in_driver(sdata)) 656f6837ba8SJohannes Berg return; 65777be2c54SEmmanuel Grumbach 65839ecc01dSJohannes Berg trace_drv_flush(local, queues, drop); 659a80f7c0bSJohannes Berg if (local->ops->flush) 66077be2c54SEmmanuel Grumbach local->ops->flush(&local->hw, vif, queues, drop); 6614efc76bdSJohannes Berg trace_drv_return_void(local); 662a80f7c0bSJohannes Berg } 6635ce6e438SJohannes Berg 6645ce6e438SJohannes Berg static inline void drv_channel_switch(struct ieee80211_local *local, 6650f791eb4SLuciano Coelho struct ieee80211_sub_if_data *sdata, 6665ce6e438SJohannes Berg struct ieee80211_channel_switch *ch_switch) 6675ce6e438SJohannes Berg { 6685ce6e438SJohannes Berg might_sleep(); 6695ce6e438SJohannes Berg 6700f791eb4SLuciano Coelho trace_drv_channel_switch(local, sdata, ch_switch); 6710f791eb4SLuciano Coelho local->ops->channel_switch(&local->hw, &sdata->vif, ch_switch); 6724efc76bdSJohannes Berg trace_drv_return_void(local); 6735ce6e438SJohannes Berg } 6745ce6e438SJohannes Berg 67515d96753SBruno Randolf 67615d96753SBruno Randolf static inline int drv_set_antenna(struct ieee80211_local *local, 67715d96753SBruno Randolf u32 tx_ant, u32 rx_ant) 67815d96753SBruno Randolf { 67915d96753SBruno Randolf int ret = -EOPNOTSUPP; 68015d96753SBruno Randolf might_sleep(); 68115d96753SBruno Randolf if (local->ops->set_antenna) 68215d96753SBruno Randolf ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant); 68315d96753SBruno Randolf trace_drv_set_antenna(local, tx_ant, rx_ant, ret); 68415d96753SBruno Randolf return ret; 68515d96753SBruno Randolf } 68615d96753SBruno Randolf 68715d96753SBruno Randolf static inline int drv_get_antenna(struct ieee80211_local *local, 68815d96753SBruno Randolf u32 *tx_ant, u32 *rx_ant) 68915d96753SBruno Randolf { 69015d96753SBruno Randolf int ret = -EOPNOTSUPP; 69115d96753SBruno Randolf might_sleep(); 69215d96753SBruno Randolf if (local->ops->get_antenna) 69315d96753SBruno Randolf ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant); 69415d96753SBruno Randolf trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret); 69515d96753SBruno Randolf return ret; 69615d96753SBruno Randolf } 69715d96753SBruno Randolf 69821f83589SJohannes Berg static inline int drv_remain_on_channel(struct ieee80211_local *local, 69949884568SEliad Peller struct ieee80211_sub_if_data *sdata, 70021f83589SJohannes Berg struct ieee80211_channel *chan, 701d339d5caSIlan Peer unsigned int duration, 702d339d5caSIlan Peer enum ieee80211_roc_type type) 70321f83589SJohannes Berg { 70421f83589SJohannes Berg int ret; 70521f83589SJohannes Berg 70621f83589SJohannes Berg might_sleep(); 70721f83589SJohannes Berg 708d339d5caSIlan Peer trace_drv_remain_on_channel(local, sdata, chan, duration, type); 70949884568SEliad Peller ret = local->ops->remain_on_channel(&local->hw, &sdata->vif, 710d339d5caSIlan Peer chan, duration, type); 71121f83589SJohannes Berg trace_drv_return_int(local, ret); 71221f83589SJohannes Berg 71321f83589SJohannes Berg return ret; 71421f83589SJohannes Berg } 71521f83589SJohannes Berg 7165db4c4b9SEmmanuel Grumbach static inline int 7175db4c4b9SEmmanuel Grumbach drv_cancel_remain_on_channel(struct ieee80211_local *local, 7185db4c4b9SEmmanuel Grumbach struct ieee80211_sub_if_data *sdata) 71921f83589SJohannes Berg { 72021f83589SJohannes Berg int ret; 72121f83589SJohannes Berg 72221f83589SJohannes Berg might_sleep(); 72321f83589SJohannes Berg 7245db4c4b9SEmmanuel Grumbach trace_drv_cancel_remain_on_channel(local, sdata); 7255db4c4b9SEmmanuel Grumbach ret = local->ops->cancel_remain_on_channel(&local->hw, &sdata->vif); 72621f83589SJohannes Berg trace_drv_return_int(local, ret); 72721f83589SJohannes Berg 72821f83589SJohannes Berg return ret; 72921f83589SJohannes Berg } 73021f83589SJohannes Berg 73138c09159SJohn W. Linville static inline int drv_set_ringparam(struct ieee80211_local *local, 73238c09159SJohn W. Linville u32 tx, u32 rx) 73338c09159SJohn W. Linville { 73438c09159SJohn W. Linville int ret = -ENOTSUPP; 73538c09159SJohn W. Linville 73638c09159SJohn W. Linville might_sleep(); 73738c09159SJohn W. Linville 73838c09159SJohn W. Linville trace_drv_set_ringparam(local, tx, rx); 73938c09159SJohn W. Linville if (local->ops->set_ringparam) 74038c09159SJohn W. Linville ret = local->ops->set_ringparam(&local->hw, tx, rx); 74138c09159SJohn W. Linville trace_drv_return_int(local, ret); 74238c09159SJohn W. Linville 74338c09159SJohn W. Linville return ret; 74438c09159SJohn W. Linville } 74538c09159SJohn W. Linville 74638c09159SJohn W. Linville static inline void drv_get_ringparam(struct ieee80211_local *local, 74738c09159SJohn W. Linville u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max) 74838c09159SJohn W. Linville { 74938c09159SJohn W. Linville might_sleep(); 75038c09159SJohn W. Linville 75138c09159SJohn W. Linville trace_drv_get_ringparam(local, tx, tx_max, rx, rx_max); 75238c09159SJohn W. Linville if (local->ops->get_ringparam) 75338c09159SJohn W. Linville local->ops->get_ringparam(&local->hw, tx, tx_max, rx, rx_max); 75438c09159SJohn W. Linville trace_drv_return_void(local); 75538c09159SJohn W. Linville } 75638c09159SJohn W. Linville 757e8306f98SVivek Natarajan static inline bool drv_tx_frames_pending(struct ieee80211_local *local) 758e8306f98SVivek Natarajan { 759e8306f98SVivek Natarajan bool ret = false; 760e8306f98SVivek Natarajan 761e8306f98SVivek Natarajan might_sleep(); 762e8306f98SVivek Natarajan 763e8306f98SVivek Natarajan trace_drv_tx_frames_pending(local); 764e8306f98SVivek Natarajan if (local->ops->tx_frames_pending) 765e8306f98SVivek Natarajan ret = local->ops->tx_frames_pending(&local->hw); 766e8306f98SVivek Natarajan trace_drv_return_bool(local, ret); 767e8306f98SVivek Natarajan 768e8306f98SVivek Natarajan return ret; 769e8306f98SVivek Natarajan } 770bdbfd6b5SSujith Manoharan 771bdbfd6b5SSujith Manoharan static inline int drv_set_bitrate_mask(struct ieee80211_local *local, 772bdbfd6b5SSujith Manoharan struct ieee80211_sub_if_data *sdata, 773bdbfd6b5SSujith Manoharan const struct cfg80211_bitrate_mask *mask) 774bdbfd6b5SSujith Manoharan { 775bdbfd6b5SSujith Manoharan int ret = -EOPNOTSUPP; 776bdbfd6b5SSujith Manoharan 777bdbfd6b5SSujith Manoharan might_sleep(); 778bdbfd6b5SSujith Manoharan 779f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 780f6837ba8SJohannes Berg return -EIO; 7817b7eab6fSJohannes Berg 782bdbfd6b5SSujith Manoharan trace_drv_set_bitrate_mask(local, sdata, mask); 783bdbfd6b5SSujith Manoharan if (local->ops->set_bitrate_mask) 784bdbfd6b5SSujith Manoharan ret = local->ops->set_bitrate_mask(&local->hw, 785bdbfd6b5SSujith Manoharan &sdata->vif, mask); 786bdbfd6b5SSujith Manoharan trace_drv_return_int(local, ret); 787bdbfd6b5SSujith Manoharan 788bdbfd6b5SSujith Manoharan return ret; 789bdbfd6b5SSujith Manoharan } 790bdbfd6b5SSujith Manoharan 791c68f4b89SJohannes Berg static inline void drv_set_rekey_data(struct ieee80211_local *local, 792c68f4b89SJohannes Berg struct ieee80211_sub_if_data *sdata, 793c68f4b89SJohannes Berg struct cfg80211_gtk_rekey_data *data) 794c68f4b89SJohannes Berg { 795f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 796f6837ba8SJohannes Berg return; 7977b7eab6fSJohannes Berg 798c68f4b89SJohannes Berg trace_drv_set_rekey_data(local, sdata, data); 799c68f4b89SJohannes Berg if (local->ops->set_rekey_data) 800c68f4b89SJohannes Berg local->ops->set_rekey_data(&local->hw, &sdata->vif, data); 801c68f4b89SJohannes Berg trace_drv_return_void(local); 802c68f4b89SJohannes Berg } 803c68f4b89SJohannes Berg 804a8182929SEmmanuel Grumbach static inline void drv_event_callback(struct ieee80211_local *local, 805887da917SEmmanuel Grumbach struct ieee80211_sub_if_data *sdata, 806a8182929SEmmanuel Grumbach const struct ieee80211_event *event) 807615f7b9bSMeenakshi Venkataraman { 808a8182929SEmmanuel Grumbach trace_drv_event_callback(local, sdata, event); 809a8182929SEmmanuel Grumbach if (local->ops->event_callback) 810a8182929SEmmanuel Grumbach local->ops->event_callback(&local->hw, &sdata->vif, event); 811615f7b9bSMeenakshi Venkataraman trace_drv_return_void(local); 812615f7b9bSMeenakshi Venkataraman } 8134049e09aSJohannes Berg 8144049e09aSJohannes Berg static inline void 8154049e09aSJohannes Berg drv_release_buffered_frames(struct ieee80211_local *local, 8164049e09aSJohannes Berg struct sta_info *sta, u16 tids, int num_frames, 8174049e09aSJohannes Berg enum ieee80211_frame_release_type reason, 8184049e09aSJohannes Berg bool more_data) 8194049e09aSJohannes Berg { 8204049e09aSJohannes Berg trace_drv_release_buffered_frames(local, &sta->sta, tids, num_frames, 8214049e09aSJohannes Berg reason, more_data); 8224049e09aSJohannes Berg if (local->ops->release_buffered_frames) 8234049e09aSJohannes Berg local->ops->release_buffered_frames(&local->hw, &sta->sta, tids, 8244049e09aSJohannes Berg num_frames, reason, 8254049e09aSJohannes Berg more_data); 8264049e09aSJohannes Berg trace_drv_return_void(local); 8274049e09aSJohannes Berg } 82840b96408SJohannes Berg 82940b96408SJohannes Berg static inline void 83040b96408SJohannes Berg drv_allow_buffered_frames(struct ieee80211_local *local, 83140b96408SJohannes Berg struct sta_info *sta, u16 tids, int num_frames, 83240b96408SJohannes Berg enum ieee80211_frame_release_type reason, 83340b96408SJohannes Berg bool more_data) 83440b96408SJohannes Berg { 83540b96408SJohannes Berg trace_drv_allow_buffered_frames(local, &sta->sta, tids, num_frames, 83640b96408SJohannes Berg reason, more_data); 83740b96408SJohannes Berg if (local->ops->allow_buffered_frames) 83840b96408SJohannes Berg local->ops->allow_buffered_frames(&local->hw, &sta->sta, 83940b96408SJohannes Berg tids, num_frames, reason, 84040b96408SJohannes Berg more_data); 84140b96408SJohannes Berg trace_drv_return_void(local); 84240b96408SJohannes Berg } 84366572cfcSVictor Goldenshtein 844a1845fc7SJohannes Berg static inline void drv_mgd_prepare_tx(struct ieee80211_local *local, 845d4e36e55SIlan Peer struct ieee80211_sub_if_data *sdata, 84615fae341SJohannes Berg struct ieee80211_prep_tx_info *info) 847a1845fc7SJohannes Berg { 848a1845fc7SJohannes Berg might_sleep(); 849a1845fc7SJohannes Berg 850f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 851f6837ba8SJohannes Berg return; 852a1845fc7SJohannes Berg WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION); 853a1845fc7SJohannes Berg 85415fae341SJohannes Berg trace_drv_mgd_prepare_tx(local, sdata, info->duration, 85515fae341SJohannes Berg info->subtype, info->success); 856a1845fc7SJohannes Berg if (local->ops->mgd_prepare_tx) 85715fae341SJohannes Berg local->ops->mgd_prepare_tx(&local->hw, &sdata->vif, info); 85815fae341SJohannes Berg trace_drv_return_void(local); 85915fae341SJohannes Berg } 86015fae341SJohannes Berg 86115fae341SJohannes Berg static inline void drv_mgd_complete_tx(struct ieee80211_local *local, 86215fae341SJohannes Berg struct ieee80211_sub_if_data *sdata, 86315fae341SJohannes Berg struct ieee80211_prep_tx_info *info) 86415fae341SJohannes Berg { 86515fae341SJohannes Berg might_sleep(); 86615fae341SJohannes Berg 86715fae341SJohannes Berg if (!check_sdata_in_driver(sdata)) 86815fae341SJohannes Berg return; 86915fae341SJohannes Berg WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION); 87015fae341SJohannes Berg 87115fae341SJohannes Berg trace_drv_mgd_complete_tx(local, sdata, info->duration, 87215fae341SJohannes Berg info->subtype, info->success); 87315fae341SJohannes Berg if (local->ops->mgd_complete_tx) 87415fae341SJohannes Berg local->ops->mgd_complete_tx(&local->hw, &sdata->vif, info); 875a1845fc7SJohannes Berg trace_drv_return_void(local); 876a1845fc7SJohannes Berg } 877c3645eacSMichal Kazior 878ee10f2c7SArik Nemtsov static inline void 879ee10f2c7SArik Nemtsov drv_mgd_protect_tdls_discover(struct ieee80211_local *local, 880ee10f2c7SArik Nemtsov struct ieee80211_sub_if_data *sdata) 881ee10f2c7SArik Nemtsov { 882ee10f2c7SArik Nemtsov might_sleep(); 883ee10f2c7SArik Nemtsov 884ee10f2c7SArik Nemtsov if (!check_sdata_in_driver(sdata)) 885ee10f2c7SArik Nemtsov return; 886ee10f2c7SArik Nemtsov WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION); 887ee10f2c7SArik Nemtsov 888ee10f2c7SArik Nemtsov trace_drv_mgd_protect_tdls_discover(local, sdata); 889ee10f2c7SArik Nemtsov if (local->ops->mgd_protect_tdls_discover) 890ee10f2c7SArik Nemtsov local->ops->mgd_protect_tdls_discover(&local->hw, &sdata->vif); 891ee10f2c7SArik Nemtsov trace_drv_return_void(local); 892ee10f2c7SArik Nemtsov } 893ee10f2c7SArik Nemtsov 894c3645eacSMichal Kazior static inline int drv_add_chanctx(struct ieee80211_local *local, 895c3645eacSMichal Kazior struct ieee80211_chanctx *ctx) 896c3645eacSMichal Kazior { 897c3645eacSMichal Kazior int ret = -EOPNOTSUPP; 898c3645eacSMichal Kazior 899dcae9e02SChaitanya T K might_sleep(); 900dcae9e02SChaitanya T K 901c3645eacSMichal Kazior trace_drv_add_chanctx(local, ctx); 902c3645eacSMichal Kazior if (local->ops->add_chanctx) 903c3645eacSMichal Kazior ret = local->ops->add_chanctx(&local->hw, &ctx->conf); 904c3645eacSMichal Kazior trace_drv_return_int(local, ret); 9058a61af65SJohannes Berg if (!ret) 9068a61af65SJohannes Berg ctx->driver_present = true; 907c3645eacSMichal Kazior 908c3645eacSMichal Kazior return ret; 909c3645eacSMichal Kazior } 910c3645eacSMichal Kazior 911c3645eacSMichal Kazior static inline void drv_remove_chanctx(struct ieee80211_local *local, 912c3645eacSMichal Kazior struct ieee80211_chanctx *ctx) 913c3645eacSMichal Kazior { 914dcae9e02SChaitanya T K might_sleep(); 915dcae9e02SChaitanya T K 916f6837ba8SJohannes Berg if (WARN_ON(!ctx->driver_present)) 917f6837ba8SJohannes Berg return; 918f6837ba8SJohannes Berg 919c3645eacSMichal Kazior trace_drv_remove_chanctx(local, ctx); 920c3645eacSMichal Kazior if (local->ops->remove_chanctx) 921c3645eacSMichal Kazior local->ops->remove_chanctx(&local->hw, &ctx->conf); 922c3645eacSMichal Kazior trace_drv_return_void(local); 9238a61af65SJohannes Berg ctx->driver_present = false; 924c3645eacSMichal Kazior } 925c3645eacSMichal Kazior 926c3645eacSMichal Kazior static inline void drv_change_chanctx(struct ieee80211_local *local, 927c3645eacSMichal Kazior struct ieee80211_chanctx *ctx, 928c3645eacSMichal Kazior u32 changed) 929c3645eacSMichal Kazior { 930dcae9e02SChaitanya T K might_sleep(); 931dcae9e02SChaitanya T K 932c3645eacSMichal Kazior trace_drv_change_chanctx(local, ctx, changed); 9338a61af65SJohannes Berg if (local->ops->change_chanctx) { 9348a61af65SJohannes Berg WARN_ON_ONCE(!ctx->driver_present); 935c3645eacSMichal Kazior local->ops->change_chanctx(&local->hw, &ctx->conf, changed); 9368a61af65SJohannes Berg } 937c3645eacSMichal Kazior trace_drv_return_void(local); 938c3645eacSMichal Kazior } 939c3645eacSMichal Kazior 940c3645eacSMichal Kazior static inline int drv_assign_vif_chanctx(struct ieee80211_local *local, 941c3645eacSMichal Kazior struct ieee80211_sub_if_data *sdata, 942b4f85443SJohannes Berg unsigned int link_id, 943c3645eacSMichal Kazior struct ieee80211_chanctx *ctx) 944c3645eacSMichal Kazior { 945c3645eacSMichal Kazior int ret = 0; 946c3645eacSMichal Kazior 947f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 948f6837ba8SJohannes Berg return -EIO; 949c3645eacSMichal Kazior 950b4f85443SJohannes Berg trace_drv_assign_vif_chanctx(local, sdata, link_id, ctx); 9518a61af65SJohannes Berg if (local->ops->assign_vif_chanctx) { 9528a61af65SJohannes Berg WARN_ON_ONCE(!ctx->driver_present); 953c3645eacSMichal Kazior ret = local->ops->assign_vif_chanctx(&local->hw, 954c3645eacSMichal Kazior &sdata->vif, 955b4f85443SJohannes Berg link_id, 956c3645eacSMichal Kazior &ctx->conf); 9578a61af65SJohannes Berg } 958c3645eacSMichal Kazior trace_drv_return_int(local, ret); 959c3645eacSMichal Kazior 960c3645eacSMichal Kazior return ret; 961c3645eacSMichal Kazior } 962c3645eacSMichal Kazior 963c3645eacSMichal Kazior static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local, 964c3645eacSMichal Kazior struct ieee80211_sub_if_data *sdata, 965b4f85443SJohannes Berg unsigned int link_id, 966c3645eacSMichal Kazior struct ieee80211_chanctx *ctx) 967c3645eacSMichal Kazior { 968dcae9e02SChaitanya T K might_sleep(); 969dcae9e02SChaitanya T K 970f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 971f6837ba8SJohannes Berg return; 972c3645eacSMichal Kazior 973b4f85443SJohannes Berg trace_drv_unassign_vif_chanctx(local, sdata, link_id, ctx); 9748a61af65SJohannes Berg if (local->ops->unassign_vif_chanctx) { 9758a61af65SJohannes Berg WARN_ON_ONCE(!ctx->driver_present); 976c3645eacSMichal Kazior local->ops->unassign_vif_chanctx(&local->hw, 977c3645eacSMichal Kazior &sdata->vif, 978b4f85443SJohannes Berg link_id, 979c3645eacSMichal Kazior &ctx->conf); 9808a61af65SJohannes Berg } 981c3645eacSMichal Kazior trace_drv_return_void(local); 982c3645eacSMichal Kazior } 983c3645eacSMichal Kazior 98442677ed3SDenys Vlasenko int drv_switch_vif_chanctx(struct ieee80211_local *local, 9851a5f0c13SLuciano Coelho struct ieee80211_vif_chanctx_switch *vifs, 98642677ed3SDenys Vlasenko int n_vifs, enum ieee80211_chanctx_switch_mode mode); 9871a5f0c13SLuciano Coelho 9881041638fSJohannes Berg static inline int drv_start_ap(struct ieee80211_local *local, 989ae7ba17bSShaul Triebitz struct ieee80211_sub_if_data *sdata, 990ae7ba17bSShaul Triebitz unsigned int link_id) 9911041638fSJohannes Berg { 9921041638fSJohannes Berg int ret = 0; 9931041638fSJohannes Berg 994dcae9e02SChaitanya T K might_sleep(); 995dcae9e02SChaitanya T K 996f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 997f6837ba8SJohannes Berg return -EIO; 9981041638fSJohannes Berg 999*d8675a63SJohannes Berg trace_drv_start_ap(local, sdata, link_id); 10001041638fSJohannes Berg if (local->ops->start_ap) 1001ae7ba17bSShaul Triebitz ret = local->ops->start_ap(&local->hw, &sdata->vif, link_id); 10021041638fSJohannes Berg trace_drv_return_int(local, ret); 10031041638fSJohannes Berg return ret; 10041041638fSJohannes Berg } 10051041638fSJohannes Berg 10061041638fSJohannes Berg static inline void drv_stop_ap(struct ieee80211_local *local, 1007ae7ba17bSShaul Triebitz struct ieee80211_sub_if_data *sdata, 1008ae7ba17bSShaul Triebitz unsigned int link_id) 10091041638fSJohannes Berg { 1010f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 1011f6837ba8SJohannes Berg return; 10121041638fSJohannes Berg 1013ae7ba17bSShaul Triebitz trace_drv_stop_ap(local, sdata, link_id); 10141041638fSJohannes Berg if (local->ops->stop_ap) 1015ae7ba17bSShaul Triebitz local->ops->stop_ap(&local->hw, &sdata->vif, link_id); 10161041638fSJohannes Berg trace_drv_return_void(local); 10171041638fSJohannes Berg } 10181041638fSJohannes Berg 1019cf2c92d8SEliad Peller static inline void 1020cf2c92d8SEliad Peller drv_reconfig_complete(struct ieee80211_local *local, 1021cf2c92d8SEliad Peller enum ieee80211_reconfig_type reconfig_type) 10229214ad7fSJohannes Berg { 10239214ad7fSJohannes Berg might_sleep(); 10249214ad7fSJohannes Berg 1025cf2c92d8SEliad Peller trace_drv_reconfig_complete(local, reconfig_type); 1026cf2c92d8SEliad Peller if (local->ops->reconfig_complete) 1027cf2c92d8SEliad Peller local->ops->reconfig_complete(&local->hw, reconfig_type); 10289214ad7fSJohannes Berg trace_drv_return_void(local); 10299214ad7fSJohannes Berg } 10309214ad7fSJohannes Berg 1031de5fad81SYoni Divinsky static inline void 1032de5fad81SYoni Divinsky drv_set_default_unicast_key(struct ieee80211_local *local, 1033de5fad81SYoni Divinsky struct ieee80211_sub_if_data *sdata, 1034de5fad81SYoni Divinsky int key_idx) 1035de5fad81SYoni Divinsky { 1036f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 1037f6837ba8SJohannes Berg return; 1038de5fad81SYoni Divinsky 1039de5fad81SYoni Divinsky WARN_ON_ONCE(key_idx < -1 || key_idx > 3); 1040de5fad81SYoni Divinsky 1041de5fad81SYoni Divinsky trace_drv_set_default_unicast_key(local, sdata, key_idx); 1042de5fad81SYoni Divinsky if (local->ops->set_default_unicast_key) 1043de5fad81SYoni Divinsky local->ops->set_default_unicast_key(&local->hw, &sdata->vif, 1044de5fad81SYoni Divinsky key_idx); 1045de5fad81SYoni Divinsky trace_drv_return_void(local); 1046de5fad81SYoni Divinsky } 1047de5fad81SYoni Divinsky 1048a65240c1SJohannes Berg #if IS_ENABLED(CONFIG_IPV6) 1049a65240c1SJohannes Berg static inline void drv_ipv6_addr_change(struct ieee80211_local *local, 1050a65240c1SJohannes Berg struct ieee80211_sub_if_data *sdata, 1051a65240c1SJohannes Berg struct inet6_dev *idev) 1052a65240c1SJohannes Berg { 1053a65240c1SJohannes Berg trace_drv_ipv6_addr_change(local, sdata); 1054a65240c1SJohannes Berg if (local->ops->ipv6_addr_change) 1055a65240c1SJohannes Berg local->ops->ipv6_addr_change(&local->hw, &sdata->vif, idev); 1056a65240c1SJohannes Berg trace_drv_return_void(local); 1057a65240c1SJohannes Berg } 1058a65240c1SJohannes Berg #endif 1059a65240c1SJohannes Berg 106073da7d5bSSimon Wunderlich static inline void 106173da7d5bSSimon Wunderlich drv_channel_switch_beacon(struct ieee80211_sub_if_data *sdata, 106273da7d5bSSimon Wunderlich struct cfg80211_chan_def *chandef) 106373da7d5bSSimon Wunderlich { 106473da7d5bSSimon Wunderlich struct ieee80211_local *local = sdata->local; 106573da7d5bSSimon Wunderlich 106673da7d5bSSimon Wunderlich if (local->ops->channel_switch_beacon) { 106773da7d5bSSimon Wunderlich trace_drv_channel_switch_beacon(local, sdata, chandef); 106873da7d5bSSimon Wunderlich local->ops->channel_switch_beacon(&local->hw, &sdata->vif, 106973da7d5bSSimon Wunderlich chandef); 107073da7d5bSSimon Wunderlich } 107173da7d5bSSimon Wunderlich } 107273da7d5bSSimon Wunderlich 10736d027bccSLuciano Coelho static inline int 10746d027bccSLuciano Coelho drv_pre_channel_switch(struct ieee80211_sub_if_data *sdata, 10756d027bccSLuciano Coelho struct ieee80211_channel_switch *ch_switch) 10766d027bccSLuciano Coelho { 10776d027bccSLuciano Coelho struct ieee80211_local *local = sdata->local; 10786d027bccSLuciano Coelho int ret = 0; 10796d027bccSLuciano Coelho 10806d027bccSLuciano Coelho if (!check_sdata_in_driver(sdata)) 10816d027bccSLuciano Coelho return -EIO; 10826d027bccSLuciano Coelho 10836d027bccSLuciano Coelho trace_drv_pre_channel_switch(local, sdata, ch_switch); 10846d027bccSLuciano Coelho if (local->ops->pre_channel_switch) 10856d027bccSLuciano Coelho ret = local->ops->pre_channel_switch(&local->hw, &sdata->vif, 10866d027bccSLuciano Coelho ch_switch); 10876d027bccSLuciano Coelho trace_drv_return_int(local, ret); 10886d027bccSLuciano Coelho return ret; 10896d027bccSLuciano Coelho } 10906d027bccSLuciano Coelho 1091f1d65583SLuciano Coelho static inline int 1092f1d65583SLuciano Coelho drv_post_channel_switch(struct ieee80211_sub_if_data *sdata) 1093f1d65583SLuciano Coelho { 1094f1d65583SLuciano Coelho struct ieee80211_local *local = sdata->local; 1095f1d65583SLuciano Coelho int ret = 0; 1096f1d65583SLuciano Coelho 1097f1d65583SLuciano Coelho if (!check_sdata_in_driver(sdata)) 1098f1d65583SLuciano Coelho return -EIO; 1099f1d65583SLuciano Coelho 1100f1d65583SLuciano Coelho trace_drv_post_channel_switch(local, sdata); 1101f1d65583SLuciano Coelho if (local->ops->post_channel_switch) 1102f1d65583SLuciano Coelho ret = local->ops->post_channel_switch(&local->hw, &sdata->vif); 1103f1d65583SLuciano Coelho trace_drv_return_int(local, ret); 1104f1d65583SLuciano Coelho return ret; 1105f1d65583SLuciano Coelho } 1106f1d65583SLuciano Coelho 1107b9cc81d8SSara Sharon static inline void 1108b9cc81d8SSara Sharon drv_abort_channel_switch(struct ieee80211_sub_if_data *sdata) 1109b9cc81d8SSara Sharon { 1110b9cc81d8SSara Sharon struct ieee80211_local *local = sdata->local; 1111b9cc81d8SSara Sharon 1112b9cc81d8SSara Sharon if (!check_sdata_in_driver(sdata)) 1113b9cc81d8SSara Sharon return; 1114b9cc81d8SSara Sharon 1115b9cc81d8SSara Sharon trace_drv_abort_channel_switch(local, sdata); 1116b9cc81d8SSara Sharon 1117b9cc81d8SSara Sharon if (local->ops->abort_channel_switch) 1118b9cc81d8SSara Sharon local->ops->abort_channel_switch(&local->hw, &sdata->vif); 1119b9cc81d8SSara Sharon } 1120b9cc81d8SSara Sharon 1121fafd2bceSSara Sharon static inline void 1122fafd2bceSSara Sharon drv_channel_switch_rx_beacon(struct ieee80211_sub_if_data *sdata, 1123fafd2bceSSara Sharon struct ieee80211_channel_switch *ch_switch) 1124fafd2bceSSara Sharon { 1125fafd2bceSSara Sharon struct ieee80211_local *local = sdata->local; 1126fafd2bceSSara Sharon 1127fafd2bceSSara Sharon if (!check_sdata_in_driver(sdata)) 1128fafd2bceSSara Sharon return; 1129fafd2bceSSara Sharon 1130fafd2bceSSara Sharon trace_drv_channel_switch_rx_beacon(local, sdata, ch_switch); 1131fafd2bceSSara Sharon if (local->ops->channel_switch_rx_beacon) 1132fafd2bceSSara Sharon local->ops->channel_switch_rx_beacon(&local->hw, &sdata->vif, 1133fafd2bceSSara Sharon ch_switch); 1134fafd2bceSSara Sharon } 1135fafd2bceSSara Sharon 113655fff501SJohannes Berg static inline int drv_join_ibss(struct ieee80211_local *local, 113755fff501SJohannes Berg struct ieee80211_sub_if_data *sdata) 113855fff501SJohannes Berg { 113955fff501SJohannes Berg int ret = 0; 114055fff501SJohannes Berg 114155fff501SJohannes Berg might_sleep(); 1142f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 1143f6837ba8SJohannes Berg return -EIO; 114455fff501SJohannes Berg 114555fff501SJohannes Berg trace_drv_join_ibss(local, sdata, &sdata->vif.bss_conf); 114655fff501SJohannes Berg if (local->ops->join_ibss) 114755fff501SJohannes Berg ret = local->ops->join_ibss(&local->hw, &sdata->vif); 114855fff501SJohannes Berg trace_drv_return_int(local, ret); 114955fff501SJohannes Berg return ret; 115055fff501SJohannes Berg } 115155fff501SJohannes Berg 115255fff501SJohannes Berg static inline void drv_leave_ibss(struct ieee80211_local *local, 115355fff501SJohannes Berg struct ieee80211_sub_if_data *sdata) 115455fff501SJohannes Berg { 115555fff501SJohannes Berg might_sleep(); 1156f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 1157f6837ba8SJohannes Berg return; 115855fff501SJohannes Berg 115955fff501SJohannes Berg trace_drv_leave_ibss(local, sdata); 116055fff501SJohannes Berg if (local->ops->leave_ibss) 116155fff501SJohannes Berg local->ops->leave_ibss(&local->hw, &sdata->vif); 116255fff501SJohannes Berg trace_drv_return_void(local); 116355fff501SJohannes Berg } 116455fff501SJohannes Berg 1165cca674d4SAntonio Quartulli static inline u32 drv_get_expected_throughput(struct ieee80211_local *local, 11664fdbc67aSMaxim Altshul struct sta_info *sta) 1167cca674d4SAntonio Quartulli { 1168cca674d4SAntonio Quartulli u32 ret = 0; 1169cca674d4SAntonio Quartulli 11704fdbc67aSMaxim Altshul trace_drv_get_expected_throughput(&sta->sta); 11714fdbc67aSMaxim Altshul if (local->ops->get_expected_throughput && sta->uploaded) 11724fdbc67aSMaxim Altshul ret = local->ops->get_expected_throughput(&local->hw, &sta->sta); 1173cca674d4SAntonio Quartulli trace_drv_return_u32(local, ret); 1174cca674d4SAntonio Quartulli 1175cca674d4SAntonio Quartulli return ret; 1176cca674d4SAntonio Quartulli } 1177cca674d4SAntonio Quartulli 11785b3dc42bSFelix Fietkau static inline int drv_get_txpower(struct ieee80211_local *local, 11795b3dc42bSFelix Fietkau struct ieee80211_sub_if_data *sdata, int *dbm) 11805b3dc42bSFelix Fietkau { 11815b3dc42bSFelix Fietkau int ret; 11825b3dc42bSFelix Fietkau 11835b3dc42bSFelix Fietkau if (!local->ops->get_txpower) 11845b3dc42bSFelix Fietkau return -EOPNOTSUPP; 11855b3dc42bSFelix Fietkau 11865b3dc42bSFelix Fietkau ret = local->ops->get_txpower(&local->hw, &sdata->vif, dbm); 11875b3dc42bSFelix Fietkau trace_drv_get_txpower(local, sdata, *dbm, ret); 11885b3dc42bSFelix Fietkau 11895b3dc42bSFelix Fietkau return ret; 11905b3dc42bSFelix Fietkau } 11915b3dc42bSFelix Fietkau 1192a7a6bdd0SArik Nemtsov static inline int 1193a7a6bdd0SArik Nemtsov drv_tdls_channel_switch(struct ieee80211_local *local, 1194a7a6bdd0SArik Nemtsov struct ieee80211_sub_if_data *sdata, 1195a7a6bdd0SArik Nemtsov struct ieee80211_sta *sta, u8 oper_class, 1196a7a6bdd0SArik Nemtsov struct cfg80211_chan_def *chandef, 1197a7a6bdd0SArik Nemtsov struct sk_buff *tmpl_skb, u32 ch_sw_tm_ie) 1198a7a6bdd0SArik Nemtsov { 1199a7a6bdd0SArik Nemtsov int ret; 1200a7a6bdd0SArik Nemtsov 1201a7a6bdd0SArik Nemtsov might_sleep(); 1202a7a6bdd0SArik Nemtsov if (!check_sdata_in_driver(sdata)) 1203a7a6bdd0SArik Nemtsov return -EIO; 1204a7a6bdd0SArik Nemtsov 1205a7a6bdd0SArik Nemtsov if (!local->ops->tdls_channel_switch) 1206a7a6bdd0SArik Nemtsov return -EOPNOTSUPP; 1207a7a6bdd0SArik Nemtsov 1208a7a6bdd0SArik Nemtsov trace_drv_tdls_channel_switch(local, sdata, sta, oper_class, chandef); 1209a7a6bdd0SArik Nemtsov ret = local->ops->tdls_channel_switch(&local->hw, &sdata->vif, sta, 1210a7a6bdd0SArik Nemtsov oper_class, chandef, tmpl_skb, 1211a7a6bdd0SArik Nemtsov ch_sw_tm_ie); 1212a7a6bdd0SArik Nemtsov trace_drv_return_int(local, ret); 1213a7a6bdd0SArik Nemtsov return ret; 1214a7a6bdd0SArik Nemtsov } 1215a7a6bdd0SArik Nemtsov 1216a7a6bdd0SArik Nemtsov static inline void 1217a7a6bdd0SArik Nemtsov drv_tdls_cancel_channel_switch(struct ieee80211_local *local, 1218a7a6bdd0SArik Nemtsov struct ieee80211_sub_if_data *sdata, 1219a7a6bdd0SArik Nemtsov struct ieee80211_sta *sta) 1220a7a6bdd0SArik Nemtsov { 1221a7a6bdd0SArik Nemtsov might_sleep(); 1222a7a6bdd0SArik Nemtsov if (!check_sdata_in_driver(sdata)) 1223a7a6bdd0SArik Nemtsov return; 1224a7a6bdd0SArik Nemtsov 1225a7a6bdd0SArik Nemtsov if (!local->ops->tdls_cancel_channel_switch) 1226a7a6bdd0SArik Nemtsov return; 1227a7a6bdd0SArik Nemtsov 1228a7a6bdd0SArik Nemtsov trace_drv_tdls_cancel_channel_switch(local, sdata, sta); 1229a7a6bdd0SArik Nemtsov local->ops->tdls_cancel_channel_switch(&local->hw, &sdata->vif, sta); 1230a7a6bdd0SArik Nemtsov trace_drv_return_void(local); 1231a7a6bdd0SArik Nemtsov } 1232a7a6bdd0SArik Nemtsov 12338a4d32f3SArik Nemtsov static inline void 12348a4d32f3SArik Nemtsov drv_tdls_recv_channel_switch(struct ieee80211_local *local, 12358a4d32f3SArik Nemtsov struct ieee80211_sub_if_data *sdata, 12368a4d32f3SArik Nemtsov struct ieee80211_tdls_ch_sw_params *params) 12378a4d32f3SArik Nemtsov { 12388a4d32f3SArik Nemtsov trace_drv_tdls_recv_channel_switch(local, sdata, params); 12398a4d32f3SArik Nemtsov if (local->ops->tdls_recv_channel_switch) 12408a4d32f3SArik Nemtsov local->ops->tdls_recv_channel_switch(&local->hw, &sdata->vif, 12418a4d32f3SArik Nemtsov params); 12428a4d32f3SArik Nemtsov trace_drv_return_void(local); 12438a4d32f3SArik Nemtsov } 12448a4d32f3SArik Nemtsov 1245e7881bd5SJohannes Berg static inline void drv_wake_tx_queue(struct ieee80211_local *local, 1246e7881bd5SJohannes Berg struct txq_info *txq) 1247ba8c3d6fSFelix Fietkau { 1248e7881bd5SJohannes Berg struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->txq.vif); 1249e7881bd5SJohannes Berg 1250db7205afSJohannes Berg /* In reconfig don't transmit now, but mark for waking later */ 1251db7205afSJohannes Berg if (local->in_reconfig) { 1252db7205afSJohannes Berg set_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txq->flags); 12534856bfd2SFelix Fietkau return; 1254db7205afSJohannes Berg } 12554856bfd2SFelix Fietkau 1256e7881bd5SJohannes Berg if (!check_sdata_in_driver(sdata)) 1257e7881bd5SJohannes Berg return; 1258e7881bd5SJohannes Berg 1259e7881bd5SJohannes Berg trace_drv_wake_tx_queue(local, sdata, txq); 1260e7881bd5SJohannes Berg local->ops->wake_tx_queue(&local->hw, &txq->txq); 1261ba8c3d6fSFelix Fietkau } 1262ba8c3d6fSFelix Fietkau 126318667600SToke Høiland-Jørgensen static inline void schedule_and_wake_txq(struct ieee80211_local *local, 126418667600SToke Høiland-Jørgensen struct txq_info *txqi) 126518667600SToke Høiland-Jørgensen { 1266390298e8SToke Høiland-Jørgensen ieee80211_schedule_txq(&local->hw, &txqi->txq); 126718667600SToke Høiland-Jørgensen drv_wake_tx_queue(local, txqi); 126818667600SToke Høiland-Jørgensen } 126918667600SToke Høiland-Jørgensen 12709739fe29SSara Sharon static inline int drv_can_aggregate_in_amsdu(struct ieee80211_local *local, 12719739fe29SSara Sharon struct sk_buff *head, 12729739fe29SSara Sharon struct sk_buff *skb) 12739739fe29SSara Sharon { 12749739fe29SSara Sharon if (!local->ops->can_aggregate_in_amsdu) 12759739fe29SSara Sharon return true; 12769739fe29SSara Sharon 12779739fe29SSara Sharon return local->ops->can_aggregate_in_amsdu(&local->hw, head, skb); 12789739fe29SSara Sharon } 12799739fe29SSara Sharon 1280bc847970SPradeep Kumar Chitrapu static inline int 1281bc847970SPradeep Kumar Chitrapu drv_get_ftm_responder_stats(struct ieee80211_local *local, 1282bc847970SPradeep Kumar Chitrapu struct ieee80211_sub_if_data *sdata, 1283bc847970SPradeep Kumar Chitrapu struct cfg80211_ftm_responder_stats *ftm_stats) 1284bc847970SPradeep Kumar Chitrapu { 1285bc847970SPradeep Kumar Chitrapu u32 ret = -EOPNOTSUPP; 1286bc847970SPradeep Kumar Chitrapu 1287bc847970SPradeep Kumar Chitrapu if (local->ops->get_ftm_responder_stats) 1288bc847970SPradeep Kumar Chitrapu ret = local->ops->get_ftm_responder_stats(&local->hw, 1289bc847970SPradeep Kumar Chitrapu &sdata->vif, 1290bc847970SPradeep Kumar Chitrapu ftm_stats); 1291bc847970SPradeep Kumar Chitrapu trace_drv_get_ftm_responder_stats(local, sdata, ftm_stats); 1292bc847970SPradeep Kumar Chitrapu 1293bc847970SPradeep Kumar Chitrapu return ret; 1294bc847970SPradeep Kumar Chitrapu } 1295bc847970SPradeep Kumar Chitrapu 1296cee7013bSJohannes Berg static inline int drv_start_pmsr(struct ieee80211_local *local, 1297cee7013bSJohannes Berg struct ieee80211_sub_if_data *sdata, 1298cee7013bSJohannes Berg struct cfg80211_pmsr_request *request) 1299cee7013bSJohannes Berg { 1300cee7013bSJohannes Berg int ret = -EOPNOTSUPP; 1301cee7013bSJohannes Berg 1302cee7013bSJohannes Berg might_sleep(); 1303cee7013bSJohannes Berg if (!check_sdata_in_driver(sdata)) 1304cee7013bSJohannes Berg return -EIO; 1305cee7013bSJohannes Berg 1306cee7013bSJohannes Berg trace_drv_start_pmsr(local, sdata); 1307cee7013bSJohannes Berg 1308cee7013bSJohannes Berg if (local->ops->start_pmsr) 1309cee7013bSJohannes Berg ret = local->ops->start_pmsr(&local->hw, &sdata->vif, request); 1310cee7013bSJohannes Berg trace_drv_return_int(local, ret); 1311cee7013bSJohannes Berg 1312cee7013bSJohannes Berg return ret; 1313cee7013bSJohannes Berg } 1314cee7013bSJohannes Berg 1315cee7013bSJohannes Berg static inline void drv_abort_pmsr(struct ieee80211_local *local, 1316cee7013bSJohannes Berg struct ieee80211_sub_if_data *sdata, 1317cee7013bSJohannes Berg struct cfg80211_pmsr_request *request) 1318cee7013bSJohannes Berg { 1319cee7013bSJohannes Berg trace_drv_abort_pmsr(local, sdata); 1320cee7013bSJohannes Berg 1321cee7013bSJohannes Berg might_sleep(); 1322cee7013bSJohannes Berg if (!check_sdata_in_driver(sdata)) 1323cee7013bSJohannes Berg return; 1324cee7013bSJohannes Berg 1325cee7013bSJohannes Berg if (local->ops->abort_pmsr) 1326cee7013bSJohannes Berg local->ops->abort_pmsr(&local->hw, &sdata->vif, request); 1327cee7013bSJohannes Berg trace_drv_return_void(local); 1328cee7013bSJohannes Berg } 1329cee7013bSJohannes Berg 1330708d50edSAyala Beker static inline int drv_start_nan(struct ieee80211_local *local, 1331708d50edSAyala Beker struct ieee80211_sub_if_data *sdata, 1332708d50edSAyala Beker struct cfg80211_nan_conf *conf) 1333708d50edSAyala Beker { 1334708d50edSAyala Beker int ret; 1335708d50edSAyala Beker 1336708d50edSAyala Beker might_sleep(); 1337708d50edSAyala Beker check_sdata_in_driver(sdata); 1338708d50edSAyala Beker 1339708d50edSAyala Beker trace_drv_start_nan(local, sdata, conf); 1340708d50edSAyala Beker ret = local->ops->start_nan(&local->hw, &sdata->vif, conf); 1341708d50edSAyala Beker trace_drv_return_int(local, ret); 1342708d50edSAyala Beker return ret; 1343708d50edSAyala Beker } 1344708d50edSAyala Beker 1345708d50edSAyala Beker static inline void drv_stop_nan(struct ieee80211_local *local, 1346708d50edSAyala Beker struct ieee80211_sub_if_data *sdata) 1347708d50edSAyala Beker { 1348708d50edSAyala Beker might_sleep(); 1349708d50edSAyala Beker check_sdata_in_driver(sdata); 1350708d50edSAyala Beker 1351708d50edSAyala Beker trace_drv_stop_nan(local, sdata); 1352708d50edSAyala Beker local->ops->stop_nan(&local->hw, &sdata->vif); 1353708d50edSAyala Beker trace_drv_return_void(local); 1354708d50edSAyala Beker } 1355708d50edSAyala Beker 13565953ff6dSAyala Beker static inline int drv_nan_change_conf(struct ieee80211_local *local, 13575953ff6dSAyala Beker struct ieee80211_sub_if_data *sdata, 13585953ff6dSAyala Beker struct cfg80211_nan_conf *conf, 13595953ff6dSAyala Beker u32 changes) 13605953ff6dSAyala Beker { 13615953ff6dSAyala Beker int ret; 13625953ff6dSAyala Beker 13635953ff6dSAyala Beker might_sleep(); 13645953ff6dSAyala Beker check_sdata_in_driver(sdata); 13655953ff6dSAyala Beker 13665953ff6dSAyala Beker if (!local->ops->nan_change_conf) 13675953ff6dSAyala Beker return -EOPNOTSUPP; 13685953ff6dSAyala Beker 13695953ff6dSAyala Beker trace_drv_nan_change_conf(local, sdata, conf, changes); 13705953ff6dSAyala Beker ret = local->ops->nan_change_conf(&local->hw, &sdata->vif, conf, 13715953ff6dSAyala Beker changes); 13725953ff6dSAyala Beker trace_drv_return_int(local, ret); 13735953ff6dSAyala Beker 13745953ff6dSAyala Beker return ret; 13755953ff6dSAyala Beker } 13765953ff6dSAyala Beker 1377167e33f4SAyala Beker static inline int drv_add_nan_func(struct ieee80211_local *local, 1378167e33f4SAyala Beker struct ieee80211_sub_if_data *sdata, 1379167e33f4SAyala Beker const struct cfg80211_nan_func *nan_func) 1380167e33f4SAyala Beker { 1381167e33f4SAyala Beker int ret; 1382167e33f4SAyala Beker 1383167e33f4SAyala Beker might_sleep(); 1384167e33f4SAyala Beker check_sdata_in_driver(sdata); 1385167e33f4SAyala Beker 1386167e33f4SAyala Beker if (!local->ops->add_nan_func) 1387167e33f4SAyala Beker return -EOPNOTSUPP; 1388167e33f4SAyala Beker 1389167e33f4SAyala Beker trace_drv_add_nan_func(local, sdata, nan_func); 1390167e33f4SAyala Beker ret = local->ops->add_nan_func(&local->hw, &sdata->vif, nan_func); 1391167e33f4SAyala Beker trace_drv_return_int(local, ret); 1392167e33f4SAyala Beker 1393167e33f4SAyala Beker return ret; 1394167e33f4SAyala Beker } 1395167e33f4SAyala Beker 1396167e33f4SAyala Beker static inline void drv_del_nan_func(struct ieee80211_local *local, 1397167e33f4SAyala Beker struct ieee80211_sub_if_data *sdata, 1398167e33f4SAyala Beker u8 instance_id) 1399167e33f4SAyala Beker { 1400167e33f4SAyala Beker might_sleep(); 1401167e33f4SAyala Beker check_sdata_in_driver(sdata); 1402167e33f4SAyala Beker 1403167e33f4SAyala Beker trace_drv_del_nan_func(local, sdata, instance_id); 1404167e33f4SAyala Beker if (local->ops->del_nan_func) 1405167e33f4SAyala Beker local->ops->del_nan_func(&local->hw, &sdata->vif, instance_id); 1406167e33f4SAyala Beker trace_drv_return_void(local); 1407167e33f4SAyala Beker } 1408167e33f4SAyala Beker 1409370f51d5STamizh chelvam static inline int drv_set_tid_config(struct ieee80211_local *local, 1410370f51d5STamizh chelvam struct ieee80211_sub_if_data *sdata, 1411370f51d5STamizh chelvam struct ieee80211_sta *sta, 1412370f51d5STamizh chelvam struct cfg80211_tid_config *tid_conf) 1413370f51d5STamizh chelvam { 1414370f51d5STamizh chelvam int ret; 1415370f51d5STamizh chelvam 1416370f51d5STamizh chelvam might_sleep(); 1417370f51d5STamizh chelvam ret = local->ops->set_tid_config(&local->hw, &sdata->vif, sta, 1418370f51d5STamizh chelvam tid_conf); 1419370f51d5STamizh chelvam trace_drv_return_int(local, ret); 1420370f51d5STamizh chelvam 1421370f51d5STamizh chelvam return ret; 1422370f51d5STamizh chelvam } 1423370f51d5STamizh chelvam 1424370f51d5STamizh chelvam static inline int drv_reset_tid_config(struct ieee80211_local *local, 1425370f51d5STamizh chelvam struct ieee80211_sub_if_data *sdata, 142660c2ef0eSSergey Matyukevich struct ieee80211_sta *sta, u8 tids) 1427370f51d5STamizh chelvam { 1428370f51d5STamizh chelvam int ret; 1429370f51d5STamizh chelvam 1430370f51d5STamizh chelvam might_sleep(); 143160c2ef0eSSergey Matyukevich ret = local->ops->reset_tid_config(&local->hw, &sdata->vif, sta, tids); 1432370f51d5STamizh chelvam trace_drv_return_int(local, ret); 1433370f51d5STamizh chelvam 1434370f51d5STamizh chelvam return ret; 1435370f51d5STamizh chelvam } 14366aea26ceSFelix Fietkau 14376aea26ceSFelix Fietkau static inline void drv_update_vif_offload(struct ieee80211_local *local, 14386aea26ceSFelix Fietkau struct ieee80211_sub_if_data *sdata) 14396aea26ceSFelix Fietkau { 14406aea26ceSFelix Fietkau might_sleep(); 14416aea26ceSFelix Fietkau check_sdata_in_driver(sdata); 14426aea26ceSFelix Fietkau 14436aea26ceSFelix Fietkau if (!local->ops->update_vif_offload) 14446aea26ceSFelix Fietkau return; 14456aea26ceSFelix Fietkau 14466aea26ceSFelix Fietkau trace_drv_update_vif_offload(local, sdata); 14476aea26ceSFelix Fietkau local->ops->update_vif_offload(&local->hw, &sdata->vif); 14486aea26ceSFelix Fietkau trace_drv_return_void(local); 14496aea26ceSFelix Fietkau } 14506aea26ceSFelix Fietkau 14511ff4e8f2SFelix Fietkau static inline void drv_sta_set_4addr(struct ieee80211_local *local, 14521ff4e8f2SFelix Fietkau struct ieee80211_sub_if_data *sdata, 14531ff4e8f2SFelix Fietkau struct ieee80211_sta *sta, bool enabled) 14541ff4e8f2SFelix Fietkau { 14551ff4e8f2SFelix Fietkau sdata = get_bss_sdata(sdata); 14561ff4e8f2SFelix Fietkau if (!check_sdata_in_driver(sdata)) 14571ff4e8f2SFelix Fietkau return; 14581ff4e8f2SFelix Fietkau 14591ff4e8f2SFelix Fietkau trace_drv_sta_set_4addr(local, sdata, sta, enabled); 14601ff4e8f2SFelix Fietkau if (local->ops->sta_set_4addr) 14611ff4e8f2SFelix Fietkau local->ops->sta_set_4addr(&local->hw, &sdata->vif, sta, enabled); 14621ff4e8f2SFelix Fietkau trace_drv_return_void(local); 14631ff4e8f2SFelix Fietkau } 14641ff4e8f2SFelix Fietkau 146580a915ecSFelix Fietkau static inline void drv_sta_set_decap_offload(struct ieee80211_local *local, 146680a915ecSFelix Fietkau struct ieee80211_sub_if_data *sdata, 146780a915ecSFelix Fietkau struct ieee80211_sta *sta, 146880a915ecSFelix Fietkau bool enabled) 146980a915ecSFelix Fietkau { 147080a915ecSFelix Fietkau sdata = get_bss_sdata(sdata); 147180a915ecSFelix Fietkau if (!check_sdata_in_driver(sdata)) 147280a915ecSFelix Fietkau return; 147380a915ecSFelix Fietkau 147480a915ecSFelix Fietkau trace_drv_sta_set_decap_offload(local, sdata, sta, enabled); 147580a915ecSFelix Fietkau if (local->ops->sta_set_decap_offload) 147680a915ecSFelix Fietkau local->ops->sta_set_decap_offload(&local->hw, &sdata->vif, sta, 147780a915ecSFelix Fietkau enabled); 147880a915ecSFelix Fietkau trace_drv_return_void(local); 147980a915ecSFelix Fietkau } 148080a915ecSFelix Fietkau 1481f5a4c24eSLorenzo Bianconi static inline void drv_add_twt_setup(struct ieee80211_local *local, 1482f5a4c24eSLorenzo Bianconi struct ieee80211_sub_if_data *sdata, 1483f5a4c24eSLorenzo Bianconi struct ieee80211_sta *sta, 1484f5a4c24eSLorenzo Bianconi struct ieee80211_twt_setup *twt) 1485f5a4c24eSLorenzo Bianconi { 1486f5a4c24eSLorenzo Bianconi struct ieee80211_twt_params *twt_agrt; 1487f5a4c24eSLorenzo Bianconi 1488f5a4c24eSLorenzo Bianconi might_sleep(); 1489f5a4c24eSLorenzo Bianconi 1490f5a4c24eSLorenzo Bianconi if (!check_sdata_in_driver(sdata)) 1491f5a4c24eSLorenzo Bianconi return; 1492f5a4c24eSLorenzo Bianconi 1493f5a4c24eSLorenzo Bianconi twt_agrt = (void *)twt->params; 1494f5a4c24eSLorenzo Bianconi 1495f5a4c24eSLorenzo Bianconi trace_drv_add_twt_setup(local, sta, twt, twt_agrt); 1496f5a4c24eSLorenzo Bianconi local->ops->add_twt_setup(&local->hw, sta, twt); 1497f5a4c24eSLorenzo Bianconi trace_drv_return_void(local); 1498f5a4c24eSLorenzo Bianconi } 1499f5a4c24eSLorenzo Bianconi 1500f5a4c24eSLorenzo Bianconi static inline void drv_twt_teardown_request(struct ieee80211_local *local, 1501f5a4c24eSLorenzo Bianconi struct ieee80211_sub_if_data *sdata, 1502f5a4c24eSLorenzo Bianconi struct ieee80211_sta *sta, 1503f5a4c24eSLorenzo Bianconi u8 flowid) 1504f5a4c24eSLorenzo Bianconi { 1505f5a4c24eSLorenzo Bianconi might_sleep(); 1506f5a4c24eSLorenzo Bianconi if (!check_sdata_in_driver(sdata)) 1507f5a4c24eSLorenzo Bianconi return; 1508f5a4c24eSLorenzo Bianconi 1509f5a4c24eSLorenzo Bianconi if (!local->ops->twt_teardown_request) 1510f5a4c24eSLorenzo Bianconi return; 1511f5a4c24eSLorenzo Bianconi 1512f5a4c24eSLorenzo Bianconi trace_drv_twt_teardown_request(local, sta, flowid); 1513f5a4c24eSLorenzo Bianconi local->ops->twt_teardown_request(&local->hw, sta, flowid); 1514f5a4c24eSLorenzo Bianconi trace_drv_return_void(local); 1515f5a4c24eSLorenzo Bianconi } 1516f5a4c24eSLorenzo Bianconi 1517d787a3e3SFelix Fietkau static inline int drv_net_fill_forward_path(struct ieee80211_local *local, 1518d787a3e3SFelix Fietkau struct ieee80211_sub_if_data *sdata, 1519d787a3e3SFelix Fietkau struct ieee80211_sta *sta, 1520d787a3e3SFelix Fietkau struct net_device_path_ctx *ctx, 1521d787a3e3SFelix Fietkau struct net_device_path *path) 1522d787a3e3SFelix Fietkau { 1523d787a3e3SFelix Fietkau int ret = -EOPNOTSUPP; 1524d787a3e3SFelix Fietkau 1525d787a3e3SFelix Fietkau sdata = get_bss_sdata(sdata); 1526d787a3e3SFelix Fietkau if (!check_sdata_in_driver(sdata)) 1527d787a3e3SFelix Fietkau return -EIO; 1528d787a3e3SFelix Fietkau 1529d787a3e3SFelix Fietkau trace_drv_net_fill_forward_path(local, sdata, sta); 1530d787a3e3SFelix Fietkau if (local->ops->net_fill_forward_path) 1531d787a3e3SFelix Fietkau ret = local->ops->net_fill_forward_path(&local->hw, 1532d787a3e3SFelix Fietkau &sdata->vif, sta, 1533d787a3e3SFelix Fietkau ctx, path); 1534d787a3e3SFelix Fietkau trace_drv_return_int(local, ret); 1535d787a3e3SFelix Fietkau 1536d787a3e3SFelix Fietkau return ret; 1537d787a3e3SFelix Fietkau } 1538d787a3e3SFelix Fietkau 1539d8787ec6SJohannes Berg static inline int drv_change_vif_links(struct ieee80211_local *local, 1540d8787ec6SJohannes Berg struct ieee80211_sub_if_data *sdata, 1541d8787ec6SJohannes Berg u16 old_links, u16 new_links, 1542d8787ec6SJohannes Berg struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS]) 1543d8787ec6SJohannes Berg { 1544d8787ec6SJohannes Berg int ret = -EOPNOTSUPP; 1545d8787ec6SJohannes Berg 1546d8787ec6SJohannes Berg might_sleep(); 1547d8787ec6SJohannes Berg 1548d8787ec6SJohannes Berg if (!check_sdata_in_driver(sdata)) 1549d8787ec6SJohannes Berg return -EIO; 1550d8787ec6SJohannes Berg 1551d8787ec6SJohannes Berg trace_drv_change_vif_links(local, sdata, old_links, new_links); 1552d8787ec6SJohannes Berg if (local->ops->change_vif_links) 1553d8787ec6SJohannes Berg ret = local->ops->change_vif_links(&local->hw, &sdata->vif, 1554d8787ec6SJohannes Berg old_links, new_links, old); 1555d8787ec6SJohannes Berg trace_drv_return_int(local, ret); 1556d8787ec6SJohannes Berg 1557d8787ec6SJohannes Berg return ret; 1558d8787ec6SJohannes Berg } 1559d8787ec6SJohannes Berg 1560cb71f1d1SJohannes Berg static inline int drv_change_sta_links(struct ieee80211_local *local, 1561cb71f1d1SJohannes Berg struct ieee80211_sub_if_data *sdata, 1562cb71f1d1SJohannes Berg struct ieee80211_sta *sta, 1563cb71f1d1SJohannes Berg u16 old_links, u16 new_links) 1564cb71f1d1SJohannes Berg { 1565cb71f1d1SJohannes Berg int ret = -EOPNOTSUPP; 1566cb71f1d1SJohannes Berg 1567cb71f1d1SJohannes Berg might_sleep(); 1568cb71f1d1SJohannes Berg 1569cb71f1d1SJohannes Berg if (!check_sdata_in_driver(sdata)) 1570cb71f1d1SJohannes Berg return -EIO; 1571cb71f1d1SJohannes Berg 1572cb71f1d1SJohannes Berg trace_drv_change_sta_links(local, sdata, sta, old_links, new_links); 1573cb71f1d1SJohannes Berg if (local->ops->change_sta_links) 1574cb71f1d1SJohannes Berg ret = local->ops->change_sta_links(&local->hw, &sdata->vif, sta, 1575cb71f1d1SJohannes Berg old_links, new_links); 1576cb71f1d1SJohannes Berg trace_drv_return_int(local, ret); 1577cb71f1d1SJohannes Berg 1578cb71f1d1SJohannes Berg return ret; 1579cb71f1d1SJohannes Berg } 1580cb71f1d1SJohannes Berg 158124487981SJohannes Berg #endif /* __MAC80211_DRIVER_OPS */ 1582