xref: /openbmc/linux/net/mac80211/driver-ops.h (revision d8675a63518c6148827838058feb7f18403faed1)
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