xref: /openbmc/linux/net/mac80211/driver-ops.h (revision c3645eac)
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"
6011ad0e9SJohannes 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",
12f142c6b9SJohannes Berg 	     sdata->dev ? sdata->dev->name : sdata->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 
2536323f81SThomas Huehn static inline void drv_tx(struct ieee80211_local *local,
2636323f81SThomas Huehn 			  struct ieee80211_tx_control *control,
2736323f81SThomas Huehn 			  struct sk_buff *skb)
2824487981SJohannes Berg {
2936323f81SThomas Huehn 	local->ops->tx(&local->hw, control, skb);
3024487981SJohannes Berg }
3124487981SJohannes Berg 
32e352114fSBen Greear static inline void drv_get_et_strings(struct ieee80211_sub_if_data *sdata,
33e352114fSBen Greear 				      u32 sset, u8 *data)
34e352114fSBen Greear {
35e352114fSBen Greear 	struct ieee80211_local *local = sdata->local;
36e352114fSBen Greear 	if (local->ops->get_et_strings) {
37e352114fSBen Greear 		trace_drv_get_et_strings(local, sset);
38e352114fSBen Greear 		local->ops->get_et_strings(&local->hw, &sdata->vif, sset, data);
39e352114fSBen Greear 		trace_drv_return_void(local);
40e352114fSBen Greear 	}
41e352114fSBen Greear }
42e352114fSBen Greear 
43e352114fSBen Greear static inline void drv_get_et_stats(struct ieee80211_sub_if_data *sdata,
44e352114fSBen Greear 				    struct ethtool_stats *stats,
45e352114fSBen Greear 				    u64 *data)
46e352114fSBen Greear {
47e352114fSBen Greear 	struct ieee80211_local *local = sdata->local;
48e352114fSBen Greear 	if (local->ops->get_et_stats) {
49e352114fSBen Greear 		trace_drv_get_et_stats(local);
50e352114fSBen Greear 		local->ops->get_et_stats(&local->hw, &sdata->vif, stats, data);
51e352114fSBen Greear 		trace_drv_return_void(local);
52e352114fSBen Greear 	}
53e352114fSBen Greear }
54e352114fSBen Greear 
55e352114fSBen Greear static inline int drv_get_et_sset_count(struct ieee80211_sub_if_data *sdata,
56e352114fSBen Greear 					int sset)
57e352114fSBen Greear {
58e352114fSBen Greear 	struct ieee80211_local *local = sdata->local;
59e352114fSBen Greear 	int rv = 0;
60e352114fSBen Greear 	if (local->ops->get_et_sset_count) {
61e352114fSBen Greear 		trace_drv_get_et_sset_count(local, sset);
62e352114fSBen Greear 		rv = local->ops->get_et_sset_count(&local->hw, &sdata->vif,
63e352114fSBen Greear 						   sset);
64e352114fSBen Greear 		trace_drv_return_int(local, rv);
65e352114fSBen Greear 	}
66e352114fSBen Greear 	return rv;
67e352114fSBen Greear }
68e352114fSBen Greear 
6924487981SJohannes Berg static inline int drv_start(struct ieee80211_local *local)
7024487981SJohannes Berg {
71ea77f12fSJohannes Berg 	int ret;
72ea77f12fSJohannes Berg 
73e1781ed3SKalle Valo 	might_sleep();
74e1781ed3SKalle Valo 
754efc76bdSJohannes Berg 	trace_drv_start(local);
76ea77f12fSJohannes Berg 	local->started = true;
77ea77f12fSJohannes Berg 	smp_mb();
78ea77f12fSJohannes Berg 	ret = local->ops->start(&local->hw);
794efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
800a2b8bb2SJohannes Berg 	return ret;
8124487981SJohannes Berg }
8224487981SJohannes Berg 
8324487981SJohannes Berg static inline void drv_stop(struct ieee80211_local *local)
8424487981SJohannes Berg {
85e1781ed3SKalle Valo 	might_sleep();
86e1781ed3SKalle Valo 
870a2b8bb2SJohannes Berg 	trace_drv_stop(local);
884efc76bdSJohannes Berg 	local->ops->stop(&local->hw);
894efc76bdSJohannes Berg 	trace_drv_return_void(local);
90ea77f12fSJohannes Berg 
91ea77f12fSJohannes Berg 	/* sync away all work on the tasklet before clearing started */
92ea77f12fSJohannes Berg 	tasklet_disable(&local->tasklet);
93ea77f12fSJohannes Berg 	tasklet_enable(&local->tasklet);
94ea77f12fSJohannes Berg 
95ea77f12fSJohannes Berg 	barrier();
96ea77f12fSJohannes Berg 
97ea77f12fSJohannes Berg 	local->started = false;
9824487981SJohannes Berg }
9924487981SJohannes Berg 
100eecc4800SJohannes Berg #ifdef CONFIG_PM
101eecc4800SJohannes Berg static inline int drv_suspend(struct ieee80211_local *local,
102eecc4800SJohannes Berg 			      struct cfg80211_wowlan *wowlan)
103eecc4800SJohannes Berg {
104eecc4800SJohannes Berg 	int ret;
105eecc4800SJohannes Berg 
106eecc4800SJohannes Berg 	might_sleep();
107eecc4800SJohannes Berg 
108eecc4800SJohannes Berg 	trace_drv_suspend(local);
109eecc4800SJohannes Berg 	ret = local->ops->suspend(&local->hw, wowlan);
110eecc4800SJohannes Berg 	trace_drv_return_int(local, ret);
111eecc4800SJohannes Berg 	return ret;
112eecc4800SJohannes Berg }
113eecc4800SJohannes Berg 
114eecc4800SJohannes Berg static inline int drv_resume(struct ieee80211_local *local)
115eecc4800SJohannes Berg {
116eecc4800SJohannes Berg 	int ret;
117eecc4800SJohannes Berg 
118eecc4800SJohannes Berg 	might_sleep();
119eecc4800SJohannes Berg 
120eecc4800SJohannes Berg 	trace_drv_resume(local);
121eecc4800SJohannes Berg 	ret = local->ops->resume(&local->hw);
122eecc4800SJohannes Berg 	trace_drv_return_int(local, ret);
123eecc4800SJohannes Berg 	return ret;
124eecc4800SJohannes Berg }
1256d52563fSJohannes Berg 
1266d52563fSJohannes Berg static inline void drv_set_wakeup(struct ieee80211_local *local,
1276d52563fSJohannes Berg 				  bool enabled)
1286d52563fSJohannes Berg {
1296d52563fSJohannes Berg 	might_sleep();
1306d52563fSJohannes Berg 
1316d52563fSJohannes Berg 	if (!local->ops->set_wakeup)
1326d52563fSJohannes Berg 		return;
1336d52563fSJohannes Berg 
1346d52563fSJohannes Berg 	trace_drv_set_wakeup(local, enabled);
1356d52563fSJohannes Berg 	local->ops->set_wakeup(&local->hw, enabled);
1366d52563fSJohannes Berg 	trace_drv_return_void(local);
1376d52563fSJohannes Berg }
138eecc4800SJohannes Berg #endif
139eecc4800SJohannes Berg 
14024487981SJohannes Berg static inline int drv_add_interface(struct ieee80211_local *local,
1417b7eab6fSJohannes Berg 				    struct ieee80211_sub_if_data *sdata)
14224487981SJohannes Berg {
143e1781ed3SKalle Valo 	int ret;
144e1781ed3SKalle Valo 
145e1781ed3SKalle Valo 	might_sleep();
146e1781ed3SKalle Valo 
1477b7eab6fSJohannes Berg 	if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
1484b6f1dd6SJohannes Berg 		    (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
1494b6f1dd6SJohannes Berg 		     !(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF))))
1507b7eab6fSJohannes Berg 		return -EINVAL;
1517b7eab6fSJohannes Berg 
1527b7eab6fSJohannes Berg 	trace_drv_add_interface(local, sdata);
1537b7eab6fSJohannes Berg 	ret = local->ops->add_interface(&local->hw, &sdata->vif);
1544efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
1557b7eab6fSJohannes Berg 
1567b7eab6fSJohannes Berg 	if (ret == 0)
1577b7eab6fSJohannes Berg 		sdata->flags |= IEEE80211_SDATA_IN_DRIVER;
1587b7eab6fSJohannes Berg 
1590a2b8bb2SJohannes Berg 	return ret;
16024487981SJohannes Berg }
16124487981SJohannes Berg 
16234d4bc4dSJohannes Berg static inline int drv_change_interface(struct ieee80211_local *local,
16334d4bc4dSJohannes Berg 				       struct ieee80211_sub_if_data *sdata,
1642ca27bcfSJohannes Berg 				       enum nl80211_iftype type, bool p2p)
16534d4bc4dSJohannes Berg {
16634d4bc4dSJohannes Berg 	int ret;
16734d4bc4dSJohannes Berg 
16834d4bc4dSJohannes Berg 	might_sleep();
16934d4bc4dSJohannes Berg 
1707b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
1717b7eab6fSJohannes Berg 
1722ca27bcfSJohannes Berg 	trace_drv_change_interface(local, sdata, type, p2p);
1732ca27bcfSJohannes Berg 	ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p);
17434d4bc4dSJohannes Berg 	trace_drv_return_int(local, ret);
17534d4bc4dSJohannes Berg 	return ret;
17634d4bc4dSJohannes Berg }
17734d4bc4dSJohannes Berg 
17824487981SJohannes Berg static inline void drv_remove_interface(struct ieee80211_local *local,
1797b7eab6fSJohannes Berg 					struct ieee80211_sub_if_data *sdata)
18024487981SJohannes Berg {
181e1781ed3SKalle Valo 	might_sleep();
182e1781ed3SKalle Valo 
1837b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
1847b7eab6fSJohannes Berg 
1857b7eab6fSJohannes Berg 	trace_drv_remove_interface(local, sdata);
1867b7eab6fSJohannes Berg 	local->ops->remove_interface(&local->hw, &sdata->vif);
1877b7eab6fSJohannes Berg 	sdata->flags &= ~IEEE80211_SDATA_IN_DRIVER;
1884efc76bdSJohannes Berg 	trace_drv_return_void(local);
18924487981SJohannes Berg }
19024487981SJohannes Berg 
19124487981SJohannes Berg static inline int drv_config(struct ieee80211_local *local, u32 changed)
19224487981SJohannes Berg {
193e1781ed3SKalle Valo 	int ret;
194e1781ed3SKalle Valo 
195e1781ed3SKalle Valo 	might_sleep();
196e1781ed3SKalle Valo 
1974efc76bdSJohannes Berg 	trace_drv_config(local, changed);
198e1781ed3SKalle Valo 	ret = local->ops->config(&local->hw, changed);
1994efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
2000a2b8bb2SJohannes Berg 	return ret;
20124487981SJohannes Berg }
20224487981SJohannes Berg 
20324487981SJohannes Berg static inline void drv_bss_info_changed(struct ieee80211_local *local,
20412375ef9SJohannes Berg 					struct ieee80211_sub_if_data *sdata,
20524487981SJohannes Berg 					struct ieee80211_bss_conf *info,
20624487981SJohannes Berg 					u32 changed)
20724487981SJohannes Berg {
208e1781ed3SKalle Valo 	might_sleep();
209e1781ed3SKalle Valo 
2107b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
2117b7eab6fSJohannes Berg 
2124efc76bdSJohannes Berg 	trace_drv_bss_info_changed(local, sdata, info, changed);
21324487981SJohannes Berg 	if (local->ops->bss_info_changed)
21412375ef9SJohannes Berg 		local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed);
2154efc76bdSJohannes Berg 	trace_drv_return_void(local);
21624487981SJohannes Berg }
21724487981SJohannes Berg 
2183ac64beeSJohannes Berg static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
21922bedad3SJiri Pirko 					struct netdev_hw_addr_list *mc_list)
22024487981SJohannes Berg {
2213ac64beeSJohannes Berg 	u64 ret = 0;
2223ac64beeSJohannes Berg 
2234efc76bdSJohannes Berg 	trace_drv_prepare_multicast(local, mc_list->count);
2244efc76bdSJohannes Berg 
2253ac64beeSJohannes Berg 	if (local->ops->prepare_multicast)
22622bedad3SJiri Pirko 		ret = local->ops->prepare_multicast(&local->hw, mc_list);
2273ac64beeSJohannes Berg 
2284efc76bdSJohannes Berg 	trace_drv_return_u64(local, ret);
2293ac64beeSJohannes Berg 
2303ac64beeSJohannes Berg 	return ret;
2313ac64beeSJohannes Berg }
2323ac64beeSJohannes Berg 
2333ac64beeSJohannes Berg static inline void drv_configure_filter(struct ieee80211_local *local,
2343ac64beeSJohannes Berg 					unsigned int changed_flags,
2353ac64beeSJohannes Berg 					unsigned int *total_flags,
2363ac64beeSJohannes Berg 					u64 multicast)
2373ac64beeSJohannes Berg {
2383ac64beeSJohannes Berg 	might_sleep();
2393ac64beeSJohannes Berg 
2400a2b8bb2SJohannes Berg 	trace_drv_configure_filter(local, changed_flags, total_flags,
2413ac64beeSJohannes Berg 				   multicast);
2424efc76bdSJohannes Berg 	local->ops->configure_filter(&local->hw, changed_flags, total_flags,
2434efc76bdSJohannes Berg 				     multicast);
2444efc76bdSJohannes Berg 	trace_drv_return_void(local);
24524487981SJohannes Berg }
24624487981SJohannes Berg 
24724487981SJohannes Berg static inline int drv_set_tim(struct ieee80211_local *local,
24824487981SJohannes Berg 			      struct ieee80211_sta *sta, bool set)
24924487981SJohannes Berg {
2500a2b8bb2SJohannes Berg 	int ret = 0;
2514efc76bdSJohannes Berg 	trace_drv_set_tim(local, sta, set);
25224487981SJohannes Berg 	if (local->ops->set_tim)
2530a2b8bb2SJohannes Berg 		ret = local->ops->set_tim(&local->hw, sta, set);
2544efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
2550a2b8bb2SJohannes Berg 	return ret;
25624487981SJohannes Berg }
25724487981SJohannes Berg 
25824487981SJohannes Berg static inline int drv_set_key(struct ieee80211_local *local,
25912375ef9SJohannes Berg 			      enum set_key_cmd cmd,
26012375ef9SJohannes Berg 			      struct ieee80211_sub_if_data *sdata,
26124487981SJohannes Berg 			      struct ieee80211_sta *sta,
26224487981SJohannes Berg 			      struct ieee80211_key_conf *key)
26324487981SJohannes Berg {
264e1781ed3SKalle Valo 	int ret;
265e1781ed3SKalle Valo 
266e1781ed3SKalle Valo 	might_sleep();
267e1781ed3SKalle Valo 
268077f4939SJohannes Berg 	sdata = get_bss_sdata(sdata);
2697b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
2707b7eab6fSJohannes Berg 
2714efc76bdSJohannes Berg 	trace_drv_set_key(local, cmd, sdata, sta, key);
272e1781ed3SKalle Valo 	ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key);
2734efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
2740a2b8bb2SJohannes Berg 	return ret;
27524487981SJohannes Berg }
27624487981SJohannes Berg 
27724487981SJohannes Berg static inline void drv_update_tkip_key(struct ieee80211_local *local,
278b3fbdcf4SJohannes Berg 				       struct ieee80211_sub_if_data *sdata,
27924487981SJohannes Berg 				       struct ieee80211_key_conf *conf,
280b3fbdcf4SJohannes Berg 				       struct sta_info *sta, u32 iv32,
28124487981SJohannes Berg 				       u16 *phase1key)
28224487981SJohannes Berg {
283b3fbdcf4SJohannes Berg 	struct ieee80211_sta *ista = NULL;
284b3fbdcf4SJohannes Berg 
285b3fbdcf4SJohannes Berg 	if (sta)
286b3fbdcf4SJohannes Berg 		ista = &sta->sta;
287b3fbdcf4SJohannes Berg 
288077f4939SJohannes Berg 	sdata = get_bss_sdata(sdata);
2897b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
2907b7eab6fSJohannes Berg 
2914efc76bdSJohannes Berg 	trace_drv_update_tkip_key(local, sdata, conf, ista, iv32);
29224487981SJohannes Berg 	if (local->ops->update_tkip_key)
293b3fbdcf4SJohannes Berg 		local->ops->update_tkip_key(&local->hw, &sdata->vif, conf,
294b3fbdcf4SJohannes Berg 					    ista, iv32, phase1key);
2954efc76bdSJohannes Berg 	trace_drv_return_void(local);
29624487981SJohannes Berg }
29724487981SJohannes Berg 
29824487981SJohannes Berg static inline int drv_hw_scan(struct ieee80211_local *local,
299a060bbfeSJohannes Berg 			      struct ieee80211_sub_if_data *sdata,
30024487981SJohannes Berg 			      struct cfg80211_scan_request *req)
30124487981SJohannes Berg {
302e1781ed3SKalle Valo 	int ret;
303e1781ed3SKalle Valo 
304e1781ed3SKalle Valo 	might_sleep();
305e1781ed3SKalle Valo 
3067b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
3077b7eab6fSJohannes Berg 
30879f460caSLuciano Coelho 	trace_drv_hw_scan(local, sdata);
309a060bbfeSJohannes Berg 	ret = local->ops->hw_scan(&local->hw, &sdata->vif, req);
3104efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
3110a2b8bb2SJohannes Berg 	return ret;
31224487981SJohannes Berg }
31324487981SJohannes Berg 
314b856439bSEliad Peller static inline void drv_cancel_hw_scan(struct ieee80211_local *local,
315b856439bSEliad Peller 				      struct ieee80211_sub_if_data *sdata)
316b856439bSEliad Peller {
317b856439bSEliad Peller 	might_sleep();
318b856439bSEliad Peller 
3197b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
3207b7eab6fSJohannes Berg 
321b856439bSEliad Peller 	trace_drv_cancel_hw_scan(local, sdata);
322b856439bSEliad Peller 	local->ops->cancel_hw_scan(&local->hw, &sdata->vif);
323b856439bSEliad Peller 	trace_drv_return_void(local);
324b856439bSEliad Peller }
325b856439bSEliad Peller 
32679f460caSLuciano Coelho static inline int
32779f460caSLuciano Coelho drv_sched_scan_start(struct ieee80211_local *local,
32879f460caSLuciano Coelho 		     struct ieee80211_sub_if_data *sdata,
32979f460caSLuciano Coelho 		     struct cfg80211_sched_scan_request *req,
33079f460caSLuciano Coelho 		     struct ieee80211_sched_scan_ies *ies)
33179f460caSLuciano Coelho {
33279f460caSLuciano Coelho 	int ret;
33379f460caSLuciano Coelho 
33479f460caSLuciano Coelho 	might_sleep();
33579f460caSLuciano Coelho 
3367b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
3377b7eab6fSJohannes Berg 
33879f460caSLuciano Coelho 	trace_drv_sched_scan_start(local, sdata);
33979f460caSLuciano Coelho 	ret = local->ops->sched_scan_start(&local->hw, &sdata->vif,
34079f460caSLuciano Coelho 					      req, ies);
34179f460caSLuciano Coelho 	trace_drv_return_int(local, ret);
34279f460caSLuciano Coelho 	return ret;
34379f460caSLuciano Coelho }
34479f460caSLuciano Coelho 
34579f460caSLuciano Coelho static inline void drv_sched_scan_stop(struct ieee80211_local *local,
34679f460caSLuciano Coelho 				       struct ieee80211_sub_if_data *sdata)
34779f460caSLuciano Coelho {
34879f460caSLuciano Coelho 	might_sleep();
34979f460caSLuciano Coelho 
3507b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
3517b7eab6fSJohannes Berg 
35279f460caSLuciano Coelho 	trace_drv_sched_scan_stop(local, sdata);
35379f460caSLuciano Coelho 	local->ops->sched_scan_stop(&local->hw, &sdata->vif);
35479f460caSLuciano Coelho 	trace_drv_return_void(local);
35579f460caSLuciano Coelho }
35679f460caSLuciano Coelho 
35724487981SJohannes Berg static inline void drv_sw_scan_start(struct ieee80211_local *local)
35824487981SJohannes Berg {
359e1781ed3SKalle Valo 	might_sleep();
360e1781ed3SKalle Valo 
3614efc76bdSJohannes Berg 	trace_drv_sw_scan_start(local);
36224487981SJohannes Berg 	if (local->ops->sw_scan_start)
36324487981SJohannes Berg 		local->ops->sw_scan_start(&local->hw);
3644efc76bdSJohannes Berg 	trace_drv_return_void(local);
36524487981SJohannes Berg }
36624487981SJohannes Berg 
36724487981SJohannes Berg static inline void drv_sw_scan_complete(struct ieee80211_local *local)
36824487981SJohannes Berg {
369e1781ed3SKalle Valo 	might_sleep();
370e1781ed3SKalle Valo 
3714efc76bdSJohannes Berg 	trace_drv_sw_scan_complete(local);
37224487981SJohannes Berg 	if (local->ops->sw_scan_complete)
37324487981SJohannes Berg 		local->ops->sw_scan_complete(&local->hw);
3744efc76bdSJohannes Berg 	trace_drv_return_void(local);
37524487981SJohannes Berg }
37624487981SJohannes Berg 
37724487981SJohannes Berg static inline int drv_get_stats(struct ieee80211_local *local,
37824487981SJohannes Berg 				struct ieee80211_low_level_stats *stats)
37924487981SJohannes Berg {
3800a2b8bb2SJohannes Berg 	int ret = -EOPNOTSUPP;
3810a2b8bb2SJohannes Berg 
382e1781ed3SKalle Valo 	might_sleep();
383e1781ed3SKalle Valo 
3840a2b8bb2SJohannes Berg 	if (local->ops->get_stats)
3850a2b8bb2SJohannes Berg 		ret = local->ops->get_stats(&local->hw, stats);
3860a2b8bb2SJohannes Berg 	trace_drv_get_stats(local, stats, ret);
3870a2b8bb2SJohannes Berg 
3880a2b8bb2SJohannes Berg 	return ret;
38924487981SJohannes Berg }
39024487981SJohannes Berg 
39124487981SJohannes Berg static inline void drv_get_tkip_seq(struct ieee80211_local *local,
39224487981SJohannes Berg 				    u8 hw_key_idx, u32 *iv32, u16 *iv16)
39324487981SJohannes Berg {
39424487981SJohannes Berg 	if (local->ops->get_tkip_seq)
39524487981SJohannes Berg 		local->ops->get_tkip_seq(&local->hw, hw_key_idx, iv32, iv16);
3960a2b8bb2SJohannes Berg 	trace_drv_get_tkip_seq(local, hw_key_idx, iv32, iv16);
39724487981SJohannes Berg }
39824487981SJohannes Berg 
399f23a4780SArik Nemtsov static inline int drv_set_frag_threshold(struct ieee80211_local *local,
400f23a4780SArik Nemtsov 					u32 value)
401f23a4780SArik Nemtsov {
402f23a4780SArik Nemtsov 	int ret = 0;
403f23a4780SArik Nemtsov 
404f23a4780SArik Nemtsov 	might_sleep();
405f23a4780SArik Nemtsov 
406f23a4780SArik Nemtsov 	trace_drv_set_frag_threshold(local, value);
407f23a4780SArik Nemtsov 	if (local->ops->set_frag_threshold)
408f23a4780SArik Nemtsov 		ret = local->ops->set_frag_threshold(&local->hw, value);
409f23a4780SArik Nemtsov 	trace_drv_return_int(local, ret);
410f23a4780SArik Nemtsov 	return ret;
411f23a4780SArik Nemtsov }
412f23a4780SArik Nemtsov 
41324487981SJohannes Berg static inline int drv_set_rts_threshold(struct ieee80211_local *local,
41424487981SJohannes Berg 					u32 value)
41524487981SJohannes Berg {
4160a2b8bb2SJohannes Berg 	int ret = 0;
417e1781ed3SKalle Valo 
418e1781ed3SKalle Valo 	might_sleep();
419e1781ed3SKalle Valo 
4204efc76bdSJohannes Berg 	trace_drv_set_rts_threshold(local, value);
42124487981SJohannes Berg 	if (local->ops->set_rts_threshold)
4220a2b8bb2SJohannes Berg 		ret = local->ops->set_rts_threshold(&local->hw, value);
4234efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
4240a2b8bb2SJohannes Berg 	return ret;
42524487981SJohannes Berg }
42624487981SJohannes Berg 
427310bc676SLukáš Turek static inline int drv_set_coverage_class(struct ieee80211_local *local,
428310bc676SLukáš Turek 					 u8 value)
429310bc676SLukáš Turek {
430310bc676SLukáš Turek 	int ret = 0;
431310bc676SLukáš Turek 	might_sleep();
432310bc676SLukáš Turek 
4334efc76bdSJohannes Berg 	trace_drv_set_coverage_class(local, value);
434310bc676SLukáš Turek 	if (local->ops->set_coverage_class)
435310bc676SLukáš Turek 		local->ops->set_coverage_class(&local->hw, value);
436310bc676SLukáš Turek 	else
437310bc676SLukáš Turek 		ret = -EOPNOTSUPP;
438310bc676SLukáš Turek 
4394efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
440310bc676SLukáš Turek 	return ret;
441310bc676SLukáš Turek }
442310bc676SLukáš Turek 
44324487981SJohannes Berg static inline void drv_sta_notify(struct ieee80211_local *local,
44412375ef9SJohannes Berg 				  struct ieee80211_sub_if_data *sdata,
44524487981SJohannes Berg 				  enum sta_notify_cmd cmd,
44624487981SJohannes Berg 				  struct ieee80211_sta *sta)
44724487981SJohannes Berg {
448bc192f89SFelix Fietkau 	sdata = get_bss_sdata(sdata);
4497b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
4507b7eab6fSJohannes Berg 
4514efc76bdSJohannes Berg 	trace_drv_sta_notify(local, sdata, cmd, sta);
45224487981SJohannes Berg 	if (local->ops->sta_notify)
45312375ef9SJohannes Berg 		local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta);
4544efc76bdSJohannes Berg 	trace_drv_return_void(local);
45524487981SJohannes Berg }
45624487981SJohannes Berg 
45734e89507SJohannes Berg static inline int drv_sta_add(struct ieee80211_local *local,
45834e89507SJohannes Berg 			      struct ieee80211_sub_if_data *sdata,
45934e89507SJohannes Berg 			      struct ieee80211_sta *sta)
46034e89507SJohannes Berg {
46134e89507SJohannes Berg 	int ret = 0;
46234e89507SJohannes Berg 
46334e89507SJohannes Berg 	might_sleep();
46434e89507SJohannes Berg 
465bc192f89SFelix Fietkau 	sdata = get_bss_sdata(sdata);
4667b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
4677b7eab6fSJohannes Berg 
4684efc76bdSJohannes Berg 	trace_drv_sta_add(local, sdata, sta);
46934e89507SJohannes Berg 	if (local->ops->sta_add)
47034e89507SJohannes Berg 		ret = local->ops->sta_add(&local->hw, &sdata->vif, sta);
47134e89507SJohannes Berg 
4724efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
47334e89507SJohannes Berg 
47434e89507SJohannes Berg 	return ret;
47534e89507SJohannes Berg }
47634e89507SJohannes Berg 
47734e89507SJohannes Berg static inline void drv_sta_remove(struct ieee80211_local *local,
47834e89507SJohannes Berg 				  struct ieee80211_sub_if_data *sdata,
47934e89507SJohannes Berg 				  struct ieee80211_sta *sta)
48034e89507SJohannes Berg {
48134e89507SJohannes Berg 	might_sleep();
48234e89507SJohannes Berg 
483bc192f89SFelix Fietkau 	sdata = get_bss_sdata(sdata);
4847b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
4857b7eab6fSJohannes Berg 
4864efc76bdSJohannes Berg 	trace_drv_sta_remove(local, sdata, sta);
48734e89507SJohannes Berg 	if (local->ops->sta_remove)
48834e89507SJohannes Berg 		local->ops->sta_remove(&local->hw, &sdata->vif, sta);
48934e89507SJohannes Berg 
4904efc76bdSJohannes Berg 	trace_drv_return_void(local);
49134e89507SJohannes Berg }
49234e89507SJohannes Berg 
493f09603a2SJohannes Berg static inline __must_check
494f09603a2SJohannes Berg int drv_sta_state(struct ieee80211_local *local,
495f09603a2SJohannes Berg 		  struct ieee80211_sub_if_data *sdata,
496f09603a2SJohannes Berg 		  struct sta_info *sta,
497f09603a2SJohannes Berg 		  enum ieee80211_sta_state old_state,
498f09603a2SJohannes Berg 		  enum ieee80211_sta_state new_state)
499f09603a2SJohannes Berg {
500f09603a2SJohannes Berg 	int ret = 0;
501f09603a2SJohannes Berg 
502f09603a2SJohannes Berg 	might_sleep();
503f09603a2SJohannes Berg 
504f09603a2SJohannes Berg 	sdata = get_bss_sdata(sdata);
505f09603a2SJohannes Berg 	check_sdata_in_driver(sdata);
506f09603a2SJohannes Berg 
507f09603a2SJohannes Berg 	trace_drv_sta_state(local, sdata, &sta->sta, old_state, new_state);
508a4ec45a4SJohannes Berg 	if (local->ops->sta_state) {
509f09603a2SJohannes Berg 		ret = local->ops->sta_state(&local->hw, &sdata->vif, &sta->sta,
510f09603a2SJohannes Berg 					    old_state, new_state);
511a4ec45a4SJohannes Berg 	} else if (old_state == IEEE80211_STA_AUTH &&
512a4ec45a4SJohannes Berg 		   new_state == IEEE80211_STA_ASSOC) {
513a4ec45a4SJohannes Berg 		ret = drv_sta_add(local, sdata, &sta->sta);
514a4ec45a4SJohannes Berg 		if (ret == 0)
515a4ec45a4SJohannes Berg 			sta->uploaded = true;
516a4ec45a4SJohannes Berg 	} else if (old_state == IEEE80211_STA_ASSOC &&
517a4ec45a4SJohannes Berg 		   new_state == IEEE80211_STA_AUTH) {
518a4ec45a4SJohannes Berg 		drv_sta_remove(local, sdata, &sta->sta);
519a4ec45a4SJohannes Berg 	}
520f09603a2SJohannes Berg 	trace_drv_return_int(local, ret);
521f09603a2SJohannes Berg 	return ret;
522f09603a2SJohannes Berg }
523f09603a2SJohannes Berg 
5248f727ef3SJohannes Berg static inline void drv_sta_rc_update(struct ieee80211_local *local,
5258f727ef3SJohannes Berg 				     struct ieee80211_sub_if_data *sdata,
5268f727ef3SJohannes Berg 				     struct ieee80211_sta *sta, u32 changed)
5278f727ef3SJohannes Berg {
5288f727ef3SJohannes Berg 	sdata = get_bss_sdata(sdata);
5298f727ef3SJohannes Berg 	check_sdata_in_driver(sdata);
5308f727ef3SJohannes Berg 
531e687f61eSAntonio Quartulli 	WARN_ON(changed & IEEE80211_RC_SUPP_RATES_CHANGED &&
532e687f61eSAntonio Quartulli 		sdata->vif.type != NL80211_IFTYPE_ADHOC);
533e687f61eSAntonio Quartulli 
5348f727ef3SJohannes Berg 	trace_drv_sta_rc_update(local, sdata, sta, changed);
5358f727ef3SJohannes Berg 	if (local->ops->sta_rc_update)
5368f727ef3SJohannes Berg 		local->ops->sta_rc_update(&local->hw, &sdata->vif,
5378f727ef3SJohannes Berg 					  sta, changed);
5388f727ef3SJohannes Berg 
5398f727ef3SJohannes Berg 	trace_drv_return_void(local);
5408f727ef3SJohannes Berg }
5418f727ef3SJohannes Berg 
542f6f3def3SEliad Peller static inline int drv_conf_tx(struct ieee80211_local *local,
543a3304b0aSJohannes Berg 			      struct ieee80211_sub_if_data *sdata, u16 ac,
54424487981SJohannes Berg 			      const struct ieee80211_tx_queue_params *params)
54524487981SJohannes Berg {
5460a2b8bb2SJohannes Berg 	int ret = -EOPNOTSUPP;
547e1781ed3SKalle Valo 
548e1781ed3SKalle Valo 	might_sleep();
549e1781ed3SKalle Valo 
5507b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
5517b7eab6fSJohannes Berg 
552a3304b0aSJohannes Berg 	trace_drv_conf_tx(local, sdata, ac, params);
55324487981SJohannes Berg 	if (local->ops->conf_tx)
5548a3a3c85SEliad Peller 		ret = local->ops->conf_tx(&local->hw, &sdata->vif,
555a3304b0aSJohannes Berg 					  ac, params);
5564efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
5570a2b8bb2SJohannes Berg 	return ret;
55824487981SJohannes Berg }
55924487981SJohannes Berg 
56037a41b4aSEliad Peller static inline u64 drv_get_tsf(struct ieee80211_local *local,
56137a41b4aSEliad Peller 			      struct ieee80211_sub_if_data *sdata)
56224487981SJohannes Berg {
5630a2b8bb2SJohannes Berg 	u64 ret = -1ULL;
564e1781ed3SKalle Valo 
565e1781ed3SKalle Valo 	might_sleep();
566e1781ed3SKalle Valo 
5677b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
5687b7eab6fSJohannes Berg 
56937a41b4aSEliad Peller 	trace_drv_get_tsf(local, sdata);
57024487981SJohannes Berg 	if (local->ops->get_tsf)
57137a41b4aSEliad Peller 		ret = local->ops->get_tsf(&local->hw, &sdata->vif);
5724efc76bdSJohannes Berg 	trace_drv_return_u64(local, ret);
5730a2b8bb2SJohannes Berg 	return ret;
57424487981SJohannes Berg }
57524487981SJohannes Berg 
57637a41b4aSEliad Peller static inline void drv_set_tsf(struct ieee80211_local *local,
57737a41b4aSEliad Peller 			       struct ieee80211_sub_if_data *sdata,
57837a41b4aSEliad Peller 			       u64 tsf)
57924487981SJohannes Berg {
580e1781ed3SKalle Valo 	might_sleep();
581e1781ed3SKalle Valo 
5827b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
5837b7eab6fSJohannes Berg 
58437a41b4aSEliad Peller 	trace_drv_set_tsf(local, sdata, tsf);
58524487981SJohannes Berg 	if (local->ops->set_tsf)
58637a41b4aSEliad Peller 		local->ops->set_tsf(&local->hw, &sdata->vif, tsf);
5874efc76bdSJohannes Berg 	trace_drv_return_void(local);
58824487981SJohannes Berg }
58924487981SJohannes Berg 
59037a41b4aSEliad Peller static inline void drv_reset_tsf(struct ieee80211_local *local,
59137a41b4aSEliad Peller 				 struct ieee80211_sub_if_data *sdata)
59224487981SJohannes Berg {
593e1781ed3SKalle Valo 	might_sleep();
594e1781ed3SKalle Valo 
5957b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
5967b7eab6fSJohannes Berg 
59737a41b4aSEliad Peller 	trace_drv_reset_tsf(local, sdata);
59824487981SJohannes Berg 	if (local->ops->reset_tsf)
59937a41b4aSEliad Peller 		local->ops->reset_tsf(&local->hw, &sdata->vif);
6004efc76bdSJohannes Berg 	trace_drv_return_void(local);
60124487981SJohannes Berg }
60224487981SJohannes Berg 
60324487981SJohannes Berg static inline int drv_tx_last_beacon(struct ieee80211_local *local)
60424487981SJohannes Berg {
60591f44b02STim Harvey 	int ret = 0; /* default unsuported op for less congestion */
606e1781ed3SKalle Valo 
607e1781ed3SKalle Valo 	might_sleep();
608e1781ed3SKalle Valo 
6094efc76bdSJohannes Berg 	trace_drv_tx_last_beacon(local);
61024487981SJohannes Berg 	if (local->ops->tx_last_beacon)
6110a2b8bb2SJohannes Berg 		ret = local->ops->tx_last_beacon(&local->hw);
6124efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
6130a2b8bb2SJohannes Berg 	return ret;
61424487981SJohannes Berg }
61524487981SJohannes Berg 
61624487981SJohannes Berg static inline int drv_ampdu_action(struct ieee80211_local *local,
61712375ef9SJohannes Berg 				   struct ieee80211_sub_if_data *sdata,
61824487981SJohannes Berg 				   enum ieee80211_ampdu_mlme_action action,
61924487981SJohannes Berg 				   struct ieee80211_sta *sta, u16 tid,
6200b01f030SJohannes Berg 				   u16 *ssn, u8 buf_size)
62124487981SJohannes Berg {
6220a2b8bb2SJohannes Berg 	int ret = -EOPNOTSUPP;
623cfcdbde3SJohannes Berg 
624cfcdbde3SJohannes Berg 	might_sleep();
625cfcdbde3SJohannes Berg 
626bc192f89SFelix Fietkau 	sdata = get_bss_sdata(sdata);
6277b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
6287b7eab6fSJohannes Berg 
6290b01f030SJohannes Berg 	trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size);
6304efc76bdSJohannes Berg 
63124487981SJohannes Berg 	if (local->ops->ampdu_action)
63212375ef9SJohannes Berg 		ret = local->ops->ampdu_action(&local->hw, &sdata->vif, action,
6330b01f030SJohannes Berg 					       sta, tid, ssn, buf_size);
63485ad181eSJohannes Berg 
6354efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
6364efc76bdSJohannes Berg 
6370a2b8bb2SJohannes Berg 	return ret;
63824487981SJohannes Berg }
6391f87f7d3SJohannes Berg 
6401289723eSHolger Schurig static inline int drv_get_survey(struct ieee80211_local *local, int idx,
6411289723eSHolger Schurig 				struct survey_info *survey)
6421289723eSHolger Schurig {
6431289723eSHolger Schurig 	int ret = -EOPNOTSUPP;
644c466d4efSJohn W. Linville 
645c466d4efSJohn W. Linville 	trace_drv_get_survey(local, idx, survey);
646c466d4efSJohn W. Linville 
64735dd0509SHolger Schurig 	if (local->ops->get_survey)
6481289723eSHolger Schurig 		ret = local->ops->get_survey(&local->hw, idx, survey);
649c466d4efSJohn W. Linville 
650c466d4efSJohn W. Linville 	trace_drv_return_int(local, ret);
651c466d4efSJohn W. Linville 
6521289723eSHolger Schurig 	return ret;
6531289723eSHolger Schurig }
6541f87f7d3SJohannes Berg 
6551f87f7d3SJohannes Berg static inline void drv_rfkill_poll(struct ieee80211_local *local)
6561f87f7d3SJohannes Berg {
657e1781ed3SKalle Valo 	might_sleep();
658e1781ed3SKalle Valo 
6591f87f7d3SJohannes Berg 	if (local->ops->rfkill_poll)
6601f87f7d3SJohannes Berg 		local->ops->rfkill_poll(&local->hw);
6611f87f7d3SJohannes Berg }
662a80f7c0bSJohannes Berg 
663a80f7c0bSJohannes Berg static inline void drv_flush(struct ieee80211_local *local, bool drop)
664a80f7c0bSJohannes Berg {
665e1781ed3SKalle Valo 	might_sleep();
666e1781ed3SKalle Valo 
667a80f7c0bSJohannes Berg 	trace_drv_flush(local, drop);
668a80f7c0bSJohannes Berg 	if (local->ops->flush)
669a80f7c0bSJohannes Berg 		local->ops->flush(&local->hw, drop);
6704efc76bdSJohannes Berg 	trace_drv_return_void(local);
671a80f7c0bSJohannes Berg }
6725ce6e438SJohannes Berg 
6735ce6e438SJohannes Berg static inline void drv_channel_switch(struct ieee80211_local *local,
6745ce6e438SJohannes Berg 				     struct ieee80211_channel_switch *ch_switch)
6755ce6e438SJohannes Berg {
6765ce6e438SJohannes Berg 	might_sleep();
6775ce6e438SJohannes Berg 
6785ce6e438SJohannes Berg 	trace_drv_channel_switch(local, ch_switch);
6794efc76bdSJohannes Berg 	local->ops->channel_switch(&local->hw, ch_switch);
6804efc76bdSJohannes Berg 	trace_drv_return_void(local);
6815ce6e438SJohannes Berg }
6825ce6e438SJohannes Berg 
68315d96753SBruno Randolf 
68415d96753SBruno Randolf static inline int drv_set_antenna(struct ieee80211_local *local,
68515d96753SBruno Randolf 				  u32 tx_ant, u32 rx_ant)
68615d96753SBruno Randolf {
68715d96753SBruno Randolf 	int ret = -EOPNOTSUPP;
68815d96753SBruno Randolf 	might_sleep();
68915d96753SBruno Randolf 	if (local->ops->set_antenna)
69015d96753SBruno Randolf 		ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant);
69115d96753SBruno Randolf 	trace_drv_set_antenna(local, tx_ant, rx_ant, ret);
69215d96753SBruno Randolf 	return ret;
69315d96753SBruno Randolf }
69415d96753SBruno Randolf 
69515d96753SBruno Randolf static inline int drv_get_antenna(struct ieee80211_local *local,
69615d96753SBruno Randolf 				  u32 *tx_ant, u32 *rx_ant)
69715d96753SBruno Randolf {
69815d96753SBruno Randolf 	int ret = -EOPNOTSUPP;
69915d96753SBruno Randolf 	might_sleep();
70015d96753SBruno Randolf 	if (local->ops->get_antenna)
70115d96753SBruno Randolf 		ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant);
70215d96753SBruno Randolf 	trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret);
70315d96753SBruno Randolf 	return ret;
70415d96753SBruno Randolf }
70515d96753SBruno Randolf 
70621f83589SJohannes Berg static inline int drv_remain_on_channel(struct ieee80211_local *local,
70721f83589SJohannes Berg 					struct ieee80211_channel *chan,
70821f83589SJohannes Berg 					enum nl80211_channel_type chantype,
70921f83589SJohannes Berg 					unsigned int duration)
71021f83589SJohannes Berg {
71121f83589SJohannes Berg 	int ret;
71221f83589SJohannes Berg 
71321f83589SJohannes Berg 	might_sleep();
71421f83589SJohannes Berg 
71521f83589SJohannes Berg 	trace_drv_remain_on_channel(local, chan, chantype, duration);
71621f83589SJohannes Berg 	ret = local->ops->remain_on_channel(&local->hw, chan, chantype,
71721f83589SJohannes Berg 					    duration);
71821f83589SJohannes Berg 	trace_drv_return_int(local, ret);
71921f83589SJohannes Berg 
72021f83589SJohannes Berg 	return ret;
72121f83589SJohannes Berg }
72221f83589SJohannes Berg 
72321f83589SJohannes Berg static inline int drv_cancel_remain_on_channel(struct ieee80211_local *local)
72421f83589SJohannes Berg {
72521f83589SJohannes Berg 	int ret;
72621f83589SJohannes Berg 
72721f83589SJohannes Berg 	might_sleep();
72821f83589SJohannes Berg 
72921f83589SJohannes Berg 	trace_drv_cancel_remain_on_channel(local);
73021f83589SJohannes Berg 	ret = local->ops->cancel_remain_on_channel(&local->hw);
73121f83589SJohannes Berg 	trace_drv_return_int(local, ret);
73221f83589SJohannes Berg 
73321f83589SJohannes Berg 	return ret;
73421f83589SJohannes Berg }
73521f83589SJohannes Berg 
73638c09159SJohn W. Linville static inline int drv_set_ringparam(struct ieee80211_local *local,
73738c09159SJohn W. Linville 				    u32 tx, u32 rx)
73838c09159SJohn W. Linville {
73938c09159SJohn W. Linville 	int ret = -ENOTSUPP;
74038c09159SJohn W. Linville 
74138c09159SJohn W. Linville 	might_sleep();
74238c09159SJohn W. Linville 
74338c09159SJohn W. Linville 	trace_drv_set_ringparam(local, tx, rx);
74438c09159SJohn W. Linville 	if (local->ops->set_ringparam)
74538c09159SJohn W. Linville 		ret = local->ops->set_ringparam(&local->hw, tx, rx);
74638c09159SJohn W. Linville 	trace_drv_return_int(local, ret);
74738c09159SJohn W. Linville 
74838c09159SJohn W. Linville 	return ret;
74938c09159SJohn W. Linville }
75038c09159SJohn W. Linville 
75138c09159SJohn W. Linville static inline void drv_get_ringparam(struct ieee80211_local *local,
75238c09159SJohn W. Linville 				     u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
75338c09159SJohn W. Linville {
75438c09159SJohn W. Linville 	might_sleep();
75538c09159SJohn W. Linville 
75638c09159SJohn W. Linville 	trace_drv_get_ringparam(local, tx, tx_max, rx, rx_max);
75738c09159SJohn W. Linville 	if (local->ops->get_ringparam)
75838c09159SJohn W. Linville 		local->ops->get_ringparam(&local->hw, tx, tx_max, rx, rx_max);
75938c09159SJohn W. Linville 	trace_drv_return_void(local);
76038c09159SJohn W. Linville }
76138c09159SJohn W. Linville 
762e8306f98SVivek Natarajan static inline bool drv_tx_frames_pending(struct ieee80211_local *local)
763e8306f98SVivek Natarajan {
764e8306f98SVivek Natarajan 	bool ret = false;
765e8306f98SVivek Natarajan 
766e8306f98SVivek Natarajan 	might_sleep();
767e8306f98SVivek Natarajan 
768e8306f98SVivek Natarajan 	trace_drv_tx_frames_pending(local);
769e8306f98SVivek Natarajan 	if (local->ops->tx_frames_pending)
770e8306f98SVivek Natarajan 		ret = local->ops->tx_frames_pending(&local->hw);
771e8306f98SVivek Natarajan 	trace_drv_return_bool(local, ret);
772e8306f98SVivek Natarajan 
773e8306f98SVivek Natarajan 	return ret;
774e8306f98SVivek Natarajan }
775bdbfd6b5SSujith Manoharan 
776bdbfd6b5SSujith Manoharan static inline int drv_set_bitrate_mask(struct ieee80211_local *local,
777bdbfd6b5SSujith Manoharan 				       struct ieee80211_sub_if_data *sdata,
778bdbfd6b5SSujith Manoharan 				       const struct cfg80211_bitrate_mask *mask)
779bdbfd6b5SSujith Manoharan {
780bdbfd6b5SSujith Manoharan 	int ret = -EOPNOTSUPP;
781bdbfd6b5SSujith Manoharan 
782bdbfd6b5SSujith Manoharan 	might_sleep();
783bdbfd6b5SSujith Manoharan 
7847b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
7857b7eab6fSJohannes Berg 
786bdbfd6b5SSujith Manoharan 	trace_drv_set_bitrate_mask(local, sdata, mask);
787bdbfd6b5SSujith Manoharan 	if (local->ops->set_bitrate_mask)
788bdbfd6b5SSujith Manoharan 		ret = local->ops->set_bitrate_mask(&local->hw,
789bdbfd6b5SSujith Manoharan 						   &sdata->vif, mask);
790bdbfd6b5SSujith Manoharan 	trace_drv_return_int(local, ret);
791bdbfd6b5SSujith Manoharan 
792bdbfd6b5SSujith Manoharan 	return ret;
793bdbfd6b5SSujith Manoharan }
794bdbfd6b5SSujith Manoharan 
795c68f4b89SJohannes Berg static inline void drv_set_rekey_data(struct ieee80211_local *local,
796c68f4b89SJohannes Berg 				      struct ieee80211_sub_if_data *sdata,
797c68f4b89SJohannes Berg 				      struct cfg80211_gtk_rekey_data *data)
798c68f4b89SJohannes Berg {
7997b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
8007b7eab6fSJohannes Berg 
801c68f4b89SJohannes Berg 	trace_drv_set_rekey_data(local, sdata, data);
802c68f4b89SJohannes Berg 	if (local->ops->set_rekey_data)
803c68f4b89SJohannes Berg 		local->ops->set_rekey_data(&local->hw, &sdata->vif, data);
804c68f4b89SJohannes Berg 	trace_drv_return_void(local);
805c68f4b89SJohannes Berg }
806c68f4b89SJohannes Berg 
807615f7b9bSMeenakshi Venkataraman static inline void drv_rssi_callback(struct ieee80211_local *local,
808615f7b9bSMeenakshi Venkataraman 				     const enum ieee80211_rssi_event event)
809615f7b9bSMeenakshi Venkataraman {
810615f7b9bSMeenakshi Venkataraman 	trace_drv_rssi_callback(local, event);
811615f7b9bSMeenakshi Venkataraman 	if (local->ops->rssi_callback)
812615f7b9bSMeenakshi Venkataraman 		local->ops->rssi_callback(&local->hw, event);
813615f7b9bSMeenakshi Venkataraman 	trace_drv_return_void(local);
814615f7b9bSMeenakshi Venkataraman }
8154049e09aSJohannes Berg 
8164049e09aSJohannes Berg static inline void
8174049e09aSJohannes Berg drv_release_buffered_frames(struct ieee80211_local *local,
8184049e09aSJohannes Berg 			    struct sta_info *sta, u16 tids, int num_frames,
8194049e09aSJohannes Berg 			    enum ieee80211_frame_release_type reason,
8204049e09aSJohannes Berg 			    bool more_data)
8214049e09aSJohannes Berg {
8224049e09aSJohannes Berg 	trace_drv_release_buffered_frames(local, &sta->sta, tids, num_frames,
8234049e09aSJohannes Berg 					  reason, more_data);
8244049e09aSJohannes Berg 	if (local->ops->release_buffered_frames)
8254049e09aSJohannes Berg 		local->ops->release_buffered_frames(&local->hw, &sta->sta, tids,
8264049e09aSJohannes Berg 						    num_frames, reason,
8274049e09aSJohannes Berg 						    more_data);
8284049e09aSJohannes Berg 	trace_drv_return_void(local);
8294049e09aSJohannes Berg }
83040b96408SJohannes Berg 
83140b96408SJohannes Berg static inline void
83240b96408SJohannes Berg drv_allow_buffered_frames(struct ieee80211_local *local,
83340b96408SJohannes Berg 			  struct sta_info *sta, u16 tids, int num_frames,
83440b96408SJohannes Berg 			  enum ieee80211_frame_release_type reason,
83540b96408SJohannes Berg 			  bool more_data)
83640b96408SJohannes Berg {
83740b96408SJohannes Berg 	trace_drv_allow_buffered_frames(local, &sta->sta, tids, num_frames,
83840b96408SJohannes Berg 					reason, more_data);
83940b96408SJohannes Berg 	if (local->ops->allow_buffered_frames)
84040b96408SJohannes Berg 		local->ops->allow_buffered_frames(&local->hw, &sta->sta,
84140b96408SJohannes Berg 						  tids, num_frames, reason,
84240b96408SJohannes Berg 						  more_data);
84340b96408SJohannes Berg 	trace_drv_return_void(local);
84440b96408SJohannes Berg }
84566572cfcSVictor Goldenshtein 
84666572cfcSVictor Goldenshtein static inline int drv_get_rssi(struct ieee80211_local *local,
84766572cfcSVictor Goldenshtein 				struct ieee80211_sub_if_data *sdata,
84866572cfcSVictor Goldenshtein 				struct ieee80211_sta *sta,
84966572cfcSVictor Goldenshtein 				s8 *rssi_dbm)
85066572cfcSVictor Goldenshtein {
85166572cfcSVictor Goldenshtein 	int ret;
85266572cfcSVictor Goldenshtein 
85366572cfcSVictor Goldenshtein 	might_sleep();
85466572cfcSVictor Goldenshtein 
85566572cfcSVictor Goldenshtein 	ret = local->ops->get_rssi(&local->hw, &sdata->vif, sta, rssi_dbm);
85666572cfcSVictor Goldenshtein 	trace_drv_get_rssi(local, sta, *rssi_dbm, ret);
85766572cfcSVictor Goldenshtein 
85866572cfcSVictor Goldenshtein 	return ret;
85966572cfcSVictor Goldenshtein }
860a1845fc7SJohannes Berg 
861a1845fc7SJohannes Berg static inline void drv_mgd_prepare_tx(struct ieee80211_local *local,
862a1845fc7SJohannes Berg 				      struct ieee80211_sub_if_data *sdata)
863a1845fc7SJohannes Berg {
864a1845fc7SJohannes Berg 	might_sleep();
865a1845fc7SJohannes Berg 
866a1845fc7SJohannes Berg 	check_sdata_in_driver(sdata);
867a1845fc7SJohannes Berg 	WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
868a1845fc7SJohannes Berg 
869a1845fc7SJohannes Berg 	trace_drv_mgd_prepare_tx(local, sdata);
870a1845fc7SJohannes Berg 	if (local->ops->mgd_prepare_tx)
871a1845fc7SJohannes Berg 		local->ops->mgd_prepare_tx(&local->hw, &sdata->vif);
872a1845fc7SJohannes Berg 	trace_drv_return_void(local);
873a1845fc7SJohannes Berg }
874c3645eacSMichal Kazior 
875c3645eacSMichal Kazior static inline int drv_add_chanctx(struct ieee80211_local *local,
876c3645eacSMichal Kazior 				  struct ieee80211_chanctx *ctx)
877c3645eacSMichal Kazior {
878c3645eacSMichal Kazior 	int ret = -EOPNOTSUPP;
879c3645eacSMichal Kazior 
880c3645eacSMichal Kazior 	trace_drv_add_chanctx(local, ctx);
881c3645eacSMichal Kazior 	if (local->ops->add_chanctx)
882c3645eacSMichal Kazior 		ret = local->ops->add_chanctx(&local->hw, &ctx->conf);
883c3645eacSMichal Kazior 	trace_drv_return_int(local, ret);
884c3645eacSMichal Kazior 
885c3645eacSMichal Kazior 	return ret;
886c3645eacSMichal Kazior }
887c3645eacSMichal Kazior 
888c3645eacSMichal Kazior static inline void drv_remove_chanctx(struct ieee80211_local *local,
889c3645eacSMichal Kazior 				      struct ieee80211_chanctx *ctx)
890c3645eacSMichal Kazior {
891c3645eacSMichal Kazior 	trace_drv_remove_chanctx(local, ctx);
892c3645eacSMichal Kazior 	if (local->ops->remove_chanctx)
893c3645eacSMichal Kazior 		local->ops->remove_chanctx(&local->hw, &ctx->conf);
894c3645eacSMichal Kazior 	trace_drv_return_void(local);
895c3645eacSMichal Kazior }
896c3645eacSMichal Kazior 
897c3645eacSMichal Kazior static inline void drv_change_chanctx(struct ieee80211_local *local,
898c3645eacSMichal Kazior 				      struct ieee80211_chanctx *ctx,
899c3645eacSMichal Kazior 				      u32 changed)
900c3645eacSMichal Kazior {
901c3645eacSMichal Kazior 	trace_drv_change_chanctx(local, ctx, changed);
902c3645eacSMichal Kazior 	if (local->ops->change_chanctx)
903c3645eacSMichal Kazior 		local->ops->change_chanctx(&local->hw, &ctx->conf, changed);
904c3645eacSMichal Kazior 	trace_drv_return_void(local);
905c3645eacSMichal Kazior }
906c3645eacSMichal Kazior 
907c3645eacSMichal Kazior static inline int drv_assign_vif_chanctx(struct ieee80211_local *local,
908c3645eacSMichal Kazior 					 struct ieee80211_sub_if_data *sdata,
909c3645eacSMichal Kazior 					 struct ieee80211_chanctx *ctx)
910c3645eacSMichal Kazior {
911c3645eacSMichal Kazior 	int ret = 0;
912c3645eacSMichal Kazior 
913c3645eacSMichal Kazior 	check_sdata_in_driver(sdata);
914c3645eacSMichal Kazior 
915c3645eacSMichal Kazior 	trace_drv_assign_vif_chanctx(local, sdata, ctx);
916c3645eacSMichal Kazior 	if (local->ops->assign_vif_chanctx)
917c3645eacSMichal Kazior 		ret = local->ops->assign_vif_chanctx(&local->hw,
918c3645eacSMichal Kazior 						     &sdata->vif,
919c3645eacSMichal Kazior 						     &ctx->conf);
920c3645eacSMichal Kazior 	trace_drv_return_int(local, ret);
921c3645eacSMichal Kazior 
922c3645eacSMichal Kazior 	return ret;
923c3645eacSMichal Kazior }
924c3645eacSMichal Kazior 
925c3645eacSMichal Kazior static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local,
926c3645eacSMichal Kazior 					    struct ieee80211_sub_if_data *sdata,
927c3645eacSMichal Kazior 					    struct ieee80211_chanctx *ctx)
928c3645eacSMichal Kazior {
929c3645eacSMichal Kazior 	check_sdata_in_driver(sdata);
930c3645eacSMichal Kazior 
931c3645eacSMichal Kazior 	trace_drv_unassign_vif_chanctx(local, sdata, ctx);
932c3645eacSMichal Kazior 	if (local->ops->unassign_vif_chanctx)
933c3645eacSMichal Kazior 		local->ops->unassign_vif_chanctx(&local->hw,
934c3645eacSMichal Kazior 						 &sdata->vif,
935c3645eacSMichal Kazior 						 &ctx->conf);
936c3645eacSMichal Kazior 	trace_drv_return_void(local);
937c3645eacSMichal Kazior }
938c3645eacSMichal Kazior 
93924487981SJohannes Berg #endif /* __MAC80211_DRIVER_OPS */
940