xref: /openbmc/linux/net/mac80211/driver-ops.h (revision 8a61af65)
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 
49377d2ece6SSujith Manoharan #ifdef CONFIG_MAC80211_DEBUGFS
49477d2ece6SSujith Manoharan static inline void drv_sta_add_debugfs(struct ieee80211_local *local,
49577d2ece6SSujith Manoharan 				       struct ieee80211_sub_if_data *sdata,
49677d2ece6SSujith Manoharan 				       struct ieee80211_sta *sta,
49777d2ece6SSujith Manoharan 				       struct dentry *dir)
49877d2ece6SSujith Manoharan {
49977d2ece6SSujith Manoharan 	might_sleep();
50077d2ece6SSujith Manoharan 
50177d2ece6SSujith Manoharan 	sdata = get_bss_sdata(sdata);
50277d2ece6SSujith Manoharan 	check_sdata_in_driver(sdata);
50377d2ece6SSujith Manoharan 
50477d2ece6SSujith Manoharan 	if (local->ops->sta_add_debugfs)
50577d2ece6SSujith Manoharan 		local->ops->sta_add_debugfs(&local->hw, &sdata->vif,
50677d2ece6SSujith Manoharan 					    sta, dir);
50777d2ece6SSujith Manoharan }
50877d2ece6SSujith Manoharan 
50977d2ece6SSujith Manoharan static inline void drv_sta_remove_debugfs(struct ieee80211_local *local,
51077d2ece6SSujith Manoharan 					  struct ieee80211_sub_if_data *sdata,
51177d2ece6SSujith Manoharan 					  struct ieee80211_sta *sta,
51277d2ece6SSujith Manoharan 					  struct dentry *dir)
51377d2ece6SSujith Manoharan {
51477d2ece6SSujith Manoharan 	might_sleep();
51577d2ece6SSujith Manoharan 
51677d2ece6SSujith Manoharan 	sdata = get_bss_sdata(sdata);
51777d2ece6SSujith Manoharan 	check_sdata_in_driver(sdata);
51877d2ece6SSujith Manoharan 
51977d2ece6SSujith Manoharan 	if (local->ops->sta_remove_debugfs)
52077d2ece6SSujith Manoharan 		local->ops->sta_remove_debugfs(&local->hw, &sdata->vif,
52177d2ece6SSujith Manoharan 					       sta, dir);
52277d2ece6SSujith Manoharan }
52377d2ece6SSujith Manoharan #endif
52477d2ece6SSujith Manoharan 
525f09603a2SJohannes Berg static inline __must_check
526f09603a2SJohannes Berg int drv_sta_state(struct ieee80211_local *local,
527f09603a2SJohannes Berg 		  struct ieee80211_sub_if_data *sdata,
528f09603a2SJohannes Berg 		  struct sta_info *sta,
529f09603a2SJohannes Berg 		  enum ieee80211_sta_state old_state,
530f09603a2SJohannes Berg 		  enum ieee80211_sta_state new_state)
531f09603a2SJohannes Berg {
532f09603a2SJohannes Berg 	int ret = 0;
533f09603a2SJohannes Berg 
534f09603a2SJohannes Berg 	might_sleep();
535f09603a2SJohannes Berg 
536f09603a2SJohannes Berg 	sdata = get_bss_sdata(sdata);
537f09603a2SJohannes Berg 	check_sdata_in_driver(sdata);
538f09603a2SJohannes Berg 
539f09603a2SJohannes Berg 	trace_drv_sta_state(local, sdata, &sta->sta, old_state, new_state);
540a4ec45a4SJohannes Berg 	if (local->ops->sta_state) {
541f09603a2SJohannes Berg 		ret = local->ops->sta_state(&local->hw, &sdata->vif, &sta->sta,
542f09603a2SJohannes Berg 					    old_state, new_state);
543a4ec45a4SJohannes Berg 	} else if (old_state == IEEE80211_STA_AUTH &&
544a4ec45a4SJohannes Berg 		   new_state == IEEE80211_STA_ASSOC) {
545a4ec45a4SJohannes Berg 		ret = drv_sta_add(local, sdata, &sta->sta);
546a4ec45a4SJohannes Berg 		if (ret == 0)
547a4ec45a4SJohannes Berg 			sta->uploaded = true;
548a4ec45a4SJohannes Berg 	} else if (old_state == IEEE80211_STA_ASSOC &&
549a4ec45a4SJohannes Berg 		   new_state == IEEE80211_STA_AUTH) {
550a4ec45a4SJohannes Berg 		drv_sta_remove(local, sdata, &sta->sta);
551a4ec45a4SJohannes Berg 	}
552f09603a2SJohannes Berg 	trace_drv_return_int(local, ret);
553f09603a2SJohannes Berg 	return ret;
554f09603a2SJohannes Berg }
555f09603a2SJohannes Berg 
5568f727ef3SJohannes Berg static inline void drv_sta_rc_update(struct ieee80211_local *local,
5578f727ef3SJohannes Berg 				     struct ieee80211_sub_if_data *sdata,
5588f727ef3SJohannes Berg 				     struct ieee80211_sta *sta, u32 changed)
5598f727ef3SJohannes Berg {
5608f727ef3SJohannes Berg 	sdata = get_bss_sdata(sdata);
5618f727ef3SJohannes Berg 	check_sdata_in_driver(sdata);
5628f727ef3SJohannes Berg 
563e687f61eSAntonio Quartulli 	WARN_ON(changed & IEEE80211_RC_SUPP_RATES_CHANGED &&
564e687f61eSAntonio Quartulli 		sdata->vif.type != NL80211_IFTYPE_ADHOC);
565e687f61eSAntonio Quartulli 
5668f727ef3SJohannes Berg 	trace_drv_sta_rc_update(local, sdata, sta, changed);
5678f727ef3SJohannes Berg 	if (local->ops->sta_rc_update)
5688f727ef3SJohannes Berg 		local->ops->sta_rc_update(&local->hw, &sdata->vif,
5698f727ef3SJohannes Berg 					  sta, changed);
5708f727ef3SJohannes Berg 
5718f727ef3SJohannes Berg 	trace_drv_return_void(local);
5728f727ef3SJohannes Berg }
5738f727ef3SJohannes Berg 
574f6f3def3SEliad Peller static inline int drv_conf_tx(struct ieee80211_local *local,
575a3304b0aSJohannes Berg 			      struct ieee80211_sub_if_data *sdata, u16 ac,
57624487981SJohannes Berg 			      const struct ieee80211_tx_queue_params *params)
57724487981SJohannes Berg {
5780a2b8bb2SJohannes Berg 	int ret = -EOPNOTSUPP;
579e1781ed3SKalle Valo 
580e1781ed3SKalle Valo 	might_sleep();
581e1781ed3SKalle Valo 
5827b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
5837b7eab6fSJohannes Berg 
584a3304b0aSJohannes Berg 	trace_drv_conf_tx(local, sdata, ac, params);
58524487981SJohannes Berg 	if (local->ops->conf_tx)
5868a3a3c85SEliad Peller 		ret = local->ops->conf_tx(&local->hw, &sdata->vif,
587a3304b0aSJohannes Berg 					  ac, params);
5884efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
5890a2b8bb2SJohannes Berg 	return ret;
59024487981SJohannes Berg }
59124487981SJohannes Berg 
59237a41b4aSEliad Peller static inline u64 drv_get_tsf(struct ieee80211_local *local,
59337a41b4aSEliad Peller 			      struct ieee80211_sub_if_data *sdata)
59424487981SJohannes Berg {
5950a2b8bb2SJohannes Berg 	u64 ret = -1ULL;
596e1781ed3SKalle Valo 
597e1781ed3SKalle Valo 	might_sleep();
598e1781ed3SKalle Valo 
5997b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
6007b7eab6fSJohannes Berg 
60137a41b4aSEliad Peller 	trace_drv_get_tsf(local, sdata);
60224487981SJohannes Berg 	if (local->ops->get_tsf)
60337a41b4aSEliad Peller 		ret = local->ops->get_tsf(&local->hw, &sdata->vif);
6044efc76bdSJohannes Berg 	trace_drv_return_u64(local, ret);
6050a2b8bb2SJohannes Berg 	return ret;
60624487981SJohannes Berg }
60724487981SJohannes Berg 
60837a41b4aSEliad Peller static inline void drv_set_tsf(struct ieee80211_local *local,
60937a41b4aSEliad Peller 			       struct ieee80211_sub_if_data *sdata,
61037a41b4aSEliad Peller 			       u64 tsf)
61124487981SJohannes Berg {
612e1781ed3SKalle Valo 	might_sleep();
613e1781ed3SKalle Valo 
6147b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
6157b7eab6fSJohannes Berg 
61637a41b4aSEliad Peller 	trace_drv_set_tsf(local, sdata, tsf);
61724487981SJohannes Berg 	if (local->ops->set_tsf)
61837a41b4aSEliad Peller 		local->ops->set_tsf(&local->hw, &sdata->vif, tsf);
6194efc76bdSJohannes Berg 	trace_drv_return_void(local);
62024487981SJohannes Berg }
62124487981SJohannes Berg 
62237a41b4aSEliad Peller static inline void drv_reset_tsf(struct ieee80211_local *local,
62337a41b4aSEliad Peller 				 struct ieee80211_sub_if_data *sdata)
62424487981SJohannes Berg {
625e1781ed3SKalle Valo 	might_sleep();
626e1781ed3SKalle Valo 
6277b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
6287b7eab6fSJohannes Berg 
62937a41b4aSEliad Peller 	trace_drv_reset_tsf(local, sdata);
63024487981SJohannes Berg 	if (local->ops->reset_tsf)
63137a41b4aSEliad Peller 		local->ops->reset_tsf(&local->hw, &sdata->vif);
6324efc76bdSJohannes Berg 	trace_drv_return_void(local);
63324487981SJohannes Berg }
63424487981SJohannes Berg 
63524487981SJohannes Berg static inline int drv_tx_last_beacon(struct ieee80211_local *local)
63624487981SJohannes Berg {
63702582e9bSMasanari Iida 	int ret = 0; /* default unsupported op for less congestion */
638e1781ed3SKalle Valo 
639e1781ed3SKalle Valo 	might_sleep();
640e1781ed3SKalle Valo 
6414efc76bdSJohannes Berg 	trace_drv_tx_last_beacon(local);
64224487981SJohannes Berg 	if (local->ops->tx_last_beacon)
6430a2b8bb2SJohannes Berg 		ret = local->ops->tx_last_beacon(&local->hw);
6444efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
6450a2b8bb2SJohannes Berg 	return ret;
64624487981SJohannes Berg }
64724487981SJohannes Berg 
64824487981SJohannes Berg static inline int drv_ampdu_action(struct ieee80211_local *local,
64912375ef9SJohannes Berg 				   struct ieee80211_sub_if_data *sdata,
65024487981SJohannes Berg 				   enum ieee80211_ampdu_mlme_action action,
65124487981SJohannes Berg 				   struct ieee80211_sta *sta, u16 tid,
6520b01f030SJohannes Berg 				   u16 *ssn, u8 buf_size)
65324487981SJohannes Berg {
6540a2b8bb2SJohannes Berg 	int ret = -EOPNOTSUPP;
655cfcdbde3SJohannes Berg 
656cfcdbde3SJohannes Berg 	might_sleep();
657cfcdbde3SJohannes Berg 
658bc192f89SFelix Fietkau 	sdata = get_bss_sdata(sdata);
6597b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
6607b7eab6fSJohannes Berg 
6610b01f030SJohannes Berg 	trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size);
6624efc76bdSJohannes Berg 
66324487981SJohannes Berg 	if (local->ops->ampdu_action)
66412375ef9SJohannes Berg 		ret = local->ops->ampdu_action(&local->hw, &sdata->vif, action,
6650b01f030SJohannes Berg 					       sta, tid, ssn, buf_size);
66685ad181eSJohannes Berg 
6674efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
6684efc76bdSJohannes Berg 
6690a2b8bb2SJohannes Berg 	return ret;
67024487981SJohannes Berg }
6711f87f7d3SJohannes Berg 
6721289723eSHolger Schurig static inline int drv_get_survey(struct ieee80211_local *local, int idx,
6731289723eSHolger Schurig 				struct survey_info *survey)
6741289723eSHolger Schurig {
6751289723eSHolger Schurig 	int ret = -EOPNOTSUPP;
676c466d4efSJohn W. Linville 
677c466d4efSJohn W. Linville 	trace_drv_get_survey(local, idx, survey);
678c466d4efSJohn W. Linville 
67935dd0509SHolger Schurig 	if (local->ops->get_survey)
6801289723eSHolger Schurig 		ret = local->ops->get_survey(&local->hw, idx, survey);
681c466d4efSJohn W. Linville 
682c466d4efSJohn W. Linville 	trace_drv_return_int(local, ret);
683c466d4efSJohn W. Linville 
6841289723eSHolger Schurig 	return ret;
6851289723eSHolger Schurig }
6861f87f7d3SJohannes Berg 
6871f87f7d3SJohannes Berg static inline void drv_rfkill_poll(struct ieee80211_local *local)
6881f87f7d3SJohannes Berg {
689e1781ed3SKalle Valo 	might_sleep();
690e1781ed3SKalle Valo 
6911f87f7d3SJohannes Berg 	if (local->ops->rfkill_poll)
6921f87f7d3SJohannes Berg 		local->ops->rfkill_poll(&local->hw);
6931f87f7d3SJohannes Berg }
694a80f7c0bSJohannes Berg 
695a80f7c0bSJohannes Berg static inline void drv_flush(struct ieee80211_local *local, bool drop)
696a80f7c0bSJohannes Berg {
697e1781ed3SKalle Valo 	might_sleep();
698e1781ed3SKalle Valo 
699a80f7c0bSJohannes Berg 	trace_drv_flush(local, drop);
700a80f7c0bSJohannes Berg 	if (local->ops->flush)
701a80f7c0bSJohannes Berg 		local->ops->flush(&local->hw, drop);
7024efc76bdSJohannes Berg 	trace_drv_return_void(local);
703a80f7c0bSJohannes Berg }
7045ce6e438SJohannes Berg 
7055ce6e438SJohannes Berg static inline void drv_channel_switch(struct ieee80211_local *local,
7065ce6e438SJohannes Berg 				     struct ieee80211_channel_switch *ch_switch)
7075ce6e438SJohannes Berg {
7085ce6e438SJohannes Berg 	might_sleep();
7095ce6e438SJohannes Berg 
7105ce6e438SJohannes Berg 	trace_drv_channel_switch(local, ch_switch);
7114efc76bdSJohannes Berg 	local->ops->channel_switch(&local->hw, ch_switch);
7124efc76bdSJohannes Berg 	trace_drv_return_void(local);
7135ce6e438SJohannes Berg }
7145ce6e438SJohannes Berg 
71515d96753SBruno Randolf 
71615d96753SBruno Randolf static inline int drv_set_antenna(struct ieee80211_local *local,
71715d96753SBruno Randolf 				  u32 tx_ant, u32 rx_ant)
71815d96753SBruno Randolf {
71915d96753SBruno Randolf 	int ret = -EOPNOTSUPP;
72015d96753SBruno Randolf 	might_sleep();
72115d96753SBruno Randolf 	if (local->ops->set_antenna)
72215d96753SBruno Randolf 		ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant);
72315d96753SBruno Randolf 	trace_drv_set_antenna(local, tx_ant, rx_ant, ret);
72415d96753SBruno Randolf 	return ret;
72515d96753SBruno Randolf }
72615d96753SBruno Randolf 
72715d96753SBruno Randolf static inline int drv_get_antenna(struct ieee80211_local *local,
72815d96753SBruno Randolf 				  u32 *tx_ant, u32 *rx_ant)
72915d96753SBruno Randolf {
73015d96753SBruno Randolf 	int ret = -EOPNOTSUPP;
73115d96753SBruno Randolf 	might_sleep();
73215d96753SBruno Randolf 	if (local->ops->get_antenna)
73315d96753SBruno Randolf 		ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant);
73415d96753SBruno Randolf 	trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret);
73515d96753SBruno Randolf 	return ret;
73615d96753SBruno Randolf }
73715d96753SBruno Randolf 
73821f83589SJohannes Berg static inline int drv_remain_on_channel(struct ieee80211_local *local,
73949884568SEliad Peller 					struct ieee80211_sub_if_data *sdata,
74021f83589SJohannes Berg 					struct ieee80211_channel *chan,
74121f83589SJohannes Berg 					unsigned int duration)
74221f83589SJohannes Berg {
74321f83589SJohannes Berg 	int ret;
74421f83589SJohannes Berg 
74521f83589SJohannes Berg 	might_sleep();
74621f83589SJohannes Berg 
74742d97a59SJohannes Berg 	trace_drv_remain_on_channel(local, sdata, chan, duration);
74849884568SEliad Peller 	ret = local->ops->remain_on_channel(&local->hw, &sdata->vif,
74942d97a59SJohannes Berg 					    chan, duration);
75021f83589SJohannes Berg 	trace_drv_return_int(local, ret);
75121f83589SJohannes Berg 
75221f83589SJohannes Berg 	return ret;
75321f83589SJohannes Berg }
75421f83589SJohannes Berg 
75521f83589SJohannes Berg static inline int drv_cancel_remain_on_channel(struct ieee80211_local *local)
75621f83589SJohannes Berg {
75721f83589SJohannes Berg 	int ret;
75821f83589SJohannes Berg 
75921f83589SJohannes Berg 	might_sleep();
76021f83589SJohannes Berg 
76121f83589SJohannes Berg 	trace_drv_cancel_remain_on_channel(local);
76221f83589SJohannes Berg 	ret = local->ops->cancel_remain_on_channel(&local->hw);
76321f83589SJohannes Berg 	trace_drv_return_int(local, ret);
76421f83589SJohannes Berg 
76521f83589SJohannes Berg 	return ret;
76621f83589SJohannes Berg }
76721f83589SJohannes Berg 
76838c09159SJohn W. Linville static inline int drv_set_ringparam(struct ieee80211_local *local,
76938c09159SJohn W. Linville 				    u32 tx, u32 rx)
77038c09159SJohn W. Linville {
77138c09159SJohn W. Linville 	int ret = -ENOTSUPP;
77238c09159SJohn W. Linville 
77338c09159SJohn W. Linville 	might_sleep();
77438c09159SJohn W. Linville 
77538c09159SJohn W. Linville 	trace_drv_set_ringparam(local, tx, rx);
77638c09159SJohn W. Linville 	if (local->ops->set_ringparam)
77738c09159SJohn W. Linville 		ret = local->ops->set_ringparam(&local->hw, tx, rx);
77838c09159SJohn W. Linville 	trace_drv_return_int(local, ret);
77938c09159SJohn W. Linville 
78038c09159SJohn W. Linville 	return ret;
78138c09159SJohn W. Linville }
78238c09159SJohn W. Linville 
78338c09159SJohn W. Linville static inline void drv_get_ringparam(struct ieee80211_local *local,
78438c09159SJohn W. Linville 				     u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
78538c09159SJohn W. Linville {
78638c09159SJohn W. Linville 	might_sleep();
78738c09159SJohn W. Linville 
78838c09159SJohn W. Linville 	trace_drv_get_ringparam(local, tx, tx_max, rx, rx_max);
78938c09159SJohn W. Linville 	if (local->ops->get_ringparam)
79038c09159SJohn W. Linville 		local->ops->get_ringparam(&local->hw, tx, tx_max, rx, rx_max);
79138c09159SJohn W. Linville 	trace_drv_return_void(local);
79238c09159SJohn W. Linville }
79338c09159SJohn W. Linville 
794e8306f98SVivek Natarajan static inline bool drv_tx_frames_pending(struct ieee80211_local *local)
795e8306f98SVivek Natarajan {
796e8306f98SVivek Natarajan 	bool ret = false;
797e8306f98SVivek Natarajan 
798e8306f98SVivek Natarajan 	might_sleep();
799e8306f98SVivek Natarajan 
800e8306f98SVivek Natarajan 	trace_drv_tx_frames_pending(local);
801e8306f98SVivek Natarajan 	if (local->ops->tx_frames_pending)
802e8306f98SVivek Natarajan 		ret = local->ops->tx_frames_pending(&local->hw);
803e8306f98SVivek Natarajan 	trace_drv_return_bool(local, ret);
804e8306f98SVivek Natarajan 
805e8306f98SVivek Natarajan 	return ret;
806e8306f98SVivek Natarajan }
807bdbfd6b5SSujith Manoharan 
808bdbfd6b5SSujith Manoharan static inline int drv_set_bitrate_mask(struct ieee80211_local *local,
809bdbfd6b5SSujith Manoharan 				       struct ieee80211_sub_if_data *sdata,
810bdbfd6b5SSujith Manoharan 				       const struct cfg80211_bitrate_mask *mask)
811bdbfd6b5SSujith Manoharan {
812bdbfd6b5SSujith Manoharan 	int ret = -EOPNOTSUPP;
813bdbfd6b5SSujith Manoharan 
814bdbfd6b5SSujith Manoharan 	might_sleep();
815bdbfd6b5SSujith Manoharan 
8167b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
8177b7eab6fSJohannes Berg 
818bdbfd6b5SSujith Manoharan 	trace_drv_set_bitrate_mask(local, sdata, mask);
819bdbfd6b5SSujith Manoharan 	if (local->ops->set_bitrate_mask)
820bdbfd6b5SSujith Manoharan 		ret = local->ops->set_bitrate_mask(&local->hw,
821bdbfd6b5SSujith Manoharan 						   &sdata->vif, mask);
822bdbfd6b5SSujith Manoharan 	trace_drv_return_int(local, ret);
823bdbfd6b5SSujith Manoharan 
824bdbfd6b5SSujith Manoharan 	return ret;
825bdbfd6b5SSujith Manoharan }
826bdbfd6b5SSujith Manoharan 
827c68f4b89SJohannes Berg static inline void drv_set_rekey_data(struct ieee80211_local *local,
828c68f4b89SJohannes Berg 				      struct ieee80211_sub_if_data *sdata,
829c68f4b89SJohannes Berg 				      struct cfg80211_gtk_rekey_data *data)
830c68f4b89SJohannes Berg {
8317b7eab6fSJohannes Berg 	check_sdata_in_driver(sdata);
8327b7eab6fSJohannes Berg 
833c68f4b89SJohannes Berg 	trace_drv_set_rekey_data(local, sdata, data);
834c68f4b89SJohannes Berg 	if (local->ops->set_rekey_data)
835c68f4b89SJohannes Berg 		local->ops->set_rekey_data(&local->hw, &sdata->vif, data);
836c68f4b89SJohannes Berg 	trace_drv_return_void(local);
837c68f4b89SJohannes Berg }
838c68f4b89SJohannes Berg 
839615f7b9bSMeenakshi Venkataraman static inline void drv_rssi_callback(struct ieee80211_local *local,
840615f7b9bSMeenakshi Venkataraman 				     const enum ieee80211_rssi_event event)
841615f7b9bSMeenakshi Venkataraman {
842615f7b9bSMeenakshi Venkataraman 	trace_drv_rssi_callback(local, event);
843615f7b9bSMeenakshi Venkataraman 	if (local->ops->rssi_callback)
844615f7b9bSMeenakshi Venkataraman 		local->ops->rssi_callback(&local->hw, event);
845615f7b9bSMeenakshi Venkataraman 	trace_drv_return_void(local);
846615f7b9bSMeenakshi Venkataraman }
8474049e09aSJohannes Berg 
8484049e09aSJohannes Berg static inline void
8494049e09aSJohannes Berg drv_release_buffered_frames(struct ieee80211_local *local,
8504049e09aSJohannes Berg 			    struct sta_info *sta, u16 tids, int num_frames,
8514049e09aSJohannes Berg 			    enum ieee80211_frame_release_type reason,
8524049e09aSJohannes Berg 			    bool more_data)
8534049e09aSJohannes Berg {
8544049e09aSJohannes Berg 	trace_drv_release_buffered_frames(local, &sta->sta, tids, num_frames,
8554049e09aSJohannes Berg 					  reason, more_data);
8564049e09aSJohannes Berg 	if (local->ops->release_buffered_frames)
8574049e09aSJohannes Berg 		local->ops->release_buffered_frames(&local->hw, &sta->sta, tids,
8584049e09aSJohannes Berg 						    num_frames, reason,
8594049e09aSJohannes Berg 						    more_data);
8604049e09aSJohannes Berg 	trace_drv_return_void(local);
8614049e09aSJohannes Berg }
86240b96408SJohannes Berg 
86340b96408SJohannes Berg static inline void
86440b96408SJohannes Berg drv_allow_buffered_frames(struct ieee80211_local *local,
86540b96408SJohannes Berg 			  struct sta_info *sta, u16 tids, int num_frames,
86640b96408SJohannes Berg 			  enum ieee80211_frame_release_type reason,
86740b96408SJohannes Berg 			  bool more_data)
86840b96408SJohannes Berg {
86940b96408SJohannes Berg 	trace_drv_allow_buffered_frames(local, &sta->sta, tids, num_frames,
87040b96408SJohannes Berg 					reason, more_data);
87140b96408SJohannes Berg 	if (local->ops->allow_buffered_frames)
87240b96408SJohannes Berg 		local->ops->allow_buffered_frames(&local->hw, &sta->sta,
87340b96408SJohannes Berg 						  tids, num_frames, reason,
87440b96408SJohannes Berg 						  more_data);
87540b96408SJohannes Berg 	trace_drv_return_void(local);
87640b96408SJohannes Berg }
87766572cfcSVictor Goldenshtein 
87866572cfcSVictor Goldenshtein static inline int drv_get_rssi(struct ieee80211_local *local,
87966572cfcSVictor Goldenshtein 				struct ieee80211_sub_if_data *sdata,
88066572cfcSVictor Goldenshtein 				struct ieee80211_sta *sta,
88166572cfcSVictor Goldenshtein 				s8 *rssi_dbm)
88266572cfcSVictor Goldenshtein {
88366572cfcSVictor Goldenshtein 	int ret;
88466572cfcSVictor Goldenshtein 
88566572cfcSVictor Goldenshtein 	might_sleep();
88666572cfcSVictor Goldenshtein 
88766572cfcSVictor Goldenshtein 	ret = local->ops->get_rssi(&local->hw, &sdata->vif, sta, rssi_dbm);
88866572cfcSVictor Goldenshtein 	trace_drv_get_rssi(local, sta, *rssi_dbm, ret);
88966572cfcSVictor Goldenshtein 
89066572cfcSVictor Goldenshtein 	return ret;
89166572cfcSVictor Goldenshtein }
892a1845fc7SJohannes Berg 
893a1845fc7SJohannes Berg static inline void drv_mgd_prepare_tx(struct ieee80211_local *local,
894a1845fc7SJohannes Berg 				      struct ieee80211_sub_if_data *sdata)
895a1845fc7SJohannes Berg {
896a1845fc7SJohannes Berg 	might_sleep();
897a1845fc7SJohannes Berg 
898a1845fc7SJohannes Berg 	check_sdata_in_driver(sdata);
899a1845fc7SJohannes Berg 	WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
900a1845fc7SJohannes Berg 
901a1845fc7SJohannes Berg 	trace_drv_mgd_prepare_tx(local, sdata);
902a1845fc7SJohannes Berg 	if (local->ops->mgd_prepare_tx)
903a1845fc7SJohannes Berg 		local->ops->mgd_prepare_tx(&local->hw, &sdata->vif);
904a1845fc7SJohannes Berg 	trace_drv_return_void(local);
905a1845fc7SJohannes Berg }
906c3645eacSMichal Kazior 
907c3645eacSMichal Kazior static inline int drv_add_chanctx(struct ieee80211_local *local,
908c3645eacSMichal Kazior 				  struct ieee80211_chanctx *ctx)
909c3645eacSMichal Kazior {
910c3645eacSMichal Kazior 	int ret = -EOPNOTSUPP;
911c3645eacSMichal Kazior 
912c3645eacSMichal Kazior 	trace_drv_add_chanctx(local, ctx);
913c3645eacSMichal Kazior 	if (local->ops->add_chanctx)
914c3645eacSMichal Kazior 		ret = local->ops->add_chanctx(&local->hw, &ctx->conf);
915c3645eacSMichal Kazior 	trace_drv_return_int(local, ret);
9168a61af65SJohannes Berg 	if (!ret)
9178a61af65SJohannes Berg 		ctx->driver_present = true;
918c3645eacSMichal Kazior 
919c3645eacSMichal Kazior 	return ret;
920c3645eacSMichal Kazior }
921c3645eacSMichal Kazior 
922c3645eacSMichal Kazior static inline void drv_remove_chanctx(struct ieee80211_local *local,
923c3645eacSMichal Kazior 				      struct ieee80211_chanctx *ctx)
924c3645eacSMichal Kazior {
925c3645eacSMichal Kazior 	trace_drv_remove_chanctx(local, ctx);
926c3645eacSMichal Kazior 	if (local->ops->remove_chanctx)
927c3645eacSMichal Kazior 		local->ops->remove_chanctx(&local->hw, &ctx->conf);
928c3645eacSMichal Kazior 	trace_drv_return_void(local);
9298a61af65SJohannes Berg 	ctx->driver_present = false;
930c3645eacSMichal Kazior }
931c3645eacSMichal Kazior 
932c3645eacSMichal Kazior static inline void drv_change_chanctx(struct ieee80211_local *local,
933c3645eacSMichal Kazior 				      struct ieee80211_chanctx *ctx,
934c3645eacSMichal Kazior 				      u32 changed)
935c3645eacSMichal Kazior {
936c3645eacSMichal Kazior 	trace_drv_change_chanctx(local, ctx, changed);
9378a61af65SJohannes Berg 	if (local->ops->change_chanctx) {
9388a61af65SJohannes Berg 		WARN_ON_ONCE(!ctx->driver_present);
939c3645eacSMichal Kazior 		local->ops->change_chanctx(&local->hw, &ctx->conf, changed);
9408a61af65SJohannes Berg 	}
941c3645eacSMichal Kazior 	trace_drv_return_void(local);
942c3645eacSMichal Kazior }
943c3645eacSMichal Kazior 
944c3645eacSMichal Kazior static inline int drv_assign_vif_chanctx(struct ieee80211_local *local,
945c3645eacSMichal Kazior 					 struct ieee80211_sub_if_data *sdata,
946c3645eacSMichal Kazior 					 struct ieee80211_chanctx *ctx)
947c3645eacSMichal Kazior {
948c3645eacSMichal Kazior 	int ret = 0;
949c3645eacSMichal Kazior 
950c3645eacSMichal Kazior 	check_sdata_in_driver(sdata);
951c3645eacSMichal Kazior 
952c3645eacSMichal Kazior 	trace_drv_assign_vif_chanctx(local, sdata, ctx);
9538a61af65SJohannes Berg 	if (local->ops->assign_vif_chanctx) {
9548a61af65SJohannes Berg 		WARN_ON_ONCE(!ctx->driver_present);
955c3645eacSMichal Kazior 		ret = local->ops->assign_vif_chanctx(&local->hw,
956c3645eacSMichal Kazior 						     &sdata->vif,
957c3645eacSMichal Kazior 						     &ctx->conf);
9588a61af65SJohannes Berg 	}
959c3645eacSMichal Kazior 	trace_drv_return_int(local, ret);
960c3645eacSMichal Kazior 
961c3645eacSMichal Kazior 	return ret;
962c3645eacSMichal Kazior }
963c3645eacSMichal Kazior 
964c3645eacSMichal Kazior static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local,
965c3645eacSMichal Kazior 					    struct ieee80211_sub_if_data *sdata,
966c3645eacSMichal Kazior 					    struct ieee80211_chanctx *ctx)
967c3645eacSMichal Kazior {
968c3645eacSMichal Kazior 	check_sdata_in_driver(sdata);
969c3645eacSMichal Kazior 
970c3645eacSMichal Kazior 	trace_drv_unassign_vif_chanctx(local, sdata, ctx);
9718a61af65SJohannes Berg 	if (local->ops->unassign_vif_chanctx) {
9728a61af65SJohannes Berg 		WARN_ON_ONCE(!ctx->driver_present);
973c3645eacSMichal Kazior 		local->ops->unassign_vif_chanctx(&local->hw,
974c3645eacSMichal Kazior 						 &sdata->vif,
975c3645eacSMichal Kazior 						 &ctx->conf);
9768a61af65SJohannes Berg 	}
977c3645eacSMichal Kazior 	trace_drv_return_void(local);
978c3645eacSMichal Kazior }
979c3645eacSMichal Kazior 
9801041638fSJohannes Berg static inline int drv_start_ap(struct ieee80211_local *local,
9811041638fSJohannes Berg 			       struct ieee80211_sub_if_data *sdata)
9821041638fSJohannes Berg {
9831041638fSJohannes Berg 	int ret = 0;
9841041638fSJohannes Berg 
9851041638fSJohannes Berg 	check_sdata_in_driver(sdata);
9861041638fSJohannes Berg 
9871041638fSJohannes Berg 	trace_drv_start_ap(local, sdata, &sdata->vif.bss_conf);
9881041638fSJohannes Berg 	if (local->ops->start_ap)
9891041638fSJohannes Berg 		ret = local->ops->start_ap(&local->hw, &sdata->vif);
9901041638fSJohannes Berg 	trace_drv_return_int(local, ret);
9911041638fSJohannes Berg 	return ret;
9921041638fSJohannes Berg }
9931041638fSJohannes Berg 
9941041638fSJohannes Berg static inline void drv_stop_ap(struct ieee80211_local *local,
9951041638fSJohannes Berg 			       struct ieee80211_sub_if_data *sdata)
9961041638fSJohannes Berg {
9971041638fSJohannes Berg 	check_sdata_in_driver(sdata);
9981041638fSJohannes Berg 
9991041638fSJohannes Berg 	trace_drv_stop_ap(local, sdata);
10001041638fSJohannes Berg 	if (local->ops->stop_ap)
10011041638fSJohannes Berg 		local->ops->stop_ap(&local->hw, &sdata->vif);
10021041638fSJohannes Berg 	trace_drv_return_void(local);
10031041638fSJohannes Berg }
10041041638fSJohannes Berg 
10059214ad7fSJohannes Berg static inline void drv_restart_complete(struct ieee80211_local *local)
10069214ad7fSJohannes Berg {
10079214ad7fSJohannes Berg 	might_sleep();
10089214ad7fSJohannes Berg 
10099214ad7fSJohannes Berg 	trace_drv_restart_complete(local);
10109214ad7fSJohannes Berg 	if (local->ops->restart_complete)
10119214ad7fSJohannes Berg 		local->ops->restart_complete(&local->hw);
10129214ad7fSJohannes Berg 	trace_drv_return_void(local);
10139214ad7fSJohannes Berg }
10149214ad7fSJohannes Berg 
101524487981SJohannes Berg #endif /* __MAC80211_DRIVER_OPS */
1016