xref: /openbmc/linux/net/mac80211/driver-ops.h (revision d787a3e3)
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
515fae341SJohannes Berg * Copyright (C) 2018 - 2019, 2021 Intel Corporation
6f59374ebSSara Sharon */
7f59374ebSSara Sharon 
824487981SJohannes Berg #ifndef __MAC80211_DRIVER_OPS
924487981SJohannes Berg #define __MAC80211_DRIVER_OPS
1024487981SJohannes Berg 
1124487981SJohannes Berg #include <net/mac80211.h>
1224487981SJohannes Berg #include "ieee80211_i.h"
13011ad0e9SJohannes Berg #include "trace.h"
1424487981SJohannes Berg 
15c8ad0106SJohannes Berg #define check_sdata_in_driver(sdata)	({					\
16c8ad0106SJohannes Berg 	!WARN_ONCE(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER),			\
17c8ad0106SJohannes Berg 		   "%s: Failed check-sdata-in-driver check, flags: 0x%x\n",	\
18c8ad0106SJohannes Berg 		   sdata->dev ? sdata->dev->name : sdata->name, sdata->flags);	\
19c8ad0106SJohannes 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 
531ba905bf4SAshok Raj Nagarajan __must_check
532ba905bf4SAshok Raj Nagarajan int drv_sta_set_txpwr(struct ieee80211_local *local,
533ba905bf4SAshok Raj Nagarajan 		      struct ieee80211_sub_if_data *sdata,
534ba905bf4SAshok Raj Nagarajan 		      struct sta_info *sta);
535ba905bf4SAshok Raj Nagarajan 
5364fbd572cSDenys Vlasenko void drv_sta_rc_update(struct ieee80211_local *local,
5378f727ef3SJohannes Berg 		       struct ieee80211_sub_if_data *sdata,
5384fbd572cSDenys Vlasenko 		       struct ieee80211_sta *sta, u32 changed);
5398f727ef3SJohannes Berg 
540f815e2b3SJohannes Berg static inline void drv_sta_rate_tbl_update(struct ieee80211_local *local,
541f815e2b3SJohannes Berg 					   struct ieee80211_sub_if_data *sdata,
542f815e2b3SJohannes Berg 					   struct ieee80211_sta *sta)
543f815e2b3SJohannes Berg {
544f815e2b3SJohannes Berg 	sdata = get_bss_sdata(sdata);
545f815e2b3SJohannes Berg 	if (!check_sdata_in_driver(sdata))
546f815e2b3SJohannes Berg 		return;
547f815e2b3SJohannes Berg 
548f815e2b3SJohannes Berg 	trace_drv_sta_rate_tbl_update(local, sdata, sta);
549f815e2b3SJohannes Berg 	if (local->ops->sta_rate_tbl_update)
550f815e2b3SJohannes Berg 		local->ops->sta_rate_tbl_update(&local->hw, &sdata->vif, sta);
551f815e2b3SJohannes Berg 
552f815e2b3SJohannes Berg 	trace_drv_return_void(local);
553f815e2b3SJohannes Berg }
554f815e2b3SJohannes Berg 
5552b9a7e1bSJohannes Berg static inline void drv_sta_statistics(struct ieee80211_local *local,
5562b9a7e1bSJohannes Berg 				      struct ieee80211_sub_if_data *sdata,
5572b9a7e1bSJohannes Berg 				      struct ieee80211_sta *sta,
5582b9a7e1bSJohannes Berg 				      struct station_info *sinfo)
5592b9a7e1bSJohannes Berg {
5602b9a7e1bSJohannes Berg 	sdata = get_bss_sdata(sdata);
5612b9a7e1bSJohannes Berg 	if (!check_sdata_in_driver(sdata))
5622b9a7e1bSJohannes Berg 		return;
5632b9a7e1bSJohannes Berg 
5642b9a7e1bSJohannes Berg 	trace_drv_sta_statistics(local, sdata, sta);
5652b9a7e1bSJohannes Berg 	if (local->ops->sta_statistics)
5662b9a7e1bSJohannes Berg 		local->ops->sta_statistics(&local->hw, &sdata->vif, sta, sinfo);
5672b9a7e1bSJohannes Berg 	trace_drv_return_void(local);
5682b9a7e1bSJohannes Berg }
5692b9a7e1bSJohannes Berg 
570b23dcd4aSDenys Vlasenko int drv_conf_tx(struct ieee80211_local *local,
571a3304b0aSJohannes Berg 		struct ieee80211_sub_if_data *sdata, u16 ac,
572b23dcd4aSDenys Vlasenko 		const struct ieee80211_tx_queue_params *params);
57324487981SJohannes Berg 
574416eb9fcSDenys Vlasenko u64 drv_get_tsf(struct ieee80211_local *local,
575416eb9fcSDenys Vlasenko 		struct ieee80211_sub_if_data *sdata);
576416eb9fcSDenys Vlasenko void drv_set_tsf(struct ieee80211_local *local,
57737a41b4aSEliad Peller 		 struct ieee80211_sub_if_data *sdata,
578416eb9fcSDenys Vlasenko 		 u64 tsf);
579354d381bSPedersen, Thomas void drv_offset_tsf(struct ieee80211_local *local,
580354d381bSPedersen, Thomas 		    struct ieee80211_sub_if_data *sdata,
581354d381bSPedersen, Thomas 		    s64 offset);
582416eb9fcSDenys Vlasenko void drv_reset_tsf(struct ieee80211_local *local,
583416eb9fcSDenys Vlasenko 		   struct ieee80211_sub_if_data *sdata);
58424487981SJohannes Berg 
58524487981SJohannes Berg static inline int drv_tx_last_beacon(struct ieee80211_local *local)
58624487981SJohannes Berg {
58702582e9bSMasanari Iida 	int ret = 0; /* default unsupported op for less congestion */
588e1781ed3SKalle Valo 
589e1781ed3SKalle Valo 	might_sleep();
590e1781ed3SKalle Valo 
5914efc76bdSJohannes Berg 	trace_drv_tx_last_beacon(local);
59224487981SJohannes Berg 	if (local->ops->tx_last_beacon)
5930a2b8bb2SJohannes Berg 		ret = local->ops->tx_last_beacon(&local->hw);
5944efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
5950a2b8bb2SJohannes Berg 	return ret;
59624487981SJohannes Berg }
59724487981SJohannes Berg 
5986db96838SDenys Vlasenko int drv_ampdu_action(struct ieee80211_local *local,
59912375ef9SJohannes Berg 		     struct ieee80211_sub_if_data *sdata,
60050ea05efSSara Sharon 		     struct ieee80211_ampdu_params *params);
6011f87f7d3SJohannes Berg 
6021289723eSHolger Schurig static inline int drv_get_survey(struct ieee80211_local *local, int idx,
6031289723eSHolger Schurig 				struct survey_info *survey)
6041289723eSHolger Schurig {
6051289723eSHolger Schurig 	int ret = -EOPNOTSUPP;
606c466d4efSJohn W. Linville 
607c466d4efSJohn W. Linville 	trace_drv_get_survey(local, idx, survey);
608c466d4efSJohn W. Linville 
60935dd0509SHolger Schurig 	if (local->ops->get_survey)
6101289723eSHolger Schurig 		ret = local->ops->get_survey(&local->hw, idx, survey);
611c466d4efSJohn W. Linville 
612c466d4efSJohn W. Linville 	trace_drv_return_int(local, ret);
613c466d4efSJohn W. Linville 
6141289723eSHolger Schurig 	return ret;
6151289723eSHolger Schurig }
6161f87f7d3SJohannes Berg 
6171f87f7d3SJohannes Berg static inline void drv_rfkill_poll(struct ieee80211_local *local)
6181f87f7d3SJohannes Berg {
619e1781ed3SKalle Valo 	might_sleep();
620e1781ed3SKalle Valo 
6211f87f7d3SJohannes Berg 	if (local->ops->rfkill_poll)
6221f87f7d3SJohannes Berg 		local->ops->rfkill_poll(&local->hw);
6231f87f7d3SJohannes Berg }
624a80f7c0bSJohannes Berg 
62539ecc01dSJohannes Berg static inline void drv_flush(struct ieee80211_local *local,
62677be2c54SEmmanuel Grumbach 			     struct ieee80211_sub_if_data *sdata,
62739ecc01dSJohannes Berg 			     u32 queues, bool drop)
628a80f7c0bSJohannes Berg {
62977be2c54SEmmanuel Grumbach 	struct ieee80211_vif *vif = sdata ? &sdata->vif : NULL;
63077be2c54SEmmanuel Grumbach 
631e1781ed3SKalle Valo 	might_sleep();
632e1781ed3SKalle Valo 
633f6837ba8SJohannes Berg 	if (sdata && !check_sdata_in_driver(sdata))
634f6837ba8SJohannes Berg 		return;
63577be2c54SEmmanuel Grumbach 
63639ecc01dSJohannes Berg 	trace_drv_flush(local, queues, drop);
637a80f7c0bSJohannes Berg 	if (local->ops->flush)
63877be2c54SEmmanuel Grumbach 		local->ops->flush(&local->hw, vif, queues, drop);
6394efc76bdSJohannes Berg 	trace_drv_return_void(local);
640a80f7c0bSJohannes Berg }
6415ce6e438SJohannes Berg 
6425ce6e438SJohannes Berg static inline void drv_channel_switch(struct ieee80211_local *local,
6430f791eb4SLuciano Coelho 				      struct ieee80211_sub_if_data *sdata,
6445ce6e438SJohannes Berg 				      struct ieee80211_channel_switch *ch_switch)
6455ce6e438SJohannes Berg {
6465ce6e438SJohannes Berg 	might_sleep();
6475ce6e438SJohannes Berg 
6480f791eb4SLuciano Coelho 	trace_drv_channel_switch(local, sdata, ch_switch);
6490f791eb4SLuciano Coelho 	local->ops->channel_switch(&local->hw, &sdata->vif, ch_switch);
6504efc76bdSJohannes Berg 	trace_drv_return_void(local);
6515ce6e438SJohannes Berg }
6525ce6e438SJohannes Berg 
65315d96753SBruno Randolf 
65415d96753SBruno Randolf static inline int drv_set_antenna(struct ieee80211_local *local,
65515d96753SBruno Randolf 				  u32 tx_ant, u32 rx_ant)
65615d96753SBruno Randolf {
65715d96753SBruno Randolf 	int ret = -EOPNOTSUPP;
65815d96753SBruno Randolf 	might_sleep();
65915d96753SBruno Randolf 	if (local->ops->set_antenna)
66015d96753SBruno Randolf 		ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant);
66115d96753SBruno Randolf 	trace_drv_set_antenna(local, tx_ant, rx_ant, ret);
66215d96753SBruno Randolf 	return ret;
66315d96753SBruno Randolf }
66415d96753SBruno Randolf 
66515d96753SBruno Randolf static inline int drv_get_antenna(struct ieee80211_local *local,
66615d96753SBruno Randolf 				  u32 *tx_ant, u32 *rx_ant)
66715d96753SBruno Randolf {
66815d96753SBruno Randolf 	int ret = -EOPNOTSUPP;
66915d96753SBruno Randolf 	might_sleep();
67015d96753SBruno Randolf 	if (local->ops->get_antenna)
67115d96753SBruno Randolf 		ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant);
67215d96753SBruno Randolf 	trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret);
67315d96753SBruno Randolf 	return ret;
67415d96753SBruno Randolf }
67515d96753SBruno Randolf 
67621f83589SJohannes Berg static inline int drv_remain_on_channel(struct ieee80211_local *local,
67749884568SEliad Peller 					struct ieee80211_sub_if_data *sdata,
67821f83589SJohannes Berg 					struct ieee80211_channel *chan,
679d339d5caSIlan Peer 					unsigned int duration,
680d339d5caSIlan Peer 					enum ieee80211_roc_type type)
68121f83589SJohannes Berg {
68221f83589SJohannes Berg 	int ret;
68321f83589SJohannes Berg 
68421f83589SJohannes Berg 	might_sleep();
68521f83589SJohannes Berg 
686d339d5caSIlan Peer 	trace_drv_remain_on_channel(local, sdata, chan, duration, type);
68749884568SEliad Peller 	ret = local->ops->remain_on_channel(&local->hw, &sdata->vif,
688d339d5caSIlan Peer 					    chan, duration, type);
68921f83589SJohannes Berg 	trace_drv_return_int(local, ret);
69021f83589SJohannes Berg 
69121f83589SJohannes Berg 	return ret;
69221f83589SJohannes Berg }
69321f83589SJohannes Berg 
6945db4c4b9SEmmanuel Grumbach static inline int
6955db4c4b9SEmmanuel Grumbach drv_cancel_remain_on_channel(struct ieee80211_local *local,
6965db4c4b9SEmmanuel Grumbach 			     struct ieee80211_sub_if_data *sdata)
69721f83589SJohannes Berg {
69821f83589SJohannes Berg 	int ret;
69921f83589SJohannes Berg 
70021f83589SJohannes Berg 	might_sleep();
70121f83589SJohannes Berg 
7025db4c4b9SEmmanuel Grumbach 	trace_drv_cancel_remain_on_channel(local, sdata);
7035db4c4b9SEmmanuel Grumbach 	ret = local->ops->cancel_remain_on_channel(&local->hw, &sdata->vif);
70421f83589SJohannes Berg 	trace_drv_return_int(local, ret);
70521f83589SJohannes Berg 
70621f83589SJohannes Berg 	return ret;
70721f83589SJohannes Berg }
70821f83589SJohannes Berg 
70938c09159SJohn W. Linville static inline int drv_set_ringparam(struct ieee80211_local *local,
71038c09159SJohn W. Linville 				    u32 tx, u32 rx)
71138c09159SJohn W. Linville {
71238c09159SJohn W. Linville 	int ret = -ENOTSUPP;
71338c09159SJohn W. Linville 
71438c09159SJohn W. Linville 	might_sleep();
71538c09159SJohn W. Linville 
71638c09159SJohn W. Linville 	trace_drv_set_ringparam(local, tx, rx);
71738c09159SJohn W. Linville 	if (local->ops->set_ringparam)
71838c09159SJohn W. Linville 		ret = local->ops->set_ringparam(&local->hw, tx, rx);
71938c09159SJohn W. Linville 	trace_drv_return_int(local, ret);
72038c09159SJohn W. Linville 
72138c09159SJohn W. Linville 	return ret;
72238c09159SJohn W. Linville }
72338c09159SJohn W. Linville 
72438c09159SJohn W. Linville static inline void drv_get_ringparam(struct ieee80211_local *local,
72538c09159SJohn W. Linville 				     u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
72638c09159SJohn W. Linville {
72738c09159SJohn W. Linville 	might_sleep();
72838c09159SJohn W. Linville 
72938c09159SJohn W. Linville 	trace_drv_get_ringparam(local, tx, tx_max, rx, rx_max);
73038c09159SJohn W. Linville 	if (local->ops->get_ringparam)
73138c09159SJohn W. Linville 		local->ops->get_ringparam(&local->hw, tx, tx_max, rx, rx_max);
73238c09159SJohn W. Linville 	trace_drv_return_void(local);
73338c09159SJohn W. Linville }
73438c09159SJohn W. Linville 
735e8306f98SVivek Natarajan static inline bool drv_tx_frames_pending(struct ieee80211_local *local)
736e8306f98SVivek Natarajan {
737e8306f98SVivek Natarajan 	bool ret = false;
738e8306f98SVivek Natarajan 
739e8306f98SVivek Natarajan 	might_sleep();
740e8306f98SVivek Natarajan 
741e8306f98SVivek Natarajan 	trace_drv_tx_frames_pending(local);
742e8306f98SVivek Natarajan 	if (local->ops->tx_frames_pending)
743e8306f98SVivek Natarajan 		ret = local->ops->tx_frames_pending(&local->hw);
744e8306f98SVivek Natarajan 	trace_drv_return_bool(local, ret);
745e8306f98SVivek Natarajan 
746e8306f98SVivek Natarajan 	return ret;
747e8306f98SVivek Natarajan }
748bdbfd6b5SSujith Manoharan 
749bdbfd6b5SSujith Manoharan static inline int drv_set_bitrate_mask(struct ieee80211_local *local,
750bdbfd6b5SSujith Manoharan 				       struct ieee80211_sub_if_data *sdata,
751bdbfd6b5SSujith Manoharan 				       const struct cfg80211_bitrate_mask *mask)
752bdbfd6b5SSujith Manoharan {
753bdbfd6b5SSujith Manoharan 	int ret = -EOPNOTSUPP;
754bdbfd6b5SSujith Manoharan 
755bdbfd6b5SSujith Manoharan 	might_sleep();
756bdbfd6b5SSujith Manoharan 
757f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
758f6837ba8SJohannes Berg 		return -EIO;
7597b7eab6fSJohannes Berg 
760bdbfd6b5SSujith Manoharan 	trace_drv_set_bitrate_mask(local, sdata, mask);
761bdbfd6b5SSujith Manoharan 	if (local->ops->set_bitrate_mask)
762bdbfd6b5SSujith Manoharan 		ret = local->ops->set_bitrate_mask(&local->hw,
763bdbfd6b5SSujith Manoharan 						   &sdata->vif, mask);
764bdbfd6b5SSujith Manoharan 	trace_drv_return_int(local, ret);
765bdbfd6b5SSujith Manoharan 
766bdbfd6b5SSujith Manoharan 	return ret;
767bdbfd6b5SSujith Manoharan }
768bdbfd6b5SSujith Manoharan 
769c68f4b89SJohannes Berg static inline void drv_set_rekey_data(struct ieee80211_local *local,
770c68f4b89SJohannes Berg 				      struct ieee80211_sub_if_data *sdata,
771c68f4b89SJohannes Berg 				      struct cfg80211_gtk_rekey_data *data)
772c68f4b89SJohannes Berg {
773f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
774f6837ba8SJohannes Berg 		return;
7757b7eab6fSJohannes Berg 
776c68f4b89SJohannes Berg 	trace_drv_set_rekey_data(local, sdata, data);
777c68f4b89SJohannes Berg 	if (local->ops->set_rekey_data)
778c68f4b89SJohannes Berg 		local->ops->set_rekey_data(&local->hw, &sdata->vif, data);
779c68f4b89SJohannes Berg 	trace_drv_return_void(local);
780c68f4b89SJohannes Berg }
781c68f4b89SJohannes Berg 
782a8182929SEmmanuel Grumbach static inline void drv_event_callback(struct ieee80211_local *local,
783887da917SEmmanuel Grumbach 				      struct ieee80211_sub_if_data *sdata,
784a8182929SEmmanuel Grumbach 				      const struct ieee80211_event *event)
785615f7b9bSMeenakshi Venkataraman {
786a8182929SEmmanuel Grumbach 	trace_drv_event_callback(local, sdata, event);
787a8182929SEmmanuel Grumbach 	if (local->ops->event_callback)
788a8182929SEmmanuel Grumbach 		local->ops->event_callback(&local->hw, &sdata->vif, event);
789615f7b9bSMeenakshi Venkataraman 	trace_drv_return_void(local);
790615f7b9bSMeenakshi Venkataraman }
7914049e09aSJohannes Berg 
7924049e09aSJohannes Berg static inline void
7934049e09aSJohannes Berg drv_release_buffered_frames(struct ieee80211_local *local,
7944049e09aSJohannes Berg 			    struct sta_info *sta, u16 tids, int num_frames,
7954049e09aSJohannes Berg 			    enum ieee80211_frame_release_type reason,
7964049e09aSJohannes Berg 			    bool more_data)
7974049e09aSJohannes Berg {
7984049e09aSJohannes Berg 	trace_drv_release_buffered_frames(local, &sta->sta, tids, num_frames,
7994049e09aSJohannes Berg 					  reason, more_data);
8004049e09aSJohannes Berg 	if (local->ops->release_buffered_frames)
8014049e09aSJohannes Berg 		local->ops->release_buffered_frames(&local->hw, &sta->sta, tids,
8024049e09aSJohannes Berg 						    num_frames, reason,
8034049e09aSJohannes Berg 						    more_data);
8044049e09aSJohannes Berg 	trace_drv_return_void(local);
8054049e09aSJohannes Berg }
80640b96408SJohannes Berg 
80740b96408SJohannes Berg static inline void
80840b96408SJohannes Berg drv_allow_buffered_frames(struct ieee80211_local *local,
80940b96408SJohannes Berg 			  struct sta_info *sta, u16 tids, int num_frames,
81040b96408SJohannes Berg 			  enum ieee80211_frame_release_type reason,
81140b96408SJohannes Berg 			  bool more_data)
81240b96408SJohannes Berg {
81340b96408SJohannes Berg 	trace_drv_allow_buffered_frames(local, &sta->sta, tids, num_frames,
81440b96408SJohannes Berg 					reason, more_data);
81540b96408SJohannes Berg 	if (local->ops->allow_buffered_frames)
81640b96408SJohannes Berg 		local->ops->allow_buffered_frames(&local->hw, &sta->sta,
81740b96408SJohannes Berg 						  tids, num_frames, reason,
81840b96408SJohannes Berg 						  more_data);
81940b96408SJohannes Berg 	trace_drv_return_void(local);
82040b96408SJohannes Berg }
82166572cfcSVictor Goldenshtein 
822a1845fc7SJohannes Berg static inline void drv_mgd_prepare_tx(struct ieee80211_local *local,
823d4e36e55SIlan Peer 				      struct ieee80211_sub_if_data *sdata,
82415fae341SJohannes Berg 				      struct ieee80211_prep_tx_info *info)
825a1845fc7SJohannes Berg {
826a1845fc7SJohannes Berg 	might_sleep();
827a1845fc7SJohannes Berg 
828f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
829f6837ba8SJohannes Berg 		return;
830a1845fc7SJohannes Berg 	WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
831a1845fc7SJohannes Berg 
83215fae341SJohannes Berg 	trace_drv_mgd_prepare_tx(local, sdata, info->duration,
83315fae341SJohannes Berg 				 info->subtype, info->success);
834a1845fc7SJohannes Berg 	if (local->ops->mgd_prepare_tx)
83515fae341SJohannes Berg 		local->ops->mgd_prepare_tx(&local->hw, &sdata->vif, info);
83615fae341SJohannes Berg 	trace_drv_return_void(local);
83715fae341SJohannes Berg }
83815fae341SJohannes Berg 
83915fae341SJohannes Berg static inline void drv_mgd_complete_tx(struct ieee80211_local *local,
84015fae341SJohannes Berg 				       struct ieee80211_sub_if_data *sdata,
84115fae341SJohannes Berg 				       struct ieee80211_prep_tx_info *info)
84215fae341SJohannes Berg {
84315fae341SJohannes Berg 	might_sleep();
84415fae341SJohannes Berg 
84515fae341SJohannes Berg 	if (!check_sdata_in_driver(sdata))
84615fae341SJohannes Berg 		return;
84715fae341SJohannes Berg 	WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
84815fae341SJohannes Berg 
84915fae341SJohannes Berg 	trace_drv_mgd_complete_tx(local, sdata, info->duration,
85015fae341SJohannes Berg 				  info->subtype, info->success);
85115fae341SJohannes Berg 	if (local->ops->mgd_complete_tx)
85215fae341SJohannes Berg 		local->ops->mgd_complete_tx(&local->hw, &sdata->vif, info);
853a1845fc7SJohannes Berg 	trace_drv_return_void(local);
854a1845fc7SJohannes Berg }
855c3645eacSMichal Kazior 
856ee10f2c7SArik Nemtsov static inline void
857ee10f2c7SArik Nemtsov drv_mgd_protect_tdls_discover(struct ieee80211_local *local,
858ee10f2c7SArik Nemtsov 			      struct ieee80211_sub_if_data *sdata)
859ee10f2c7SArik Nemtsov {
860ee10f2c7SArik Nemtsov 	might_sleep();
861ee10f2c7SArik Nemtsov 
862ee10f2c7SArik Nemtsov 	if (!check_sdata_in_driver(sdata))
863ee10f2c7SArik Nemtsov 		return;
864ee10f2c7SArik Nemtsov 	WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
865ee10f2c7SArik Nemtsov 
866ee10f2c7SArik Nemtsov 	trace_drv_mgd_protect_tdls_discover(local, sdata);
867ee10f2c7SArik Nemtsov 	if (local->ops->mgd_protect_tdls_discover)
868ee10f2c7SArik Nemtsov 		local->ops->mgd_protect_tdls_discover(&local->hw, &sdata->vif);
869ee10f2c7SArik Nemtsov 	trace_drv_return_void(local);
870ee10f2c7SArik Nemtsov }
871ee10f2c7SArik Nemtsov 
872c3645eacSMichal Kazior static inline int drv_add_chanctx(struct ieee80211_local *local,
873c3645eacSMichal Kazior 				  struct ieee80211_chanctx *ctx)
874c3645eacSMichal Kazior {
875c3645eacSMichal Kazior 	int ret = -EOPNOTSUPP;
876c3645eacSMichal Kazior 
877dcae9e02SChaitanya T K 	might_sleep();
878dcae9e02SChaitanya T K 
879c3645eacSMichal Kazior 	trace_drv_add_chanctx(local, ctx);
880c3645eacSMichal Kazior 	if (local->ops->add_chanctx)
881c3645eacSMichal Kazior 		ret = local->ops->add_chanctx(&local->hw, &ctx->conf);
882c3645eacSMichal Kazior 	trace_drv_return_int(local, ret);
8838a61af65SJohannes Berg 	if (!ret)
8848a61af65SJohannes Berg 		ctx->driver_present = true;
885c3645eacSMichal Kazior 
886c3645eacSMichal Kazior 	return ret;
887c3645eacSMichal Kazior }
888c3645eacSMichal Kazior 
889c3645eacSMichal Kazior static inline void drv_remove_chanctx(struct ieee80211_local *local,
890c3645eacSMichal Kazior 				      struct ieee80211_chanctx *ctx)
891c3645eacSMichal Kazior {
892dcae9e02SChaitanya T K 	might_sleep();
893dcae9e02SChaitanya T K 
894f6837ba8SJohannes Berg 	if (WARN_ON(!ctx->driver_present))
895f6837ba8SJohannes Berg 		return;
896f6837ba8SJohannes Berg 
897c3645eacSMichal Kazior 	trace_drv_remove_chanctx(local, ctx);
898c3645eacSMichal Kazior 	if (local->ops->remove_chanctx)
899c3645eacSMichal Kazior 		local->ops->remove_chanctx(&local->hw, &ctx->conf);
900c3645eacSMichal Kazior 	trace_drv_return_void(local);
9018a61af65SJohannes Berg 	ctx->driver_present = false;
902c3645eacSMichal Kazior }
903c3645eacSMichal Kazior 
904c3645eacSMichal Kazior static inline void drv_change_chanctx(struct ieee80211_local *local,
905c3645eacSMichal Kazior 				      struct ieee80211_chanctx *ctx,
906c3645eacSMichal Kazior 				      u32 changed)
907c3645eacSMichal Kazior {
908dcae9e02SChaitanya T K 	might_sleep();
909dcae9e02SChaitanya T K 
910c3645eacSMichal Kazior 	trace_drv_change_chanctx(local, ctx, changed);
9118a61af65SJohannes Berg 	if (local->ops->change_chanctx) {
9128a61af65SJohannes Berg 		WARN_ON_ONCE(!ctx->driver_present);
913c3645eacSMichal Kazior 		local->ops->change_chanctx(&local->hw, &ctx->conf, changed);
9148a61af65SJohannes Berg 	}
915c3645eacSMichal Kazior 	trace_drv_return_void(local);
916c3645eacSMichal Kazior }
917c3645eacSMichal Kazior 
918c3645eacSMichal Kazior static inline int drv_assign_vif_chanctx(struct ieee80211_local *local,
919c3645eacSMichal Kazior 					 struct ieee80211_sub_if_data *sdata,
920c3645eacSMichal Kazior 					 struct ieee80211_chanctx *ctx)
921c3645eacSMichal Kazior {
922c3645eacSMichal Kazior 	int ret = 0;
923c3645eacSMichal Kazior 
924f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
925f6837ba8SJohannes Berg 		return -EIO;
926c3645eacSMichal Kazior 
927c3645eacSMichal Kazior 	trace_drv_assign_vif_chanctx(local, sdata, ctx);
9288a61af65SJohannes Berg 	if (local->ops->assign_vif_chanctx) {
9298a61af65SJohannes Berg 		WARN_ON_ONCE(!ctx->driver_present);
930c3645eacSMichal Kazior 		ret = local->ops->assign_vif_chanctx(&local->hw,
931c3645eacSMichal Kazior 						     &sdata->vif,
932c3645eacSMichal Kazior 						     &ctx->conf);
9338a61af65SJohannes Berg 	}
934c3645eacSMichal Kazior 	trace_drv_return_int(local, ret);
935c3645eacSMichal Kazior 
936c3645eacSMichal Kazior 	return ret;
937c3645eacSMichal Kazior }
938c3645eacSMichal Kazior 
939c3645eacSMichal Kazior static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local,
940c3645eacSMichal Kazior 					    struct ieee80211_sub_if_data *sdata,
941c3645eacSMichal Kazior 					    struct ieee80211_chanctx *ctx)
942c3645eacSMichal Kazior {
943dcae9e02SChaitanya T K 	might_sleep();
944dcae9e02SChaitanya T K 
945f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
946f6837ba8SJohannes Berg 		return;
947c3645eacSMichal Kazior 
948c3645eacSMichal Kazior 	trace_drv_unassign_vif_chanctx(local, sdata, ctx);
9498a61af65SJohannes Berg 	if (local->ops->unassign_vif_chanctx) {
9508a61af65SJohannes Berg 		WARN_ON_ONCE(!ctx->driver_present);
951c3645eacSMichal Kazior 		local->ops->unassign_vif_chanctx(&local->hw,
952c3645eacSMichal Kazior 						 &sdata->vif,
953c3645eacSMichal Kazior 						 &ctx->conf);
9548a61af65SJohannes Berg 	}
955c3645eacSMichal Kazior 	trace_drv_return_void(local);
956c3645eacSMichal Kazior }
957c3645eacSMichal Kazior 
95842677ed3SDenys Vlasenko int drv_switch_vif_chanctx(struct ieee80211_local *local,
9591a5f0c13SLuciano Coelho 			   struct ieee80211_vif_chanctx_switch *vifs,
96042677ed3SDenys Vlasenko 			   int n_vifs, enum ieee80211_chanctx_switch_mode mode);
9611a5f0c13SLuciano Coelho 
9621041638fSJohannes Berg static inline int drv_start_ap(struct ieee80211_local *local,
9631041638fSJohannes Berg 			       struct ieee80211_sub_if_data *sdata)
9641041638fSJohannes Berg {
9651041638fSJohannes Berg 	int ret = 0;
9661041638fSJohannes Berg 
967dcae9e02SChaitanya T K 	might_sleep();
968dcae9e02SChaitanya T K 
969f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
970f6837ba8SJohannes Berg 		return -EIO;
9711041638fSJohannes Berg 
9721041638fSJohannes Berg 	trace_drv_start_ap(local, sdata, &sdata->vif.bss_conf);
9731041638fSJohannes Berg 	if (local->ops->start_ap)
9741041638fSJohannes Berg 		ret = local->ops->start_ap(&local->hw, &sdata->vif);
9751041638fSJohannes Berg 	trace_drv_return_int(local, ret);
9761041638fSJohannes Berg 	return ret;
9771041638fSJohannes Berg }
9781041638fSJohannes Berg 
9791041638fSJohannes Berg static inline void drv_stop_ap(struct ieee80211_local *local,
9801041638fSJohannes Berg 			       struct ieee80211_sub_if_data *sdata)
9811041638fSJohannes Berg {
982f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
983f6837ba8SJohannes Berg 		return;
9841041638fSJohannes Berg 
9851041638fSJohannes Berg 	trace_drv_stop_ap(local, sdata);
9861041638fSJohannes Berg 	if (local->ops->stop_ap)
9871041638fSJohannes Berg 		local->ops->stop_ap(&local->hw, &sdata->vif);
9881041638fSJohannes Berg 	trace_drv_return_void(local);
9891041638fSJohannes Berg }
9901041638fSJohannes Berg 
991cf2c92d8SEliad Peller static inline void
992cf2c92d8SEliad Peller drv_reconfig_complete(struct ieee80211_local *local,
993cf2c92d8SEliad Peller 		      enum ieee80211_reconfig_type reconfig_type)
9949214ad7fSJohannes Berg {
9959214ad7fSJohannes Berg 	might_sleep();
9969214ad7fSJohannes Berg 
997cf2c92d8SEliad Peller 	trace_drv_reconfig_complete(local, reconfig_type);
998cf2c92d8SEliad Peller 	if (local->ops->reconfig_complete)
999cf2c92d8SEliad Peller 		local->ops->reconfig_complete(&local->hw, reconfig_type);
10009214ad7fSJohannes Berg 	trace_drv_return_void(local);
10019214ad7fSJohannes Berg }
10029214ad7fSJohannes Berg 
1003de5fad81SYoni Divinsky static inline void
1004de5fad81SYoni Divinsky drv_set_default_unicast_key(struct ieee80211_local *local,
1005de5fad81SYoni Divinsky 			    struct ieee80211_sub_if_data *sdata,
1006de5fad81SYoni Divinsky 			    int key_idx)
1007de5fad81SYoni Divinsky {
1008f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
1009f6837ba8SJohannes Berg 		return;
1010de5fad81SYoni Divinsky 
1011de5fad81SYoni Divinsky 	WARN_ON_ONCE(key_idx < -1 || key_idx > 3);
1012de5fad81SYoni Divinsky 
1013de5fad81SYoni Divinsky 	trace_drv_set_default_unicast_key(local, sdata, key_idx);
1014de5fad81SYoni Divinsky 	if (local->ops->set_default_unicast_key)
1015de5fad81SYoni Divinsky 		local->ops->set_default_unicast_key(&local->hw, &sdata->vif,
1016de5fad81SYoni Divinsky 						    key_idx);
1017de5fad81SYoni Divinsky 	trace_drv_return_void(local);
1018de5fad81SYoni Divinsky }
1019de5fad81SYoni Divinsky 
1020a65240c1SJohannes Berg #if IS_ENABLED(CONFIG_IPV6)
1021a65240c1SJohannes Berg static inline void drv_ipv6_addr_change(struct ieee80211_local *local,
1022a65240c1SJohannes Berg 					struct ieee80211_sub_if_data *sdata,
1023a65240c1SJohannes Berg 					struct inet6_dev *idev)
1024a65240c1SJohannes Berg {
1025a65240c1SJohannes Berg 	trace_drv_ipv6_addr_change(local, sdata);
1026a65240c1SJohannes Berg 	if (local->ops->ipv6_addr_change)
1027a65240c1SJohannes Berg 		local->ops->ipv6_addr_change(&local->hw, &sdata->vif, idev);
1028a65240c1SJohannes Berg 	trace_drv_return_void(local);
1029a65240c1SJohannes Berg }
1030a65240c1SJohannes Berg #endif
1031a65240c1SJohannes Berg 
103273da7d5bSSimon Wunderlich static inline void
103373da7d5bSSimon Wunderlich drv_channel_switch_beacon(struct ieee80211_sub_if_data *sdata,
103473da7d5bSSimon Wunderlich 			  struct cfg80211_chan_def *chandef)
103573da7d5bSSimon Wunderlich {
103673da7d5bSSimon Wunderlich 	struct ieee80211_local *local = sdata->local;
103773da7d5bSSimon Wunderlich 
103873da7d5bSSimon Wunderlich 	if (local->ops->channel_switch_beacon) {
103973da7d5bSSimon Wunderlich 		trace_drv_channel_switch_beacon(local, sdata, chandef);
104073da7d5bSSimon Wunderlich 		local->ops->channel_switch_beacon(&local->hw, &sdata->vif,
104173da7d5bSSimon Wunderlich 						  chandef);
104273da7d5bSSimon Wunderlich 	}
104373da7d5bSSimon Wunderlich }
104473da7d5bSSimon Wunderlich 
10456d027bccSLuciano Coelho static inline int
10466d027bccSLuciano Coelho drv_pre_channel_switch(struct ieee80211_sub_if_data *sdata,
10476d027bccSLuciano Coelho 		       struct ieee80211_channel_switch *ch_switch)
10486d027bccSLuciano Coelho {
10496d027bccSLuciano Coelho 	struct ieee80211_local *local = sdata->local;
10506d027bccSLuciano Coelho 	int ret = 0;
10516d027bccSLuciano Coelho 
10526d027bccSLuciano Coelho 	if (!check_sdata_in_driver(sdata))
10536d027bccSLuciano Coelho 		return -EIO;
10546d027bccSLuciano Coelho 
10556d027bccSLuciano Coelho 	trace_drv_pre_channel_switch(local, sdata, ch_switch);
10566d027bccSLuciano Coelho 	if (local->ops->pre_channel_switch)
10576d027bccSLuciano Coelho 		ret = local->ops->pre_channel_switch(&local->hw, &sdata->vif,
10586d027bccSLuciano Coelho 						     ch_switch);
10596d027bccSLuciano Coelho 	trace_drv_return_int(local, ret);
10606d027bccSLuciano Coelho 	return ret;
10616d027bccSLuciano Coelho }
10626d027bccSLuciano Coelho 
1063f1d65583SLuciano Coelho static inline int
1064f1d65583SLuciano Coelho drv_post_channel_switch(struct ieee80211_sub_if_data *sdata)
1065f1d65583SLuciano Coelho {
1066f1d65583SLuciano Coelho 	struct ieee80211_local *local = sdata->local;
1067f1d65583SLuciano Coelho 	int ret = 0;
1068f1d65583SLuciano Coelho 
1069f1d65583SLuciano Coelho 	if (!check_sdata_in_driver(sdata))
1070f1d65583SLuciano Coelho 		return -EIO;
1071f1d65583SLuciano Coelho 
1072f1d65583SLuciano Coelho 	trace_drv_post_channel_switch(local, sdata);
1073f1d65583SLuciano Coelho 	if (local->ops->post_channel_switch)
1074f1d65583SLuciano Coelho 		ret = local->ops->post_channel_switch(&local->hw, &sdata->vif);
1075f1d65583SLuciano Coelho 	trace_drv_return_int(local, ret);
1076f1d65583SLuciano Coelho 	return ret;
1077f1d65583SLuciano Coelho }
1078f1d65583SLuciano Coelho 
1079b9cc81d8SSara Sharon static inline void
1080b9cc81d8SSara Sharon drv_abort_channel_switch(struct ieee80211_sub_if_data *sdata)
1081b9cc81d8SSara Sharon {
1082b9cc81d8SSara Sharon 	struct ieee80211_local *local = sdata->local;
1083b9cc81d8SSara Sharon 
1084b9cc81d8SSara Sharon 	if (!check_sdata_in_driver(sdata))
1085b9cc81d8SSara Sharon 		return;
1086b9cc81d8SSara Sharon 
1087b9cc81d8SSara Sharon 	trace_drv_abort_channel_switch(local, sdata);
1088b9cc81d8SSara Sharon 
1089b9cc81d8SSara Sharon 	if (local->ops->abort_channel_switch)
1090b9cc81d8SSara Sharon 		local->ops->abort_channel_switch(&local->hw, &sdata->vif);
1091b9cc81d8SSara Sharon }
1092b9cc81d8SSara Sharon 
1093fafd2bceSSara Sharon static inline void
1094fafd2bceSSara Sharon drv_channel_switch_rx_beacon(struct ieee80211_sub_if_data *sdata,
1095fafd2bceSSara Sharon 			     struct ieee80211_channel_switch *ch_switch)
1096fafd2bceSSara Sharon {
1097fafd2bceSSara Sharon 	struct ieee80211_local *local = sdata->local;
1098fafd2bceSSara Sharon 
1099fafd2bceSSara Sharon 	if (!check_sdata_in_driver(sdata))
1100fafd2bceSSara Sharon 		return;
1101fafd2bceSSara Sharon 
1102fafd2bceSSara Sharon 	trace_drv_channel_switch_rx_beacon(local, sdata, ch_switch);
1103fafd2bceSSara Sharon 	if (local->ops->channel_switch_rx_beacon)
1104fafd2bceSSara Sharon 		local->ops->channel_switch_rx_beacon(&local->hw, &sdata->vif,
1105fafd2bceSSara Sharon 						     ch_switch);
1106fafd2bceSSara Sharon }
1107fafd2bceSSara Sharon 
110855fff501SJohannes Berg static inline int drv_join_ibss(struct ieee80211_local *local,
110955fff501SJohannes Berg 				struct ieee80211_sub_if_data *sdata)
111055fff501SJohannes Berg {
111155fff501SJohannes Berg 	int ret = 0;
111255fff501SJohannes Berg 
111355fff501SJohannes Berg 	might_sleep();
1114f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
1115f6837ba8SJohannes Berg 		return -EIO;
111655fff501SJohannes Berg 
111755fff501SJohannes Berg 	trace_drv_join_ibss(local, sdata, &sdata->vif.bss_conf);
111855fff501SJohannes Berg 	if (local->ops->join_ibss)
111955fff501SJohannes Berg 		ret = local->ops->join_ibss(&local->hw, &sdata->vif);
112055fff501SJohannes Berg 	trace_drv_return_int(local, ret);
112155fff501SJohannes Berg 	return ret;
112255fff501SJohannes Berg }
112355fff501SJohannes Berg 
112455fff501SJohannes Berg static inline void drv_leave_ibss(struct ieee80211_local *local,
112555fff501SJohannes Berg 				  struct ieee80211_sub_if_data *sdata)
112655fff501SJohannes Berg {
112755fff501SJohannes Berg 	might_sleep();
1128f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
1129f6837ba8SJohannes Berg 		return;
113055fff501SJohannes Berg 
113155fff501SJohannes Berg 	trace_drv_leave_ibss(local, sdata);
113255fff501SJohannes Berg 	if (local->ops->leave_ibss)
113355fff501SJohannes Berg 		local->ops->leave_ibss(&local->hw, &sdata->vif);
113455fff501SJohannes Berg 	trace_drv_return_void(local);
113555fff501SJohannes Berg }
113655fff501SJohannes Berg 
1137cca674d4SAntonio Quartulli static inline u32 drv_get_expected_throughput(struct ieee80211_local *local,
11384fdbc67aSMaxim Altshul 					      struct sta_info *sta)
1139cca674d4SAntonio Quartulli {
1140cca674d4SAntonio Quartulli 	u32 ret = 0;
1141cca674d4SAntonio Quartulli 
11424fdbc67aSMaxim Altshul 	trace_drv_get_expected_throughput(&sta->sta);
11434fdbc67aSMaxim Altshul 	if (local->ops->get_expected_throughput && sta->uploaded)
11444fdbc67aSMaxim Altshul 		ret = local->ops->get_expected_throughput(&local->hw, &sta->sta);
1145cca674d4SAntonio Quartulli 	trace_drv_return_u32(local, ret);
1146cca674d4SAntonio Quartulli 
1147cca674d4SAntonio Quartulli 	return ret;
1148cca674d4SAntonio Quartulli }
1149cca674d4SAntonio Quartulli 
11505b3dc42bSFelix Fietkau static inline int drv_get_txpower(struct ieee80211_local *local,
11515b3dc42bSFelix Fietkau 				  struct ieee80211_sub_if_data *sdata, int *dbm)
11525b3dc42bSFelix Fietkau {
11535b3dc42bSFelix Fietkau 	int ret;
11545b3dc42bSFelix Fietkau 
11555b3dc42bSFelix Fietkau 	if (!local->ops->get_txpower)
11565b3dc42bSFelix Fietkau 		return -EOPNOTSUPP;
11575b3dc42bSFelix Fietkau 
11585b3dc42bSFelix Fietkau 	ret = local->ops->get_txpower(&local->hw, &sdata->vif, dbm);
11595b3dc42bSFelix Fietkau 	trace_drv_get_txpower(local, sdata, *dbm, ret);
11605b3dc42bSFelix Fietkau 
11615b3dc42bSFelix Fietkau 	return ret;
11625b3dc42bSFelix Fietkau }
11635b3dc42bSFelix Fietkau 
1164a7a6bdd0SArik Nemtsov static inline int
1165a7a6bdd0SArik Nemtsov drv_tdls_channel_switch(struct ieee80211_local *local,
1166a7a6bdd0SArik Nemtsov 			struct ieee80211_sub_if_data *sdata,
1167a7a6bdd0SArik Nemtsov 			struct ieee80211_sta *sta, u8 oper_class,
1168a7a6bdd0SArik Nemtsov 			struct cfg80211_chan_def *chandef,
1169a7a6bdd0SArik Nemtsov 			struct sk_buff *tmpl_skb, u32 ch_sw_tm_ie)
1170a7a6bdd0SArik Nemtsov {
1171a7a6bdd0SArik Nemtsov 	int ret;
1172a7a6bdd0SArik Nemtsov 
1173a7a6bdd0SArik Nemtsov 	might_sleep();
1174a7a6bdd0SArik Nemtsov 	if (!check_sdata_in_driver(sdata))
1175a7a6bdd0SArik Nemtsov 		return -EIO;
1176a7a6bdd0SArik Nemtsov 
1177a7a6bdd0SArik Nemtsov 	if (!local->ops->tdls_channel_switch)
1178a7a6bdd0SArik Nemtsov 		return -EOPNOTSUPP;
1179a7a6bdd0SArik Nemtsov 
1180a7a6bdd0SArik Nemtsov 	trace_drv_tdls_channel_switch(local, sdata, sta, oper_class, chandef);
1181a7a6bdd0SArik Nemtsov 	ret = local->ops->tdls_channel_switch(&local->hw, &sdata->vif, sta,
1182a7a6bdd0SArik Nemtsov 					      oper_class, chandef, tmpl_skb,
1183a7a6bdd0SArik Nemtsov 					      ch_sw_tm_ie);
1184a7a6bdd0SArik Nemtsov 	trace_drv_return_int(local, ret);
1185a7a6bdd0SArik Nemtsov 	return ret;
1186a7a6bdd0SArik Nemtsov }
1187a7a6bdd0SArik Nemtsov 
1188a7a6bdd0SArik Nemtsov static inline void
1189a7a6bdd0SArik Nemtsov drv_tdls_cancel_channel_switch(struct ieee80211_local *local,
1190a7a6bdd0SArik Nemtsov 			       struct ieee80211_sub_if_data *sdata,
1191a7a6bdd0SArik Nemtsov 			       struct ieee80211_sta *sta)
1192a7a6bdd0SArik Nemtsov {
1193a7a6bdd0SArik Nemtsov 	might_sleep();
1194a7a6bdd0SArik Nemtsov 	if (!check_sdata_in_driver(sdata))
1195a7a6bdd0SArik Nemtsov 		return;
1196a7a6bdd0SArik Nemtsov 
1197a7a6bdd0SArik Nemtsov 	if (!local->ops->tdls_cancel_channel_switch)
1198a7a6bdd0SArik Nemtsov 		return;
1199a7a6bdd0SArik Nemtsov 
1200a7a6bdd0SArik Nemtsov 	trace_drv_tdls_cancel_channel_switch(local, sdata, sta);
1201a7a6bdd0SArik Nemtsov 	local->ops->tdls_cancel_channel_switch(&local->hw, &sdata->vif, sta);
1202a7a6bdd0SArik Nemtsov 	trace_drv_return_void(local);
1203a7a6bdd0SArik Nemtsov }
1204a7a6bdd0SArik Nemtsov 
12058a4d32f3SArik Nemtsov static inline void
12068a4d32f3SArik Nemtsov drv_tdls_recv_channel_switch(struct ieee80211_local *local,
12078a4d32f3SArik Nemtsov 			     struct ieee80211_sub_if_data *sdata,
12088a4d32f3SArik Nemtsov 			     struct ieee80211_tdls_ch_sw_params *params)
12098a4d32f3SArik Nemtsov {
12108a4d32f3SArik Nemtsov 	trace_drv_tdls_recv_channel_switch(local, sdata, params);
12118a4d32f3SArik Nemtsov 	if (local->ops->tdls_recv_channel_switch)
12128a4d32f3SArik Nemtsov 		local->ops->tdls_recv_channel_switch(&local->hw, &sdata->vif,
12138a4d32f3SArik Nemtsov 						     params);
12148a4d32f3SArik Nemtsov 	trace_drv_return_void(local);
12158a4d32f3SArik Nemtsov }
12168a4d32f3SArik Nemtsov 
1217e7881bd5SJohannes Berg static inline void drv_wake_tx_queue(struct ieee80211_local *local,
1218e7881bd5SJohannes Berg 				     struct txq_info *txq)
1219ba8c3d6fSFelix Fietkau {
1220e7881bd5SJohannes Berg 	struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->txq.vif);
1221e7881bd5SJohannes Berg 
12224856bfd2SFelix Fietkau 	if (local->in_reconfig)
12234856bfd2SFelix Fietkau 		return;
12244856bfd2SFelix Fietkau 
1225e7881bd5SJohannes Berg 	if (!check_sdata_in_driver(sdata))
1226e7881bd5SJohannes Berg 		return;
1227e7881bd5SJohannes Berg 
1228e7881bd5SJohannes Berg 	trace_drv_wake_tx_queue(local, sdata, txq);
1229e7881bd5SJohannes Berg 	local->ops->wake_tx_queue(&local->hw, &txq->txq);
1230ba8c3d6fSFelix Fietkau }
1231ba8c3d6fSFelix Fietkau 
123218667600SToke Høiland-Jørgensen static inline void schedule_and_wake_txq(struct ieee80211_local *local,
123318667600SToke Høiland-Jørgensen 					 struct txq_info *txqi)
123418667600SToke Høiland-Jørgensen {
1235390298e8SToke Høiland-Jørgensen 	ieee80211_schedule_txq(&local->hw, &txqi->txq);
123618667600SToke Høiland-Jørgensen 	drv_wake_tx_queue(local, txqi);
123718667600SToke Høiland-Jørgensen }
123818667600SToke Høiland-Jørgensen 
12399739fe29SSara Sharon static inline int drv_can_aggregate_in_amsdu(struct ieee80211_local *local,
12409739fe29SSara Sharon 					     struct sk_buff *head,
12419739fe29SSara Sharon 					     struct sk_buff *skb)
12429739fe29SSara Sharon {
12439739fe29SSara Sharon 	if (!local->ops->can_aggregate_in_amsdu)
12449739fe29SSara Sharon 		return true;
12459739fe29SSara Sharon 
12469739fe29SSara Sharon 	return local->ops->can_aggregate_in_amsdu(&local->hw, head, skb);
12479739fe29SSara Sharon }
12489739fe29SSara Sharon 
1249bc847970SPradeep Kumar Chitrapu static inline int
1250bc847970SPradeep Kumar Chitrapu drv_get_ftm_responder_stats(struct ieee80211_local *local,
1251bc847970SPradeep Kumar Chitrapu 			    struct ieee80211_sub_if_data *sdata,
1252bc847970SPradeep Kumar Chitrapu 			    struct cfg80211_ftm_responder_stats *ftm_stats)
1253bc847970SPradeep Kumar Chitrapu {
1254bc847970SPradeep Kumar Chitrapu 	u32 ret = -EOPNOTSUPP;
1255bc847970SPradeep Kumar Chitrapu 
1256bc847970SPradeep Kumar Chitrapu 	if (local->ops->get_ftm_responder_stats)
1257bc847970SPradeep Kumar Chitrapu 		ret = local->ops->get_ftm_responder_stats(&local->hw,
1258bc847970SPradeep Kumar Chitrapu 							 &sdata->vif,
1259bc847970SPradeep Kumar Chitrapu 							 ftm_stats);
1260bc847970SPradeep Kumar Chitrapu 	trace_drv_get_ftm_responder_stats(local, sdata, ftm_stats);
1261bc847970SPradeep Kumar Chitrapu 
1262bc847970SPradeep Kumar Chitrapu 	return ret;
1263bc847970SPradeep Kumar Chitrapu }
1264bc847970SPradeep Kumar Chitrapu 
1265cee7013bSJohannes Berg static inline int drv_start_pmsr(struct ieee80211_local *local,
1266cee7013bSJohannes Berg 				 struct ieee80211_sub_if_data *sdata,
1267cee7013bSJohannes Berg 				 struct cfg80211_pmsr_request *request)
1268cee7013bSJohannes Berg {
1269cee7013bSJohannes Berg 	int ret = -EOPNOTSUPP;
1270cee7013bSJohannes Berg 
1271cee7013bSJohannes Berg 	might_sleep();
1272cee7013bSJohannes Berg 	if (!check_sdata_in_driver(sdata))
1273cee7013bSJohannes Berg 		return -EIO;
1274cee7013bSJohannes Berg 
1275cee7013bSJohannes Berg 	trace_drv_start_pmsr(local, sdata);
1276cee7013bSJohannes Berg 
1277cee7013bSJohannes Berg 	if (local->ops->start_pmsr)
1278cee7013bSJohannes Berg 		ret = local->ops->start_pmsr(&local->hw, &sdata->vif, request);
1279cee7013bSJohannes Berg 	trace_drv_return_int(local, ret);
1280cee7013bSJohannes Berg 
1281cee7013bSJohannes Berg 	return ret;
1282cee7013bSJohannes Berg }
1283cee7013bSJohannes Berg 
1284cee7013bSJohannes Berg static inline void drv_abort_pmsr(struct ieee80211_local *local,
1285cee7013bSJohannes Berg 				  struct ieee80211_sub_if_data *sdata,
1286cee7013bSJohannes Berg 				  struct cfg80211_pmsr_request *request)
1287cee7013bSJohannes Berg {
1288cee7013bSJohannes Berg 	trace_drv_abort_pmsr(local, sdata);
1289cee7013bSJohannes Berg 
1290cee7013bSJohannes Berg 	might_sleep();
1291cee7013bSJohannes Berg 	if (!check_sdata_in_driver(sdata))
1292cee7013bSJohannes Berg 		return;
1293cee7013bSJohannes Berg 
1294cee7013bSJohannes Berg 	if (local->ops->abort_pmsr)
1295cee7013bSJohannes Berg 		local->ops->abort_pmsr(&local->hw, &sdata->vif, request);
1296cee7013bSJohannes Berg 	trace_drv_return_void(local);
1297cee7013bSJohannes Berg }
1298cee7013bSJohannes Berg 
1299708d50edSAyala Beker static inline int drv_start_nan(struct ieee80211_local *local,
1300708d50edSAyala Beker 				struct ieee80211_sub_if_data *sdata,
1301708d50edSAyala Beker 				struct cfg80211_nan_conf *conf)
1302708d50edSAyala Beker {
1303708d50edSAyala Beker 	int ret;
1304708d50edSAyala Beker 
1305708d50edSAyala Beker 	might_sleep();
1306708d50edSAyala Beker 	check_sdata_in_driver(sdata);
1307708d50edSAyala Beker 
1308708d50edSAyala Beker 	trace_drv_start_nan(local, sdata, conf);
1309708d50edSAyala Beker 	ret = local->ops->start_nan(&local->hw, &sdata->vif, conf);
1310708d50edSAyala Beker 	trace_drv_return_int(local, ret);
1311708d50edSAyala Beker 	return ret;
1312708d50edSAyala Beker }
1313708d50edSAyala Beker 
1314708d50edSAyala Beker static inline void drv_stop_nan(struct ieee80211_local *local,
1315708d50edSAyala Beker 				struct ieee80211_sub_if_data *sdata)
1316708d50edSAyala Beker {
1317708d50edSAyala Beker 	might_sleep();
1318708d50edSAyala Beker 	check_sdata_in_driver(sdata);
1319708d50edSAyala Beker 
1320708d50edSAyala Beker 	trace_drv_stop_nan(local, sdata);
1321708d50edSAyala Beker 	local->ops->stop_nan(&local->hw, &sdata->vif);
1322708d50edSAyala Beker 	trace_drv_return_void(local);
1323708d50edSAyala Beker }
1324708d50edSAyala Beker 
13255953ff6dSAyala Beker static inline int drv_nan_change_conf(struct ieee80211_local *local,
13265953ff6dSAyala Beker 				       struct ieee80211_sub_if_data *sdata,
13275953ff6dSAyala Beker 				       struct cfg80211_nan_conf *conf,
13285953ff6dSAyala Beker 				       u32 changes)
13295953ff6dSAyala Beker {
13305953ff6dSAyala Beker 	int ret;
13315953ff6dSAyala Beker 
13325953ff6dSAyala Beker 	might_sleep();
13335953ff6dSAyala Beker 	check_sdata_in_driver(sdata);
13345953ff6dSAyala Beker 
13355953ff6dSAyala Beker 	if (!local->ops->nan_change_conf)
13365953ff6dSAyala Beker 		return -EOPNOTSUPP;
13375953ff6dSAyala Beker 
13385953ff6dSAyala Beker 	trace_drv_nan_change_conf(local, sdata, conf, changes);
13395953ff6dSAyala Beker 	ret = local->ops->nan_change_conf(&local->hw, &sdata->vif, conf,
13405953ff6dSAyala Beker 					  changes);
13415953ff6dSAyala Beker 	trace_drv_return_int(local, ret);
13425953ff6dSAyala Beker 
13435953ff6dSAyala Beker 	return ret;
13445953ff6dSAyala Beker }
13455953ff6dSAyala Beker 
1346167e33f4SAyala Beker static inline int drv_add_nan_func(struct ieee80211_local *local,
1347167e33f4SAyala Beker 				   struct ieee80211_sub_if_data *sdata,
1348167e33f4SAyala Beker 				   const struct cfg80211_nan_func *nan_func)
1349167e33f4SAyala Beker {
1350167e33f4SAyala Beker 	int ret;
1351167e33f4SAyala Beker 
1352167e33f4SAyala Beker 	might_sleep();
1353167e33f4SAyala Beker 	check_sdata_in_driver(sdata);
1354167e33f4SAyala Beker 
1355167e33f4SAyala Beker 	if (!local->ops->add_nan_func)
1356167e33f4SAyala Beker 		return -EOPNOTSUPP;
1357167e33f4SAyala Beker 
1358167e33f4SAyala Beker 	trace_drv_add_nan_func(local, sdata, nan_func);
1359167e33f4SAyala Beker 	ret = local->ops->add_nan_func(&local->hw, &sdata->vif, nan_func);
1360167e33f4SAyala Beker 	trace_drv_return_int(local, ret);
1361167e33f4SAyala Beker 
1362167e33f4SAyala Beker 	return ret;
1363167e33f4SAyala Beker }
1364167e33f4SAyala Beker 
1365167e33f4SAyala Beker static inline void drv_del_nan_func(struct ieee80211_local *local,
1366167e33f4SAyala Beker 				   struct ieee80211_sub_if_data *sdata,
1367167e33f4SAyala Beker 				   u8 instance_id)
1368167e33f4SAyala Beker {
1369167e33f4SAyala Beker 	might_sleep();
1370167e33f4SAyala Beker 	check_sdata_in_driver(sdata);
1371167e33f4SAyala Beker 
1372167e33f4SAyala Beker 	trace_drv_del_nan_func(local, sdata, instance_id);
1373167e33f4SAyala Beker 	if (local->ops->del_nan_func)
1374167e33f4SAyala Beker 		local->ops->del_nan_func(&local->hw, &sdata->vif, instance_id);
1375167e33f4SAyala Beker 	trace_drv_return_void(local);
1376167e33f4SAyala Beker }
1377167e33f4SAyala Beker 
1378370f51d5STamizh chelvam static inline int drv_set_tid_config(struct ieee80211_local *local,
1379370f51d5STamizh chelvam 				     struct ieee80211_sub_if_data *sdata,
1380370f51d5STamizh chelvam 				     struct ieee80211_sta *sta,
1381370f51d5STamizh chelvam 				     struct cfg80211_tid_config *tid_conf)
1382370f51d5STamizh chelvam {
1383370f51d5STamizh chelvam 	int ret;
1384370f51d5STamizh chelvam 
1385370f51d5STamizh chelvam 	might_sleep();
1386370f51d5STamizh chelvam 	ret = local->ops->set_tid_config(&local->hw, &sdata->vif, sta,
1387370f51d5STamizh chelvam 					 tid_conf);
1388370f51d5STamizh chelvam 	trace_drv_return_int(local, ret);
1389370f51d5STamizh chelvam 
1390370f51d5STamizh chelvam 	return ret;
1391370f51d5STamizh chelvam }
1392370f51d5STamizh chelvam 
1393370f51d5STamizh chelvam static inline int drv_reset_tid_config(struct ieee80211_local *local,
1394370f51d5STamizh chelvam 				       struct ieee80211_sub_if_data *sdata,
139560c2ef0eSSergey Matyukevich 				       struct ieee80211_sta *sta, u8 tids)
1396370f51d5STamizh chelvam {
1397370f51d5STamizh chelvam 	int ret;
1398370f51d5STamizh chelvam 
1399370f51d5STamizh chelvam 	might_sleep();
140060c2ef0eSSergey Matyukevich 	ret = local->ops->reset_tid_config(&local->hw, &sdata->vif, sta, tids);
1401370f51d5STamizh chelvam 	trace_drv_return_int(local, ret);
1402370f51d5STamizh chelvam 
1403370f51d5STamizh chelvam 	return ret;
1404370f51d5STamizh chelvam }
14056aea26ceSFelix Fietkau 
14066aea26ceSFelix Fietkau static inline void drv_update_vif_offload(struct ieee80211_local *local,
14076aea26ceSFelix Fietkau 					  struct ieee80211_sub_if_data *sdata)
14086aea26ceSFelix Fietkau {
14096aea26ceSFelix Fietkau 	might_sleep();
14106aea26ceSFelix Fietkau 	check_sdata_in_driver(sdata);
14116aea26ceSFelix Fietkau 
14126aea26ceSFelix Fietkau 	if (!local->ops->update_vif_offload)
14136aea26ceSFelix Fietkau 		return;
14146aea26ceSFelix Fietkau 
14156aea26ceSFelix Fietkau 	trace_drv_update_vif_offload(local, sdata);
14166aea26ceSFelix Fietkau 	local->ops->update_vif_offload(&local->hw, &sdata->vif);
14176aea26ceSFelix Fietkau 	trace_drv_return_void(local);
14186aea26ceSFelix Fietkau }
14196aea26ceSFelix Fietkau 
14201ff4e8f2SFelix Fietkau static inline void drv_sta_set_4addr(struct ieee80211_local *local,
14211ff4e8f2SFelix Fietkau 				     struct ieee80211_sub_if_data *sdata,
14221ff4e8f2SFelix Fietkau 				     struct ieee80211_sta *sta, bool enabled)
14231ff4e8f2SFelix Fietkau {
14241ff4e8f2SFelix Fietkau 	sdata = get_bss_sdata(sdata);
14251ff4e8f2SFelix Fietkau 	if (!check_sdata_in_driver(sdata))
14261ff4e8f2SFelix Fietkau 		return;
14271ff4e8f2SFelix Fietkau 
14281ff4e8f2SFelix Fietkau 	trace_drv_sta_set_4addr(local, sdata, sta, enabled);
14291ff4e8f2SFelix Fietkau 	if (local->ops->sta_set_4addr)
14301ff4e8f2SFelix Fietkau 		local->ops->sta_set_4addr(&local->hw, &sdata->vif, sta, enabled);
14311ff4e8f2SFelix Fietkau 	trace_drv_return_void(local);
14321ff4e8f2SFelix Fietkau }
14331ff4e8f2SFelix Fietkau 
143480a915ecSFelix Fietkau static inline void drv_sta_set_decap_offload(struct ieee80211_local *local,
143580a915ecSFelix Fietkau 					     struct ieee80211_sub_if_data *sdata,
143680a915ecSFelix Fietkau 					     struct ieee80211_sta *sta,
143780a915ecSFelix Fietkau 					     bool enabled)
143880a915ecSFelix Fietkau {
143980a915ecSFelix Fietkau 	sdata = get_bss_sdata(sdata);
144080a915ecSFelix Fietkau 	if (!check_sdata_in_driver(sdata))
144180a915ecSFelix Fietkau 		return;
144280a915ecSFelix Fietkau 
144380a915ecSFelix Fietkau 	trace_drv_sta_set_decap_offload(local, sdata, sta, enabled);
144480a915ecSFelix Fietkau 	if (local->ops->sta_set_decap_offload)
144580a915ecSFelix Fietkau 		local->ops->sta_set_decap_offload(&local->hw, &sdata->vif, sta,
144680a915ecSFelix Fietkau 						  enabled);
144780a915ecSFelix Fietkau 	trace_drv_return_void(local);
144880a915ecSFelix Fietkau }
144980a915ecSFelix Fietkau 
1450f5a4c24eSLorenzo Bianconi static inline void drv_add_twt_setup(struct ieee80211_local *local,
1451f5a4c24eSLorenzo Bianconi 				     struct ieee80211_sub_if_data *sdata,
1452f5a4c24eSLorenzo Bianconi 				     struct ieee80211_sta *sta,
1453f5a4c24eSLorenzo Bianconi 				     struct ieee80211_twt_setup *twt)
1454f5a4c24eSLorenzo Bianconi {
1455f5a4c24eSLorenzo Bianconi 	struct ieee80211_twt_params *twt_agrt;
1456f5a4c24eSLorenzo Bianconi 
1457f5a4c24eSLorenzo Bianconi 	might_sleep();
1458f5a4c24eSLorenzo Bianconi 
1459f5a4c24eSLorenzo Bianconi 	if (!check_sdata_in_driver(sdata))
1460f5a4c24eSLorenzo Bianconi 		return;
1461f5a4c24eSLorenzo Bianconi 
1462f5a4c24eSLorenzo Bianconi 	twt_agrt = (void *)twt->params;
1463f5a4c24eSLorenzo Bianconi 
1464f5a4c24eSLorenzo Bianconi 	trace_drv_add_twt_setup(local, sta, twt, twt_agrt);
1465f5a4c24eSLorenzo Bianconi 	local->ops->add_twt_setup(&local->hw, sta, twt);
1466f5a4c24eSLorenzo Bianconi 	trace_drv_return_void(local);
1467f5a4c24eSLorenzo Bianconi }
1468f5a4c24eSLorenzo Bianconi 
1469f5a4c24eSLorenzo Bianconi static inline void drv_twt_teardown_request(struct ieee80211_local *local,
1470f5a4c24eSLorenzo Bianconi 					    struct ieee80211_sub_if_data *sdata,
1471f5a4c24eSLorenzo Bianconi 					    struct ieee80211_sta *sta,
1472f5a4c24eSLorenzo Bianconi 					    u8 flowid)
1473f5a4c24eSLorenzo Bianconi {
1474f5a4c24eSLorenzo Bianconi 	might_sleep();
1475f5a4c24eSLorenzo Bianconi 	if (!check_sdata_in_driver(sdata))
1476f5a4c24eSLorenzo Bianconi 		return;
1477f5a4c24eSLorenzo Bianconi 
1478f5a4c24eSLorenzo Bianconi 	if (!local->ops->twt_teardown_request)
1479f5a4c24eSLorenzo Bianconi 		return;
1480f5a4c24eSLorenzo Bianconi 
1481f5a4c24eSLorenzo Bianconi 	trace_drv_twt_teardown_request(local, sta, flowid);
1482f5a4c24eSLorenzo Bianconi 	local->ops->twt_teardown_request(&local->hw, sta, flowid);
1483f5a4c24eSLorenzo Bianconi 	trace_drv_return_void(local);
1484f5a4c24eSLorenzo Bianconi }
1485f5a4c24eSLorenzo Bianconi 
1486*d787a3e3SFelix Fietkau static inline int drv_net_fill_forward_path(struct ieee80211_local *local,
1487*d787a3e3SFelix Fietkau 					    struct ieee80211_sub_if_data *sdata,
1488*d787a3e3SFelix Fietkau 					    struct ieee80211_sta *sta,
1489*d787a3e3SFelix Fietkau 					    struct net_device_path_ctx *ctx,
1490*d787a3e3SFelix Fietkau 					    struct net_device_path *path)
1491*d787a3e3SFelix Fietkau {
1492*d787a3e3SFelix Fietkau 	int ret = -EOPNOTSUPP;
1493*d787a3e3SFelix Fietkau 
1494*d787a3e3SFelix Fietkau 	sdata = get_bss_sdata(sdata);
1495*d787a3e3SFelix Fietkau 	if (!check_sdata_in_driver(sdata))
1496*d787a3e3SFelix Fietkau 		return -EIO;
1497*d787a3e3SFelix Fietkau 
1498*d787a3e3SFelix Fietkau 	trace_drv_net_fill_forward_path(local, sdata, sta);
1499*d787a3e3SFelix Fietkau 	if (local->ops->net_fill_forward_path)
1500*d787a3e3SFelix Fietkau 		ret = local->ops->net_fill_forward_path(&local->hw,
1501*d787a3e3SFelix Fietkau 							&sdata->vif, sta,
1502*d787a3e3SFelix Fietkau 							ctx, path);
1503*d787a3e3SFelix Fietkau 	trace_drv_return_int(local, ret);
1504*d787a3e3SFelix Fietkau 
1505*d787a3e3SFelix Fietkau 	return ret;
1506*d787a3e3SFelix Fietkau }
1507*d787a3e3SFelix Fietkau 
150824487981SJohannes Berg #endif /* __MAC80211_DRIVER_OPS */
1509