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