xref: /openbmc/linux/net/mac80211/driver-ops.h (revision 3a3713ec)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
2f59374ebSSara Sharon /*
3f59374ebSSara Sharon * Portions of this file
4f59374ebSSara Sharon * Copyright(c) 2016 Intel Deutschland GmbH
5f59374ebSSara Sharon */
6f59374ebSSara Sharon 
724487981SJohannes Berg #ifndef __MAC80211_DRIVER_OPS
824487981SJohannes Berg #define __MAC80211_DRIVER_OPS
924487981SJohannes Berg 
1024487981SJohannes Berg #include <net/mac80211.h>
1124487981SJohannes Berg #include "ieee80211_i.h"
12011ad0e9SJohannes Berg #include "trace.h"
1324487981SJohannes Berg 
14f6837ba8SJohannes Berg static inline bool check_sdata_in_driver(struct ieee80211_sub_if_data *sdata)
157b7eab6fSJohannes Berg {
16f6837ba8SJohannes Berg 	return !WARN(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER),
17d17087e7SBen Greear 		     "%s:  Failed check-sdata-in-driver check, flags: 0x%x\n",
18f142c6b9SJohannes Berg 		     sdata->dev ? sdata->dev->name : sdata->name, sdata->flags);
197b7eab6fSJohannes Berg }
207b7eab6fSJohannes Berg 
21bc192f89SFelix Fietkau static inline struct ieee80211_sub_if_data *
22bc192f89SFelix Fietkau get_bss_sdata(struct ieee80211_sub_if_data *sdata)
23bc192f89SFelix Fietkau {
24bc192f89SFelix Fietkau 	if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
25bc192f89SFelix Fietkau 		sdata = container_of(sdata->bss, struct ieee80211_sub_if_data,
26bc192f89SFelix Fietkau 				     u.ap);
27bc192f89SFelix Fietkau 
28bc192f89SFelix Fietkau 	return sdata;
29bc192f89SFelix Fietkau }
30bc192f89SFelix Fietkau 
3136323f81SThomas Huehn static inline void drv_tx(struct ieee80211_local *local,
3236323f81SThomas Huehn 			  struct ieee80211_tx_control *control,
3336323f81SThomas Huehn 			  struct sk_buff *skb)
3424487981SJohannes Berg {
3536323f81SThomas Huehn 	local->ops->tx(&local->hw, control, skb);
3624487981SJohannes Berg }
3724487981SJohannes Berg 
38f59374ebSSara Sharon static inline void drv_sync_rx_queues(struct ieee80211_local *local,
39f59374ebSSara Sharon 				      struct sta_info *sta)
40f59374ebSSara Sharon {
41f59374ebSSara Sharon 	if (local->ops->sync_rx_queues) {
42f59374ebSSara Sharon 		trace_drv_sync_rx_queues(local, sta->sdata, &sta->sta);
43f59374ebSSara Sharon 		local->ops->sync_rx_queues(&local->hw);
44f59374ebSSara Sharon 		trace_drv_return_void(local);
45f59374ebSSara Sharon 	}
46f59374ebSSara Sharon }
47f59374ebSSara Sharon 
48e352114fSBen Greear static inline void drv_get_et_strings(struct ieee80211_sub_if_data *sdata,
49e352114fSBen Greear 				      u32 sset, u8 *data)
50e352114fSBen Greear {
51e352114fSBen Greear 	struct ieee80211_local *local = sdata->local;
52e352114fSBen Greear 	if (local->ops->get_et_strings) {
53e352114fSBen Greear 		trace_drv_get_et_strings(local, sset);
54e352114fSBen Greear 		local->ops->get_et_strings(&local->hw, &sdata->vif, sset, data);
55e352114fSBen Greear 		trace_drv_return_void(local);
56e352114fSBen Greear 	}
57e352114fSBen Greear }
58e352114fSBen Greear 
59e352114fSBen Greear static inline void drv_get_et_stats(struct ieee80211_sub_if_data *sdata,
60e352114fSBen Greear 				    struct ethtool_stats *stats,
61e352114fSBen Greear 				    u64 *data)
62e352114fSBen Greear {
63e352114fSBen Greear 	struct ieee80211_local *local = sdata->local;
64e352114fSBen Greear 	if (local->ops->get_et_stats) {
65e352114fSBen Greear 		trace_drv_get_et_stats(local);
66e352114fSBen Greear 		local->ops->get_et_stats(&local->hw, &sdata->vif, stats, data);
67e352114fSBen Greear 		trace_drv_return_void(local);
68e352114fSBen Greear 	}
69e352114fSBen Greear }
70e352114fSBen Greear 
71e352114fSBen Greear static inline int drv_get_et_sset_count(struct ieee80211_sub_if_data *sdata,
72e352114fSBen Greear 					int sset)
73e352114fSBen Greear {
74e352114fSBen Greear 	struct ieee80211_local *local = sdata->local;
75e352114fSBen Greear 	int rv = 0;
76e352114fSBen Greear 	if (local->ops->get_et_sset_count) {
77e352114fSBen Greear 		trace_drv_get_et_sset_count(local, sset);
78e352114fSBen Greear 		rv = local->ops->get_et_sset_count(&local->hw, &sdata->vif,
79e352114fSBen Greear 						   sset);
80e352114fSBen Greear 		trace_drv_return_int(local, rv);
81e352114fSBen Greear 	}
82e352114fSBen Greear 	return rv;
83e352114fSBen Greear }
84e352114fSBen Greear 
85968a76ceSEliad Peller int drv_start(struct ieee80211_local *local);
86968a76ceSEliad Peller void drv_stop(struct ieee80211_local *local);
8724487981SJohannes Berg 
88eecc4800SJohannes Berg #ifdef CONFIG_PM
89eecc4800SJohannes Berg static inline int drv_suspend(struct ieee80211_local *local,
90eecc4800SJohannes Berg 			      struct cfg80211_wowlan *wowlan)
91eecc4800SJohannes Berg {
92eecc4800SJohannes Berg 	int ret;
93eecc4800SJohannes Berg 
94eecc4800SJohannes Berg 	might_sleep();
95eecc4800SJohannes Berg 
96eecc4800SJohannes Berg 	trace_drv_suspend(local);
97eecc4800SJohannes Berg 	ret = local->ops->suspend(&local->hw, wowlan);
98eecc4800SJohannes Berg 	trace_drv_return_int(local, ret);
99eecc4800SJohannes Berg 	return ret;
100eecc4800SJohannes Berg }
101eecc4800SJohannes Berg 
102eecc4800SJohannes Berg static inline int drv_resume(struct ieee80211_local *local)
103eecc4800SJohannes Berg {
104eecc4800SJohannes Berg 	int ret;
105eecc4800SJohannes Berg 
106eecc4800SJohannes Berg 	might_sleep();
107eecc4800SJohannes Berg 
108eecc4800SJohannes Berg 	trace_drv_resume(local);
109eecc4800SJohannes Berg 	ret = local->ops->resume(&local->hw);
110eecc4800SJohannes Berg 	trace_drv_return_int(local, ret);
111eecc4800SJohannes Berg 	return ret;
112eecc4800SJohannes Berg }
1136d52563fSJohannes Berg 
1146d52563fSJohannes Berg static inline void drv_set_wakeup(struct ieee80211_local *local,
1156d52563fSJohannes Berg 				  bool enabled)
1166d52563fSJohannes Berg {
1176d52563fSJohannes Berg 	might_sleep();
1186d52563fSJohannes Berg 
1196d52563fSJohannes Berg 	if (!local->ops->set_wakeup)
1206d52563fSJohannes Berg 		return;
1216d52563fSJohannes Berg 
1226d52563fSJohannes Berg 	trace_drv_set_wakeup(local, enabled);
1236d52563fSJohannes Berg 	local->ops->set_wakeup(&local->hw, enabled);
1246d52563fSJohannes Berg 	trace_drv_return_void(local);
1256d52563fSJohannes Berg }
126eecc4800SJohannes Berg #endif
127eecc4800SJohannes Berg 
1289aae296aSDenys Vlasenko int drv_add_interface(struct ieee80211_local *local,
1299aae296aSDenys Vlasenko 		      struct ieee80211_sub_if_data *sdata);
130e1781ed3SKalle Valo 
1319aae296aSDenys Vlasenko int drv_change_interface(struct ieee80211_local *local,
13234d4bc4dSJohannes Berg 			 struct ieee80211_sub_if_data *sdata,
1339aae296aSDenys Vlasenko 			 enum nl80211_iftype type, bool p2p);
13434d4bc4dSJohannes Berg 
1359aae296aSDenys Vlasenko void drv_remove_interface(struct ieee80211_local *local,
1369aae296aSDenys Vlasenko 			  struct ieee80211_sub_if_data *sdata);
13724487981SJohannes Berg 
13824487981SJohannes Berg static inline int drv_config(struct ieee80211_local *local, u32 changed)
13924487981SJohannes Berg {
140e1781ed3SKalle Valo 	int ret;
141e1781ed3SKalle Valo 
142e1781ed3SKalle Valo 	might_sleep();
143e1781ed3SKalle Valo 
1444efc76bdSJohannes Berg 	trace_drv_config(local, changed);
145e1781ed3SKalle Valo 	ret = local->ops->config(&local->hw, changed);
1464efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
1470a2b8bb2SJohannes Berg 	return ret;
14824487981SJohannes Berg }
14924487981SJohannes Berg 
15024487981SJohannes Berg static inline void drv_bss_info_changed(struct ieee80211_local *local,
15112375ef9SJohannes Berg 					struct ieee80211_sub_if_data *sdata,
15224487981SJohannes Berg 					struct ieee80211_bss_conf *info,
15324487981SJohannes Berg 					u32 changed)
15424487981SJohannes Berg {
155e1781ed3SKalle Valo 	might_sleep();
156e1781ed3SKalle Valo 
1575bbe754dSJohannes Berg 	if (WARN_ON_ONCE(changed & (BSS_CHANGED_BEACON |
158b8dc1a35SJohannes Berg 				    BSS_CHANGED_BEACON_ENABLED) &&
159b8dc1a35SJohannes Berg 			 sdata->vif.type != NL80211_IFTYPE_AP &&
160b8dc1a35SJohannes Berg 			 sdata->vif.type != NL80211_IFTYPE_ADHOC &&
161239281f8SRostislav Lisovy 			 sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
162239281f8SRostislav Lisovy 			 sdata->vif.type != NL80211_IFTYPE_OCB))
1635bbe754dSJohannes Berg 		return;
1645bbe754dSJohannes Berg 
1655bbe754dSJohannes Berg 	if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE ||
166708d50edSAyala Beker 			 sdata->vif.type == NL80211_IFTYPE_NAN ||
16742bd20d9SAviya Erenfeld 			 (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
1683a3713ecSPeter Große 			  !sdata->vif.mu_mimo_owner &&
1693a3713ecSPeter Große 			  !(changed & BSS_CHANGED_TXPOWER))))
1705bbe754dSJohannes Berg 		return;
171b8dc1a35SJohannes Berg 
172f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
173f6837ba8SJohannes Berg 		return;
1747b7eab6fSJohannes Berg 
1754efc76bdSJohannes Berg 	trace_drv_bss_info_changed(local, sdata, info, changed);
17624487981SJohannes Berg 	if (local->ops->bss_info_changed)
17712375ef9SJohannes Berg 		local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed);
1784efc76bdSJohannes Berg 	trace_drv_return_void(local);
17924487981SJohannes Berg }
18024487981SJohannes Berg 
1813ac64beeSJohannes Berg static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
18222bedad3SJiri Pirko 					struct netdev_hw_addr_list *mc_list)
18324487981SJohannes Berg {
1843ac64beeSJohannes Berg 	u64 ret = 0;
1853ac64beeSJohannes Berg 
1864efc76bdSJohannes Berg 	trace_drv_prepare_multicast(local, mc_list->count);
1874efc76bdSJohannes Berg 
1883ac64beeSJohannes Berg 	if (local->ops->prepare_multicast)
18922bedad3SJiri Pirko 		ret = local->ops->prepare_multicast(&local->hw, mc_list);
1903ac64beeSJohannes Berg 
1914efc76bdSJohannes Berg 	trace_drv_return_u64(local, ret);
1923ac64beeSJohannes Berg 
1933ac64beeSJohannes Berg 	return ret;
1943ac64beeSJohannes Berg }
1953ac64beeSJohannes Berg 
1963ac64beeSJohannes Berg static inline void drv_configure_filter(struct ieee80211_local *local,
1973ac64beeSJohannes Berg 					unsigned int changed_flags,
1983ac64beeSJohannes Berg 					unsigned int *total_flags,
1993ac64beeSJohannes Berg 					u64 multicast)
2003ac64beeSJohannes Berg {
2013ac64beeSJohannes Berg 	might_sleep();
2023ac64beeSJohannes Berg 
2030a2b8bb2SJohannes Berg 	trace_drv_configure_filter(local, changed_flags, total_flags,
2043ac64beeSJohannes Berg 				   multicast);
2054efc76bdSJohannes Berg 	local->ops->configure_filter(&local->hw, changed_flags, total_flags,
2064efc76bdSJohannes Berg 				     multicast);
2074efc76bdSJohannes Berg 	trace_drv_return_void(local);
20824487981SJohannes Berg }
20924487981SJohannes Berg 
2101b09b556SAndrei Otcheretianski static inline void drv_config_iface_filter(struct ieee80211_local *local,
2111b09b556SAndrei Otcheretianski 					   struct ieee80211_sub_if_data *sdata,
2121b09b556SAndrei Otcheretianski 					   unsigned int filter_flags,
2131b09b556SAndrei Otcheretianski 					   unsigned int changed_flags)
2141b09b556SAndrei Otcheretianski {
2151b09b556SAndrei Otcheretianski 	might_sleep();
2161b09b556SAndrei Otcheretianski 
2171b09b556SAndrei Otcheretianski 	trace_drv_config_iface_filter(local, sdata, filter_flags,
2181b09b556SAndrei Otcheretianski 				      changed_flags);
2191b09b556SAndrei Otcheretianski 	if (local->ops->config_iface_filter)
2201b09b556SAndrei Otcheretianski 		local->ops->config_iface_filter(&local->hw, &sdata->vif,
2211b09b556SAndrei Otcheretianski 						filter_flags,
2221b09b556SAndrei Otcheretianski 						changed_flags);
2231b09b556SAndrei Otcheretianski 	trace_drv_return_void(local);
2241b09b556SAndrei Otcheretianski }
2251b09b556SAndrei Otcheretianski 
22624487981SJohannes Berg static inline int drv_set_tim(struct ieee80211_local *local,
22724487981SJohannes Berg 			      struct ieee80211_sta *sta, bool set)
22824487981SJohannes Berg {
2290a2b8bb2SJohannes Berg 	int ret = 0;
2304efc76bdSJohannes Berg 	trace_drv_set_tim(local, sta, set);
23124487981SJohannes Berg 	if (local->ops->set_tim)
2320a2b8bb2SJohannes Berg 		ret = local->ops->set_tim(&local->hw, sta, set);
2334efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
2340a2b8bb2SJohannes Berg 	return ret;
23524487981SJohannes Berg }
23624487981SJohannes Berg 
23724487981SJohannes Berg static inline int drv_set_key(struct ieee80211_local *local,
23812375ef9SJohannes Berg 			      enum set_key_cmd cmd,
23912375ef9SJohannes Berg 			      struct ieee80211_sub_if_data *sdata,
24024487981SJohannes Berg 			      struct ieee80211_sta *sta,
24124487981SJohannes Berg 			      struct ieee80211_key_conf *key)
24224487981SJohannes Berg {
243e1781ed3SKalle Valo 	int ret;
244e1781ed3SKalle Valo 
245e1781ed3SKalle Valo 	might_sleep();
246e1781ed3SKalle Valo 
247077f4939SJohannes Berg 	sdata = get_bss_sdata(sdata);
248f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
249f6837ba8SJohannes Berg 		return -EIO;
2507b7eab6fSJohannes Berg 
2514efc76bdSJohannes Berg 	trace_drv_set_key(local, cmd, sdata, sta, key);
252e1781ed3SKalle Valo 	ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key);
2534efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
2540a2b8bb2SJohannes Berg 	return ret;
25524487981SJohannes Berg }
25624487981SJohannes Berg 
25724487981SJohannes Berg static inline void drv_update_tkip_key(struct ieee80211_local *local,
258b3fbdcf4SJohannes Berg 				       struct ieee80211_sub_if_data *sdata,
25924487981SJohannes Berg 				       struct ieee80211_key_conf *conf,
260b3fbdcf4SJohannes Berg 				       struct sta_info *sta, u32 iv32,
26124487981SJohannes Berg 				       u16 *phase1key)
26224487981SJohannes Berg {
263b3fbdcf4SJohannes Berg 	struct ieee80211_sta *ista = NULL;
264b3fbdcf4SJohannes Berg 
265b3fbdcf4SJohannes Berg 	if (sta)
266b3fbdcf4SJohannes Berg 		ista = &sta->sta;
267b3fbdcf4SJohannes Berg 
268077f4939SJohannes Berg 	sdata = get_bss_sdata(sdata);
269f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
270f6837ba8SJohannes Berg 		return;
2717b7eab6fSJohannes Berg 
2724efc76bdSJohannes Berg 	trace_drv_update_tkip_key(local, sdata, conf, ista, iv32);
27324487981SJohannes Berg 	if (local->ops->update_tkip_key)
274b3fbdcf4SJohannes Berg 		local->ops->update_tkip_key(&local->hw, &sdata->vif, conf,
275b3fbdcf4SJohannes Berg 					    ista, iv32, phase1key);
2764efc76bdSJohannes Berg 	trace_drv_return_void(local);
27724487981SJohannes Berg }
27824487981SJohannes Berg 
27924487981SJohannes Berg static inline int drv_hw_scan(struct ieee80211_local *local,
280a060bbfeSJohannes Berg 			      struct ieee80211_sub_if_data *sdata,
281c56ef672SDavid Spinadel 			      struct ieee80211_scan_request *req)
28224487981SJohannes Berg {
283e1781ed3SKalle Valo 	int ret;
284e1781ed3SKalle Valo 
285e1781ed3SKalle Valo 	might_sleep();
286e1781ed3SKalle Valo 
287f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
288f6837ba8SJohannes Berg 		return -EIO;
2897b7eab6fSJohannes Berg 
29079f460caSLuciano Coelho 	trace_drv_hw_scan(local, sdata);
291a060bbfeSJohannes Berg 	ret = local->ops->hw_scan(&local->hw, &sdata->vif, req);
2924efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
2930a2b8bb2SJohannes Berg 	return ret;
29424487981SJohannes Berg }
29524487981SJohannes Berg 
296b856439bSEliad Peller static inline void drv_cancel_hw_scan(struct ieee80211_local *local,
297b856439bSEliad Peller 				      struct ieee80211_sub_if_data *sdata)
298b856439bSEliad Peller {
299b856439bSEliad Peller 	might_sleep();
300b856439bSEliad Peller 
301f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
302f6837ba8SJohannes Berg 		return;
3037b7eab6fSJohannes Berg 
304b856439bSEliad Peller 	trace_drv_cancel_hw_scan(local, sdata);
305b856439bSEliad Peller 	local->ops->cancel_hw_scan(&local->hw, &sdata->vif);
306b856439bSEliad Peller 	trace_drv_return_void(local);
307b856439bSEliad Peller }
308b856439bSEliad Peller 
30979f460caSLuciano Coelho static inline int
31079f460caSLuciano Coelho drv_sched_scan_start(struct ieee80211_local *local,
31179f460caSLuciano Coelho 		     struct ieee80211_sub_if_data *sdata,
31279f460caSLuciano Coelho 		     struct cfg80211_sched_scan_request *req,
313633e2713SDavid Spinadel 		     struct ieee80211_scan_ies *ies)
31479f460caSLuciano Coelho {
31579f460caSLuciano Coelho 	int ret;
31679f460caSLuciano Coelho 
31779f460caSLuciano Coelho 	might_sleep();
31879f460caSLuciano Coelho 
319f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
320f6837ba8SJohannes Berg 		return -EIO;
3217b7eab6fSJohannes Berg 
32279f460caSLuciano Coelho 	trace_drv_sched_scan_start(local, sdata);
32379f460caSLuciano Coelho 	ret = local->ops->sched_scan_start(&local->hw, &sdata->vif,
32479f460caSLuciano Coelho 					      req, ies);
32579f460caSLuciano Coelho 	trace_drv_return_int(local, ret);
32679f460caSLuciano Coelho 	return ret;
32779f460caSLuciano Coelho }
32879f460caSLuciano Coelho 
32937e3308cSJohannes Berg static inline int drv_sched_scan_stop(struct ieee80211_local *local,
33079f460caSLuciano Coelho 				      struct ieee80211_sub_if_data *sdata)
33179f460caSLuciano Coelho {
33237e3308cSJohannes Berg 	int ret;
33337e3308cSJohannes Berg 
33479f460caSLuciano Coelho 	might_sleep();
33579f460caSLuciano Coelho 
336f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
337f6837ba8SJohannes Berg 		return -EIO;
3387b7eab6fSJohannes Berg 
33979f460caSLuciano Coelho 	trace_drv_sched_scan_stop(local, sdata);
34037e3308cSJohannes Berg 	ret = local->ops->sched_scan_stop(&local->hw, &sdata->vif);
34137e3308cSJohannes Berg 	trace_drv_return_int(local, ret);
34237e3308cSJohannes Berg 
34337e3308cSJohannes Berg 	return ret;
34479f460caSLuciano Coelho }
34579f460caSLuciano Coelho 
346a344d677SJohannes Berg static inline void drv_sw_scan_start(struct ieee80211_local *local,
347a344d677SJohannes Berg 				     struct ieee80211_sub_if_data *sdata,
348a344d677SJohannes Berg 				     const u8 *mac_addr)
34924487981SJohannes Berg {
350e1781ed3SKalle Valo 	might_sleep();
351e1781ed3SKalle Valo 
352a344d677SJohannes Berg 	trace_drv_sw_scan_start(local, sdata, mac_addr);
35324487981SJohannes Berg 	if (local->ops->sw_scan_start)
354a344d677SJohannes Berg 		local->ops->sw_scan_start(&local->hw, &sdata->vif, mac_addr);
3554efc76bdSJohannes Berg 	trace_drv_return_void(local);
35624487981SJohannes Berg }
35724487981SJohannes Berg 
358a344d677SJohannes Berg static inline void drv_sw_scan_complete(struct ieee80211_local *local,
359a344d677SJohannes Berg 					struct ieee80211_sub_if_data *sdata)
36024487981SJohannes Berg {
361e1781ed3SKalle Valo 	might_sleep();
362e1781ed3SKalle Valo 
363a344d677SJohannes Berg 	trace_drv_sw_scan_complete(local, sdata);
36424487981SJohannes Berg 	if (local->ops->sw_scan_complete)
365a344d677SJohannes Berg 		local->ops->sw_scan_complete(&local->hw, &sdata->vif);
3664efc76bdSJohannes Berg 	trace_drv_return_void(local);
36724487981SJohannes Berg }
36824487981SJohannes Berg 
36924487981SJohannes Berg static inline int drv_get_stats(struct ieee80211_local *local,
37024487981SJohannes Berg 				struct ieee80211_low_level_stats *stats)
37124487981SJohannes Berg {
3720a2b8bb2SJohannes Berg 	int ret = -EOPNOTSUPP;
3730a2b8bb2SJohannes Berg 
374e1781ed3SKalle Valo 	might_sleep();
375e1781ed3SKalle Valo 
3760a2b8bb2SJohannes Berg 	if (local->ops->get_stats)
3770a2b8bb2SJohannes Berg 		ret = local->ops->get_stats(&local->hw, stats);
3780a2b8bb2SJohannes Berg 	trace_drv_get_stats(local, stats, ret);
3790a2b8bb2SJohannes Berg 
3800a2b8bb2SJohannes Berg 	return ret;
38124487981SJohannes Berg }
38224487981SJohannes Berg 
3839352c19fSJohannes Berg static inline void drv_get_key_seq(struct ieee80211_local *local,
3849352c19fSJohannes Berg 				   struct ieee80211_key *key,
3859352c19fSJohannes Berg 				   struct ieee80211_key_seq *seq)
38624487981SJohannes Berg {
3879352c19fSJohannes Berg 	if (local->ops->get_key_seq)
3889352c19fSJohannes Berg 		local->ops->get_key_seq(&local->hw, &key->conf, seq);
3899352c19fSJohannes Berg 	trace_drv_get_key_seq(local, &key->conf);
39024487981SJohannes Berg }
39124487981SJohannes Berg 
392f23a4780SArik Nemtsov static inline int drv_set_frag_threshold(struct ieee80211_local *local,
393f23a4780SArik Nemtsov 					u32 value)
394f23a4780SArik Nemtsov {
395f23a4780SArik Nemtsov 	int ret = 0;
396f23a4780SArik Nemtsov 
397f23a4780SArik Nemtsov 	might_sleep();
398f23a4780SArik Nemtsov 
399f23a4780SArik Nemtsov 	trace_drv_set_frag_threshold(local, value);
400f23a4780SArik Nemtsov 	if (local->ops->set_frag_threshold)
401f23a4780SArik Nemtsov 		ret = local->ops->set_frag_threshold(&local->hw, value);
402f23a4780SArik Nemtsov 	trace_drv_return_int(local, ret);
403f23a4780SArik Nemtsov 	return ret;
404f23a4780SArik Nemtsov }
405f23a4780SArik Nemtsov 
40624487981SJohannes Berg static inline int drv_set_rts_threshold(struct ieee80211_local *local,
40724487981SJohannes Berg 					u32 value)
40824487981SJohannes Berg {
4090a2b8bb2SJohannes Berg 	int ret = 0;
410e1781ed3SKalle Valo 
411e1781ed3SKalle Valo 	might_sleep();
412e1781ed3SKalle Valo 
4134efc76bdSJohannes Berg 	trace_drv_set_rts_threshold(local, value);
41424487981SJohannes Berg 	if (local->ops->set_rts_threshold)
4150a2b8bb2SJohannes Berg 		ret = local->ops->set_rts_threshold(&local->hw, value);
4164efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
4170a2b8bb2SJohannes Berg 	return ret;
41824487981SJohannes Berg }
41924487981SJohannes Berg 
420310bc676SLukáš Turek static inline int drv_set_coverage_class(struct ieee80211_local *local,
421a4bcaf55SLorenzo Bianconi 					 s16 value)
422310bc676SLukáš Turek {
423310bc676SLukáš Turek 	int ret = 0;
424310bc676SLukáš Turek 	might_sleep();
425310bc676SLukáš Turek 
4264efc76bdSJohannes Berg 	trace_drv_set_coverage_class(local, value);
427310bc676SLukáš Turek 	if (local->ops->set_coverage_class)
428310bc676SLukáš Turek 		local->ops->set_coverage_class(&local->hw, value);
429310bc676SLukáš Turek 	else
430310bc676SLukáš Turek 		ret = -EOPNOTSUPP;
431310bc676SLukáš Turek 
4324efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
433310bc676SLukáš Turek 	return ret;
434310bc676SLukáš Turek }
435310bc676SLukáš Turek 
43624487981SJohannes Berg static inline void drv_sta_notify(struct ieee80211_local *local,
43712375ef9SJohannes Berg 				  struct ieee80211_sub_if_data *sdata,
43824487981SJohannes Berg 				  enum sta_notify_cmd cmd,
43924487981SJohannes Berg 				  struct ieee80211_sta *sta)
44024487981SJohannes Berg {
441bc192f89SFelix Fietkau 	sdata = get_bss_sdata(sdata);
442f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
443f6837ba8SJohannes Berg 		return;
4447b7eab6fSJohannes Berg 
4454efc76bdSJohannes Berg 	trace_drv_sta_notify(local, sdata, cmd, sta);
44624487981SJohannes Berg 	if (local->ops->sta_notify)
44712375ef9SJohannes Berg 		local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta);
4484efc76bdSJohannes Berg 	trace_drv_return_void(local);
44924487981SJohannes Berg }
45024487981SJohannes Berg 
45134e89507SJohannes Berg static inline int drv_sta_add(struct ieee80211_local *local,
45234e89507SJohannes Berg 			      struct ieee80211_sub_if_data *sdata,
45334e89507SJohannes Berg 			      struct ieee80211_sta *sta)
45434e89507SJohannes Berg {
45534e89507SJohannes Berg 	int ret = 0;
45634e89507SJohannes Berg 
45734e89507SJohannes Berg 	might_sleep();
45834e89507SJohannes Berg 
459bc192f89SFelix Fietkau 	sdata = get_bss_sdata(sdata);
460f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
461f6837ba8SJohannes Berg 		return -EIO;
4627b7eab6fSJohannes Berg 
4634efc76bdSJohannes Berg 	trace_drv_sta_add(local, sdata, sta);
46434e89507SJohannes Berg 	if (local->ops->sta_add)
46534e89507SJohannes Berg 		ret = local->ops->sta_add(&local->hw, &sdata->vif, sta);
46634e89507SJohannes Berg 
4674efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
46834e89507SJohannes Berg 
46934e89507SJohannes Berg 	return ret;
47034e89507SJohannes Berg }
47134e89507SJohannes Berg 
47234e89507SJohannes Berg static inline void drv_sta_remove(struct ieee80211_local *local,
47334e89507SJohannes Berg 				  struct ieee80211_sub_if_data *sdata,
47434e89507SJohannes Berg 				  struct ieee80211_sta *sta)
47534e89507SJohannes Berg {
47634e89507SJohannes Berg 	might_sleep();
47734e89507SJohannes Berg 
478bc192f89SFelix Fietkau 	sdata = get_bss_sdata(sdata);
479f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
480f6837ba8SJohannes Berg 		return;
4817b7eab6fSJohannes Berg 
4824efc76bdSJohannes Berg 	trace_drv_sta_remove(local, sdata, sta);
48334e89507SJohannes Berg 	if (local->ops->sta_remove)
48434e89507SJohannes Berg 		local->ops->sta_remove(&local->hw, &sdata->vif, sta);
48534e89507SJohannes Berg 
4864efc76bdSJohannes Berg 	trace_drv_return_void(local);
48734e89507SJohannes Berg }
48834e89507SJohannes Berg 
48977d2ece6SSujith Manoharan #ifdef CONFIG_MAC80211_DEBUGFS
49077d2ece6SSujith Manoharan static inline void drv_sta_add_debugfs(struct ieee80211_local *local,
49177d2ece6SSujith Manoharan 				       struct ieee80211_sub_if_data *sdata,
49277d2ece6SSujith Manoharan 				       struct ieee80211_sta *sta,
49377d2ece6SSujith Manoharan 				       struct dentry *dir)
49477d2ece6SSujith Manoharan {
49577d2ece6SSujith Manoharan 	might_sleep();
49677d2ece6SSujith Manoharan 
49777d2ece6SSujith Manoharan 	sdata = get_bss_sdata(sdata);
498f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
499f6837ba8SJohannes Berg 		return;
50077d2ece6SSujith Manoharan 
50177d2ece6SSujith Manoharan 	if (local->ops->sta_add_debugfs)
50277d2ece6SSujith Manoharan 		local->ops->sta_add_debugfs(&local->hw, &sdata->vif,
50377d2ece6SSujith Manoharan 					    sta, dir);
50477d2ece6SSujith Manoharan }
50577d2ece6SSujith Manoharan #endif
50677d2ece6SSujith Manoharan 
5076a9d1b91SJohannes Berg static inline void drv_sta_pre_rcu_remove(struct ieee80211_local *local,
5086a9d1b91SJohannes Berg 					  struct ieee80211_sub_if_data *sdata,
5096a9d1b91SJohannes Berg 					  struct sta_info *sta)
5106a9d1b91SJohannes Berg {
5116a9d1b91SJohannes Berg 	might_sleep();
5126a9d1b91SJohannes Berg 
5136a9d1b91SJohannes Berg 	sdata = get_bss_sdata(sdata);
514f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
515f6837ba8SJohannes Berg 		return;
5166a9d1b91SJohannes Berg 
5176a9d1b91SJohannes Berg 	trace_drv_sta_pre_rcu_remove(local, sdata, &sta->sta);
5186a9d1b91SJohannes Berg 	if (local->ops->sta_pre_rcu_remove)
5196a9d1b91SJohannes Berg 		local->ops->sta_pre_rcu_remove(&local->hw, &sdata->vif,
5206a9d1b91SJohannes Berg 					       &sta->sta);
5216a9d1b91SJohannes Berg 	trace_drv_return_void(local);
5226a9d1b91SJohannes Berg }
5236a9d1b91SJohannes Berg 
524727da60bSDenys Vlasenko __must_check
525f09603a2SJohannes Berg int drv_sta_state(struct ieee80211_local *local,
526f09603a2SJohannes Berg 		  struct ieee80211_sub_if_data *sdata,
527f09603a2SJohannes Berg 		  struct sta_info *sta,
528f09603a2SJohannes Berg 		  enum ieee80211_sta_state old_state,
529727da60bSDenys Vlasenko 		  enum ieee80211_sta_state new_state);
530f09603a2SJohannes Berg 
5314fbd572cSDenys Vlasenko void drv_sta_rc_update(struct ieee80211_local *local,
5328f727ef3SJohannes Berg 		       struct ieee80211_sub_if_data *sdata,
5334fbd572cSDenys Vlasenko 		       struct ieee80211_sta *sta, u32 changed);
5348f727ef3SJohannes Berg 
535f815e2b3SJohannes Berg static inline void drv_sta_rate_tbl_update(struct ieee80211_local *local,
536f815e2b3SJohannes Berg 					   struct ieee80211_sub_if_data *sdata,
537f815e2b3SJohannes Berg 					   struct ieee80211_sta *sta)
538f815e2b3SJohannes Berg {
539f815e2b3SJohannes Berg 	sdata = get_bss_sdata(sdata);
540f815e2b3SJohannes Berg 	if (!check_sdata_in_driver(sdata))
541f815e2b3SJohannes Berg 		return;
542f815e2b3SJohannes Berg 
543f815e2b3SJohannes Berg 	trace_drv_sta_rate_tbl_update(local, sdata, sta);
544f815e2b3SJohannes Berg 	if (local->ops->sta_rate_tbl_update)
545f815e2b3SJohannes Berg 		local->ops->sta_rate_tbl_update(&local->hw, &sdata->vif, sta);
546f815e2b3SJohannes Berg 
547f815e2b3SJohannes Berg 	trace_drv_return_void(local);
548f815e2b3SJohannes Berg }
549f815e2b3SJohannes Berg 
5502b9a7e1bSJohannes Berg static inline void drv_sta_statistics(struct ieee80211_local *local,
5512b9a7e1bSJohannes Berg 				      struct ieee80211_sub_if_data *sdata,
5522b9a7e1bSJohannes Berg 				      struct ieee80211_sta *sta,
5532b9a7e1bSJohannes Berg 				      struct station_info *sinfo)
5542b9a7e1bSJohannes Berg {
5552b9a7e1bSJohannes Berg 	sdata = get_bss_sdata(sdata);
5562b9a7e1bSJohannes Berg 	if (!check_sdata_in_driver(sdata))
5572b9a7e1bSJohannes Berg 		return;
5582b9a7e1bSJohannes Berg 
5592b9a7e1bSJohannes Berg 	trace_drv_sta_statistics(local, sdata, sta);
5602b9a7e1bSJohannes Berg 	if (local->ops->sta_statistics)
5612b9a7e1bSJohannes Berg 		local->ops->sta_statistics(&local->hw, &sdata->vif, sta, sinfo);
5622b9a7e1bSJohannes Berg 	trace_drv_return_void(local);
5632b9a7e1bSJohannes Berg }
5642b9a7e1bSJohannes Berg 
565b23dcd4aSDenys Vlasenko int drv_conf_tx(struct ieee80211_local *local,
566a3304b0aSJohannes Berg 		struct ieee80211_sub_if_data *sdata, u16 ac,
567b23dcd4aSDenys Vlasenko 		const struct ieee80211_tx_queue_params *params);
56824487981SJohannes Berg 
569416eb9fcSDenys Vlasenko u64 drv_get_tsf(struct ieee80211_local *local,
570416eb9fcSDenys Vlasenko 		struct ieee80211_sub_if_data *sdata);
571416eb9fcSDenys Vlasenko void drv_set_tsf(struct ieee80211_local *local,
57237a41b4aSEliad Peller 		 struct ieee80211_sub_if_data *sdata,
573416eb9fcSDenys Vlasenko 		 u64 tsf);
574354d381bSPedersen, Thomas void drv_offset_tsf(struct ieee80211_local *local,
575354d381bSPedersen, Thomas 		    struct ieee80211_sub_if_data *sdata,
576354d381bSPedersen, Thomas 		    s64 offset);
577416eb9fcSDenys Vlasenko void drv_reset_tsf(struct ieee80211_local *local,
578416eb9fcSDenys Vlasenko 		   struct ieee80211_sub_if_data *sdata);
57924487981SJohannes Berg 
58024487981SJohannes Berg static inline int drv_tx_last_beacon(struct ieee80211_local *local)
58124487981SJohannes Berg {
58202582e9bSMasanari Iida 	int ret = 0; /* default unsupported op for less congestion */
583e1781ed3SKalle Valo 
584e1781ed3SKalle Valo 	might_sleep();
585e1781ed3SKalle Valo 
5864efc76bdSJohannes Berg 	trace_drv_tx_last_beacon(local);
58724487981SJohannes Berg 	if (local->ops->tx_last_beacon)
5880a2b8bb2SJohannes Berg 		ret = local->ops->tx_last_beacon(&local->hw);
5894efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
5900a2b8bb2SJohannes Berg 	return ret;
59124487981SJohannes Berg }
59224487981SJohannes Berg 
5936db96838SDenys Vlasenko int drv_ampdu_action(struct ieee80211_local *local,
59412375ef9SJohannes Berg 		     struct ieee80211_sub_if_data *sdata,
59550ea05efSSara Sharon 		     struct ieee80211_ampdu_params *params);
5961f87f7d3SJohannes Berg 
5971289723eSHolger Schurig static inline int drv_get_survey(struct ieee80211_local *local, int idx,
5981289723eSHolger Schurig 				struct survey_info *survey)
5991289723eSHolger Schurig {
6001289723eSHolger Schurig 	int ret = -EOPNOTSUPP;
601c466d4efSJohn W. Linville 
602c466d4efSJohn W. Linville 	trace_drv_get_survey(local, idx, survey);
603c466d4efSJohn W. Linville 
60435dd0509SHolger Schurig 	if (local->ops->get_survey)
6051289723eSHolger Schurig 		ret = local->ops->get_survey(&local->hw, idx, survey);
606c466d4efSJohn W. Linville 
607c466d4efSJohn W. Linville 	trace_drv_return_int(local, ret);
608c466d4efSJohn W. Linville 
6091289723eSHolger Schurig 	return ret;
6101289723eSHolger Schurig }
6111f87f7d3SJohannes Berg 
6121f87f7d3SJohannes Berg static inline void drv_rfkill_poll(struct ieee80211_local *local)
6131f87f7d3SJohannes Berg {
614e1781ed3SKalle Valo 	might_sleep();
615e1781ed3SKalle Valo 
6161f87f7d3SJohannes Berg 	if (local->ops->rfkill_poll)
6171f87f7d3SJohannes Berg 		local->ops->rfkill_poll(&local->hw);
6181f87f7d3SJohannes Berg }
619a80f7c0bSJohannes Berg 
62039ecc01dSJohannes Berg static inline void drv_flush(struct ieee80211_local *local,
62177be2c54SEmmanuel Grumbach 			     struct ieee80211_sub_if_data *sdata,
62239ecc01dSJohannes Berg 			     u32 queues, bool drop)
623a80f7c0bSJohannes Berg {
62477be2c54SEmmanuel Grumbach 	struct ieee80211_vif *vif = sdata ? &sdata->vif : NULL;
62577be2c54SEmmanuel Grumbach 
626e1781ed3SKalle Valo 	might_sleep();
627e1781ed3SKalle Valo 
628f6837ba8SJohannes Berg 	if (sdata && !check_sdata_in_driver(sdata))
629f6837ba8SJohannes Berg 		return;
63077be2c54SEmmanuel Grumbach 
63139ecc01dSJohannes Berg 	trace_drv_flush(local, queues, drop);
632a80f7c0bSJohannes Berg 	if (local->ops->flush)
63377be2c54SEmmanuel Grumbach 		local->ops->flush(&local->hw, vif, queues, drop);
6344efc76bdSJohannes Berg 	trace_drv_return_void(local);
635a80f7c0bSJohannes Berg }
6365ce6e438SJohannes Berg 
6375ce6e438SJohannes Berg static inline void drv_channel_switch(struct ieee80211_local *local,
6380f791eb4SLuciano Coelho 				      struct ieee80211_sub_if_data *sdata,
6395ce6e438SJohannes Berg 				      struct ieee80211_channel_switch *ch_switch)
6405ce6e438SJohannes Berg {
6415ce6e438SJohannes Berg 	might_sleep();
6425ce6e438SJohannes Berg 
6430f791eb4SLuciano Coelho 	trace_drv_channel_switch(local, sdata, ch_switch);
6440f791eb4SLuciano Coelho 	local->ops->channel_switch(&local->hw, &sdata->vif, ch_switch);
6454efc76bdSJohannes Berg 	trace_drv_return_void(local);
6465ce6e438SJohannes Berg }
6475ce6e438SJohannes Berg 
64815d96753SBruno Randolf 
64915d96753SBruno Randolf static inline int drv_set_antenna(struct ieee80211_local *local,
65015d96753SBruno Randolf 				  u32 tx_ant, u32 rx_ant)
65115d96753SBruno Randolf {
65215d96753SBruno Randolf 	int ret = -EOPNOTSUPP;
65315d96753SBruno Randolf 	might_sleep();
65415d96753SBruno Randolf 	if (local->ops->set_antenna)
65515d96753SBruno Randolf 		ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant);
65615d96753SBruno Randolf 	trace_drv_set_antenna(local, tx_ant, rx_ant, ret);
65715d96753SBruno Randolf 	return ret;
65815d96753SBruno Randolf }
65915d96753SBruno Randolf 
66015d96753SBruno Randolf static inline int drv_get_antenna(struct ieee80211_local *local,
66115d96753SBruno Randolf 				  u32 *tx_ant, u32 *rx_ant)
66215d96753SBruno Randolf {
66315d96753SBruno Randolf 	int ret = -EOPNOTSUPP;
66415d96753SBruno Randolf 	might_sleep();
66515d96753SBruno Randolf 	if (local->ops->get_antenna)
66615d96753SBruno Randolf 		ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant);
66715d96753SBruno Randolf 	trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret);
66815d96753SBruno Randolf 	return ret;
66915d96753SBruno Randolf }
67015d96753SBruno Randolf 
67121f83589SJohannes Berg static inline int drv_remain_on_channel(struct ieee80211_local *local,
67249884568SEliad Peller 					struct ieee80211_sub_if_data *sdata,
67321f83589SJohannes Berg 					struct ieee80211_channel *chan,
674d339d5caSIlan Peer 					unsigned int duration,
675d339d5caSIlan Peer 					enum ieee80211_roc_type type)
67621f83589SJohannes Berg {
67721f83589SJohannes Berg 	int ret;
67821f83589SJohannes Berg 
67921f83589SJohannes Berg 	might_sleep();
68021f83589SJohannes Berg 
681d339d5caSIlan Peer 	trace_drv_remain_on_channel(local, sdata, chan, duration, type);
68249884568SEliad Peller 	ret = local->ops->remain_on_channel(&local->hw, &sdata->vif,
683d339d5caSIlan Peer 					    chan, duration, type);
68421f83589SJohannes Berg 	trace_drv_return_int(local, ret);
68521f83589SJohannes Berg 
68621f83589SJohannes Berg 	return ret;
68721f83589SJohannes Berg }
68821f83589SJohannes Berg 
68921f83589SJohannes Berg static inline int drv_cancel_remain_on_channel(struct ieee80211_local *local)
69021f83589SJohannes Berg {
69121f83589SJohannes Berg 	int ret;
69221f83589SJohannes Berg 
69321f83589SJohannes Berg 	might_sleep();
69421f83589SJohannes Berg 
69521f83589SJohannes Berg 	trace_drv_cancel_remain_on_channel(local);
69621f83589SJohannes Berg 	ret = local->ops->cancel_remain_on_channel(&local->hw);
69721f83589SJohannes Berg 	trace_drv_return_int(local, ret);
69821f83589SJohannes Berg 
69921f83589SJohannes Berg 	return ret;
70021f83589SJohannes Berg }
70121f83589SJohannes Berg 
70238c09159SJohn W. Linville static inline int drv_set_ringparam(struct ieee80211_local *local,
70338c09159SJohn W. Linville 				    u32 tx, u32 rx)
70438c09159SJohn W. Linville {
70538c09159SJohn W. Linville 	int ret = -ENOTSUPP;
70638c09159SJohn W. Linville 
70738c09159SJohn W. Linville 	might_sleep();
70838c09159SJohn W. Linville 
70938c09159SJohn W. Linville 	trace_drv_set_ringparam(local, tx, rx);
71038c09159SJohn W. Linville 	if (local->ops->set_ringparam)
71138c09159SJohn W. Linville 		ret = local->ops->set_ringparam(&local->hw, tx, rx);
71238c09159SJohn W. Linville 	trace_drv_return_int(local, ret);
71338c09159SJohn W. Linville 
71438c09159SJohn W. Linville 	return ret;
71538c09159SJohn W. Linville }
71638c09159SJohn W. Linville 
71738c09159SJohn W. Linville static inline void drv_get_ringparam(struct ieee80211_local *local,
71838c09159SJohn W. Linville 				     u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
71938c09159SJohn W. Linville {
72038c09159SJohn W. Linville 	might_sleep();
72138c09159SJohn W. Linville 
72238c09159SJohn W. Linville 	trace_drv_get_ringparam(local, tx, tx_max, rx, rx_max);
72338c09159SJohn W. Linville 	if (local->ops->get_ringparam)
72438c09159SJohn W. Linville 		local->ops->get_ringparam(&local->hw, tx, tx_max, rx, rx_max);
72538c09159SJohn W. Linville 	trace_drv_return_void(local);
72638c09159SJohn W. Linville }
72738c09159SJohn W. Linville 
728e8306f98SVivek Natarajan static inline bool drv_tx_frames_pending(struct ieee80211_local *local)
729e8306f98SVivek Natarajan {
730e8306f98SVivek Natarajan 	bool ret = false;
731e8306f98SVivek Natarajan 
732e8306f98SVivek Natarajan 	might_sleep();
733e8306f98SVivek Natarajan 
734e8306f98SVivek Natarajan 	trace_drv_tx_frames_pending(local);
735e8306f98SVivek Natarajan 	if (local->ops->tx_frames_pending)
736e8306f98SVivek Natarajan 		ret = local->ops->tx_frames_pending(&local->hw);
737e8306f98SVivek Natarajan 	trace_drv_return_bool(local, ret);
738e8306f98SVivek Natarajan 
739e8306f98SVivek Natarajan 	return ret;
740e8306f98SVivek Natarajan }
741bdbfd6b5SSujith Manoharan 
742bdbfd6b5SSujith Manoharan static inline int drv_set_bitrate_mask(struct ieee80211_local *local,
743bdbfd6b5SSujith Manoharan 				       struct ieee80211_sub_if_data *sdata,
744bdbfd6b5SSujith Manoharan 				       const struct cfg80211_bitrate_mask *mask)
745bdbfd6b5SSujith Manoharan {
746bdbfd6b5SSujith Manoharan 	int ret = -EOPNOTSUPP;
747bdbfd6b5SSujith Manoharan 
748bdbfd6b5SSujith Manoharan 	might_sleep();
749bdbfd6b5SSujith Manoharan 
750f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
751f6837ba8SJohannes Berg 		return -EIO;
7527b7eab6fSJohannes Berg 
753bdbfd6b5SSujith Manoharan 	trace_drv_set_bitrate_mask(local, sdata, mask);
754bdbfd6b5SSujith Manoharan 	if (local->ops->set_bitrate_mask)
755bdbfd6b5SSujith Manoharan 		ret = local->ops->set_bitrate_mask(&local->hw,
756bdbfd6b5SSujith Manoharan 						   &sdata->vif, mask);
757bdbfd6b5SSujith Manoharan 	trace_drv_return_int(local, ret);
758bdbfd6b5SSujith Manoharan 
759bdbfd6b5SSujith Manoharan 	return ret;
760bdbfd6b5SSujith Manoharan }
761bdbfd6b5SSujith Manoharan 
762c68f4b89SJohannes Berg static inline void drv_set_rekey_data(struct ieee80211_local *local,
763c68f4b89SJohannes Berg 				      struct ieee80211_sub_if_data *sdata,
764c68f4b89SJohannes Berg 				      struct cfg80211_gtk_rekey_data *data)
765c68f4b89SJohannes Berg {
766f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
767f6837ba8SJohannes Berg 		return;
7687b7eab6fSJohannes Berg 
769c68f4b89SJohannes Berg 	trace_drv_set_rekey_data(local, sdata, data);
770c68f4b89SJohannes Berg 	if (local->ops->set_rekey_data)
771c68f4b89SJohannes Berg 		local->ops->set_rekey_data(&local->hw, &sdata->vif, data);
772c68f4b89SJohannes Berg 	trace_drv_return_void(local);
773c68f4b89SJohannes Berg }
774c68f4b89SJohannes Berg 
775a8182929SEmmanuel Grumbach static inline void drv_event_callback(struct ieee80211_local *local,
776887da917SEmmanuel Grumbach 				      struct ieee80211_sub_if_data *sdata,
777a8182929SEmmanuel Grumbach 				      const struct ieee80211_event *event)
778615f7b9bSMeenakshi Venkataraman {
779a8182929SEmmanuel Grumbach 	trace_drv_event_callback(local, sdata, event);
780a8182929SEmmanuel Grumbach 	if (local->ops->event_callback)
781a8182929SEmmanuel Grumbach 		local->ops->event_callback(&local->hw, &sdata->vif, event);
782615f7b9bSMeenakshi Venkataraman 	trace_drv_return_void(local);
783615f7b9bSMeenakshi Venkataraman }
7844049e09aSJohannes Berg 
7854049e09aSJohannes Berg static inline void
7864049e09aSJohannes Berg drv_release_buffered_frames(struct ieee80211_local *local,
7874049e09aSJohannes Berg 			    struct sta_info *sta, u16 tids, int num_frames,
7884049e09aSJohannes Berg 			    enum ieee80211_frame_release_type reason,
7894049e09aSJohannes Berg 			    bool more_data)
7904049e09aSJohannes Berg {
7914049e09aSJohannes Berg 	trace_drv_release_buffered_frames(local, &sta->sta, tids, num_frames,
7924049e09aSJohannes Berg 					  reason, more_data);
7934049e09aSJohannes Berg 	if (local->ops->release_buffered_frames)
7944049e09aSJohannes Berg 		local->ops->release_buffered_frames(&local->hw, &sta->sta, tids,
7954049e09aSJohannes Berg 						    num_frames, reason,
7964049e09aSJohannes Berg 						    more_data);
7974049e09aSJohannes Berg 	trace_drv_return_void(local);
7984049e09aSJohannes Berg }
79940b96408SJohannes Berg 
80040b96408SJohannes Berg static inline void
80140b96408SJohannes Berg drv_allow_buffered_frames(struct ieee80211_local *local,
80240b96408SJohannes Berg 			  struct sta_info *sta, u16 tids, int num_frames,
80340b96408SJohannes Berg 			  enum ieee80211_frame_release_type reason,
80440b96408SJohannes Berg 			  bool more_data)
80540b96408SJohannes Berg {
80640b96408SJohannes Berg 	trace_drv_allow_buffered_frames(local, &sta->sta, tids, num_frames,
80740b96408SJohannes Berg 					reason, more_data);
80840b96408SJohannes Berg 	if (local->ops->allow_buffered_frames)
80940b96408SJohannes Berg 		local->ops->allow_buffered_frames(&local->hw, &sta->sta,
81040b96408SJohannes Berg 						  tids, num_frames, reason,
81140b96408SJohannes Berg 						  more_data);
81240b96408SJohannes Berg 	trace_drv_return_void(local);
81340b96408SJohannes Berg }
81466572cfcSVictor Goldenshtein 
815a1845fc7SJohannes Berg static inline void drv_mgd_prepare_tx(struct ieee80211_local *local,
816a1845fc7SJohannes Berg 				      struct ieee80211_sub_if_data *sdata)
817a1845fc7SJohannes Berg {
818a1845fc7SJohannes Berg 	might_sleep();
819a1845fc7SJohannes Berg 
820f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
821f6837ba8SJohannes Berg 		return;
822a1845fc7SJohannes Berg 	WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
823a1845fc7SJohannes Berg 
824a1845fc7SJohannes Berg 	trace_drv_mgd_prepare_tx(local, sdata);
825a1845fc7SJohannes Berg 	if (local->ops->mgd_prepare_tx)
826a1845fc7SJohannes Berg 		local->ops->mgd_prepare_tx(&local->hw, &sdata->vif);
827a1845fc7SJohannes Berg 	trace_drv_return_void(local);
828a1845fc7SJohannes Berg }
829c3645eacSMichal Kazior 
830ee10f2c7SArik Nemtsov static inline void
831ee10f2c7SArik Nemtsov drv_mgd_protect_tdls_discover(struct ieee80211_local *local,
832ee10f2c7SArik Nemtsov 			      struct ieee80211_sub_if_data *sdata)
833ee10f2c7SArik Nemtsov {
834ee10f2c7SArik Nemtsov 	might_sleep();
835ee10f2c7SArik Nemtsov 
836ee10f2c7SArik Nemtsov 	if (!check_sdata_in_driver(sdata))
837ee10f2c7SArik Nemtsov 		return;
838ee10f2c7SArik Nemtsov 	WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
839ee10f2c7SArik Nemtsov 
840ee10f2c7SArik Nemtsov 	trace_drv_mgd_protect_tdls_discover(local, sdata);
841ee10f2c7SArik Nemtsov 	if (local->ops->mgd_protect_tdls_discover)
842ee10f2c7SArik Nemtsov 		local->ops->mgd_protect_tdls_discover(&local->hw, &sdata->vif);
843ee10f2c7SArik Nemtsov 	trace_drv_return_void(local);
844ee10f2c7SArik Nemtsov }
845ee10f2c7SArik Nemtsov 
846c3645eacSMichal Kazior static inline int drv_add_chanctx(struct ieee80211_local *local,
847c3645eacSMichal Kazior 				  struct ieee80211_chanctx *ctx)
848c3645eacSMichal Kazior {
849c3645eacSMichal Kazior 	int ret = -EOPNOTSUPP;
850c3645eacSMichal Kazior 
851dcae9e02SChaitanya T K 	might_sleep();
852dcae9e02SChaitanya T K 
853c3645eacSMichal Kazior 	trace_drv_add_chanctx(local, ctx);
854c3645eacSMichal Kazior 	if (local->ops->add_chanctx)
855c3645eacSMichal Kazior 		ret = local->ops->add_chanctx(&local->hw, &ctx->conf);
856c3645eacSMichal Kazior 	trace_drv_return_int(local, ret);
8578a61af65SJohannes Berg 	if (!ret)
8588a61af65SJohannes Berg 		ctx->driver_present = true;
859c3645eacSMichal Kazior 
860c3645eacSMichal Kazior 	return ret;
861c3645eacSMichal Kazior }
862c3645eacSMichal Kazior 
863c3645eacSMichal Kazior static inline void drv_remove_chanctx(struct ieee80211_local *local,
864c3645eacSMichal Kazior 				      struct ieee80211_chanctx *ctx)
865c3645eacSMichal Kazior {
866dcae9e02SChaitanya T K 	might_sleep();
867dcae9e02SChaitanya T K 
868f6837ba8SJohannes Berg 	if (WARN_ON(!ctx->driver_present))
869f6837ba8SJohannes Berg 		return;
870f6837ba8SJohannes Berg 
871c3645eacSMichal Kazior 	trace_drv_remove_chanctx(local, ctx);
872c3645eacSMichal Kazior 	if (local->ops->remove_chanctx)
873c3645eacSMichal Kazior 		local->ops->remove_chanctx(&local->hw, &ctx->conf);
874c3645eacSMichal Kazior 	trace_drv_return_void(local);
8758a61af65SJohannes Berg 	ctx->driver_present = false;
876c3645eacSMichal Kazior }
877c3645eacSMichal Kazior 
878c3645eacSMichal Kazior static inline void drv_change_chanctx(struct ieee80211_local *local,
879c3645eacSMichal Kazior 				      struct ieee80211_chanctx *ctx,
880c3645eacSMichal Kazior 				      u32 changed)
881c3645eacSMichal Kazior {
882dcae9e02SChaitanya T K 	might_sleep();
883dcae9e02SChaitanya T K 
884c3645eacSMichal Kazior 	trace_drv_change_chanctx(local, ctx, changed);
8858a61af65SJohannes Berg 	if (local->ops->change_chanctx) {
8868a61af65SJohannes Berg 		WARN_ON_ONCE(!ctx->driver_present);
887c3645eacSMichal Kazior 		local->ops->change_chanctx(&local->hw, &ctx->conf, changed);
8888a61af65SJohannes Berg 	}
889c3645eacSMichal Kazior 	trace_drv_return_void(local);
890c3645eacSMichal Kazior }
891c3645eacSMichal Kazior 
892c3645eacSMichal Kazior static inline int drv_assign_vif_chanctx(struct ieee80211_local *local,
893c3645eacSMichal Kazior 					 struct ieee80211_sub_if_data *sdata,
894c3645eacSMichal Kazior 					 struct ieee80211_chanctx *ctx)
895c3645eacSMichal Kazior {
896c3645eacSMichal Kazior 	int ret = 0;
897c3645eacSMichal Kazior 
898f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
899f6837ba8SJohannes Berg 		return -EIO;
900c3645eacSMichal Kazior 
901c3645eacSMichal Kazior 	trace_drv_assign_vif_chanctx(local, sdata, ctx);
9028a61af65SJohannes Berg 	if (local->ops->assign_vif_chanctx) {
9038a61af65SJohannes Berg 		WARN_ON_ONCE(!ctx->driver_present);
904c3645eacSMichal Kazior 		ret = local->ops->assign_vif_chanctx(&local->hw,
905c3645eacSMichal Kazior 						     &sdata->vif,
906c3645eacSMichal Kazior 						     &ctx->conf);
9078a61af65SJohannes Berg 	}
908c3645eacSMichal Kazior 	trace_drv_return_int(local, ret);
909c3645eacSMichal Kazior 
910c3645eacSMichal Kazior 	return ret;
911c3645eacSMichal Kazior }
912c3645eacSMichal Kazior 
913c3645eacSMichal Kazior static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local,
914c3645eacSMichal Kazior 					    struct ieee80211_sub_if_data *sdata,
915c3645eacSMichal Kazior 					    struct ieee80211_chanctx *ctx)
916c3645eacSMichal Kazior {
917dcae9e02SChaitanya T K 	might_sleep();
918dcae9e02SChaitanya T K 
919f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
920f6837ba8SJohannes Berg 		return;
921c3645eacSMichal Kazior 
922c3645eacSMichal Kazior 	trace_drv_unassign_vif_chanctx(local, sdata, ctx);
9238a61af65SJohannes Berg 	if (local->ops->unassign_vif_chanctx) {
9248a61af65SJohannes Berg 		WARN_ON_ONCE(!ctx->driver_present);
925c3645eacSMichal Kazior 		local->ops->unassign_vif_chanctx(&local->hw,
926c3645eacSMichal Kazior 						 &sdata->vif,
927c3645eacSMichal Kazior 						 &ctx->conf);
9288a61af65SJohannes Berg 	}
929c3645eacSMichal Kazior 	trace_drv_return_void(local);
930c3645eacSMichal Kazior }
931c3645eacSMichal Kazior 
93242677ed3SDenys Vlasenko int drv_switch_vif_chanctx(struct ieee80211_local *local,
9331a5f0c13SLuciano Coelho 			   struct ieee80211_vif_chanctx_switch *vifs,
93442677ed3SDenys Vlasenko 			   int n_vifs, enum ieee80211_chanctx_switch_mode mode);
9351a5f0c13SLuciano Coelho 
9361041638fSJohannes Berg static inline int drv_start_ap(struct ieee80211_local *local,
9371041638fSJohannes Berg 			       struct ieee80211_sub_if_data *sdata)
9381041638fSJohannes Berg {
9391041638fSJohannes Berg 	int ret = 0;
9401041638fSJohannes Berg 
941dcae9e02SChaitanya T K 	might_sleep();
942dcae9e02SChaitanya T K 
943f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
944f6837ba8SJohannes Berg 		return -EIO;
9451041638fSJohannes Berg 
9461041638fSJohannes Berg 	trace_drv_start_ap(local, sdata, &sdata->vif.bss_conf);
9471041638fSJohannes Berg 	if (local->ops->start_ap)
9481041638fSJohannes Berg 		ret = local->ops->start_ap(&local->hw, &sdata->vif);
9491041638fSJohannes Berg 	trace_drv_return_int(local, ret);
9501041638fSJohannes Berg 	return ret;
9511041638fSJohannes Berg }
9521041638fSJohannes Berg 
9531041638fSJohannes Berg static inline void drv_stop_ap(struct ieee80211_local *local,
9541041638fSJohannes Berg 			       struct ieee80211_sub_if_data *sdata)
9551041638fSJohannes Berg {
956f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
957f6837ba8SJohannes Berg 		return;
9581041638fSJohannes Berg 
9591041638fSJohannes Berg 	trace_drv_stop_ap(local, sdata);
9601041638fSJohannes Berg 	if (local->ops->stop_ap)
9611041638fSJohannes Berg 		local->ops->stop_ap(&local->hw, &sdata->vif);
9621041638fSJohannes Berg 	trace_drv_return_void(local);
9631041638fSJohannes Berg }
9641041638fSJohannes Berg 
965cf2c92d8SEliad Peller static inline void
966cf2c92d8SEliad Peller drv_reconfig_complete(struct ieee80211_local *local,
967cf2c92d8SEliad Peller 		      enum ieee80211_reconfig_type reconfig_type)
9689214ad7fSJohannes Berg {
9699214ad7fSJohannes Berg 	might_sleep();
9709214ad7fSJohannes Berg 
971cf2c92d8SEliad Peller 	trace_drv_reconfig_complete(local, reconfig_type);
972cf2c92d8SEliad Peller 	if (local->ops->reconfig_complete)
973cf2c92d8SEliad Peller 		local->ops->reconfig_complete(&local->hw, reconfig_type);
9749214ad7fSJohannes Berg 	trace_drv_return_void(local);
9759214ad7fSJohannes Berg }
9769214ad7fSJohannes Berg 
977de5fad81SYoni Divinsky static inline void
978de5fad81SYoni Divinsky drv_set_default_unicast_key(struct ieee80211_local *local,
979de5fad81SYoni Divinsky 			    struct ieee80211_sub_if_data *sdata,
980de5fad81SYoni Divinsky 			    int key_idx)
981de5fad81SYoni Divinsky {
982f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
983f6837ba8SJohannes Berg 		return;
984de5fad81SYoni Divinsky 
985de5fad81SYoni Divinsky 	WARN_ON_ONCE(key_idx < -1 || key_idx > 3);
986de5fad81SYoni Divinsky 
987de5fad81SYoni Divinsky 	trace_drv_set_default_unicast_key(local, sdata, key_idx);
988de5fad81SYoni Divinsky 	if (local->ops->set_default_unicast_key)
989de5fad81SYoni Divinsky 		local->ops->set_default_unicast_key(&local->hw, &sdata->vif,
990de5fad81SYoni Divinsky 						    key_idx);
991de5fad81SYoni Divinsky 	trace_drv_return_void(local);
992de5fad81SYoni Divinsky }
993de5fad81SYoni Divinsky 
994a65240c1SJohannes Berg #if IS_ENABLED(CONFIG_IPV6)
995a65240c1SJohannes Berg static inline void drv_ipv6_addr_change(struct ieee80211_local *local,
996a65240c1SJohannes Berg 					struct ieee80211_sub_if_data *sdata,
997a65240c1SJohannes Berg 					struct inet6_dev *idev)
998a65240c1SJohannes Berg {
999a65240c1SJohannes Berg 	trace_drv_ipv6_addr_change(local, sdata);
1000a65240c1SJohannes Berg 	if (local->ops->ipv6_addr_change)
1001a65240c1SJohannes Berg 		local->ops->ipv6_addr_change(&local->hw, &sdata->vif, idev);
1002a65240c1SJohannes Berg 	trace_drv_return_void(local);
1003a65240c1SJohannes Berg }
1004a65240c1SJohannes Berg #endif
1005a65240c1SJohannes Berg 
100673da7d5bSSimon Wunderlich static inline void
100773da7d5bSSimon Wunderlich drv_channel_switch_beacon(struct ieee80211_sub_if_data *sdata,
100873da7d5bSSimon Wunderlich 			  struct cfg80211_chan_def *chandef)
100973da7d5bSSimon Wunderlich {
101073da7d5bSSimon Wunderlich 	struct ieee80211_local *local = sdata->local;
101173da7d5bSSimon Wunderlich 
101273da7d5bSSimon Wunderlich 	if (local->ops->channel_switch_beacon) {
101373da7d5bSSimon Wunderlich 		trace_drv_channel_switch_beacon(local, sdata, chandef);
101473da7d5bSSimon Wunderlich 		local->ops->channel_switch_beacon(&local->hw, &sdata->vif,
101573da7d5bSSimon Wunderlich 						  chandef);
101673da7d5bSSimon Wunderlich 	}
101773da7d5bSSimon Wunderlich }
101873da7d5bSSimon Wunderlich 
10196d027bccSLuciano Coelho static inline int
10206d027bccSLuciano Coelho drv_pre_channel_switch(struct ieee80211_sub_if_data *sdata,
10216d027bccSLuciano Coelho 		       struct ieee80211_channel_switch *ch_switch)
10226d027bccSLuciano Coelho {
10236d027bccSLuciano Coelho 	struct ieee80211_local *local = sdata->local;
10246d027bccSLuciano Coelho 	int ret = 0;
10256d027bccSLuciano Coelho 
10266d027bccSLuciano Coelho 	if (!check_sdata_in_driver(sdata))
10276d027bccSLuciano Coelho 		return -EIO;
10286d027bccSLuciano Coelho 
10296d027bccSLuciano Coelho 	trace_drv_pre_channel_switch(local, sdata, ch_switch);
10306d027bccSLuciano Coelho 	if (local->ops->pre_channel_switch)
10316d027bccSLuciano Coelho 		ret = local->ops->pre_channel_switch(&local->hw, &sdata->vif,
10326d027bccSLuciano Coelho 						     ch_switch);
10336d027bccSLuciano Coelho 	trace_drv_return_int(local, ret);
10346d027bccSLuciano Coelho 	return ret;
10356d027bccSLuciano Coelho }
10366d027bccSLuciano Coelho 
1037f1d65583SLuciano Coelho static inline int
1038f1d65583SLuciano Coelho drv_post_channel_switch(struct ieee80211_sub_if_data *sdata)
1039f1d65583SLuciano Coelho {
1040f1d65583SLuciano Coelho 	struct ieee80211_local *local = sdata->local;
1041f1d65583SLuciano Coelho 	int ret = 0;
1042f1d65583SLuciano Coelho 
1043f1d65583SLuciano Coelho 	if (!check_sdata_in_driver(sdata))
1044f1d65583SLuciano Coelho 		return -EIO;
1045f1d65583SLuciano Coelho 
1046f1d65583SLuciano Coelho 	trace_drv_post_channel_switch(local, sdata);
1047f1d65583SLuciano Coelho 	if (local->ops->post_channel_switch)
1048f1d65583SLuciano Coelho 		ret = local->ops->post_channel_switch(&local->hw, &sdata->vif);
1049f1d65583SLuciano Coelho 	trace_drv_return_int(local, ret);
1050f1d65583SLuciano Coelho 	return ret;
1051f1d65583SLuciano Coelho }
1052f1d65583SLuciano Coelho 
105355fff501SJohannes Berg static inline int drv_join_ibss(struct ieee80211_local *local,
105455fff501SJohannes Berg 				struct ieee80211_sub_if_data *sdata)
105555fff501SJohannes Berg {
105655fff501SJohannes Berg 	int ret = 0;
105755fff501SJohannes Berg 
105855fff501SJohannes Berg 	might_sleep();
1059f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
1060f6837ba8SJohannes Berg 		return -EIO;
106155fff501SJohannes Berg 
106255fff501SJohannes Berg 	trace_drv_join_ibss(local, sdata, &sdata->vif.bss_conf);
106355fff501SJohannes Berg 	if (local->ops->join_ibss)
106455fff501SJohannes Berg 		ret = local->ops->join_ibss(&local->hw, &sdata->vif);
106555fff501SJohannes Berg 	trace_drv_return_int(local, ret);
106655fff501SJohannes Berg 	return ret;
106755fff501SJohannes Berg }
106855fff501SJohannes Berg 
106955fff501SJohannes Berg static inline void drv_leave_ibss(struct ieee80211_local *local,
107055fff501SJohannes Berg 				  struct ieee80211_sub_if_data *sdata)
107155fff501SJohannes Berg {
107255fff501SJohannes Berg 	might_sleep();
1073f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
1074f6837ba8SJohannes Berg 		return;
107555fff501SJohannes Berg 
107655fff501SJohannes Berg 	trace_drv_leave_ibss(local, sdata);
107755fff501SJohannes Berg 	if (local->ops->leave_ibss)
107855fff501SJohannes Berg 		local->ops->leave_ibss(&local->hw, &sdata->vif);
107955fff501SJohannes Berg 	trace_drv_return_void(local);
108055fff501SJohannes Berg }
108155fff501SJohannes Berg 
1082cca674d4SAntonio Quartulli static inline u32 drv_get_expected_throughput(struct ieee80211_local *local,
10834fdbc67aSMaxim Altshul 					      struct sta_info *sta)
1084cca674d4SAntonio Quartulli {
1085cca674d4SAntonio Quartulli 	u32 ret = 0;
1086cca674d4SAntonio Quartulli 
10874fdbc67aSMaxim Altshul 	trace_drv_get_expected_throughput(&sta->sta);
10884fdbc67aSMaxim Altshul 	if (local->ops->get_expected_throughput && sta->uploaded)
10894fdbc67aSMaxim Altshul 		ret = local->ops->get_expected_throughput(&local->hw, &sta->sta);
1090cca674d4SAntonio Quartulli 	trace_drv_return_u32(local, ret);
1091cca674d4SAntonio Quartulli 
1092cca674d4SAntonio Quartulli 	return ret;
1093cca674d4SAntonio Quartulli }
1094cca674d4SAntonio Quartulli 
10955b3dc42bSFelix Fietkau static inline int drv_get_txpower(struct ieee80211_local *local,
10965b3dc42bSFelix Fietkau 				  struct ieee80211_sub_if_data *sdata, int *dbm)
10975b3dc42bSFelix Fietkau {
10985b3dc42bSFelix Fietkau 	int ret;
10995b3dc42bSFelix Fietkau 
11005b3dc42bSFelix Fietkau 	if (!local->ops->get_txpower)
11015b3dc42bSFelix Fietkau 		return -EOPNOTSUPP;
11025b3dc42bSFelix Fietkau 
11035b3dc42bSFelix Fietkau 	ret = local->ops->get_txpower(&local->hw, &sdata->vif, dbm);
11045b3dc42bSFelix Fietkau 	trace_drv_get_txpower(local, sdata, *dbm, ret);
11055b3dc42bSFelix Fietkau 
11065b3dc42bSFelix Fietkau 	return ret;
11075b3dc42bSFelix Fietkau }
11085b3dc42bSFelix Fietkau 
1109a7a6bdd0SArik Nemtsov static inline int
1110a7a6bdd0SArik Nemtsov drv_tdls_channel_switch(struct ieee80211_local *local,
1111a7a6bdd0SArik Nemtsov 			struct ieee80211_sub_if_data *sdata,
1112a7a6bdd0SArik Nemtsov 			struct ieee80211_sta *sta, u8 oper_class,
1113a7a6bdd0SArik Nemtsov 			struct cfg80211_chan_def *chandef,
1114a7a6bdd0SArik Nemtsov 			struct sk_buff *tmpl_skb, u32 ch_sw_tm_ie)
1115a7a6bdd0SArik Nemtsov {
1116a7a6bdd0SArik Nemtsov 	int ret;
1117a7a6bdd0SArik Nemtsov 
1118a7a6bdd0SArik Nemtsov 	might_sleep();
1119a7a6bdd0SArik Nemtsov 	if (!check_sdata_in_driver(sdata))
1120a7a6bdd0SArik Nemtsov 		return -EIO;
1121a7a6bdd0SArik Nemtsov 
1122a7a6bdd0SArik Nemtsov 	if (!local->ops->tdls_channel_switch)
1123a7a6bdd0SArik Nemtsov 		return -EOPNOTSUPP;
1124a7a6bdd0SArik Nemtsov 
1125a7a6bdd0SArik Nemtsov 	trace_drv_tdls_channel_switch(local, sdata, sta, oper_class, chandef);
1126a7a6bdd0SArik Nemtsov 	ret = local->ops->tdls_channel_switch(&local->hw, &sdata->vif, sta,
1127a7a6bdd0SArik Nemtsov 					      oper_class, chandef, tmpl_skb,
1128a7a6bdd0SArik Nemtsov 					      ch_sw_tm_ie);
1129a7a6bdd0SArik Nemtsov 	trace_drv_return_int(local, ret);
1130a7a6bdd0SArik Nemtsov 	return ret;
1131a7a6bdd0SArik Nemtsov }
1132a7a6bdd0SArik Nemtsov 
1133a7a6bdd0SArik Nemtsov static inline void
1134a7a6bdd0SArik Nemtsov drv_tdls_cancel_channel_switch(struct ieee80211_local *local,
1135a7a6bdd0SArik Nemtsov 			       struct ieee80211_sub_if_data *sdata,
1136a7a6bdd0SArik Nemtsov 			       struct ieee80211_sta *sta)
1137a7a6bdd0SArik Nemtsov {
1138a7a6bdd0SArik Nemtsov 	might_sleep();
1139a7a6bdd0SArik Nemtsov 	if (!check_sdata_in_driver(sdata))
1140a7a6bdd0SArik Nemtsov 		return;
1141a7a6bdd0SArik Nemtsov 
1142a7a6bdd0SArik Nemtsov 	if (!local->ops->tdls_cancel_channel_switch)
1143a7a6bdd0SArik Nemtsov 		return;
1144a7a6bdd0SArik Nemtsov 
1145a7a6bdd0SArik Nemtsov 	trace_drv_tdls_cancel_channel_switch(local, sdata, sta);
1146a7a6bdd0SArik Nemtsov 	local->ops->tdls_cancel_channel_switch(&local->hw, &sdata->vif, sta);
1147a7a6bdd0SArik Nemtsov 	trace_drv_return_void(local);
1148a7a6bdd0SArik Nemtsov }
1149a7a6bdd0SArik Nemtsov 
11508a4d32f3SArik Nemtsov static inline void
11518a4d32f3SArik Nemtsov drv_tdls_recv_channel_switch(struct ieee80211_local *local,
11528a4d32f3SArik Nemtsov 			     struct ieee80211_sub_if_data *sdata,
11538a4d32f3SArik Nemtsov 			     struct ieee80211_tdls_ch_sw_params *params)
11548a4d32f3SArik Nemtsov {
11558a4d32f3SArik Nemtsov 	trace_drv_tdls_recv_channel_switch(local, sdata, params);
11568a4d32f3SArik Nemtsov 	if (local->ops->tdls_recv_channel_switch)
11578a4d32f3SArik Nemtsov 		local->ops->tdls_recv_channel_switch(&local->hw, &sdata->vif,
11588a4d32f3SArik Nemtsov 						     params);
11598a4d32f3SArik Nemtsov 	trace_drv_return_void(local);
11608a4d32f3SArik Nemtsov }
11618a4d32f3SArik Nemtsov 
1162e7881bd5SJohannes Berg static inline void drv_wake_tx_queue(struct ieee80211_local *local,
1163e7881bd5SJohannes Berg 				     struct txq_info *txq)
1164ba8c3d6fSFelix Fietkau {
1165e7881bd5SJohannes Berg 	struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->txq.vif);
1166e7881bd5SJohannes Berg 
1167e7881bd5SJohannes Berg 	if (!check_sdata_in_driver(sdata))
1168e7881bd5SJohannes Berg 		return;
1169e7881bd5SJohannes Berg 
1170e7881bd5SJohannes Berg 	trace_drv_wake_tx_queue(local, sdata, txq);
1171e7881bd5SJohannes Berg 	local->ops->wake_tx_queue(&local->hw, &txq->txq);
1172ba8c3d6fSFelix Fietkau }
1173ba8c3d6fSFelix Fietkau 
1174708d50edSAyala Beker static inline int drv_start_nan(struct ieee80211_local *local,
1175708d50edSAyala Beker 				struct ieee80211_sub_if_data *sdata,
1176708d50edSAyala Beker 				struct cfg80211_nan_conf *conf)
1177708d50edSAyala Beker {
1178708d50edSAyala Beker 	int ret;
1179708d50edSAyala Beker 
1180708d50edSAyala Beker 	might_sleep();
1181708d50edSAyala Beker 	check_sdata_in_driver(sdata);
1182708d50edSAyala Beker 
1183708d50edSAyala Beker 	trace_drv_start_nan(local, sdata, conf);
1184708d50edSAyala Beker 	ret = local->ops->start_nan(&local->hw, &sdata->vif, conf);
1185708d50edSAyala Beker 	trace_drv_return_int(local, ret);
1186708d50edSAyala Beker 	return ret;
1187708d50edSAyala Beker }
1188708d50edSAyala Beker 
1189708d50edSAyala Beker static inline void drv_stop_nan(struct ieee80211_local *local,
1190708d50edSAyala Beker 				struct ieee80211_sub_if_data *sdata)
1191708d50edSAyala Beker {
1192708d50edSAyala Beker 	might_sleep();
1193708d50edSAyala Beker 	check_sdata_in_driver(sdata);
1194708d50edSAyala Beker 
1195708d50edSAyala Beker 	trace_drv_stop_nan(local, sdata);
1196708d50edSAyala Beker 	local->ops->stop_nan(&local->hw, &sdata->vif);
1197708d50edSAyala Beker 	trace_drv_return_void(local);
1198708d50edSAyala Beker }
1199708d50edSAyala Beker 
12005953ff6dSAyala Beker static inline int drv_nan_change_conf(struct ieee80211_local *local,
12015953ff6dSAyala Beker 				       struct ieee80211_sub_if_data *sdata,
12025953ff6dSAyala Beker 				       struct cfg80211_nan_conf *conf,
12035953ff6dSAyala Beker 				       u32 changes)
12045953ff6dSAyala Beker {
12055953ff6dSAyala Beker 	int ret;
12065953ff6dSAyala Beker 
12075953ff6dSAyala Beker 	might_sleep();
12085953ff6dSAyala Beker 	check_sdata_in_driver(sdata);
12095953ff6dSAyala Beker 
12105953ff6dSAyala Beker 	if (!local->ops->nan_change_conf)
12115953ff6dSAyala Beker 		return -EOPNOTSUPP;
12125953ff6dSAyala Beker 
12135953ff6dSAyala Beker 	trace_drv_nan_change_conf(local, sdata, conf, changes);
12145953ff6dSAyala Beker 	ret = local->ops->nan_change_conf(&local->hw, &sdata->vif, conf,
12155953ff6dSAyala Beker 					  changes);
12165953ff6dSAyala Beker 	trace_drv_return_int(local, ret);
12175953ff6dSAyala Beker 
12185953ff6dSAyala Beker 	return ret;
12195953ff6dSAyala Beker }
12205953ff6dSAyala Beker 
1221167e33f4SAyala Beker static inline int drv_add_nan_func(struct ieee80211_local *local,
1222167e33f4SAyala Beker 				   struct ieee80211_sub_if_data *sdata,
1223167e33f4SAyala Beker 				   const struct cfg80211_nan_func *nan_func)
1224167e33f4SAyala Beker {
1225167e33f4SAyala Beker 	int ret;
1226167e33f4SAyala Beker 
1227167e33f4SAyala Beker 	might_sleep();
1228167e33f4SAyala Beker 	check_sdata_in_driver(sdata);
1229167e33f4SAyala Beker 
1230167e33f4SAyala Beker 	if (!local->ops->add_nan_func)
1231167e33f4SAyala Beker 		return -EOPNOTSUPP;
1232167e33f4SAyala Beker 
1233167e33f4SAyala Beker 	trace_drv_add_nan_func(local, sdata, nan_func);
1234167e33f4SAyala Beker 	ret = local->ops->add_nan_func(&local->hw, &sdata->vif, nan_func);
1235167e33f4SAyala Beker 	trace_drv_return_int(local, ret);
1236167e33f4SAyala Beker 
1237167e33f4SAyala Beker 	return ret;
1238167e33f4SAyala Beker }
1239167e33f4SAyala Beker 
1240167e33f4SAyala Beker static inline void drv_del_nan_func(struct ieee80211_local *local,
1241167e33f4SAyala Beker 				   struct ieee80211_sub_if_data *sdata,
1242167e33f4SAyala Beker 				   u8 instance_id)
1243167e33f4SAyala Beker {
1244167e33f4SAyala Beker 	might_sleep();
1245167e33f4SAyala Beker 	check_sdata_in_driver(sdata);
1246167e33f4SAyala Beker 
1247167e33f4SAyala Beker 	trace_drv_del_nan_func(local, sdata, instance_id);
1248167e33f4SAyala Beker 	if (local->ops->del_nan_func)
1249167e33f4SAyala Beker 		local->ops->del_nan_func(&local->hw, &sdata->vif, instance_id);
1250167e33f4SAyala Beker 	trace_drv_return_void(local);
1251167e33f4SAyala Beker }
1252167e33f4SAyala Beker 
125324487981SJohannes Berg #endif /* __MAC80211_DRIVER_OPS */
1254