xref: /openbmc/linux/net/mac80211/driver-ops.h (revision 354d381baf1126c45d03b5c0d87d22caf938b86b)
1f59374ebSSara Sharon /*
2f59374ebSSara Sharon * Portions of this file
3f59374ebSSara Sharon * Copyright(c) 2016 Intel Deutschland GmbH
4f59374ebSSara Sharon */
5f59374ebSSara Sharon 
624487981SJohannes Berg #ifndef __MAC80211_DRIVER_OPS
724487981SJohannes Berg #define __MAC80211_DRIVER_OPS
824487981SJohannes Berg 
924487981SJohannes Berg #include <net/mac80211.h>
1024487981SJohannes Berg #include "ieee80211_i.h"
11011ad0e9SJohannes Berg #include "trace.h"
1224487981SJohannes Berg 
13f6837ba8SJohannes Berg static inline bool check_sdata_in_driver(struct ieee80211_sub_if_data *sdata)
147b7eab6fSJohannes Berg {
15f6837ba8SJohannes Berg 	return !WARN(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER),
16d17087e7SBen Greear 		     "%s:  Failed check-sdata-in-driver check, flags: 0x%x\n",
17f142c6b9SJohannes Berg 		     sdata->dev ? sdata->dev->name : sdata->name, sdata->flags);
187b7eab6fSJohannes Berg }
197b7eab6fSJohannes Berg 
20bc192f89SFelix Fietkau static inline struct ieee80211_sub_if_data *
21bc192f89SFelix Fietkau get_bss_sdata(struct ieee80211_sub_if_data *sdata)
22bc192f89SFelix Fietkau {
23bc192f89SFelix Fietkau 	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
24bc192f89SFelix Fietkau 		sdata = container_of(sdata->bss, struct ieee80211_sub_if_data,
25bc192f89SFelix Fietkau 				     u.ap);
26bc192f89SFelix Fietkau 
27bc192f89SFelix Fietkau 	return sdata;
28bc192f89SFelix Fietkau }
29bc192f89SFelix Fietkau 
3036323f81SThomas Huehn static inline void drv_tx(struct ieee80211_local *local,
3136323f81SThomas Huehn 			  struct ieee80211_tx_control *control,
3236323f81SThomas Huehn 			  struct sk_buff *skb)
3324487981SJohannes Berg {
3436323f81SThomas Huehn 	local->ops->tx(&local->hw, control, skb);
3524487981SJohannes Berg }
3624487981SJohannes Berg 
37f59374ebSSara Sharon static inline void drv_sync_rx_queues(struct ieee80211_local *local,
38f59374ebSSara Sharon 				      struct sta_info *sta)
39f59374ebSSara Sharon {
40f59374ebSSara Sharon 	if (local->ops->sync_rx_queues) {
41f59374ebSSara Sharon 		trace_drv_sync_rx_queues(local, sta->sdata, &sta->sta);
42f59374ebSSara Sharon 		local->ops->sync_rx_queues(&local->hw);
43f59374ebSSara Sharon 		trace_drv_return_void(local);
44f59374ebSSara Sharon 	}
45f59374ebSSara Sharon }
46f59374ebSSara Sharon 
47e352114fSBen Greear static inline void drv_get_et_strings(struct ieee80211_sub_if_data *sdata,
48e352114fSBen Greear 				      u32 sset, u8 *data)
49e352114fSBen Greear {
50e352114fSBen Greear 	struct ieee80211_local *local = sdata->local;
51e352114fSBen Greear 	if (local->ops->get_et_strings) {
52e352114fSBen Greear 		trace_drv_get_et_strings(local, sset);
53e352114fSBen Greear 		local->ops->get_et_strings(&local->hw, &sdata->vif, sset, data);
54e352114fSBen Greear 		trace_drv_return_void(local);
55e352114fSBen Greear 	}
56e352114fSBen Greear }
57e352114fSBen Greear 
58e352114fSBen Greear static inline void drv_get_et_stats(struct ieee80211_sub_if_data *sdata,
59e352114fSBen Greear 				    struct ethtool_stats *stats,
60e352114fSBen Greear 				    u64 *data)
61e352114fSBen Greear {
62e352114fSBen Greear 	struct ieee80211_local *local = sdata->local;
63e352114fSBen Greear 	if (local->ops->get_et_stats) {
64e352114fSBen Greear 		trace_drv_get_et_stats(local);
65e352114fSBen Greear 		local->ops->get_et_stats(&local->hw, &sdata->vif, stats, data);
66e352114fSBen Greear 		trace_drv_return_void(local);
67e352114fSBen Greear 	}
68e352114fSBen Greear }
69e352114fSBen Greear 
70e352114fSBen Greear static inline int drv_get_et_sset_count(struct ieee80211_sub_if_data *sdata,
71e352114fSBen Greear 					int sset)
72e352114fSBen Greear {
73e352114fSBen Greear 	struct ieee80211_local *local = sdata->local;
74e352114fSBen Greear 	int rv = 0;
75e352114fSBen Greear 	if (local->ops->get_et_sset_count) {
76e352114fSBen Greear 		trace_drv_get_et_sset_count(local, sset);
77e352114fSBen Greear 		rv = local->ops->get_et_sset_count(&local->hw, &sdata->vif,
78e352114fSBen Greear 						   sset);
79e352114fSBen Greear 		trace_drv_return_int(local, rv);
80e352114fSBen Greear 	}
81e352114fSBen Greear 	return rv;
82e352114fSBen Greear }
83e352114fSBen Greear 
84968a76ceSEliad Peller int drv_start(struct ieee80211_local *local);
85968a76ceSEliad Peller void drv_stop(struct ieee80211_local *local);
8624487981SJohannes Berg 
87eecc4800SJohannes Berg #ifdef CONFIG_PM
88eecc4800SJohannes Berg static inline int drv_suspend(struct ieee80211_local *local,
89eecc4800SJohannes Berg 			      struct cfg80211_wowlan *wowlan)
90eecc4800SJohannes Berg {
91eecc4800SJohannes Berg 	int ret;
92eecc4800SJohannes Berg 
93eecc4800SJohannes Berg 	might_sleep();
94eecc4800SJohannes Berg 
95eecc4800SJohannes Berg 	trace_drv_suspend(local);
96eecc4800SJohannes Berg 	ret = local->ops->suspend(&local->hw, wowlan);
97eecc4800SJohannes Berg 	trace_drv_return_int(local, ret);
98eecc4800SJohannes Berg 	return ret;
99eecc4800SJohannes Berg }
100eecc4800SJohannes Berg 
101eecc4800SJohannes Berg static inline int drv_resume(struct ieee80211_local *local)
102eecc4800SJohannes Berg {
103eecc4800SJohannes Berg 	int ret;
104eecc4800SJohannes Berg 
105eecc4800SJohannes Berg 	might_sleep();
106eecc4800SJohannes Berg 
107eecc4800SJohannes Berg 	trace_drv_resume(local);
108eecc4800SJohannes Berg 	ret = local->ops->resume(&local->hw);
109eecc4800SJohannes Berg 	trace_drv_return_int(local, ret);
110eecc4800SJohannes Berg 	return ret;
111eecc4800SJohannes Berg }
1126d52563fSJohannes Berg 
1136d52563fSJohannes Berg static inline void drv_set_wakeup(struct ieee80211_local *local,
1146d52563fSJohannes Berg 				  bool enabled)
1156d52563fSJohannes Berg {
1166d52563fSJohannes Berg 	might_sleep();
1176d52563fSJohannes Berg 
1186d52563fSJohannes Berg 	if (!local->ops->set_wakeup)
1196d52563fSJohannes Berg 		return;
1206d52563fSJohannes Berg 
1216d52563fSJohannes Berg 	trace_drv_set_wakeup(local, enabled);
1226d52563fSJohannes Berg 	local->ops->set_wakeup(&local->hw, enabled);
1236d52563fSJohannes Berg 	trace_drv_return_void(local);
1246d52563fSJohannes Berg }
125eecc4800SJohannes Berg #endif
126eecc4800SJohannes Berg 
1279aae296aSDenys Vlasenko int drv_add_interface(struct ieee80211_local *local,
1289aae296aSDenys Vlasenko 		      struct ieee80211_sub_if_data *sdata);
129e1781ed3SKalle Valo 
1309aae296aSDenys Vlasenko int drv_change_interface(struct ieee80211_local *local,
13134d4bc4dSJohannes Berg 			 struct ieee80211_sub_if_data *sdata,
1329aae296aSDenys Vlasenko 			 enum nl80211_iftype type, bool p2p);
13334d4bc4dSJohannes Berg 
1349aae296aSDenys Vlasenko void drv_remove_interface(struct ieee80211_local *local,
1359aae296aSDenys Vlasenko 			  struct ieee80211_sub_if_data *sdata);
13624487981SJohannes Berg 
13724487981SJohannes Berg static inline int drv_config(struct ieee80211_local *local, u32 changed)
13824487981SJohannes Berg {
139e1781ed3SKalle Valo 	int ret;
140e1781ed3SKalle Valo 
141e1781ed3SKalle Valo 	might_sleep();
142e1781ed3SKalle Valo 
1434efc76bdSJohannes Berg 	trace_drv_config(local, changed);
144e1781ed3SKalle Valo 	ret = local->ops->config(&local->hw, changed);
1454efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
1460a2b8bb2SJohannes Berg 	return ret;
14724487981SJohannes Berg }
14824487981SJohannes Berg 
14924487981SJohannes Berg static inline void drv_bss_info_changed(struct ieee80211_local *local,
15012375ef9SJohannes Berg 					struct ieee80211_sub_if_data *sdata,
15124487981SJohannes Berg 					struct ieee80211_bss_conf *info,
15224487981SJohannes Berg 					u32 changed)
15324487981SJohannes Berg {
154e1781ed3SKalle Valo 	might_sleep();
155e1781ed3SKalle Valo 
1565bbe754dSJohannes Berg 	if (WARN_ON_ONCE(changed & (BSS_CHANGED_BEACON |
157b8dc1a35SJohannes Berg 				    BSS_CHANGED_BEACON_ENABLED) &&
158b8dc1a35SJohannes Berg 			 sdata->vif.type != NL80211_IFTYPE_AP &&
159b8dc1a35SJohannes Berg 			 sdata->vif.type != NL80211_IFTYPE_ADHOC &&
160239281f8SRostislav Lisovy 			 sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
161239281f8SRostislav Lisovy 			 sdata->vif.type != NL80211_IFTYPE_OCB))
1625bbe754dSJohannes Berg 		return;
1635bbe754dSJohannes Berg 
1645bbe754dSJohannes Berg 	if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE ||
165708d50edSAyala Beker 			 sdata->vif.type == NL80211_IFTYPE_NAN ||
16642bd20d9SAviya Erenfeld 			 (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
16742bd20d9SAviya Erenfeld 			  !sdata->vif.mu_mimo_owner)))
1685bbe754dSJohannes Berg 		return;
169b8dc1a35SJohannes Berg 
170f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
171f6837ba8SJohannes Berg 		return;
1727b7eab6fSJohannes Berg 
1734efc76bdSJohannes Berg 	trace_drv_bss_info_changed(local, sdata, info, changed);
17424487981SJohannes Berg 	if (local->ops->bss_info_changed)
17512375ef9SJohannes Berg 		local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed);
1764efc76bdSJohannes Berg 	trace_drv_return_void(local);
17724487981SJohannes Berg }
17824487981SJohannes Berg 
1793ac64beeSJohannes Berg static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
18022bedad3SJiri Pirko 					struct netdev_hw_addr_list *mc_list)
18124487981SJohannes Berg {
1823ac64beeSJohannes Berg 	u64 ret = 0;
1833ac64beeSJohannes Berg 
1844efc76bdSJohannes Berg 	trace_drv_prepare_multicast(local, mc_list->count);
1854efc76bdSJohannes Berg 
1863ac64beeSJohannes Berg 	if (local->ops->prepare_multicast)
18722bedad3SJiri Pirko 		ret = local->ops->prepare_multicast(&local->hw, mc_list);
1883ac64beeSJohannes Berg 
1894efc76bdSJohannes Berg 	trace_drv_return_u64(local, ret);
1903ac64beeSJohannes Berg 
1913ac64beeSJohannes Berg 	return ret;
1923ac64beeSJohannes Berg }
1933ac64beeSJohannes Berg 
1943ac64beeSJohannes Berg static inline void drv_configure_filter(struct ieee80211_local *local,
1953ac64beeSJohannes Berg 					unsigned int changed_flags,
1963ac64beeSJohannes Berg 					unsigned int *total_flags,
1973ac64beeSJohannes Berg 					u64 multicast)
1983ac64beeSJohannes Berg {
1993ac64beeSJohannes Berg 	might_sleep();
2003ac64beeSJohannes Berg 
2010a2b8bb2SJohannes Berg 	trace_drv_configure_filter(local, changed_flags, total_flags,
2023ac64beeSJohannes Berg 				   multicast);
2034efc76bdSJohannes Berg 	local->ops->configure_filter(&local->hw, changed_flags, total_flags,
2044efc76bdSJohannes Berg 				     multicast);
2054efc76bdSJohannes Berg 	trace_drv_return_void(local);
20624487981SJohannes Berg }
20724487981SJohannes Berg 
2081b09b556SAndrei Otcheretianski static inline void drv_config_iface_filter(struct ieee80211_local *local,
2091b09b556SAndrei Otcheretianski 					   struct ieee80211_sub_if_data *sdata,
2101b09b556SAndrei Otcheretianski 					   unsigned int filter_flags,
2111b09b556SAndrei Otcheretianski 					   unsigned int changed_flags)
2121b09b556SAndrei Otcheretianski {
2131b09b556SAndrei Otcheretianski 	might_sleep();
2141b09b556SAndrei Otcheretianski 
2151b09b556SAndrei Otcheretianski 	trace_drv_config_iface_filter(local, sdata, filter_flags,
2161b09b556SAndrei Otcheretianski 				      changed_flags);
2171b09b556SAndrei Otcheretianski 	if (local->ops->config_iface_filter)
2181b09b556SAndrei Otcheretianski 		local->ops->config_iface_filter(&local->hw, &sdata->vif,
2191b09b556SAndrei Otcheretianski 						filter_flags,
2201b09b556SAndrei Otcheretianski 						changed_flags);
2211b09b556SAndrei Otcheretianski 	trace_drv_return_void(local);
2221b09b556SAndrei Otcheretianski }
2231b09b556SAndrei Otcheretianski 
22424487981SJohannes Berg static inline int drv_set_tim(struct ieee80211_local *local,
22524487981SJohannes Berg 			      struct ieee80211_sta *sta, bool set)
22624487981SJohannes Berg {
2270a2b8bb2SJohannes Berg 	int ret = 0;
2284efc76bdSJohannes Berg 	trace_drv_set_tim(local, sta, set);
22924487981SJohannes Berg 	if (local->ops->set_tim)
2300a2b8bb2SJohannes Berg 		ret = local->ops->set_tim(&local->hw, sta, set);
2314efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
2320a2b8bb2SJohannes Berg 	return ret;
23324487981SJohannes Berg }
23424487981SJohannes Berg 
23524487981SJohannes Berg static inline int drv_set_key(struct ieee80211_local *local,
23612375ef9SJohannes Berg 			      enum set_key_cmd cmd,
23712375ef9SJohannes Berg 			      struct ieee80211_sub_if_data *sdata,
23824487981SJohannes Berg 			      struct ieee80211_sta *sta,
23924487981SJohannes Berg 			      struct ieee80211_key_conf *key)
24024487981SJohannes Berg {
241e1781ed3SKalle Valo 	int ret;
242e1781ed3SKalle Valo 
243e1781ed3SKalle Valo 	might_sleep();
244e1781ed3SKalle Valo 
245077f4939SJohannes Berg 	sdata = get_bss_sdata(sdata);
246f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
247f6837ba8SJohannes Berg 		return -EIO;
2487b7eab6fSJohannes Berg 
2494efc76bdSJohannes Berg 	trace_drv_set_key(local, cmd, sdata, sta, key);
250e1781ed3SKalle Valo 	ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key);
2514efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
2520a2b8bb2SJohannes Berg 	return ret;
25324487981SJohannes Berg }
25424487981SJohannes Berg 
25524487981SJohannes Berg static inline void drv_update_tkip_key(struct ieee80211_local *local,
256b3fbdcf4SJohannes Berg 				       struct ieee80211_sub_if_data *sdata,
25724487981SJohannes Berg 				       struct ieee80211_key_conf *conf,
258b3fbdcf4SJohannes Berg 				       struct sta_info *sta, u32 iv32,
25924487981SJohannes Berg 				       u16 *phase1key)
26024487981SJohannes Berg {
261b3fbdcf4SJohannes Berg 	struct ieee80211_sta *ista = NULL;
262b3fbdcf4SJohannes Berg 
263b3fbdcf4SJohannes Berg 	if (sta)
264b3fbdcf4SJohannes Berg 		ista = &sta->sta;
265b3fbdcf4SJohannes Berg 
266077f4939SJohannes Berg 	sdata = get_bss_sdata(sdata);
267f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
268f6837ba8SJohannes Berg 		return;
2697b7eab6fSJohannes Berg 
2704efc76bdSJohannes Berg 	trace_drv_update_tkip_key(local, sdata, conf, ista, iv32);
27124487981SJohannes Berg 	if (local->ops->update_tkip_key)
272b3fbdcf4SJohannes Berg 		local->ops->update_tkip_key(&local->hw, &sdata->vif, conf,
273b3fbdcf4SJohannes Berg 					    ista, iv32, phase1key);
2744efc76bdSJohannes Berg 	trace_drv_return_void(local);
27524487981SJohannes Berg }
27624487981SJohannes Berg 
27724487981SJohannes Berg static inline int drv_hw_scan(struct ieee80211_local *local,
278a060bbfeSJohannes Berg 			      struct ieee80211_sub_if_data *sdata,
279c56ef672SDavid Spinadel 			      struct ieee80211_scan_request *req)
28024487981SJohannes Berg {
281e1781ed3SKalle Valo 	int ret;
282e1781ed3SKalle Valo 
283e1781ed3SKalle Valo 	might_sleep();
284e1781ed3SKalle Valo 
285f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
286f6837ba8SJohannes Berg 		return -EIO;
2877b7eab6fSJohannes Berg 
28879f460caSLuciano Coelho 	trace_drv_hw_scan(local, sdata);
289a060bbfeSJohannes Berg 	ret = local->ops->hw_scan(&local->hw, &sdata->vif, req);
2904efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
2910a2b8bb2SJohannes Berg 	return ret;
29224487981SJohannes Berg }
29324487981SJohannes Berg 
294b856439bSEliad Peller static inline void drv_cancel_hw_scan(struct ieee80211_local *local,
295b856439bSEliad Peller 				      struct ieee80211_sub_if_data *sdata)
296b856439bSEliad Peller {
297b856439bSEliad Peller 	might_sleep();
298b856439bSEliad Peller 
299f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
300f6837ba8SJohannes Berg 		return;
3017b7eab6fSJohannes Berg 
302b856439bSEliad Peller 	trace_drv_cancel_hw_scan(local, sdata);
303b856439bSEliad Peller 	local->ops->cancel_hw_scan(&local->hw, &sdata->vif);
304b856439bSEliad Peller 	trace_drv_return_void(local);
305b856439bSEliad Peller }
306b856439bSEliad Peller 
30779f460caSLuciano Coelho static inline int
30879f460caSLuciano Coelho drv_sched_scan_start(struct ieee80211_local *local,
30979f460caSLuciano Coelho 		     struct ieee80211_sub_if_data *sdata,
31079f460caSLuciano Coelho 		     struct cfg80211_sched_scan_request *req,
311633e2713SDavid Spinadel 		     struct ieee80211_scan_ies *ies)
31279f460caSLuciano Coelho {
31379f460caSLuciano Coelho 	int ret;
31479f460caSLuciano Coelho 
31579f460caSLuciano Coelho 	might_sleep();
31679f460caSLuciano Coelho 
317f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
318f6837ba8SJohannes Berg 		return -EIO;
3197b7eab6fSJohannes Berg 
32079f460caSLuciano Coelho 	trace_drv_sched_scan_start(local, sdata);
32179f460caSLuciano Coelho 	ret = local->ops->sched_scan_start(&local->hw, &sdata->vif,
32279f460caSLuciano Coelho 					      req, ies);
32379f460caSLuciano Coelho 	trace_drv_return_int(local, ret);
32479f460caSLuciano Coelho 	return ret;
32579f460caSLuciano Coelho }
32679f460caSLuciano Coelho 
32737e3308cSJohannes Berg static inline int drv_sched_scan_stop(struct ieee80211_local *local,
32879f460caSLuciano Coelho 				      struct ieee80211_sub_if_data *sdata)
32979f460caSLuciano Coelho {
33037e3308cSJohannes Berg 	int ret;
33137e3308cSJohannes Berg 
33279f460caSLuciano Coelho 	might_sleep();
33379f460caSLuciano Coelho 
334f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
335f6837ba8SJohannes Berg 		return -EIO;
3367b7eab6fSJohannes Berg 
33779f460caSLuciano Coelho 	trace_drv_sched_scan_stop(local, sdata);
33837e3308cSJohannes Berg 	ret = local->ops->sched_scan_stop(&local->hw, &sdata->vif);
33937e3308cSJohannes Berg 	trace_drv_return_int(local, ret);
34037e3308cSJohannes Berg 
34137e3308cSJohannes Berg 	return ret;
34279f460caSLuciano Coelho }
34379f460caSLuciano Coelho 
344a344d677SJohannes Berg static inline void drv_sw_scan_start(struct ieee80211_local *local,
345a344d677SJohannes Berg 				     struct ieee80211_sub_if_data *sdata,
346a344d677SJohannes Berg 				     const u8 *mac_addr)
34724487981SJohannes Berg {
348e1781ed3SKalle Valo 	might_sleep();
349e1781ed3SKalle Valo 
350a344d677SJohannes Berg 	trace_drv_sw_scan_start(local, sdata, mac_addr);
35124487981SJohannes Berg 	if (local->ops->sw_scan_start)
352a344d677SJohannes Berg 		local->ops->sw_scan_start(&local->hw, &sdata->vif, mac_addr);
3534efc76bdSJohannes Berg 	trace_drv_return_void(local);
35424487981SJohannes Berg }
35524487981SJohannes Berg 
356a344d677SJohannes Berg static inline void drv_sw_scan_complete(struct ieee80211_local *local,
357a344d677SJohannes Berg 					struct ieee80211_sub_if_data *sdata)
35824487981SJohannes Berg {
359e1781ed3SKalle Valo 	might_sleep();
360e1781ed3SKalle Valo 
361a344d677SJohannes Berg 	trace_drv_sw_scan_complete(local, sdata);
36224487981SJohannes Berg 	if (local->ops->sw_scan_complete)
363a344d677SJohannes Berg 		local->ops->sw_scan_complete(&local->hw, &sdata->vif);
3644efc76bdSJohannes Berg 	trace_drv_return_void(local);
36524487981SJohannes Berg }
36624487981SJohannes Berg 
36724487981SJohannes Berg static inline int drv_get_stats(struct ieee80211_local *local,
36824487981SJohannes Berg 				struct ieee80211_low_level_stats *stats)
36924487981SJohannes Berg {
3700a2b8bb2SJohannes Berg 	int ret = -EOPNOTSUPP;
3710a2b8bb2SJohannes Berg 
372e1781ed3SKalle Valo 	might_sleep();
373e1781ed3SKalle Valo 
3740a2b8bb2SJohannes Berg 	if (local->ops->get_stats)
3750a2b8bb2SJohannes Berg 		ret = local->ops->get_stats(&local->hw, stats);
3760a2b8bb2SJohannes Berg 	trace_drv_get_stats(local, stats, ret);
3770a2b8bb2SJohannes Berg 
3780a2b8bb2SJohannes Berg 	return ret;
37924487981SJohannes Berg }
38024487981SJohannes Berg 
3819352c19fSJohannes Berg static inline void drv_get_key_seq(struct ieee80211_local *local,
3829352c19fSJohannes Berg 				   struct ieee80211_key *key,
3839352c19fSJohannes Berg 				   struct ieee80211_key_seq *seq)
38424487981SJohannes Berg {
3859352c19fSJohannes Berg 	if (local->ops->get_key_seq)
3869352c19fSJohannes Berg 		local->ops->get_key_seq(&local->hw, &key->conf, seq);
3879352c19fSJohannes Berg 	trace_drv_get_key_seq(local, &key->conf);
38824487981SJohannes Berg }
38924487981SJohannes Berg 
390f23a4780SArik Nemtsov static inline int drv_set_frag_threshold(struct ieee80211_local *local,
391f23a4780SArik Nemtsov 					u32 value)
392f23a4780SArik Nemtsov {
393f23a4780SArik Nemtsov 	int ret = 0;
394f23a4780SArik Nemtsov 
395f23a4780SArik Nemtsov 	might_sleep();
396f23a4780SArik Nemtsov 
397f23a4780SArik Nemtsov 	trace_drv_set_frag_threshold(local, value);
398f23a4780SArik Nemtsov 	if (local->ops->set_frag_threshold)
399f23a4780SArik Nemtsov 		ret = local->ops->set_frag_threshold(&local->hw, value);
400f23a4780SArik Nemtsov 	trace_drv_return_int(local, ret);
401f23a4780SArik Nemtsov 	return ret;
402f23a4780SArik Nemtsov }
403f23a4780SArik Nemtsov 
40424487981SJohannes Berg static inline int drv_set_rts_threshold(struct ieee80211_local *local,
40524487981SJohannes Berg 					u32 value)
40624487981SJohannes Berg {
4070a2b8bb2SJohannes Berg 	int ret = 0;
408e1781ed3SKalle Valo 
409e1781ed3SKalle Valo 	might_sleep();
410e1781ed3SKalle Valo 
4114efc76bdSJohannes Berg 	trace_drv_set_rts_threshold(local, value);
41224487981SJohannes Berg 	if (local->ops->set_rts_threshold)
4130a2b8bb2SJohannes Berg 		ret = local->ops->set_rts_threshold(&local->hw, value);
4144efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
4150a2b8bb2SJohannes Berg 	return ret;
41624487981SJohannes Berg }
41724487981SJohannes Berg 
418310bc676SLukáš Turek static inline int drv_set_coverage_class(struct ieee80211_local *local,
419a4bcaf55SLorenzo Bianconi 					 s16 value)
420310bc676SLukáš Turek {
421310bc676SLukáš Turek 	int ret = 0;
422310bc676SLukáš Turek 	might_sleep();
423310bc676SLukáš Turek 
4244efc76bdSJohannes Berg 	trace_drv_set_coverage_class(local, value);
425310bc676SLukáš Turek 	if (local->ops->set_coverage_class)
426310bc676SLukáš Turek 		local->ops->set_coverage_class(&local->hw, value);
427310bc676SLukáš Turek 	else
428310bc676SLukáš Turek 		ret = -EOPNOTSUPP;
429310bc676SLukáš Turek 
4304efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
431310bc676SLukáš Turek 	return ret;
432310bc676SLukáš Turek }
433310bc676SLukáš Turek 
43424487981SJohannes Berg static inline void drv_sta_notify(struct ieee80211_local *local,
43512375ef9SJohannes Berg 				  struct ieee80211_sub_if_data *sdata,
43624487981SJohannes Berg 				  enum sta_notify_cmd cmd,
43724487981SJohannes Berg 				  struct ieee80211_sta *sta)
43824487981SJohannes Berg {
439bc192f89SFelix Fietkau 	sdata = get_bss_sdata(sdata);
440f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
441f6837ba8SJohannes Berg 		return;
4427b7eab6fSJohannes Berg 
4434efc76bdSJohannes Berg 	trace_drv_sta_notify(local, sdata, cmd, sta);
44424487981SJohannes Berg 	if (local->ops->sta_notify)
44512375ef9SJohannes Berg 		local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta);
4464efc76bdSJohannes Berg 	trace_drv_return_void(local);
44724487981SJohannes Berg }
44824487981SJohannes Berg 
44934e89507SJohannes Berg static inline int drv_sta_add(struct ieee80211_local *local,
45034e89507SJohannes Berg 			      struct ieee80211_sub_if_data *sdata,
45134e89507SJohannes Berg 			      struct ieee80211_sta *sta)
45234e89507SJohannes Berg {
45334e89507SJohannes Berg 	int ret = 0;
45434e89507SJohannes Berg 
45534e89507SJohannes Berg 	might_sleep();
45634e89507SJohannes Berg 
457bc192f89SFelix Fietkau 	sdata = get_bss_sdata(sdata);
458f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
459f6837ba8SJohannes Berg 		return -EIO;
4607b7eab6fSJohannes Berg 
4614efc76bdSJohannes Berg 	trace_drv_sta_add(local, sdata, sta);
46234e89507SJohannes Berg 	if (local->ops->sta_add)
46334e89507SJohannes Berg 		ret = local->ops->sta_add(&local->hw, &sdata->vif, sta);
46434e89507SJohannes Berg 
4654efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
46634e89507SJohannes Berg 
46734e89507SJohannes Berg 	return ret;
46834e89507SJohannes Berg }
46934e89507SJohannes Berg 
47034e89507SJohannes Berg static inline void drv_sta_remove(struct ieee80211_local *local,
47134e89507SJohannes Berg 				  struct ieee80211_sub_if_data *sdata,
47234e89507SJohannes Berg 				  struct ieee80211_sta *sta)
47334e89507SJohannes Berg {
47434e89507SJohannes Berg 	might_sleep();
47534e89507SJohannes Berg 
476bc192f89SFelix Fietkau 	sdata = get_bss_sdata(sdata);
477f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
478f6837ba8SJohannes Berg 		return;
4797b7eab6fSJohannes Berg 
4804efc76bdSJohannes Berg 	trace_drv_sta_remove(local, sdata, sta);
48134e89507SJohannes Berg 	if (local->ops->sta_remove)
48234e89507SJohannes Berg 		local->ops->sta_remove(&local->hw, &sdata->vif, sta);
48334e89507SJohannes Berg 
4844efc76bdSJohannes Berg 	trace_drv_return_void(local);
48534e89507SJohannes Berg }
48634e89507SJohannes Berg 
48777d2ece6SSujith Manoharan #ifdef CONFIG_MAC80211_DEBUGFS
48877d2ece6SSujith Manoharan static inline void drv_sta_add_debugfs(struct ieee80211_local *local,
48977d2ece6SSujith Manoharan 				       struct ieee80211_sub_if_data *sdata,
49077d2ece6SSujith Manoharan 				       struct ieee80211_sta *sta,
49177d2ece6SSujith Manoharan 				       struct dentry *dir)
49277d2ece6SSujith Manoharan {
49377d2ece6SSujith Manoharan 	might_sleep();
49477d2ece6SSujith Manoharan 
49577d2ece6SSujith Manoharan 	sdata = get_bss_sdata(sdata);
496f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
497f6837ba8SJohannes Berg 		return;
49877d2ece6SSujith Manoharan 
49977d2ece6SSujith Manoharan 	if (local->ops->sta_add_debugfs)
50077d2ece6SSujith Manoharan 		local->ops->sta_add_debugfs(&local->hw, &sdata->vif,
50177d2ece6SSujith Manoharan 					    sta, dir);
50277d2ece6SSujith Manoharan }
50377d2ece6SSujith Manoharan #endif
50477d2ece6SSujith Manoharan 
5056a9d1b91SJohannes Berg static inline void drv_sta_pre_rcu_remove(struct ieee80211_local *local,
5066a9d1b91SJohannes Berg 					  struct ieee80211_sub_if_data *sdata,
5076a9d1b91SJohannes Berg 					  struct sta_info *sta)
5086a9d1b91SJohannes Berg {
5096a9d1b91SJohannes Berg 	might_sleep();
5106a9d1b91SJohannes Berg 
5116a9d1b91SJohannes Berg 	sdata = get_bss_sdata(sdata);
512f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
513f6837ba8SJohannes Berg 		return;
5146a9d1b91SJohannes Berg 
5156a9d1b91SJohannes Berg 	trace_drv_sta_pre_rcu_remove(local, sdata, &sta->sta);
5166a9d1b91SJohannes Berg 	if (local->ops->sta_pre_rcu_remove)
5176a9d1b91SJohannes Berg 		local->ops->sta_pre_rcu_remove(&local->hw, &sdata->vif,
5186a9d1b91SJohannes Berg 					       &sta->sta);
5196a9d1b91SJohannes Berg 	trace_drv_return_void(local);
5206a9d1b91SJohannes Berg }
5216a9d1b91SJohannes Berg 
522727da60bSDenys Vlasenko __must_check
523f09603a2SJohannes Berg int drv_sta_state(struct ieee80211_local *local,
524f09603a2SJohannes Berg 		  struct ieee80211_sub_if_data *sdata,
525f09603a2SJohannes Berg 		  struct sta_info *sta,
526f09603a2SJohannes Berg 		  enum ieee80211_sta_state old_state,
527727da60bSDenys Vlasenko 		  enum ieee80211_sta_state new_state);
528f09603a2SJohannes Berg 
5294fbd572cSDenys Vlasenko void drv_sta_rc_update(struct ieee80211_local *local,
5308f727ef3SJohannes Berg 		       struct ieee80211_sub_if_data *sdata,
5314fbd572cSDenys Vlasenko 		       struct ieee80211_sta *sta, u32 changed);
5328f727ef3SJohannes Berg 
533f815e2b3SJohannes Berg static inline void drv_sta_rate_tbl_update(struct ieee80211_local *local,
534f815e2b3SJohannes Berg 					   struct ieee80211_sub_if_data *sdata,
535f815e2b3SJohannes Berg 					   struct ieee80211_sta *sta)
536f815e2b3SJohannes Berg {
537f815e2b3SJohannes Berg 	sdata = get_bss_sdata(sdata);
538f815e2b3SJohannes Berg 	if (!check_sdata_in_driver(sdata))
539f815e2b3SJohannes Berg 		return;
540f815e2b3SJohannes Berg 
541f815e2b3SJohannes Berg 	trace_drv_sta_rate_tbl_update(local, sdata, sta);
542f815e2b3SJohannes Berg 	if (local->ops->sta_rate_tbl_update)
543f815e2b3SJohannes Berg 		local->ops->sta_rate_tbl_update(&local->hw, &sdata->vif, sta);
544f815e2b3SJohannes Berg 
545f815e2b3SJohannes Berg 	trace_drv_return_void(local);
546f815e2b3SJohannes Berg }
547f815e2b3SJohannes Berg 
5482b9a7e1bSJohannes Berg static inline void drv_sta_statistics(struct ieee80211_local *local,
5492b9a7e1bSJohannes Berg 				      struct ieee80211_sub_if_data *sdata,
5502b9a7e1bSJohannes Berg 				      struct ieee80211_sta *sta,
5512b9a7e1bSJohannes Berg 				      struct station_info *sinfo)
5522b9a7e1bSJohannes Berg {
5532b9a7e1bSJohannes Berg 	sdata = get_bss_sdata(sdata);
5542b9a7e1bSJohannes Berg 	if (!check_sdata_in_driver(sdata))
5552b9a7e1bSJohannes Berg 		return;
5562b9a7e1bSJohannes Berg 
5572b9a7e1bSJohannes Berg 	trace_drv_sta_statistics(local, sdata, sta);
5582b9a7e1bSJohannes Berg 	if (local->ops->sta_statistics)
5592b9a7e1bSJohannes Berg 		local->ops->sta_statistics(&local->hw, &sdata->vif, sta, sinfo);
5602b9a7e1bSJohannes Berg 	trace_drv_return_void(local);
5612b9a7e1bSJohannes Berg }
5622b9a7e1bSJohannes Berg 
563b23dcd4aSDenys Vlasenko int drv_conf_tx(struct ieee80211_local *local,
564a3304b0aSJohannes Berg 		struct ieee80211_sub_if_data *sdata, u16 ac,
565b23dcd4aSDenys Vlasenko 		const struct ieee80211_tx_queue_params *params);
56624487981SJohannes Berg 
567416eb9fcSDenys Vlasenko u64 drv_get_tsf(struct ieee80211_local *local,
568416eb9fcSDenys Vlasenko 		struct ieee80211_sub_if_data *sdata);
569416eb9fcSDenys Vlasenko void drv_set_tsf(struct ieee80211_local *local,
57037a41b4aSEliad Peller 		 struct ieee80211_sub_if_data *sdata,
571416eb9fcSDenys Vlasenko 		 u64 tsf);
572*354d381bSPedersen, Thomas void drv_offset_tsf(struct ieee80211_local *local,
573*354d381bSPedersen, Thomas 		    struct ieee80211_sub_if_data *sdata,
574*354d381bSPedersen, Thomas 		    s64 offset);
575416eb9fcSDenys Vlasenko void drv_reset_tsf(struct ieee80211_local *local,
576416eb9fcSDenys Vlasenko 		   struct ieee80211_sub_if_data *sdata);
57724487981SJohannes Berg 
57824487981SJohannes Berg static inline int drv_tx_last_beacon(struct ieee80211_local *local)
57924487981SJohannes Berg {
58002582e9bSMasanari Iida 	int ret = 0; /* default unsupported op for less congestion */
581e1781ed3SKalle Valo 
582e1781ed3SKalle Valo 	might_sleep();
583e1781ed3SKalle Valo 
5844efc76bdSJohannes Berg 	trace_drv_tx_last_beacon(local);
58524487981SJohannes Berg 	if (local->ops->tx_last_beacon)
5860a2b8bb2SJohannes Berg 		ret = local->ops->tx_last_beacon(&local->hw);
5874efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
5880a2b8bb2SJohannes Berg 	return ret;
58924487981SJohannes Berg }
59024487981SJohannes Berg 
5916db96838SDenys Vlasenko int drv_ampdu_action(struct ieee80211_local *local,
59212375ef9SJohannes Berg 		     struct ieee80211_sub_if_data *sdata,
59350ea05efSSara Sharon 		     struct ieee80211_ampdu_params *params);
5941f87f7d3SJohannes Berg 
5951289723eSHolger Schurig static inline int drv_get_survey(struct ieee80211_local *local, int idx,
5961289723eSHolger Schurig 				struct survey_info *survey)
5971289723eSHolger Schurig {
5981289723eSHolger Schurig 	int ret = -EOPNOTSUPP;
599c466d4efSJohn W. Linville 
600c466d4efSJohn W. Linville 	trace_drv_get_survey(local, idx, survey);
601c466d4efSJohn W. Linville 
60235dd0509SHolger Schurig 	if (local->ops->get_survey)
6031289723eSHolger Schurig 		ret = local->ops->get_survey(&local->hw, idx, survey);
604c466d4efSJohn W. Linville 
605c466d4efSJohn W. Linville 	trace_drv_return_int(local, ret);
606c466d4efSJohn W. Linville 
6071289723eSHolger Schurig 	return ret;
6081289723eSHolger Schurig }
6091f87f7d3SJohannes Berg 
6101f87f7d3SJohannes Berg static inline void drv_rfkill_poll(struct ieee80211_local *local)
6111f87f7d3SJohannes Berg {
612e1781ed3SKalle Valo 	might_sleep();
613e1781ed3SKalle Valo 
6141f87f7d3SJohannes Berg 	if (local->ops->rfkill_poll)
6151f87f7d3SJohannes Berg 		local->ops->rfkill_poll(&local->hw);
6161f87f7d3SJohannes Berg }
617a80f7c0bSJohannes Berg 
61839ecc01dSJohannes Berg static inline void drv_flush(struct ieee80211_local *local,
61977be2c54SEmmanuel Grumbach 			     struct ieee80211_sub_if_data *sdata,
62039ecc01dSJohannes Berg 			     u32 queues, bool drop)
621a80f7c0bSJohannes Berg {
62277be2c54SEmmanuel Grumbach 	struct ieee80211_vif *vif = sdata ? &sdata->vif : NULL;
62377be2c54SEmmanuel Grumbach 
624e1781ed3SKalle Valo 	might_sleep();
625e1781ed3SKalle Valo 
626f6837ba8SJohannes Berg 	if (sdata && !check_sdata_in_driver(sdata))
627f6837ba8SJohannes Berg 		return;
62877be2c54SEmmanuel Grumbach 
62939ecc01dSJohannes Berg 	trace_drv_flush(local, queues, drop);
630a80f7c0bSJohannes Berg 	if (local->ops->flush)
63177be2c54SEmmanuel Grumbach 		local->ops->flush(&local->hw, vif, queues, drop);
6324efc76bdSJohannes Berg 	trace_drv_return_void(local);
633a80f7c0bSJohannes Berg }
6345ce6e438SJohannes Berg 
6355ce6e438SJohannes Berg static inline void drv_channel_switch(struct ieee80211_local *local,
6360f791eb4SLuciano Coelho 				      struct ieee80211_sub_if_data *sdata,
6375ce6e438SJohannes Berg 				      struct ieee80211_channel_switch *ch_switch)
6385ce6e438SJohannes Berg {
6395ce6e438SJohannes Berg 	might_sleep();
6405ce6e438SJohannes Berg 
6410f791eb4SLuciano Coelho 	trace_drv_channel_switch(local, sdata, ch_switch);
6420f791eb4SLuciano Coelho 	local->ops->channel_switch(&local->hw, &sdata->vif, ch_switch);
6434efc76bdSJohannes Berg 	trace_drv_return_void(local);
6445ce6e438SJohannes Berg }
6455ce6e438SJohannes Berg 
64615d96753SBruno Randolf 
64715d96753SBruno Randolf static inline int drv_set_antenna(struct ieee80211_local *local,
64815d96753SBruno Randolf 				  u32 tx_ant, u32 rx_ant)
64915d96753SBruno Randolf {
65015d96753SBruno Randolf 	int ret = -EOPNOTSUPP;
65115d96753SBruno Randolf 	might_sleep();
65215d96753SBruno Randolf 	if (local->ops->set_antenna)
65315d96753SBruno Randolf 		ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant);
65415d96753SBruno Randolf 	trace_drv_set_antenna(local, tx_ant, rx_ant, ret);
65515d96753SBruno Randolf 	return ret;
65615d96753SBruno Randolf }
65715d96753SBruno Randolf 
65815d96753SBruno Randolf static inline int drv_get_antenna(struct ieee80211_local *local,
65915d96753SBruno Randolf 				  u32 *tx_ant, u32 *rx_ant)
66015d96753SBruno Randolf {
66115d96753SBruno Randolf 	int ret = -EOPNOTSUPP;
66215d96753SBruno Randolf 	might_sleep();
66315d96753SBruno Randolf 	if (local->ops->get_antenna)
66415d96753SBruno Randolf 		ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant);
66515d96753SBruno Randolf 	trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret);
66615d96753SBruno Randolf 	return ret;
66715d96753SBruno Randolf }
66815d96753SBruno Randolf 
66921f83589SJohannes Berg static inline int drv_remain_on_channel(struct ieee80211_local *local,
67049884568SEliad Peller 					struct ieee80211_sub_if_data *sdata,
67121f83589SJohannes Berg 					struct ieee80211_channel *chan,
672d339d5caSIlan Peer 					unsigned int duration,
673d339d5caSIlan Peer 					enum ieee80211_roc_type type)
67421f83589SJohannes Berg {
67521f83589SJohannes Berg 	int ret;
67621f83589SJohannes Berg 
67721f83589SJohannes Berg 	might_sleep();
67821f83589SJohannes Berg 
679d339d5caSIlan Peer 	trace_drv_remain_on_channel(local, sdata, chan, duration, type);
68049884568SEliad Peller 	ret = local->ops->remain_on_channel(&local->hw, &sdata->vif,
681d339d5caSIlan Peer 					    chan, duration, type);
68221f83589SJohannes Berg 	trace_drv_return_int(local, ret);
68321f83589SJohannes Berg 
68421f83589SJohannes Berg 	return ret;
68521f83589SJohannes Berg }
68621f83589SJohannes Berg 
68721f83589SJohannes Berg static inline int drv_cancel_remain_on_channel(struct ieee80211_local *local)
68821f83589SJohannes Berg {
68921f83589SJohannes Berg 	int ret;
69021f83589SJohannes Berg 
69121f83589SJohannes Berg 	might_sleep();
69221f83589SJohannes Berg 
69321f83589SJohannes Berg 	trace_drv_cancel_remain_on_channel(local);
69421f83589SJohannes Berg 	ret = local->ops->cancel_remain_on_channel(&local->hw);
69521f83589SJohannes Berg 	trace_drv_return_int(local, ret);
69621f83589SJohannes Berg 
69721f83589SJohannes Berg 	return ret;
69821f83589SJohannes Berg }
69921f83589SJohannes Berg 
70038c09159SJohn W. Linville static inline int drv_set_ringparam(struct ieee80211_local *local,
70138c09159SJohn W. Linville 				    u32 tx, u32 rx)
70238c09159SJohn W. Linville {
70338c09159SJohn W. Linville 	int ret = -ENOTSUPP;
70438c09159SJohn W. Linville 
70538c09159SJohn W. Linville 	might_sleep();
70638c09159SJohn W. Linville 
70738c09159SJohn W. Linville 	trace_drv_set_ringparam(local, tx, rx);
70838c09159SJohn W. Linville 	if (local->ops->set_ringparam)
70938c09159SJohn W. Linville 		ret = local->ops->set_ringparam(&local->hw, tx, rx);
71038c09159SJohn W. Linville 	trace_drv_return_int(local, ret);
71138c09159SJohn W. Linville 
71238c09159SJohn W. Linville 	return ret;
71338c09159SJohn W. Linville }
71438c09159SJohn W. Linville 
71538c09159SJohn W. Linville static inline void drv_get_ringparam(struct ieee80211_local *local,
71638c09159SJohn W. Linville 				     u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
71738c09159SJohn W. Linville {
71838c09159SJohn W. Linville 	might_sleep();
71938c09159SJohn W. Linville 
72038c09159SJohn W. Linville 	trace_drv_get_ringparam(local, tx, tx_max, rx, rx_max);
72138c09159SJohn W. Linville 	if (local->ops->get_ringparam)
72238c09159SJohn W. Linville 		local->ops->get_ringparam(&local->hw, tx, tx_max, rx, rx_max);
72338c09159SJohn W. Linville 	trace_drv_return_void(local);
72438c09159SJohn W. Linville }
72538c09159SJohn W. Linville 
726e8306f98SVivek Natarajan static inline bool drv_tx_frames_pending(struct ieee80211_local *local)
727e8306f98SVivek Natarajan {
728e8306f98SVivek Natarajan 	bool ret = false;
729e8306f98SVivek Natarajan 
730e8306f98SVivek Natarajan 	might_sleep();
731e8306f98SVivek Natarajan 
732e8306f98SVivek Natarajan 	trace_drv_tx_frames_pending(local);
733e8306f98SVivek Natarajan 	if (local->ops->tx_frames_pending)
734e8306f98SVivek Natarajan 		ret = local->ops->tx_frames_pending(&local->hw);
735e8306f98SVivek Natarajan 	trace_drv_return_bool(local, ret);
736e8306f98SVivek Natarajan 
737e8306f98SVivek Natarajan 	return ret;
738e8306f98SVivek Natarajan }
739bdbfd6b5SSujith Manoharan 
740bdbfd6b5SSujith Manoharan static inline int drv_set_bitrate_mask(struct ieee80211_local *local,
741bdbfd6b5SSujith Manoharan 				       struct ieee80211_sub_if_data *sdata,
742bdbfd6b5SSujith Manoharan 				       const struct cfg80211_bitrate_mask *mask)
743bdbfd6b5SSujith Manoharan {
744bdbfd6b5SSujith Manoharan 	int ret = -EOPNOTSUPP;
745bdbfd6b5SSujith Manoharan 
746bdbfd6b5SSujith Manoharan 	might_sleep();
747bdbfd6b5SSujith Manoharan 
748f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
749f6837ba8SJohannes Berg 		return -EIO;
7507b7eab6fSJohannes Berg 
751bdbfd6b5SSujith Manoharan 	trace_drv_set_bitrate_mask(local, sdata, mask);
752bdbfd6b5SSujith Manoharan 	if (local->ops->set_bitrate_mask)
753bdbfd6b5SSujith Manoharan 		ret = local->ops->set_bitrate_mask(&local->hw,
754bdbfd6b5SSujith Manoharan 						   &sdata->vif, mask);
755bdbfd6b5SSujith Manoharan 	trace_drv_return_int(local, ret);
756bdbfd6b5SSujith Manoharan 
757bdbfd6b5SSujith Manoharan 	return ret;
758bdbfd6b5SSujith Manoharan }
759bdbfd6b5SSujith Manoharan 
760c68f4b89SJohannes Berg static inline void drv_set_rekey_data(struct ieee80211_local *local,
761c68f4b89SJohannes Berg 				      struct ieee80211_sub_if_data *sdata,
762c68f4b89SJohannes Berg 				      struct cfg80211_gtk_rekey_data *data)
763c68f4b89SJohannes Berg {
764f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
765f6837ba8SJohannes Berg 		return;
7667b7eab6fSJohannes Berg 
767c68f4b89SJohannes Berg 	trace_drv_set_rekey_data(local, sdata, data);
768c68f4b89SJohannes Berg 	if (local->ops->set_rekey_data)
769c68f4b89SJohannes Berg 		local->ops->set_rekey_data(&local->hw, &sdata->vif, data);
770c68f4b89SJohannes Berg 	trace_drv_return_void(local);
771c68f4b89SJohannes Berg }
772c68f4b89SJohannes Berg 
773a8182929SEmmanuel Grumbach static inline void drv_event_callback(struct ieee80211_local *local,
774887da917SEmmanuel Grumbach 				      struct ieee80211_sub_if_data *sdata,
775a8182929SEmmanuel Grumbach 				      const struct ieee80211_event *event)
776615f7b9bSMeenakshi Venkataraman {
777a8182929SEmmanuel Grumbach 	trace_drv_event_callback(local, sdata, event);
778a8182929SEmmanuel Grumbach 	if (local->ops->event_callback)
779a8182929SEmmanuel Grumbach 		local->ops->event_callback(&local->hw, &sdata->vif, event);
780615f7b9bSMeenakshi Venkataraman 	trace_drv_return_void(local);
781615f7b9bSMeenakshi Venkataraman }
7824049e09aSJohannes Berg 
7834049e09aSJohannes Berg static inline void
7844049e09aSJohannes Berg drv_release_buffered_frames(struct ieee80211_local *local,
7854049e09aSJohannes Berg 			    struct sta_info *sta, u16 tids, int num_frames,
7864049e09aSJohannes Berg 			    enum ieee80211_frame_release_type reason,
7874049e09aSJohannes Berg 			    bool more_data)
7884049e09aSJohannes Berg {
7894049e09aSJohannes Berg 	trace_drv_release_buffered_frames(local, &sta->sta, tids, num_frames,
7904049e09aSJohannes Berg 					  reason, more_data);
7914049e09aSJohannes Berg 	if (local->ops->release_buffered_frames)
7924049e09aSJohannes Berg 		local->ops->release_buffered_frames(&local->hw, &sta->sta, tids,
7934049e09aSJohannes Berg 						    num_frames, reason,
7944049e09aSJohannes Berg 						    more_data);
7954049e09aSJohannes Berg 	trace_drv_return_void(local);
7964049e09aSJohannes Berg }
79740b96408SJohannes Berg 
79840b96408SJohannes Berg static inline void
79940b96408SJohannes Berg drv_allow_buffered_frames(struct ieee80211_local *local,
80040b96408SJohannes Berg 			  struct sta_info *sta, u16 tids, int num_frames,
80140b96408SJohannes Berg 			  enum ieee80211_frame_release_type reason,
80240b96408SJohannes Berg 			  bool more_data)
80340b96408SJohannes Berg {
80440b96408SJohannes Berg 	trace_drv_allow_buffered_frames(local, &sta->sta, tids, num_frames,
80540b96408SJohannes Berg 					reason, more_data);
80640b96408SJohannes Berg 	if (local->ops->allow_buffered_frames)
80740b96408SJohannes Berg 		local->ops->allow_buffered_frames(&local->hw, &sta->sta,
80840b96408SJohannes Berg 						  tids, num_frames, reason,
80940b96408SJohannes Berg 						  more_data);
81040b96408SJohannes Berg 	trace_drv_return_void(local);
81140b96408SJohannes Berg }
81266572cfcSVictor Goldenshtein 
813a1845fc7SJohannes Berg static inline void drv_mgd_prepare_tx(struct ieee80211_local *local,
814a1845fc7SJohannes Berg 				      struct ieee80211_sub_if_data *sdata)
815a1845fc7SJohannes Berg {
816a1845fc7SJohannes Berg 	might_sleep();
817a1845fc7SJohannes Berg 
818f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
819f6837ba8SJohannes Berg 		return;
820a1845fc7SJohannes Berg 	WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
821a1845fc7SJohannes Berg 
822a1845fc7SJohannes Berg 	trace_drv_mgd_prepare_tx(local, sdata);
823a1845fc7SJohannes Berg 	if (local->ops->mgd_prepare_tx)
824a1845fc7SJohannes Berg 		local->ops->mgd_prepare_tx(&local->hw, &sdata->vif);
825a1845fc7SJohannes Berg 	trace_drv_return_void(local);
826a1845fc7SJohannes Berg }
827c3645eacSMichal Kazior 
828ee10f2c7SArik Nemtsov static inline void
829ee10f2c7SArik Nemtsov drv_mgd_protect_tdls_discover(struct ieee80211_local *local,
830ee10f2c7SArik Nemtsov 			      struct ieee80211_sub_if_data *sdata)
831ee10f2c7SArik Nemtsov {
832ee10f2c7SArik Nemtsov 	might_sleep();
833ee10f2c7SArik Nemtsov 
834ee10f2c7SArik Nemtsov 	if (!check_sdata_in_driver(sdata))
835ee10f2c7SArik Nemtsov 		return;
836ee10f2c7SArik Nemtsov 	WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
837ee10f2c7SArik Nemtsov 
838ee10f2c7SArik Nemtsov 	trace_drv_mgd_protect_tdls_discover(local, sdata);
839ee10f2c7SArik Nemtsov 	if (local->ops->mgd_protect_tdls_discover)
840ee10f2c7SArik Nemtsov 		local->ops->mgd_protect_tdls_discover(&local->hw, &sdata->vif);
841ee10f2c7SArik Nemtsov 	trace_drv_return_void(local);
842ee10f2c7SArik Nemtsov }
843ee10f2c7SArik Nemtsov 
844c3645eacSMichal Kazior static inline int drv_add_chanctx(struct ieee80211_local *local,
845c3645eacSMichal Kazior 				  struct ieee80211_chanctx *ctx)
846c3645eacSMichal Kazior {
847c3645eacSMichal Kazior 	int ret = -EOPNOTSUPP;
848c3645eacSMichal Kazior 
849dcae9e02SChaitanya T K 	might_sleep();
850dcae9e02SChaitanya T K 
851c3645eacSMichal Kazior 	trace_drv_add_chanctx(local, ctx);
852c3645eacSMichal Kazior 	if (local->ops->add_chanctx)
853c3645eacSMichal Kazior 		ret = local->ops->add_chanctx(&local->hw, &ctx->conf);
854c3645eacSMichal Kazior 	trace_drv_return_int(local, ret);
8558a61af65SJohannes Berg 	if (!ret)
8568a61af65SJohannes Berg 		ctx->driver_present = true;
857c3645eacSMichal Kazior 
858c3645eacSMichal Kazior 	return ret;
859c3645eacSMichal Kazior }
860c3645eacSMichal Kazior 
861c3645eacSMichal Kazior static inline void drv_remove_chanctx(struct ieee80211_local *local,
862c3645eacSMichal Kazior 				      struct ieee80211_chanctx *ctx)
863c3645eacSMichal Kazior {
864dcae9e02SChaitanya T K 	might_sleep();
865dcae9e02SChaitanya T K 
866f6837ba8SJohannes Berg 	if (WARN_ON(!ctx->driver_present))
867f6837ba8SJohannes Berg 		return;
868f6837ba8SJohannes Berg 
869c3645eacSMichal Kazior 	trace_drv_remove_chanctx(local, ctx);
870c3645eacSMichal Kazior 	if (local->ops->remove_chanctx)
871c3645eacSMichal Kazior 		local->ops->remove_chanctx(&local->hw, &ctx->conf);
872c3645eacSMichal Kazior 	trace_drv_return_void(local);
8738a61af65SJohannes Berg 	ctx->driver_present = false;
874c3645eacSMichal Kazior }
875c3645eacSMichal Kazior 
876c3645eacSMichal Kazior static inline void drv_change_chanctx(struct ieee80211_local *local,
877c3645eacSMichal Kazior 				      struct ieee80211_chanctx *ctx,
878c3645eacSMichal Kazior 				      u32 changed)
879c3645eacSMichal Kazior {
880dcae9e02SChaitanya T K 	might_sleep();
881dcae9e02SChaitanya T K 
882c3645eacSMichal Kazior 	trace_drv_change_chanctx(local, ctx, changed);
8838a61af65SJohannes Berg 	if (local->ops->change_chanctx) {
8848a61af65SJohannes Berg 		WARN_ON_ONCE(!ctx->driver_present);
885c3645eacSMichal Kazior 		local->ops->change_chanctx(&local->hw, &ctx->conf, changed);
8868a61af65SJohannes Berg 	}
887c3645eacSMichal Kazior 	trace_drv_return_void(local);
888c3645eacSMichal Kazior }
889c3645eacSMichal Kazior 
890c3645eacSMichal Kazior static inline int drv_assign_vif_chanctx(struct ieee80211_local *local,
891c3645eacSMichal Kazior 					 struct ieee80211_sub_if_data *sdata,
892c3645eacSMichal Kazior 					 struct ieee80211_chanctx *ctx)
893c3645eacSMichal Kazior {
894c3645eacSMichal Kazior 	int ret = 0;
895c3645eacSMichal Kazior 
896f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
897f6837ba8SJohannes Berg 		return -EIO;
898c3645eacSMichal Kazior 
899c3645eacSMichal Kazior 	trace_drv_assign_vif_chanctx(local, sdata, ctx);
9008a61af65SJohannes Berg 	if (local->ops->assign_vif_chanctx) {
9018a61af65SJohannes Berg 		WARN_ON_ONCE(!ctx->driver_present);
902c3645eacSMichal Kazior 		ret = local->ops->assign_vif_chanctx(&local->hw,
903c3645eacSMichal Kazior 						     &sdata->vif,
904c3645eacSMichal Kazior 						     &ctx->conf);
9058a61af65SJohannes Berg 	}
906c3645eacSMichal Kazior 	trace_drv_return_int(local, ret);
907c3645eacSMichal Kazior 
908c3645eacSMichal Kazior 	return ret;
909c3645eacSMichal Kazior }
910c3645eacSMichal Kazior 
911c3645eacSMichal Kazior static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local,
912c3645eacSMichal Kazior 					    struct ieee80211_sub_if_data *sdata,
913c3645eacSMichal Kazior 					    struct ieee80211_chanctx *ctx)
914c3645eacSMichal Kazior {
915dcae9e02SChaitanya T K 	might_sleep();
916dcae9e02SChaitanya T K 
917f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
918f6837ba8SJohannes Berg 		return;
919c3645eacSMichal Kazior 
920c3645eacSMichal Kazior 	trace_drv_unassign_vif_chanctx(local, sdata, ctx);
9218a61af65SJohannes Berg 	if (local->ops->unassign_vif_chanctx) {
9228a61af65SJohannes Berg 		WARN_ON_ONCE(!ctx->driver_present);
923c3645eacSMichal Kazior 		local->ops->unassign_vif_chanctx(&local->hw,
924c3645eacSMichal Kazior 						 &sdata->vif,
925c3645eacSMichal Kazior 						 &ctx->conf);
9268a61af65SJohannes Berg 	}
927c3645eacSMichal Kazior 	trace_drv_return_void(local);
928c3645eacSMichal Kazior }
929c3645eacSMichal Kazior 
93042677ed3SDenys Vlasenko int drv_switch_vif_chanctx(struct ieee80211_local *local,
9311a5f0c13SLuciano Coelho 			   struct ieee80211_vif_chanctx_switch *vifs,
93242677ed3SDenys Vlasenko 			   int n_vifs, enum ieee80211_chanctx_switch_mode mode);
9331a5f0c13SLuciano Coelho 
9341041638fSJohannes Berg static inline int drv_start_ap(struct ieee80211_local *local,
9351041638fSJohannes Berg 			       struct ieee80211_sub_if_data *sdata)
9361041638fSJohannes Berg {
9371041638fSJohannes Berg 	int ret = 0;
9381041638fSJohannes Berg 
939dcae9e02SChaitanya T K 	might_sleep();
940dcae9e02SChaitanya T K 
941f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
942f6837ba8SJohannes Berg 		return -EIO;
9431041638fSJohannes Berg 
9441041638fSJohannes Berg 	trace_drv_start_ap(local, sdata, &sdata->vif.bss_conf);
9451041638fSJohannes Berg 	if (local->ops->start_ap)
9461041638fSJohannes Berg 		ret = local->ops->start_ap(&local->hw, &sdata->vif);
9471041638fSJohannes Berg 	trace_drv_return_int(local, ret);
9481041638fSJohannes Berg 	return ret;
9491041638fSJohannes Berg }
9501041638fSJohannes Berg 
9511041638fSJohannes Berg static inline void drv_stop_ap(struct ieee80211_local *local,
9521041638fSJohannes Berg 			       struct ieee80211_sub_if_data *sdata)
9531041638fSJohannes Berg {
954f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
955f6837ba8SJohannes Berg 		return;
9561041638fSJohannes Berg 
9571041638fSJohannes Berg 	trace_drv_stop_ap(local, sdata);
9581041638fSJohannes Berg 	if (local->ops->stop_ap)
9591041638fSJohannes Berg 		local->ops->stop_ap(&local->hw, &sdata->vif);
9601041638fSJohannes Berg 	trace_drv_return_void(local);
9611041638fSJohannes Berg }
9621041638fSJohannes Berg 
963cf2c92d8SEliad Peller static inline void
964cf2c92d8SEliad Peller drv_reconfig_complete(struct ieee80211_local *local,
965cf2c92d8SEliad Peller 		      enum ieee80211_reconfig_type reconfig_type)
9669214ad7fSJohannes Berg {
9679214ad7fSJohannes Berg 	might_sleep();
9689214ad7fSJohannes Berg 
969cf2c92d8SEliad Peller 	trace_drv_reconfig_complete(local, reconfig_type);
970cf2c92d8SEliad Peller 	if (local->ops->reconfig_complete)
971cf2c92d8SEliad Peller 		local->ops->reconfig_complete(&local->hw, reconfig_type);
9729214ad7fSJohannes Berg 	trace_drv_return_void(local);
9739214ad7fSJohannes Berg }
9749214ad7fSJohannes Berg 
975de5fad81SYoni Divinsky static inline void
976de5fad81SYoni Divinsky drv_set_default_unicast_key(struct ieee80211_local *local,
977de5fad81SYoni Divinsky 			    struct ieee80211_sub_if_data *sdata,
978de5fad81SYoni Divinsky 			    int key_idx)
979de5fad81SYoni Divinsky {
980f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
981f6837ba8SJohannes Berg 		return;
982de5fad81SYoni Divinsky 
983de5fad81SYoni Divinsky 	WARN_ON_ONCE(key_idx < -1 || key_idx > 3);
984de5fad81SYoni Divinsky 
985de5fad81SYoni Divinsky 	trace_drv_set_default_unicast_key(local, sdata, key_idx);
986de5fad81SYoni Divinsky 	if (local->ops->set_default_unicast_key)
987de5fad81SYoni Divinsky 		local->ops->set_default_unicast_key(&local->hw, &sdata->vif,
988de5fad81SYoni Divinsky 						    key_idx);
989de5fad81SYoni Divinsky 	trace_drv_return_void(local);
990de5fad81SYoni Divinsky }
991de5fad81SYoni Divinsky 
992a65240c1SJohannes Berg #if IS_ENABLED(CONFIG_IPV6)
993a65240c1SJohannes Berg static inline void drv_ipv6_addr_change(struct ieee80211_local *local,
994a65240c1SJohannes Berg 					struct ieee80211_sub_if_data *sdata,
995a65240c1SJohannes Berg 					struct inet6_dev *idev)
996a65240c1SJohannes Berg {
997a65240c1SJohannes Berg 	trace_drv_ipv6_addr_change(local, sdata);
998a65240c1SJohannes Berg 	if (local->ops->ipv6_addr_change)
999a65240c1SJohannes Berg 		local->ops->ipv6_addr_change(&local->hw, &sdata->vif, idev);
1000a65240c1SJohannes Berg 	trace_drv_return_void(local);
1001a65240c1SJohannes Berg }
1002a65240c1SJohannes Berg #endif
1003a65240c1SJohannes Berg 
100473da7d5bSSimon Wunderlich static inline void
100573da7d5bSSimon Wunderlich drv_channel_switch_beacon(struct ieee80211_sub_if_data *sdata,
100673da7d5bSSimon Wunderlich 			  struct cfg80211_chan_def *chandef)
100773da7d5bSSimon Wunderlich {
100873da7d5bSSimon Wunderlich 	struct ieee80211_local *local = sdata->local;
100973da7d5bSSimon Wunderlich 
101073da7d5bSSimon Wunderlich 	if (local->ops->channel_switch_beacon) {
101173da7d5bSSimon Wunderlich 		trace_drv_channel_switch_beacon(local, sdata, chandef);
101273da7d5bSSimon Wunderlich 		local->ops->channel_switch_beacon(&local->hw, &sdata->vif,
101373da7d5bSSimon Wunderlich 						  chandef);
101473da7d5bSSimon Wunderlich 	}
101573da7d5bSSimon Wunderlich }
101673da7d5bSSimon Wunderlich 
10176d027bccSLuciano Coelho static inline int
10186d027bccSLuciano Coelho drv_pre_channel_switch(struct ieee80211_sub_if_data *sdata,
10196d027bccSLuciano Coelho 		       struct ieee80211_channel_switch *ch_switch)
10206d027bccSLuciano Coelho {
10216d027bccSLuciano Coelho 	struct ieee80211_local *local = sdata->local;
10226d027bccSLuciano Coelho 	int ret = 0;
10236d027bccSLuciano Coelho 
10246d027bccSLuciano Coelho 	if (!check_sdata_in_driver(sdata))
10256d027bccSLuciano Coelho 		return -EIO;
10266d027bccSLuciano Coelho 
10276d027bccSLuciano Coelho 	trace_drv_pre_channel_switch(local, sdata, ch_switch);
10286d027bccSLuciano Coelho 	if (local->ops->pre_channel_switch)
10296d027bccSLuciano Coelho 		ret = local->ops->pre_channel_switch(&local->hw, &sdata->vif,
10306d027bccSLuciano Coelho 						     ch_switch);
10316d027bccSLuciano Coelho 	trace_drv_return_int(local, ret);
10326d027bccSLuciano Coelho 	return ret;
10336d027bccSLuciano Coelho }
10346d027bccSLuciano Coelho 
1035f1d65583SLuciano Coelho static inline int
1036f1d65583SLuciano Coelho drv_post_channel_switch(struct ieee80211_sub_if_data *sdata)
1037f1d65583SLuciano Coelho {
1038f1d65583SLuciano Coelho 	struct ieee80211_local *local = sdata->local;
1039f1d65583SLuciano Coelho 	int ret = 0;
1040f1d65583SLuciano Coelho 
1041f1d65583SLuciano Coelho 	if (!check_sdata_in_driver(sdata))
1042f1d65583SLuciano Coelho 		return -EIO;
1043f1d65583SLuciano Coelho 
1044f1d65583SLuciano Coelho 	trace_drv_post_channel_switch(local, sdata);
1045f1d65583SLuciano Coelho 	if (local->ops->post_channel_switch)
1046f1d65583SLuciano Coelho 		ret = local->ops->post_channel_switch(&local->hw, &sdata->vif);
1047f1d65583SLuciano Coelho 	trace_drv_return_int(local, ret);
1048f1d65583SLuciano Coelho 	return ret;
1049f1d65583SLuciano Coelho }
1050f1d65583SLuciano Coelho 
105155fff501SJohannes Berg static inline int drv_join_ibss(struct ieee80211_local *local,
105255fff501SJohannes Berg 				struct ieee80211_sub_if_data *sdata)
105355fff501SJohannes Berg {
105455fff501SJohannes Berg 	int ret = 0;
105555fff501SJohannes Berg 
105655fff501SJohannes Berg 	might_sleep();
1057f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
1058f6837ba8SJohannes Berg 		return -EIO;
105955fff501SJohannes Berg 
106055fff501SJohannes Berg 	trace_drv_join_ibss(local, sdata, &sdata->vif.bss_conf);
106155fff501SJohannes Berg 	if (local->ops->join_ibss)
106255fff501SJohannes Berg 		ret = local->ops->join_ibss(&local->hw, &sdata->vif);
106355fff501SJohannes Berg 	trace_drv_return_int(local, ret);
106455fff501SJohannes Berg 	return ret;
106555fff501SJohannes Berg }
106655fff501SJohannes Berg 
106755fff501SJohannes Berg static inline void drv_leave_ibss(struct ieee80211_local *local,
106855fff501SJohannes Berg 				  struct ieee80211_sub_if_data *sdata)
106955fff501SJohannes Berg {
107055fff501SJohannes Berg 	might_sleep();
1071f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
1072f6837ba8SJohannes Berg 		return;
107355fff501SJohannes Berg 
107455fff501SJohannes Berg 	trace_drv_leave_ibss(local, sdata);
107555fff501SJohannes Berg 	if (local->ops->leave_ibss)
107655fff501SJohannes Berg 		local->ops->leave_ibss(&local->hw, &sdata->vif);
107755fff501SJohannes Berg 	trace_drv_return_void(local);
107855fff501SJohannes Berg }
107955fff501SJohannes Berg 
1080cca674d4SAntonio Quartulli static inline u32 drv_get_expected_throughput(struct ieee80211_local *local,
10814fdbc67aSMaxim Altshul 					      struct sta_info *sta)
1082cca674d4SAntonio Quartulli {
1083cca674d4SAntonio Quartulli 	u32 ret = 0;
1084cca674d4SAntonio Quartulli 
10854fdbc67aSMaxim Altshul 	trace_drv_get_expected_throughput(&sta->sta);
10864fdbc67aSMaxim Altshul 	if (local->ops->get_expected_throughput && sta->uploaded)
10874fdbc67aSMaxim Altshul 		ret = local->ops->get_expected_throughput(&local->hw, &sta->sta);
1088cca674d4SAntonio Quartulli 	trace_drv_return_u32(local, ret);
1089cca674d4SAntonio Quartulli 
1090cca674d4SAntonio Quartulli 	return ret;
1091cca674d4SAntonio Quartulli }
1092cca674d4SAntonio Quartulli 
10935b3dc42bSFelix Fietkau static inline int drv_get_txpower(struct ieee80211_local *local,
10945b3dc42bSFelix Fietkau 				  struct ieee80211_sub_if_data *sdata, int *dbm)
10955b3dc42bSFelix Fietkau {
10965b3dc42bSFelix Fietkau 	int ret;
10975b3dc42bSFelix Fietkau 
10985b3dc42bSFelix Fietkau 	if (!local->ops->get_txpower)
10995b3dc42bSFelix Fietkau 		return -EOPNOTSUPP;
11005b3dc42bSFelix Fietkau 
11015b3dc42bSFelix Fietkau 	ret = local->ops->get_txpower(&local->hw, &sdata->vif, dbm);
11025b3dc42bSFelix Fietkau 	trace_drv_get_txpower(local, sdata, *dbm, ret);
11035b3dc42bSFelix Fietkau 
11045b3dc42bSFelix Fietkau 	return ret;
11055b3dc42bSFelix Fietkau }
11065b3dc42bSFelix Fietkau 
1107a7a6bdd0SArik Nemtsov static inline int
1108a7a6bdd0SArik Nemtsov drv_tdls_channel_switch(struct ieee80211_local *local,
1109a7a6bdd0SArik Nemtsov 			struct ieee80211_sub_if_data *sdata,
1110a7a6bdd0SArik Nemtsov 			struct ieee80211_sta *sta, u8 oper_class,
1111a7a6bdd0SArik Nemtsov 			struct cfg80211_chan_def *chandef,
1112a7a6bdd0SArik Nemtsov 			struct sk_buff *tmpl_skb, u32 ch_sw_tm_ie)
1113a7a6bdd0SArik Nemtsov {
1114a7a6bdd0SArik Nemtsov 	int ret;
1115a7a6bdd0SArik Nemtsov 
1116a7a6bdd0SArik Nemtsov 	might_sleep();
1117a7a6bdd0SArik Nemtsov 	if (!check_sdata_in_driver(sdata))
1118a7a6bdd0SArik Nemtsov 		return -EIO;
1119a7a6bdd0SArik Nemtsov 
1120a7a6bdd0SArik Nemtsov 	if (!local->ops->tdls_channel_switch)
1121a7a6bdd0SArik Nemtsov 		return -EOPNOTSUPP;
1122a7a6bdd0SArik Nemtsov 
1123a7a6bdd0SArik Nemtsov 	trace_drv_tdls_channel_switch(local, sdata, sta, oper_class, chandef);
1124a7a6bdd0SArik Nemtsov 	ret = local->ops->tdls_channel_switch(&local->hw, &sdata->vif, sta,
1125a7a6bdd0SArik Nemtsov 					      oper_class, chandef, tmpl_skb,
1126a7a6bdd0SArik Nemtsov 					      ch_sw_tm_ie);
1127a7a6bdd0SArik Nemtsov 	trace_drv_return_int(local, ret);
1128a7a6bdd0SArik Nemtsov 	return ret;
1129a7a6bdd0SArik Nemtsov }
1130a7a6bdd0SArik Nemtsov 
1131a7a6bdd0SArik Nemtsov static inline void
1132a7a6bdd0SArik Nemtsov drv_tdls_cancel_channel_switch(struct ieee80211_local *local,
1133a7a6bdd0SArik Nemtsov 			       struct ieee80211_sub_if_data *sdata,
1134a7a6bdd0SArik Nemtsov 			       struct ieee80211_sta *sta)
1135a7a6bdd0SArik Nemtsov {
1136a7a6bdd0SArik Nemtsov 	might_sleep();
1137a7a6bdd0SArik Nemtsov 	if (!check_sdata_in_driver(sdata))
1138a7a6bdd0SArik Nemtsov 		return;
1139a7a6bdd0SArik Nemtsov 
1140a7a6bdd0SArik Nemtsov 	if (!local->ops->tdls_cancel_channel_switch)
1141a7a6bdd0SArik Nemtsov 		return;
1142a7a6bdd0SArik Nemtsov 
1143a7a6bdd0SArik Nemtsov 	trace_drv_tdls_cancel_channel_switch(local, sdata, sta);
1144a7a6bdd0SArik Nemtsov 	local->ops->tdls_cancel_channel_switch(&local->hw, &sdata->vif, sta);
1145a7a6bdd0SArik Nemtsov 	trace_drv_return_void(local);
1146a7a6bdd0SArik Nemtsov }
1147a7a6bdd0SArik Nemtsov 
11488a4d32f3SArik Nemtsov static inline void
11498a4d32f3SArik Nemtsov drv_tdls_recv_channel_switch(struct ieee80211_local *local,
11508a4d32f3SArik Nemtsov 			     struct ieee80211_sub_if_data *sdata,
11518a4d32f3SArik Nemtsov 			     struct ieee80211_tdls_ch_sw_params *params)
11528a4d32f3SArik Nemtsov {
11538a4d32f3SArik Nemtsov 	trace_drv_tdls_recv_channel_switch(local, sdata, params);
11548a4d32f3SArik Nemtsov 	if (local->ops->tdls_recv_channel_switch)
11558a4d32f3SArik Nemtsov 		local->ops->tdls_recv_channel_switch(&local->hw, &sdata->vif,
11568a4d32f3SArik Nemtsov 						     params);
11578a4d32f3SArik Nemtsov 	trace_drv_return_void(local);
11588a4d32f3SArik Nemtsov }
11598a4d32f3SArik Nemtsov 
1160ba8c3d6fSFelix Fietkau static inline void drv_wake_tx_queue(struct ieee80211_local *local,
1161ba8c3d6fSFelix Fietkau 				     struct txq_info *txq)
1162ba8c3d6fSFelix Fietkau {
1163ba8c3d6fSFelix Fietkau 	struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->txq.vif);
1164ba8c3d6fSFelix Fietkau 
1165ba8c3d6fSFelix Fietkau 	if (!check_sdata_in_driver(sdata))
1166ba8c3d6fSFelix Fietkau 		return;
1167ba8c3d6fSFelix Fietkau 
1168ba8c3d6fSFelix Fietkau 	trace_drv_wake_tx_queue(local, sdata, txq);
1169ba8c3d6fSFelix Fietkau 	local->ops->wake_tx_queue(&local->hw, &txq->txq);
1170ba8c3d6fSFelix Fietkau }
1171ba8c3d6fSFelix Fietkau 
1172708d50edSAyala Beker static inline int drv_start_nan(struct ieee80211_local *local,
1173708d50edSAyala Beker 				struct ieee80211_sub_if_data *sdata,
1174708d50edSAyala Beker 				struct cfg80211_nan_conf *conf)
1175708d50edSAyala Beker {
1176708d50edSAyala Beker 	int ret;
1177708d50edSAyala Beker 
1178708d50edSAyala Beker 	might_sleep();
1179708d50edSAyala Beker 	check_sdata_in_driver(sdata);
1180708d50edSAyala Beker 
1181708d50edSAyala Beker 	trace_drv_start_nan(local, sdata, conf);
1182708d50edSAyala Beker 	ret = local->ops->start_nan(&local->hw, &sdata->vif, conf);
1183708d50edSAyala Beker 	trace_drv_return_int(local, ret);
1184708d50edSAyala Beker 	return ret;
1185708d50edSAyala Beker }
1186708d50edSAyala Beker 
1187708d50edSAyala Beker static inline void drv_stop_nan(struct ieee80211_local *local,
1188708d50edSAyala Beker 				struct ieee80211_sub_if_data *sdata)
1189708d50edSAyala Beker {
1190708d50edSAyala Beker 	might_sleep();
1191708d50edSAyala Beker 	check_sdata_in_driver(sdata);
1192708d50edSAyala Beker 
1193708d50edSAyala Beker 	trace_drv_stop_nan(local, sdata);
1194708d50edSAyala Beker 	local->ops->stop_nan(&local->hw, &sdata->vif);
1195708d50edSAyala Beker 	trace_drv_return_void(local);
1196708d50edSAyala Beker }
1197708d50edSAyala Beker 
11985953ff6dSAyala Beker static inline int drv_nan_change_conf(struct ieee80211_local *local,
11995953ff6dSAyala Beker 				       struct ieee80211_sub_if_data *sdata,
12005953ff6dSAyala Beker 				       struct cfg80211_nan_conf *conf,
12015953ff6dSAyala Beker 				       u32 changes)
12025953ff6dSAyala Beker {
12035953ff6dSAyala Beker 	int ret;
12045953ff6dSAyala Beker 
12055953ff6dSAyala Beker 	might_sleep();
12065953ff6dSAyala Beker 	check_sdata_in_driver(sdata);
12075953ff6dSAyala Beker 
12085953ff6dSAyala Beker 	if (!local->ops->nan_change_conf)
12095953ff6dSAyala Beker 		return -EOPNOTSUPP;
12105953ff6dSAyala Beker 
12115953ff6dSAyala Beker 	trace_drv_nan_change_conf(local, sdata, conf, changes);
12125953ff6dSAyala Beker 	ret = local->ops->nan_change_conf(&local->hw, &sdata->vif, conf,
12135953ff6dSAyala Beker 					  changes);
12145953ff6dSAyala Beker 	trace_drv_return_int(local, ret);
12155953ff6dSAyala Beker 
12165953ff6dSAyala Beker 	return ret;
12175953ff6dSAyala Beker }
12185953ff6dSAyala Beker 
1219167e33f4SAyala Beker static inline int drv_add_nan_func(struct ieee80211_local *local,
1220167e33f4SAyala Beker 				   struct ieee80211_sub_if_data *sdata,
1221167e33f4SAyala Beker 				   const struct cfg80211_nan_func *nan_func)
1222167e33f4SAyala Beker {
1223167e33f4SAyala Beker 	int ret;
1224167e33f4SAyala Beker 
1225167e33f4SAyala Beker 	might_sleep();
1226167e33f4SAyala Beker 	check_sdata_in_driver(sdata);
1227167e33f4SAyala Beker 
1228167e33f4SAyala Beker 	if (!local->ops->add_nan_func)
1229167e33f4SAyala Beker 		return -EOPNOTSUPP;
1230167e33f4SAyala Beker 
1231167e33f4SAyala Beker 	trace_drv_add_nan_func(local, sdata, nan_func);
1232167e33f4SAyala Beker 	ret = local->ops->add_nan_func(&local->hw, &sdata->vif, nan_func);
1233167e33f4SAyala Beker 	trace_drv_return_int(local, ret);
1234167e33f4SAyala Beker 
1235167e33f4SAyala Beker 	return ret;
1236167e33f4SAyala Beker }
1237167e33f4SAyala Beker 
1238167e33f4SAyala Beker static inline void drv_del_nan_func(struct ieee80211_local *local,
1239167e33f4SAyala Beker 				   struct ieee80211_sub_if_data *sdata,
1240167e33f4SAyala Beker 				   u8 instance_id)
1241167e33f4SAyala Beker {
1242167e33f4SAyala Beker 	might_sleep();
1243167e33f4SAyala Beker 	check_sdata_in_driver(sdata);
1244167e33f4SAyala Beker 
1245167e33f4SAyala Beker 	trace_drv_del_nan_func(local, sdata, instance_id);
1246167e33f4SAyala Beker 	if (local->ops->del_nan_func)
1247167e33f4SAyala Beker 		local->ops->del_nan_func(&local->hw, &sdata->vif, instance_id);
1248167e33f4SAyala Beker 	trace_drv_return_void(local);
1249167e33f4SAyala Beker }
1250167e33f4SAyala Beker 
125124487981SJohannes Berg #endif /* __MAC80211_DRIVER_OPS */
1252