xref: /openbmc/linux/net/mac80211/driver-ops.h (revision 011ad0e9f8533cd003fb760663713df2655a2114)
124487981SJohannes Berg #ifndef __MAC80211_DRIVER_OPS
224487981SJohannes Berg #define __MAC80211_DRIVER_OPS
324487981SJohannes Berg 
424487981SJohannes Berg #include <net/mac80211.h>
524487981SJohannes Berg #include "ieee80211_i.h"
6*011ad0e9SJohannes Berg #include "trace.h"
724487981SJohannes Berg 
87b7eab6fSJohannes Berg static inline void check_sdata_in_driver(struct ieee80211_sub_if_data *sdata)
97b7eab6fSJohannes Berg {
10d17087e7SBen Greear 	WARN(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER),
11d17087e7SBen Greear 	     "%s:  Failed check-sdata-in-driver check, flags: 0x%x\n",
12d17087e7SBen Greear 	     sdata->dev->name, sdata->flags);
137b7eab6fSJohannes Berg }
147b7eab6fSJohannes Berg 
15bc192f89SFelix Fietkau static inline struct ieee80211_sub_if_data *
16bc192f89SFelix Fietkau get_bss_sdata(struct ieee80211_sub_if_data *sdata)
17bc192f89SFelix Fietkau {
18bc192f89SFelix Fietkau 	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
19bc192f89SFelix Fietkau 		sdata = container_of(sdata->bss, struct ieee80211_sub_if_data,
20bc192f89SFelix Fietkau 				     u.ap);
21bc192f89SFelix Fietkau 
22bc192f89SFelix Fietkau 	return sdata;
23bc192f89SFelix Fietkau }
24bc192f89SFelix Fietkau 
257bb45683SJohannes Berg static inline void drv_tx(struct ieee80211_local *local, struct sk_buff *skb)
2624487981SJohannes Berg {
277bb45683SJohannes Berg 	local->ops->tx(&local->hw, skb);
2824487981SJohannes Berg }
2924487981SJohannes Berg 
3011127e91SJohannes Berg static inline void drv_tx_frags(struct ieee80211_local *local,
3111127e91SJohannes Berg 				struct ieee80211_vif *vif,
3211127e91SJohannes Berg 				struct ieee80211_sta *sta,
3311127e91SJohannes Berg 				struct sk_buff_head *skbs)
3411127e91SJohannes Berg {
3511127e91SJohannes Berg 	local->ops->tx_frags(&local->hw, vif, sta, skbs);
3611127e91SJohannes Berg }
3711127e91SJohannes Berg 
38e352114fSBen Greear static inline void drv_get_et_strings(struct ieee80211_sub_if_data *sdata,
39e352114fSBen Greear 				      u32 sset, u8 *data)
40e352114fSBen Greear {
41e352114fSBen Greear 	struct ieee80211_local *local = sdata->local;
42e352114fSBen Greear 	if (local->ops->get_et_strings) {
43e352114fSBen Greear 		trace_drv_get_et_strings(local, sset);
44e352114fSBen Greear 		local->ops->get_et_strings(&local->hw, &sdata->vif, sset, data);
45e352114fSBen Greear 		trace_drv_return_void(local);
46e352114fSBen Greear 	}
47e352114fSBen Greear }
48e352114fSBen Greear 
49e352114fSBen Greear static inline void drv_get_et_stats(struct ieee80211_sub_if_data *sdata,
50e352114fSBen Greear 				    struct ethtool_stats *stats,
51e352114fSBen Greear 				    u64 *data)
52e352114fSBen Greear {
53e352114fSBen Greear 	struct ieee80211_local *local = sdata->local;
54e352114fSBen Greear 	if (local->ops->get_et_stats) {
55e352114fSBen Greear 		trace_drv_get_et_stats(local);
56e352114fSBen Greear 		local->ops->get_et_stats(&local->hw, &sdata->vif, stats, data);
57e352114fSBen Greear 		trace_drv_return_void(local);
58e352114fSBen Greear 	}
59e352114fSBen Greear }
60e352114fSBen Greear 
61e352114fSBen Greear static inline int drv_get_et_sset_count(struct ieee80211_sub_if_data *sdata,
62e352114fSBen Greear 					int sset)
63e352114fSBen Greear {
64e352114fSBen Greear 	struct ieee80211_local *local = sdata->local;
65e352114fSBen Greear 	int rv = 0;
66e352114fSBen Greear 	if (local->ops->get_et_sset_count) {
67e352114fSBen Greear 		trace_drv_get_et_sset_count(local, sset);
68e352114fSBen Greear 		rv = local->ops->get_et_sset_count(&local->hw, &sdata->vif,
69e352114fSBen Greear 						   sset);
70e352114fSBen Greear 		trace_drv_return_int(local, rv);
71e352114fSBen Greear 	}
72e352114fSBen Greear 	return rv;
73e352114fSBen Greear }
74e352114fSBen Greear 
7524487981SJohannes Berg static inline int drv_start(struct ieee80211_local *local)
7624487981SJohannes Berg {
77ea77f12fSJohannes Berg 	int ret;
78ea77f12fSJohannes Berg 
79e1781ed3SKalle Valo 	might_sleep();
80e1781ed3SKalle Valo 
814efc76bdSJohannes Berg 	trace_drv_start(local);
82ea77f12fSJohannes Berg 	local->started = true;
83ea77f12fSJohannes Berg 	smp_mb();
84ea77f12fSJohannes Berg 	ret = local->ops->start(&local->hw);
854efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
860a2b8bb2SJohannes Berg 	return ret;
8724487981SJohannes Berg }
8824487981SJohannes Berg 
8924487981SJohannes Berg static inline void drv_stop(struct ieee80211_local *local)
9024487981SJohannes Berg {
91e1781ed3SKalle Valo 	might_sleep();
92e1781ed3SKalle Valo 
930a2b8bb2SJohannes Berg 	trace_drv_stop(local);
944efc76bdSJohannes Berg 	local->ops->stop(&local->hw);
954efc76bdSJohannes Berg 	trace_drv_return_void(local);
96ea77f12fSJohannes Berg 
97ea77f12fSJohannes Berg 	/* sync away all work on the tasklet before clearing started */
98ea77f12fSJohannes Berg 	tasklet_disable(&local->tasklet);
99ea77f12fSJohannes Berg 	tasklet_enable(&local->tasklet);
100ea77f12fSJohannes Berg 
101ea77f12fSJohannes Berg 	barrier();
102ea77f12fSJohannes Berg 
103ea77f12fSJohannes Berg 	local->started = false;
10424487981SJohannes Berg }
10524487981SJohannes Berg 
106eecc4800SJohannes Berg #ifdef CONFIG_PM
107eecc4800SJohannes Berg static inline int drv_suspend(struct ieee80211_local *local,
108eecc4800SJohannes Berg 			      struct cfg80211_wowlan *wowlan)
109eecc4800SJohannes Berg {
110eecc4800SJohannes Berg 	int ret;
111eecc4800SJohannes Berg 
112eecc4800SJohannes Berg 	might_sleep();
113eecc4800SJohannes Berg 
114eecc4800SJohannes Berg 	trace_drv_suspend(local);
115eecc4800SJohannes Berg 	ret = local->ops->suspend(&local->hw, wowlan);
116eecc4800SJohannes Berg 	trace_drv_return_int(local, ret);
117eecc4800SJohannes Berg 	return ret;
118eecc4800SJohannes Berg }
119eecc4800SJohannes Berg 
120eecc4800SJohannes Berg static inline int drv_resume(struct ieee80211_local *local)
121eecc4800SJohannes Berg {
122eecc4800SJohannes Berg 	int ret;
123eecc4800SJohannes Berg 
124eecc4800SJohannes Berg 	might_sleep();
125eecc4800SJohannes Berg 
126eecc4800SJohannes Berg 	trace_drv_resume(local);
127eecc4800SJohannes Berg 	ret = local->ops->resume(&local->hw);
128eecc4800SJohannes Berg 	trace_drv_return_int(local, ret);
129eecc4800SJohannes Berg 	return ret;
130eecc4800SJohannes Berg }
1316d52563fSJohannes Berg 
1326d52563fSJohannes Berg static inline void drv_set_wakeup(struct ieee80211_local *local,
1336d52563fSJohannes Berg 				  bool enabled)
1346d52563fSJohannes Berg {
1356d52563fSJohannes Berg 	might_sleep();
1366d52563fSJohannes Berg 
1376d52563fSJohannes Berg 	if (!local->ops->set_wakeup)
1386d52563fSJohannes Berg 		return;
1396d52563fSJohannes Berg 
1406d52563fSJohannes Berg 	trace_drv_set_wakeup(local, enabled);
1416d52563fSJohannes Berg 	local->ops->set_wakeup(&local->hw, enabled);
1426d52563fSJohannes Berg 	trace_drv_return_void(local);
1436d52563fSJohannes Berg }
144eecc4800SJohannes Berg #endif
145eecc4800SJohannes Berg 
14624487981SJohannes Berg static inline int drv_add_interface(struct ieee80211_local *local,
1477b7eab6fSJohannes Berg 				    struct ieee80211_sub_if_data *sdata)
14824487981SJohannes Berg {
149e1781ed3SKalle Valo 	int ret;
150e1781ed3SKalle Valo 
151e1781ed3SKalle Valo 	might_sleep();
152e1781ed3SKalle Valo 
1537b7eab6fSJohannes Berg 	if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
1544b6f1dd6SJohannes Berg 		    (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
1554b6f1dd6SJohannes Berg 		     !(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF))))
1567b7eab6fSJohannes Berg 		return -EINVAL;
1577b7eab6fSJohannes Berg 
1587b7eab6fSJohannes Berg 	trace_drv_add_interface(local, sdata);
1597b7eab6fSJohannes Berg 	ret = local->ops->add_interface(&local->hw, &sdata->vif);
1604efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
1617b7eab6fSJohannes Berg 
1627b7eab6fSJohannes Berg 	if (ret == 0)
1637b7eab6fSJohannes Berg 		sdata->flags |= IEEE80211_SDATA_IN_DRIVER;
1647b7eab6fSJohannes Berg 
1650a2b8bb2SJohannes Berg 	return ret;
16624487981SJohannes Berg }
16724487981SJohannes Berg 
16834d4bc4dSJohannes Berg static inline int drv_change_interface(struct ieee80211_local *local,
16934d4bc4dSJohannes Berg 				       struct ieee80211_sub_if_data *sdata,
1702ca27bcfSJohannes Berg 				       enum nl80211_iftype type, bool p2p)
17134d4bc4dSJohannes Berg {
17234d4bc4dSJohannes Berg 	int ret;
17334d4bc4dSJohannes Berg 
17434d4bc4dSJohannes Berg 	might_sleep();
17534d4bc4dSJohannes Berg 
1767b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
1777b7eab6fSJohannes Berg 
1782ca27bcfSJohannes Berg 	trace_drv_change_interface(local, sdata, type, p2p);
1792ca27bcfSJohannes Berg 	ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p);
18034d4bc4dSJohannes Berg 	trace_drv_return_int(local, ret);
18134d4bc4dSJohannes Berg 	return ret;
18234d4bc4dSJohannes Berg }
18334d4bc4dSJohannes Berg 
18424487981SJohannes Berg static inline void drv_remove_interface(struct ieee80211_local *local,
1857b7eab6fSJohannes Berg 					struct ieee80211_sub_if_data *sdata)
18624487981SJohannes Berg {
187e1781ed3SKalle Valo 	might_sleep();
188e1781ed3SKalle Valo 
1897b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
1907b7eab6fSJohannes Berg 
1917b7eab6fSJohannes Berg 	trace_drv_remove_interface(local, sdata);
1927b7eab6fSJohannes Berg 	local->ops->remove_interface(&local->hw, &sdata->vif);
1937b7eab6fSJohannes Berg 	sdata->flags &= ~IEEE80211_SDATA_IN_DRIVER;
1944efc76bdSJohannes Berg 	trace_drv_return_void(local);
19524487981SJohannes Berg }
19624487981SJohannes Berg 
19724487981SJohannes Berg static inline int drv_config(struct ieee80211_local *local, u32 changed)
19824487981SJohannes Berg {
199e1781ed3SKalle Valo 	int ret;
200e1781ed3SKalle Valo 
201e1781ed3SKalle Valo 	might_sleep();
202e1781ed3SKalle Valo 
2034efc76bdSJohannes Berg 	trace_drv_config(local, changed);
204e1781ed3SKalle Valo 	ret = local->ops->config(&local->hw, changed);
2054efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
2060a2b8bb2SJohannes Berg 	return ret;
20724487981SJohannes Berg }
20824487981SJohannes Berg 
20924487981SJohannes Berg static inline void drv_bss_info_changed(struct ieee80211_local *local,
21012375ef9SJohannes Berg 					struct ieee80211_sub_if_data *sdata,
21124487981SJohannes Berg 					struct ieee80211_bss_conf *info,
21224487981SJohannes Berg 					u32 changed)
21324487981SJohannes Berg {
214e1781ed3SKalle Valo 	might_sleep();
215e1781ed3SKalle Valo 
2167b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
2177b7eab6fSJohannes Berg 
2184efc76bdSJohannes Berg 	trace_drv_bss_info_changed(local, sdata, info, changed);
21924487981SJohannes Berg 	if (local->ops->bss_info_changed)
22012375ef9SJohannes Berg 		local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed);
2214efc76bdSJohannes Berg 	trace_drv_return_void(local);
22224487981SJohannes Berg }
22324487981SJohannes Berg 
2243ac64beeSJohannes Berg static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
22522bedad3SJiri Pirko 					struct netdev_hw_addr_list *mc_list)
22624487981SJohannes Berg {
2273ac64beeSJohannes Berg 	u64 ret = 0;
2283ac64beeSJohannes Berg 
2294efc76bdSJohannes Berg 	trace_drv_prepare_multicast(local, mc_list->count);
2304efc76bdSJohannes Berg 
2313ac64beeSJohannes Berg 	if (local->ops->prepare_multicast)
23222bedad3SJiri Pirko 		ret = local->ops->prepare_multicast(&local->hw, mc_list);
2333ac64beeSJohannes Berg 
2344efc76bdSJohannes Berg 	trace_drv_return_u64(local, ret);
2353ac64beeSJohannes Berg 
2363ac64beeSJohannes Berg 	return ret;
2373ac64beeSJohannes Berg }
2383ac64beeSJohannes Berg 
2393ac64beeSJohannes Berg static inline void drv_configure_filter(struct ieee80211_local *local,
2403ac64beeSJohannes Berg 					unsigned int changed_flags,
2413ac64beeSJohannes Berg 					unsigned int *total_flags,
2423ac64beeSJohannes Berg 					u64 multicast)
2433ac64beeSJohannes Berg {
2443ac64beeSJohannes Berg 	might_sleep();
2453ac64beeSJohannes Berg 
2460a2b8bb2SJohannes Berg 	trace_drv_configure_filter(local, changed_flags, total_flags,
2473ac64beeSJohannes Berg 				   multicast);
2484efc76bdSJohannes Berg 	local->ops->configure_filter(&local->hw, changed_flags, total_flags,
2494efc76bdSJohannes Berg 				     multicast);
2504efc76bdSJohannes Berg 	trace_drv_return_void(local);
25124487981SJohannes Berg }
25224487981SJohannes Berg 
25324487981SJohannes Berg static inline int drv_set_tim(struct ieee80211_local *local,
25424487981SJohannes Berg 			      struct ieee80211_sta *sta, bool set)
25524487981SJohannes Berg {
2560a2b8bb2SJohannes Berg 	int ret = 0;
2574efc76bdSJohannes Berg 	trace_drv_set_tim(local, sta, set);
25824487981SJohannes Berg 	if (local->ops->set_tim)
2590a2b8bb2SJohannes Berg 		ret = local->ops->set_tim(&local->hw, sta, set);
2604efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
2610a2b8bb2SJohannes Berg 	return ret;
26224487981SJohannes Berg }
26324487981SJohannes Berg 
26424487981SJohannes Berg static inline int drv_set_key(struct ieee80211_local *local,
26512375ef9SJohannes Berg 			      enum set_key_cmd cmd,
26612375ef9SJohannes Berg 			      struct ieee80211_sub_if_data *sdata,
26724487981SJohannes Berg 			      struct ieee80211_sta *sta,
26824487981SJohannes Berg 			      struct ieee80211_key_conf *key)
26924487981SJohannes Berg {
270e1781ed3SKalle Valo 	int ret;
271e1781ed3SKalle Valo 
272e1781ed3SKalle Valo 	might_sleep();
273e1781ed3SKalle Valo 
274077f4939SJohannes Berg 	sdata = get_bss_sdata(sdata);
2757b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
2767b7eab6fSJohannes Berg 
2774efc76bdSJohannes Berg 	trace_drv_set_key(local, cmd, sdata, sta, key);
278e1781ed3SKalle Valo 	ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key);
2794efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
2800a2b8bb2SJohannes Berg 	return ret;
28124487981SJohannes Berg }
28224487981SJohannes Berg 
28324487981SJohannes Berg static inline void drv_update_tkip_key(struct ieee80211_local *local,
284b3fbdcf4SJohannes Berg 				       struct ieee80211_sub_if_data *sdata,
28524487981SJohannes Berg 				       struct ieee80211_key_conf *conf,
286b3fbdcf4SJohannes Berg 				       struct sta_info *sta, u32 iv32,
28724487981SJohannes Berg 				       u16 *phase1key)
28824487981SJohannes Berg {
289b3fbdcf4SJohannes Berg 	struct ieee80211_sta *ista = NULL;
290b3fbdcf4SJohannes Berg 
291b3fbdcf4SJohannes Berg 	if (sta)
292b3fbdcf4SJohannes Berg 		ista = &sta->sta;
293b3fbdcf4SJohannes Berg 
294077f4939SJohannes Berg 	sdata = get_bss_sdata(sdata);
2957b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
2967b7eab6fSJohannes Berg 
2974efc76bdSJohannes Berg 	trace_drv_update_tkip_key(local, sdata, conf, ista, iv32);
29824487981SJohannes Berg 	if (local->ops->update_tkip_key)
299b3fbdcf4SJohannes Berg 		local->ops->update_tkip_key(&local->hw, &sdata->vif, conf,
300b3fbdcf4SJohannes Berg 					    ista, iv32, phase1key);
3014efc76bdSJohannes Berg 	trace_drv_return_void(local);
30224487981SJohannes Berg }
30324487981SJohannes Berg 
30424487981SJohannes Berg static inline int drv_hw_scan(struct ieee80211_local *local,
305a060bbfeSJohannes Berg 			      struct ieee80211_sub_if_data *sdata,
30624487981SJohannes Berg 			      struct cfg80211_scan_request *req)
30724487981SJohannes Berg {
308e1781ed3SKalle Valo 	int ret;
309e1781ed3SKalle Valo 
310e1781ed3SKalle Valo 	might_sleep();
311e1781ed3SKalle Valo 
3127b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
3137b7eab6fSJohannes Berg 
31479f460caSLuciano Coelho 	trace_drv_hw_scan(local, sdata);
315a060bbfeSJohannes Berg 	ret = local->ops->hw_scan(&local->hw, &sdata->vif, req);
3164efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
3170a2b8bb2SJohannes Berg 	return ret;
31824487981SJohannes Berg }
31924487981SJohannes Berg 
320b856439bSEliad Peller static inline void drv_cancel_hw_scan(struct ieee80211_local *local,
321b856439bSEliad Peller 				      struct ieee80211_sub_if_data *sdata)
322b856439bSEliad Peller {
323b856439bSEliad Peller 	might_sleep();
324b856439bSEliad Peller 
3257b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
3267b7eab6fSJohannes Berg 
327b856439bSEliad Peller 	trace_drv_cancel_hw_scan(local, sdata);
328b856439bSEliad Peller 	local->ops->cancel_hw_scan(&local->hw, &sdata->vif);
329b856439bSEliad Peller 	trace_drv_return_void(local);
330b856439bSEliad Peller }
331b856439bSEliad Peller 
33279f460caSLuciano Coelho static inline int
33379f460caSLuciano Coelho drv_sched_scan_start(struct ieee80211_local *local,
33479f460caSLuciano Coelho 		     struct ieee80211_sub_if_data *sdata,
33579f460caSLuciano Coelho 		     struct cfg80211_sched_scan_request *req,
33679f460caSLuciano Coelho 		     struct ieee80211_sched_scan_ies *ies)
33779f460caSLuciano Coelho {
33879f460caSLuciano Coelho 	int ret;
33979f460caSLuciano Coelho 
34079f460caSLuciano Coelho 	might_sleep();
34179f460caSLuciano Coelho 
3427b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
3437b7eab6fSJohannes Berg 
34479f460caSLuciano Coelho 	trace_drv_sched_scan_start(local, sdata);
34579f460caSLuciano Coelho 	ret = local->ops->sched_scan_start(&local->hw, &sdata->vif,
34679f460caSLuciano Coelho 					      req, ies);
34779f460caSLuciano Coelho 	trace_drv_return_int(local, ret);
34879f460caSLuciano Coelho 	return ret;
34979f460caSLuciano Coelho }
35079f460caSLuciano Coelho 
35179f460caSLuciano Coelho static inline void drv_sched_scan_stop(struct ieee80211_local *local,
35279f460caSLuciano Coelho 				       struct ieee80211_sub_if_data *sdata)
35379f460caSLuciano Coelho {
35479f460caSLuciano Coelho 	might_sleep();
35579f460caSLuciano Coelho 
3567b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
3577b7eab6fSJohannes Berg 
35879f460caSLuciano Coelho 	trace_drv_sched_scan_stop(local, sdata);
35979f460caSLuciano Coelho 	local->ops->sched_scan_stop(&local->hw, &sdata->vif);
36079f460caSLuciano Coelho 	trace_drv_return_void(local);
36179f460caSLuciano Coelho }
36279f460caSLuciano Coelho 
36324487981SJohannes Berg static inline void drv_sw_scan_start(struct ieee80211_local *local)
36424487981SJohannes Berg {
365e1781ed3SKalle Valo 	might_sleep();
366e1781ed3SKalle Valo 
3674efc76bdSJohannes Berg 	trace_drv_sw_scan_start(local);
36824487981SJohannes Berg 	if (local->ops->sw_scan_start)
36924487981SJohannes Berg 		local->ops->sw_scan_start(&local->hw);
3704efc76bdSJohannes Berg 	trace_drv_return_void(local);
37124487981SJohannes Berg }
37224487981SJohannes Berg 
37324487981SJohannes Berg static inline void drv_sw_scan_complete(struct ieee80211_local *local)
37424487981SJohannes Berg {
375e1781ed3SKalle Valo 	might_sleep();
376e1781ed3SKalle Valo 
3774efc76bdSJohannes Berg 	trace_drv_sw_scan_complete(local);
37824487981SJohannes Berg 	if (local->ops->sw_scan_complete)
37924487981SJohannes Berg 		local->ops->sw_scan_complete(&local->hw);
3804efc76bdSJohannes Berg 	trace_drv_return_void(local);
38124487981SJohannes Berg }
38224487981SJohannes Berg 
38324487981SJohannes Berg static inline int drv_get_stats(struct ieee80211_local *local,
38424487981SJohannes Berg 				struct ieee80211_low_level_stats *stats)
38524487981SJohannes Berg {
3860a2b8bb2SJohannes Berg 	int ret = -EOPNOTSUPP;
3870a2b8bb2SJohannes Berg 
388e1781ed3SKalle Valo 	might_sleep();
389e1781ed3SKalle Valo 
3900a2b8bb2SJohannes Berg 	if (local->ops->get_stats)
3910a2b8bb2SJohannes Berg 		ret = local->ops->get_stats(&local->hw, stats);
3920a2b8bb2SJohannes Berg 	trace_drv_get_stats(local, stats, ret);
3930a2b8bb2SJohannes Berg 
3940a2b8bb2SJohannes Berg 	return ret;
39524487981SJohannes Berg }
39624487981SJohannes Berg 
39724487981SJohannes Berg static inline void drv_get_tkip_seq(struct ieee80211_local *local,
39824487981SJohannes Berg 				    u8 hw_key_idx, u32 *iv32, u16 *iv16)
39924487981SJohannes Berg {
40024487981SJohannes Berg 	if (local->ops->get_tkip_seq)
40124487981SJohannes Berg 		local->ops->get_tkip_seq(&local->hw, hw_key_idx, iv32, iv16);
4020a2b8bb2SJohannes Berg 	trace_drv_get_tkip_seq(local, hw_key_idx, iv32, iv16);
40324487981SJohannes Berg }
40424487981SJohannes Berg 
405f23a4780SArik Nemtsov static inline int drv_set_frag_threshold(struct ieee80211_local *local,
406f23a4780SArik Nemtsov 					u32 value)
407f23a4780SArik Nemtsov {
408f23a4780SArik Nemtsov 	int ret = 0;
409f23a4780SArik Nemtsov 
410f23a4780SArik Nemtsov 	might_sleep();
411f23a4780SArik Nemtsov 
412f23a4780SArik Nemtsov 	trace_drv_set_frag_threshold(local, value);
413f23a4780SArik Nemtsov 	if (local->ops->set_frag_threshold)
414f23a4780SArik Nemtsov 		ret = local->ops->set_frag_threshold(&local->hw, value);
415f23a4780SArik Nemtsov 	trace_drv_return_int(local, ret);
416f23a4780SArik Nemtsov 	return ret;
417f23a4780SArik Nemtsov }
418f23a4780SArik Nemtsov 
41924487981SJohannes Berg static inline int drv_set_rts_threshold(struct ieee80211_local *local,
42024487981SJohannes Berg 					u32 value)
42124487981SJohannes Berg {
4220a2b8bb2SJohannes Berg 	int ret = 0;
423e1781ed3SKalle Valo 
424e1781ed3SKalle Valo 	might_sleep();
425e1781ed3SKalle Valo 
4264efc76bdSJohannes Berg 	trace_drv_set_rts_threshold(local, value);
42724487981SJohannes Berg 	if (local->ops->set_rts_threshold)
4280a2b8bb2SJohannes Berg 		ret = local->ops->set_rts_threshold(&local->hw, value);
4294efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
4300a2b8bb2SJohannes Berg 	return ret;
43124487981SJohannes Berg }
43224487981SJohannes Berg 
433310bc676SLukáš Turek static inline int drv_set_coverage_class(struct ieee80211_local *local,
434310bc676SLukáš Turek 					 u8 value)
435310bc676SLukáš Turek {
436310bc676SLukáš Turek 	int ret = 0;
437310bc676SLukáš Turek 	might_sleep();
438310bc676SLukáš Turek 
4394efc76bdSJohannes Berg 	trace_drv_set_coverage_class(local, value);
440310bc676SLukáš Turek 	if (local->ops->set_coverage_class)
441310bc676SLukáš Turek 		local->ops->set_coverage_class(&local->hw, value);
442310bc676SLukáš Turek 	else
443310bc676SLukáš Turek 		ret = -EOPNOTSUPP;
444310bc676SLukáš Turek 
4454efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
446310bc676SLukáš Turek 	return ret;
447310bc676SLukáš Turek }
448310bc676SLukáš Turek 
44924487981SJohannes Berg static inline void drv_sta_notify(struct ieee80211_local *local,
45012375ef9SJohannes Berg 				  struct ieee80211_sub_if_data *sdata,
45124487981SJohannes Berg 				  enum sta_notify_cmd cmd,
45224487981SJohannes Berg 				  struct ieee80211_sta *sta)
45324487981SJohannes Berg {
454bc192f89SFelix Fietkau 	sdata = get_bss_sdata(sdata);
4557b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
4567b7eab6fSJohannes Berg 
4574efc76bdSJohannes Berg 	trace_drv_sta_notify(local, sdata, cmd, sta);
45824487981SJohannes Berg 	if (local->ops->sta_notify)
45912375ef9SJohannes Berg 		local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta);
4604efc76bdSJohannes Berg 	trace_drv_return_void(local);
46124487981SJohannes Berg }
46224487981SJohannes Berg 
46334e89507SJohannes Berg static inline int drv_sta_add(struct ieee80211_local *local,
46434e89507SJohannes Berg 			      struct ieee80211_sub_if_data *sdata,
46534e89507SJohannes Berg 			      struct ieee80211_sta *sta)
46634e89507SJohannes Berg {
46734e89507SJohannes Berg 	int ret = 0;
46834e89507SJohannes Berg 
46934e89507SJohannes Berg 	might_sleep();
47034e89507SJohannes Berg 
471bc192f89SFelix Fietkau 	sdata = get_bss_sdata(sdata);
4727b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
4737b7eab6fSJohannes Berg 
4744efc76bdSJohannes Berg 	trace_drv_sta_add(local, sdata, sta);
47534e89507SJohannes Berg 	if (local->ops->sta_add)
47634e89507SJohannes Berg 		ret = local->ops->sta_add(&local->hw, &sdata->vif, sta);
47734e89507SJohannes Berg 
4784efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
47934e89507SJohannes Berg 
48034e89507SJohannes Berg 	return ret;
48134e89507SJohannes Berg }
48234e89507SJohannes Berg 
48334e89507SJohannes Berg static inline void drv_sta_remove(struct ieee80211_local *local,
48434e89507SJohannes Berg 				  struct ieee80211_sub_if_data *sdata,
48534e89507SJohannes Berg 				  struct ieee80211_sta *sta)
48634e89507SJohannes Berg {
48734e89507SJohannes Berg 	might_sleep();
48834e89507SJohannes Berg 
489bc192f89SFelix Fietkau 	sdata = get_bss_sdata(sdata);
4907b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
4917b7eab6fSJohannes Berg 
4924efc76bdSJohannes Berg 	trace_drv_sta_remove(local, sdata, sta);
49334e89507SJohannes Berg 	if (local->ops->sta_remove)
49434e89507SJohannes Berg 		local->ops->sta_remove(&local->hw, &sdata->vif, sta);
49534e89507SJohannes Berg 
4964efc76bdSJohannes Berg 	trace_drv_return_void(local);
49734e89507SJohannes Berg }
49834e89507SJohannes Berg 
499f09603a2SJohannes Berg static inline __must_check
500f09603a2SJohannes Berg int drv_sta_state(struct ieee80211_local *local,
501f09603a2SJohannes Berg 		  struct ieee80211_sub_if_data *sdata,
502f09603a2SJohannes Berg 		  struct sta_info *sta,
503f09603a2SJohannes Berg 		  enum ieee80211_sta_state old_state,
504f09603a2SJohannes Berg 		  enum ieee80211_sta_state new_state)
505f09603a2SJohannes Berg {
506f09603a2SJohannes Berg 	int ret = 0;
507f09603a2SJohannes Berg 
508f09603a2SJohannes Berg 	might_sleep();
509f09603a2SJohannes Berg 
510f09603a2SJohannes Berg 	sdata = get_bss_sdata(sdata);
511f09603a2SJohannes Berg 	check_sdata_in_driver(sdata);
512f09603a2SJohannes Berg 
513f09603a2SJohannes Berg 	trace_drv_sta_state(local, sdata, &sta->sta, old_state, new_state);
514a4ec45a4SJohannes Berg 	if (local->ops->sta_state) {
515f09603a2SJohannes Berg 		ret = local->ops->sta_state(&local->hw, &sdata->vif, &sta->sta,
516f09603a2SJohannes Berg 					    old_state, new_state);
517a4ec45a4SJohannes Berg 	} else if (old_state == IEEE80211_STA_AUTH &&
518a4ec45a4SJohannes Berg 		   new_state == IEEE80211_STA_ASSOC) {
519a4ec45a4SJohannes Berg 		ret = drv_sta_add(local, sdata, &sta->sta);
520a4ec45a4SJohannes Berg 		if (ret == 0)
521a4ec45a4SJohannes Berg 			sta->uploaded = true;
522a4ec45a4SJohannes Berg 	} else if (old_state == IEEE80211_STA_ASSOC &&
523a4ec45a4SJohannes Berg 		   new_state == IEEE80211_STA_AUTH) {
524a4ec45a4SJohannes Berg 		drv_sta_remove(local, sdata, &sta->sta);
525a4ec45a4SJohannes Berg 	}
526f09603a2SJohannes Berg 	trace_drv_return_int(local, ret);
527f09603a2SJohannes Berg 	return ret;
528f09603a2SJohannes Berg }
529f09603a2SJohannes Berg 
5308f727ef3SJohannes Berg static inline void drv_sta_rc_update(struct ieee80211_local *local,
5318f727ef3SJohannes Berg 				     struct ieee80211_sub_if_data *sdata,
5328f727ef3SJohannes Berg 				     struct ieee80211_sta *sta, u32 changed)
5338f727ef3SJohannes Berg {
5348f727ef3SJohannes Berg 	sdata = get_bss_sdata(sdata);
5358f727ef3SJohannes Berg 	check_sdata_in_driver(sdata);
5368f727ef3SJohannes Berg 
5378f727ef3SJohannes Berg 	trace_drv_sta_rc_update(local, sdata, sta, changed);
5388f727ef3SJohannes Berg 	if (local->ops->sta_rc_update)
5398f727ef3SJohannes Berg 		local->ops->sta_rc_update(&local->hw, &sdata->vif,
5408f727ef3SJohannes Berg 					  sta, changed);
5418f727ef3SJohannes Berg 
5428f727ef3SJohannes Berg 	trace_drv_return_void(local);
5438f727ef3SJohannes Berg }
5448f727ef3SJohannes Berg 
545f6f3def3SEliad Peller static inline int drv_conf_tx(struct ieee80211_local *local,
546a3304b0aSJohannes Berg 			      struct ieee80211_sub_if_data *sdata, u16 ac,
54724487981SJohannes Berg 			      const struct ieee80211_tx_queue_params *params)
54824487981SJohannes Berg {
5490a2b8bb2SJohannes Berg 	int ret = -EOPNOTSUPP;
550e1781ed3SKalle Valo 
551e1781ed3SKalle Valo 	might_sleep();
552e1781ed3SKalle Valo 
5537b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
5547b7eab6fSJohannes Berg 
555a3304b0aSJohannes Berg 	trace_drv_conf_tx(local, sdata, ac, params);
55624487981SJohannes Berg 	if (local->ops->conf_tx)
5578a3a3c85SEliad Peller 		ret = local->ops->conf_tx(&local->hw, &sdata->vif,
558a3304b0aSJohannes Berg 					  ac, params);
5594efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
5600a2b8bb2SJohannes Berg 	return ret;
56124487981SJohannes Berg }
56224487981SJohannes Berg 
56337a41b4aSEliad Peller static inline u64 drv_get_tsf(struct ieee80211_local *local,
56437a41b4aSEliad Peller 			      struct ieee80211_sub_if_data *sdata)
56524487981SJohannes Berg {
5660a2b8bb2SJohannes Berg 	u64 ret = -1ULL;
567e1781ed3SKalle Valo 
568e1781ed3SKalle Valo 	might_sleep();
569e1781ed3SKalle Valo 
5707b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
5717b7eab6fSJohannes Berg 
57237a41b4aSEliad Peller 	trace_drv_get_tsf(local, sdata);
57324487981SJohannes Berg 	if (local->ops->get_tsf)
57437a41b4aSEliad Peller 		ret = local->ops->get_tsf(&local->hw, &sdata->vif);
5754efc76bdSJohannes Berg 	trace_drv_return_u64(local, ret);
5760a2b8bb2SJohannes Berg 	return ret;
57724487981SJohannes Berg }
57824487981SJohannes Berg 
57937a41b4aSEliad Peller static inline void drv_set_tsf(struct ieee80211_local *local,
58037a41b4aSEliad Peller 			       struct ieee80211_sub_if_data *sdata,
58137a41b4aSEliad Peller 			       u64 tsf)
58224487981SJohannes Berg {
583e1781ed3SKalle Valo 	might_sleep();
584e1781ed3SKalle Valo 
5857b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
5867b7eab6fSJohannes Berg 
58737a41b4aSEliad Peller 	trace_drv_set_tsf(local, sdata, tsf);
58824487981SJohannes Berg 	if (local->ops->set_tsf)
58937a41b4aSEliad Peller 		local->ops->set_tsf(&local->hw, &sdata->vif, tsf);
5904efc76bdSJohannes Berg 	trace_drv_return_void(local);
59124487981SJohannes Berg }
59224487981SJohannes Berg 
59337a41b4aSEliad Peller static inline void drv_reset_tsf(struct ieee80211_local *local,
59437a41b4aSEliad Peller 				 struct ieee80211_sub_if_data *sdata)
59524487981SJohannes Berg {
596e1781ed3SKalle Valo 	might_sleep();
597e1781ed3SKalle Valo 
5987b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
5997b7eab6fSJohannes Berg 
60037a41b4aSEliad Peller 	trace_drv_reset_tsf(local, sdata);
60124487981SJohannes Berg 	if (local->ops->reset_tsf)
60237a41b4aSEliad Peller 		local->ops->reset_tsf(&local->hw, &sdata->vif);
6034efc76bdSJohannes Berg 	trace_drv_return_void(local);
60424487981SJohannes Berg }
60524487981SJohannes Berg 
60624487981SJohannes Berg static inline int drv_tx_last_beacon(struct ieee80211_local *local)
60724487981SJohannes Berg {
60891f44b02STim Harvey 	int ret = 0; /* default unsuported op for less congestion */
609e1781ed3SKalle Valo 
610e1781ed3SKalle Valo 	might_sleep();
611e1781ed3SKalle Valo 
6124efc76bdSJohannes Berg 	trace_drv_tx_last_beacon(local);
61324487981SJohannes Berg 	if (local->ops->tx_last_beacon)
6140a2b8bb2SJohannes Berg 		ret = local->ops->tx_last_beacon(&local->hw);
6154efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
6160a2b8bb2SJohannes Berg 	return ret;
61724487981SJohannes Berg }
61824487981SJohannes Berg 
61924487981SJohannes Berg static inline int drv_ampdu_action(struct ieee80211_local *local,
62012375ef9SJohannes Berg 				   struct ieee80211_sub_if_data *sdata,
62124487981SJohannes Berg 				   enum ieee80211_ampdu_mlme_action action,
62224487981SJohannes Berg 				   struct ieee80211_sta *sta, u16 tid,
6230b01f030SJohannes Berg 				   u16 *ssn, u8 buf_size)
62424487981SJohannes Berg {
6250a2b8bb2SJohannes Berg 	int ret = -EOPNOTSUPP;
626cfcdbde3SJohannes Berg 
627cfcdbde3SJohannes Berg 	might_sleep();
628cfcdbde3SJohannes Berg 
629bc192f89SFelix Fietkau 	sdata = get_bss_sdata(sdata);
6307b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
6317b7eab6fSJohannes Berg 
6320b01f030SJohannes Berg 	trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size);
6334efc76bdSJohannes Berg 
63424487981SJohannes Berg 	if (local->ops->ampdu_action)
63512375ef9SJohannes Berg 		ret = local->ops->ampdu_action(&local->hw, &sdata->vif, action,
6360b01f030SJohannes Berg 					       sta, tid, ssn, buf_size);
63785ad181eSJohannes Berg 
6384efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
6394efc76bdSJohannes Berg 
6400a2b8bb2SJohannes Berg 	return ret;
64124487981SJohannes Berg }
6421f87f7d3SJohannes Berg 
6431289723eSHolger Schurig static inline int drv_get_survey(struct ieee80211_local *local, int idx,
6441289723eSHolger Schurig 				struct survey_info *survey)
6451289723eSHolger Schurig {
6461289723eSHolger Schurig 	int ret = -EOPNOTSUPP;
647c466d4efSJohn W. Linville 
648c466d4efSJohn W. Linville 	trace_drv_get_survey(local, idx, survey);
649c466d4efSJohn W. Linville 
65035dd0509SHolger Schurig 	if (local->ops->get_survey)
6511289723eSHolger Schurig 		ret = local->ops->get_survey(&local->hw, idx, survey);
652c466d4efSJohn W. Linville 
653c466d4efSJohn W. Linville 	trace_drv_return_int(local, ret);
654c466d4efSJohn W. Linville 
6551289723eSHolger Schurig 	return ret;
6561289723eSHolger Schurig }
6571f87f7d3SJohannes Berg 
6581f87f7d3SJohannes Berg static inline void drv_rfkill_poll(struct ieee80211_local *local)
6591f87f7d3SJohannes Berg {
660e1781ed3SKalle Valo 	might_sleep();
661e1781ed3SKalle Valo 
6621f87f7d3SJohannes Berg 	if (local->ops->rfkill_poll)
6631f87f7d3SJohannes Berg 		local->ops->rfkill_poll(&local->hw);
6641f87f7d3SJohannes Berg }
665a80f7c0bSJohannes Berg 
666a80f7c0bSJohannes Berg static inline void drv_flush(struct ieee80211_local *local, bool drop)
667a80f7c0bSJohannes Berg {
668e1781ed3SKalle Valo 	might_sleep();
669e1781ed3SKalle Valo 
670a80f7c0bSJohannes Berg 	trace_drv_flush(local, drop);
671a80f7c0bSJohannes Berg 	if (local->ops->flush)
672a80f7c0bSJohannes Berg 		local->ops->flush(&local->hw, drop);
6734efc76bdSJohannes Berg 	trace_drv_return_void(local);
674a80f7c0bSJohannes Berg }
6755ce6e438SJohannes Berg 
6765ce6e438SJohannes Berg static inline void drv_channel_switch(struct ieee80211_local *local,
6775ce6e438SJohannes Berg 				     struct ieee80211_channel_switch *ch_switch)
6785ce6e438SJohannes Berg {
6795ce6e438SJohannes Berg 	might_sleep();
6805ce6e438SJohannes Berg 
6815ce6e438SJohannes Berg 	trace_drv_channel_switch(local, ch_switch);
6824efc76bdSJohannes Berg 	local->ops->channel_switch(&local->hw, ch_switch);
6834efc76bdSJohannes Berg 	trace_drv_return_void(local);
6845ce6e438SJohannes Berg }
6855ce6e438SJohannes Berg 
68615d96753SBruno Randolf 
68715d96753SBruno Randolf static inline int drv_set_antenna(struct ieee80211_local *local,
68815d96753SBruno Randolf 				  u32 tx_ant, u32 rx_ant)
68915d96753SBruno Randolf {
69015d96753SBruno Randolf 	int ret = -EOPNOTSUPP;
69115d96753SBruno Randolf 	might_sleep();
69215d96753SBruno Randolf 	if (local->ops->set_antenna)
69315d96753SBruno Randolf 		ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant);
69415d96753SBruno Randolf 	trace_drv_set_antenna(local, tx_ant, rx_ant, ret);
69515d96753SBruno Randolf 	return ret;
69615d96753SBruno Randolf }
69715d96753SBruno Randolf 
69815d96753SBruno Randolf static inline int drv_get_antenna(struct ieee80211_local *local,
69915d96753SBruno Randolf 				  u32 *tx_ant, u32 *rx_ant)
70015d96753SBruno Randolf {
70115d96753SBruno Randolf 	int ret = -EOPNOTSUPP;
70215d96753SBruno Randolf 	might_sleep();
70315d96753SBruno Randolf 	if (local->ops->get_antenna)
70415d96753SBruno Randolf 		ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant);
70515d96753SBruno Randolf 	trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret);
70615d96753SBruno Randolf 	return ret;
70715d96753SBruno Randolf }
70815d96753SBruno Randolf 
70921f83589SJohannes Berg static inline int drv_remain_on_channel(struct ieee80211_local *local,
71021f83589SJohannes Berg 					struct ieee80211_channel *chan,
71121f83589SJohannes Berg 					enum nl80211_channel_type chantype,
71221f83589SJohannes Berg 					unsigned int duration)
71321f83589SJohannes Berg {
71421f83589SJohannes Berg 	int ret;
71521f83589SJohannes Berg 
71621f83589SJohannes Berg 	might_sleep();
71721f83589SJohannes Berg 
71821f83589SJohannes Berg 	trace_drv_remain_on_channel(local, chan, chantype, duration);
71921f83589SJohannes Berg 	ret = local->ops->remain_on_channel(&local->hw, chan, chantype,
72021f83589SJohannes Berg 					    duration);
72121f83589SJohannes Berg 	trace_drv_return_int(local, ret);
72221f83589SJohannes Berg 
72321f83589SJohannes Berg 	return ret;
72421f83589SJohannes Berg }
72521f83589SJohannes Berg 
72621f83589SJohannes Berg static inline int drv_cancel_remain_on_channel(struct ieee80211_local *local)
72721f83589SJohannes Berg {
72821f83589SJohannes Berg 	int ret;
72921f83589SJohannes Berg 
73021f83589SJohannes Berg 	might_sleep();
73121f83589SJohannes Berg 
73221f83589SJohannes Berg 	trace_drv_cancel_remain_on_channel(local);
73321f83589SJohannes Berg 	ret = local->ops->cancel_remain_on_channel(&local->hw);
73421f83589SJohannes Berg 	trace_drv_return_int(local, ret);
73521f83589SJohannes Berg 
73621f83589SJohannes Berg 	return ret;
73721f83589SJohannes Berg }
73821f83589SJohannes Berg 
73938c09159SJohn W. Linville static inline int drv_set_ringparam(struct ieee80211_local *local,
74038c09159SJohn W. Linville 				    u32 tx, u32 rx)
74138c09159SJohn W. Linville {
74238c09159SJohn W. Linville 	int ret = -ENOTSUPP;
74338c09159SJohn W. Linville 
74438c09159SJohn W. Linville 	might_sleep();
74538c09159SJohn W. Linville 
74638c09159SJohn W. Linville 	trace_drv_set_ringparam(local, tx, rx);
74738c09159SJohn W. Linville 	if (local->ops->set_ringparam)
74838c09159SJohn W. Linville 		ret = local->ops->set_ringparam(&local->hw, tx, rx);
74938c09159SJohn W. Linville 	trace_drv_return_int(local, ret);
75038c09159SJohn W. Linville 
75138c09159SJohn W. Linville 	return ret;
75238c09159SJohn W. Linville }
75338c09159SJohn W. Linville 
75438c09159SJohn W. Linville static inline void drv_get_ringparam(struct ieee80211_local *local,
75538c09159SJohn W. Linville 				     u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
75638c09159SJohn W. Linville {
75738c09159SJohn W. Linville 	might_sleep();
75838c09159SJohn W. Linville 
75938c09159SJohn W. Linville 	trace_drv_get_ringparam(local, tx, tx_max, rx, rx_max);
76038c09159SJohn W. Linville 	if (local->ops->get_ringparam)
76138c09159SJohn W. Linville 		local->ops->get_ringparam(&local->hw, tx, tx_max, rx, rx_max);
76238c09159SJohn W. Linville 	trace_drv_return_void(local);
76338c09159SJohn W. Linville }
76438c09159SJohn W. Linville 
765e8306f98SVivek Natarajan static inline bool drv_tx_frames_pending(struct ieee80211_local *local)
766e8306f98SVivek Natarajan {
767e8306f98SVivek Natarajan 	bool ret = false;
768e8306f98SVivek Natarajan 
769e8306f98SVivek Natarajan 	might_sleep();
770e8306f98SVivek Natarajan 
771e8306f98SVivek Natarajan 	trace_drv_tx_frames_pending(local);
772e8306f98SVivek Natarajan 	if (local->ops->tx_frames_pending)
773e8306f98SVivek Natarajan 		ret = local->ops->tx_frames_pending(&local->hw);
774e8306f98SVivek Natarajan 	trace_drv_return_bool(local, ret);
775e8306f98SVivek Natarajan 
776e8306f98SVivek Natarajan 	return ret;
777e8306f98SVivek Natarajan }
778bdbfd6b5SSujith Manoharan 
779bdbfd6b5SSujith Manoharan static inline int drv_set_bitrate_mask(struct ieee80211_local *local,
780bdbfd6b5SSujith Manoharan 				       struct ieee80211_sub_if_data *sdata,
781bdbfd6b5SSujith Manoharan 				       const struct cfg80211_bitrate_mask *mask)
782bdbfd6b5SSujith Manoharan {
783bdbfd6b5SSujith Manoharan 	int ret = -EOPNOTSUPP;
784bdbfd6b5SSujith Manoharan 
785bdbfd6b5SSujith Manoharan 	might_sleep();
786bdbfd6b5SSujith Manoharan 
7877b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
7887b7eab6fSJohannes Berg 
789bdbfd6b5SSujith Manoharan 	trace_drv_set_bitrate_mask(local, sdata, mask);
790bdbfd6b5SSujith Manoharan 	if (local->ops->set_bitrate_mask)
791bdbfd6b5SSujith Manoharan 		ret = local->ops->set_bitrate_mask(&local->hw,
792bdbfd6b5SSujith Manoharan 						   &sdata->vif, mask);
793bdbfd6b5SSujith Manoharan 	trace_drv_return_int(local, ret);
794bdbfd6b5SSujith Manoharan 
795bdbfd6b5SSujith Manoharan 	return ret;
796bdbfd6b5SSujith Manoharan }
797bdbfd6b5SSujith Manoharan 
798c68f4b89SJohannes Berg static inline void drv_set_rekey_data(struct ieee80211_local *local,
799c68f4b89SJohannes Berg 				      struct ieee80211_sub_if_data *sdata,
800c68f4b89SJohannes Berg 				      struct cfg80211_gtk_rekey_data *data)
801c68f4b89SJohannes Berg {
8027b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
8037b7eab6fSJohannes Berg 
804c68f4b89SJohannes Berg 	trace_drv_set_rekey_data(local, sdata, data);
805c68f4b89SJohannes Berg 	if (local->ops->set_rekey_data)
806c68f4b89SJohannes Berg 		local->ops->set_rekey_data(&local->hw, &sdata->vif, data);
807c68f4b89SJohannes Berg 	trace_drv_return_void(local);
808c68f4b89SJohannes Berg }
809c68f4b89SJohannes Berg 
810615f7b9bSMeenakshi Venkataraman static inline void drv_rssi_callback(struct ieee80211_local *local,
811615f7b9bSMeenakshi Venkataraman 				     const enum ieee80211_rssi_event event)
812615f7b9bSMeenakshi Venkataraman {
813615f7b9bSMeenakshi Venkataraman 	trace_drv_rssi_callback(local, event);
814615f7b9bSMeenakshi Venkataraman 	if (local->ops->rssi_callback)
815615f7b9bSMeenakshi Venkataraman 		local->ops->rssi_callback(&local->hw, event);
816615f7b9bSMeenakshi Venkataraman 	trace_drv_return_void(local);
817615f7b9bSMeenakshi Venkataraman }
8184049e09aSJohannes Berg 
8194049e09aSJohannes Berg static inline void
8204049e09aSJohannes Berg drv_release_buffered_frames(struct ieee80211_local *local,
8214049e09aSJohannes Berg 			    struct sta_info *sta, u16 tids, int num_frames,
8224049e09aSJohannes Berg 			    enum ieee80211_frame_release_type reason,
8234049e09aSJohannes Berg 			    bool more_data)
8244049e09aSJohannes Berg {
8254049e09aSJohannes Berg 	trace_drv_release_buffered_frames(local, &sta->sta, tids, num_frames,
8264049e09aSJohannes Berg 					  reason, more_data);
8274049e09aSJohannes Berg 	if (local->ops->release_buffered_frames)
8284049e09aSJohannes Berg 		local->ops->release_buffered_frames(&local->hw, &sta->sta, tids,
8294049e09aSJohannes Berg 						    num_frames, reason,
8304049e09aSJohannes Berg 						    more_data);
8314049e09aSJohannes Berg 	trace_drv_return_void(local);
8324049e09aSJohannes Berg }
83340b96408SJohannes Berg 
83440b96408SJohannes Berg static inline void
83540b96408SJohannes Berg drv_allow_buffered_frames(struct ieee80211_local *local,
83640b96408SJohannes Berg 			  struct sta_info *sta, u16 tids, int num_frames,
83740b96408SJohannes Berg 			  enum ieee80211_frame_release_type reason,
83840b96408SJohannes Berg 			  bool more_data)
83940b96408SJohannes Berg {
84040b96408SJohannes Berg 	trace_drv_allow_buffered_frames(local, &sta->sta, tids, num_frames,
84140b96408SJohannes Berg 					reason, more_data);
84240b96408SJohannes Berg 	if (local->ops->allow_buffered_frames)
84340b96408SJohannes Berg 		local->ops->allow_buffered_frames(&local->hw, &sta->sta,
84440b96408SJohannes Berg 						  tids, num_frames, reason,
84540b96408SJohannes Berg 						  more_data);
84640b96408SJohannes Berg 	trace_drv_return_void(local);
84740b96408SJohannes Berg }
84866572cfcSVictor Goldenshtein 
84966572cfcSVictor Goldenshtein static inline int drv_get_rssi(struct ieee80211_local *local,
85066572cfcSVictor Goldenshtein 				struct ieee80211_sub_if_data *sdata,
85166572cfcSVictor Goldenshtein 				struct ieee80211_sta *sta,
85266572cfcSVictor Goldenshtein 				s8 *rssi_dbm)
85366572cfcSVictor Goldenshtein {
85466572cfcSVictor Goldenshtein 	int ret;
85566572cfcSVictor Goldenshtein 
85666572cfcSVictor Goldenshtein 	might_sleep();
85766572cfcSVictor Goldenshtein 
85866572cfcSVictor Goldenshtein 	ret = local->ops->get_rssi(&local->hw, &sdata->vif, sta, rssi_dbm);
85966572cfcSVictor Goldenshtein 	trace_drv_get_rssi(local, sta, *rssi_dbm, ret);
86066572cfcSVictor Goldenshtein 
86166572cfcSVictor Goldenshtein 	return ret;
86266572cfcSVictor Goldenshtein }
86324487981SJohannes Berg #endif /* __MAC80211_DRIVER_OPS */
864