xref: /openbmc/linux/net/mac80211/driver-ops.h (revision ee0db868)
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
5c4fdb081SJohannes Berg * Copyright (C) 2018 - 2019, 2021 - 2023 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)	({					\
16c4fdb081SJohannes Berg 	WARN_ONCE(!sdata->local->reconfig_failure &&				\
17c4fdb081SJohannes Berg 		  !(sdata->flags & IEEE80211_SDATA_IN_DRIVER),			\
18c8ad0106SJohannes Berg 		  "%s: Failed check-sdata-in-driver check, flags: 0x%x\n",	\
19c8ad0106SJohannes Berg 		  sdata->dev ? sdata->dev->name : sdata->name, sdata->flags);	\
20c4fdb081SJohannes Berg 	!!(sdata->flags & IEEE80211_SDATA_IN_DRIVER);				\
21c8ad0106SJohannes Berg })
227b7eab6fSJohannes Berg 
23bc192f89SFelix Fietkau static inline struct ieee80211_sub_if_data *
get_bss_sdata(struct ieee80211_sub_if_data * sdata)24bc192f89SFelix Fietkau get_bss_sdata(struct ieee80211_sub_if_data *sdata)
25bc192f89SFelix Fietkau {
26*ee0db868SOldřich Jedlička 	if (sdata && sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
27bc192f89SFelix Fietkau 		sdata = container_of(sdata->bss, struct ieee80211_sub_if_data,
28bc192f89SFelix Fietkau 				     u.ap);
29bc192f89SFelix Fietkau 
30bc192f89SFelix Fietkau 	return sdata;
31bc192f89SFelix Fietkau }
32bc192f89SFelix Fietkau 
drv_tx(struct ieee80211_local * local,struct ieee80211_tx_control * control,struct sk_buff * skb)3336323f81SThomas Huehn static inline void drv_tx(struct ieee80211_local *local,
3436323f81SThomas Huehn 			  struct ieee80211_tx_control *control,
3536323f81SThomas Huehn 			  struct sk_buff *skb)
3624487981SJohannes Berg {
3736323f81SThomas Huehn 	local->ops->tx(&local->hw, control, skb);
3824487981SJohannes Berg }
3924487981SJohannes Berg 
drv_sync_rx_queues(struct ieee80211_local * local,struct sta_info * sta)40f59374ebSSara Sharon static inline void drv_sync_rx_queues(struct ieee80211_local *local,
41f59374ebSSara Sharon 				      struct sta_info *sta)
42f59374ebSSara Sharon {
43f59374ebSSara Sharon 	if (local->ops->sync_rx_queues) {
44f59374ebSSara Sharon 		trace_drv_sync_rx_queues(local, sta->sdata, &sta->sta);
45f59374ebSSara Sharon 		local->ops->sync_rx_queues(&local->hw);
46f59374ebSSara Sharon 		trace_drv_return_void(local);
47f59374ebSSara Sharon 	}
48f59374ebSSara Sharon }
49f59374ebSSara Sharon 
drv_get_et_strings(struct ieee80211_sub_if_data * sdata,u32 sset,u8 * data)50e352114fSBen Greear static inline void drv_get_et_strings(struct ieee80211_sub_if_data *sdata,
51e352114fSBen Greear 				      u32 sset, u8 *data)
52e352114fSBen Greear {
53e352114fSBen Greear 	struct ieee80211_local *local = sdata->local;
54e352114fSBen Greear 	if (local->ops->get_et_strings) {
55e352114fSBen Greear 		trace_drv_get_et_strings(local, sset);
56e352114fSBen Greear 		local->ops->get_et_strings(&local->hw, &sdata->vif, sset, data);
57e352114fSBen Greear 		trace_drv_return_void(local);
58e352114fSBen Greear 	}
59e352114fSBen Greear }
60e352114fSBen Greear 
drv_get_et_stats(struct ieee80211_sub_if_data * sdata,struct ethtool_stats * stats,u64 * data)61e352114fSBen Greear static inline void drv_get_et_stats(struct ieee80211_sub_if_data *sdata,
62e352114fSBen Greear 				    struct ethtool_stats *stats,
63e352114fSBen Greear 				    u64 *data)
64e352114fSBen Greear {
65e352114fSBen Greear 	struct ieee80211_local *local = sdata->local;
66e352114fSBen Greear 	if (local->ops->get_et_stats) {
67e352114fSBen Greear 		trace_drv_get_et_stats(local);
68e352114fSBen Greear 		local->ops->get_et_stats(&local->hw, &sdata->vif, stats, data);
69e352114fSBen Greear 		trace_drv_return_void(local);
70e352114fSBen Greear 	}
71e352114fSBen Greear }
72e352114fSBen Greear 
drv_get_et_sset_count(struct ieee80211_sub_if_data * sdata,int sset)73e352114fSBen Greear static inline int drv_get_et_sset_count(struct ieee80211_sub_if_data *sdata,
74e352114fSBen Greear 					int sset)
75e352114fSBen Greear {
76e352114fSBen Greear 	struct ieee80211_local *local = sdata->local;
77e352114fSBen Greear 	int rv = 0;
78e352114fSBen Greear 	if (local->ops->get_et_sset_count) {
79e352114fSBen Greear 		trace_drv_get_et_sset_count(local, sset);
80e352114fSBen Greear 		rv = local->ops->get_et_sset_count(&local->hw, &sdata->vif,
81e352114fSBen Greear 						   sset);
82e352114fSBen Greear 		trace_drv_return_int(local, rv);
83e352114fSBen Greear 	}
84e352114fSBen Greear 	return rv;
85e352114fSBen Greear }
86e352114fSBen Greear 
87968a76ceSEliad Peller int drv_start(struct ieee80211_local *local);
88968a76ceSEliad Peller void drv_stop(struct ieee80211_local *local);
8924487981SJohannes Berg 
90eecc4800SJohannes Berg #ifdef CONFIG_PM
drv_suspend(struct ieee80211_local * local,struct cfg80211_wowlan * wowlan)91eecc4800SJohannes Berg static inline int drv_suspend(struct ieee80211_local *local,
92eecc4800SJohannes Berg 			      struct cfg80211_wowlan *wowlan)
93eecc4800SJohannes Berg {
94eecc4800SJohannes Berg 	int ret;
95eecc4800SJohannes Berg 
96eecc4800SJohannes Berg 	might_sleep();
97eecc4800SJohannes Berg 
98eecc4800SJohannes Berg 	trace_drv_suspend(local);
99eecc4800SJohannes Berg 	ret = local->ops->suspend(&local->hw, wowlan);
100eecc4800SJohannes Berg 	trace_drv_return_int(local, ret);
101eecc4800SJohannes Berg 	return ret;
102eecc4800SJohannes Berg }
103eecc4800SJohannes Berg 
drv_resume(struct ieee80211_local * local)104eecc4800SJohannes Berg static inline int drv_resume(struct ieee80211_local *local)
105eecc4800SJohannes Berg {
106eecc4800SJohannes Berg 	int ret;
107eecc4800SJohannes Berg 
108eecc4800SJohannes Berg 	might_sleep();
109eecc4800SJohannes Berg 
110eecc4800SJohannes Berg 	trace_drv_resume(local);
111eecc4800SJohannes Berg 	ret = local->ops->resume(&local->hw);
112eecc4800SJohannes Berg 	trace_drv_return_int(local, ret);
113eecc4800SJohannes Berg 	return ret;
114eecc4800SJohannes Berg }
1156d52563fSJohannes Berg 
drv_set_wakeup(struct ieee80211_local * local,bool enabled)1166d52563fSJohannes Berg static inline void drv_set_wakeup(struct ieee80211_local *local,
1176d52563fSJohannes Berg 				  bool enabled)
1186d52563fSJohannes Berg {
1196d52563fSJohannes Berg 	might_sleep();
1206d52563fSJohannes Berg 
1216d52563fSJohannes Berg 	if (!local->ops->set_wakeup)
1226d52563fSJohannes Berg 		return;
1236d52563fSJohannes Berg 
1246d52563fSJohannes Berg 	trace_drv_set_wakeup(local, enabled);
1256d52563fSJohannes Berg 	local->ops->set_wakeup(&local->hw, enabled);
1266d52563fSJohannes Berg 	trace_drv_return_void(local);
1276d52563fSJohannes Berg }
128eecc4800SJohannes Berg #endif
129eecc4800SJohannes Berg 
1309aae296aSDenys Vlasenko int drv_add_interface(struct ieee80211_local *local,
1319aae296aSDenys Vlasenko 		      struct ieee80211_sub_if_data *sdata);
132e1781ed3SKalle Valo 
1339aae296aSDenys Vlasenko int drv_change_interface(struct ieee80211_local *local,
13434d4bc4dSJohannes Berg 			 struct ieee80211_sub_if_data *sdata,
1359aae296aSDenys Vlasenko 			 enum nl80211_iftype type, bool p2p);
13634d4bc4dSJohannes Berg 
1379aae296aSDenys Vlasenko void drv_remove_interface(struct ieee80211_local *local,
1389aae296aSDenys Vlasenko 			  struct ieee80211_sub_if_data *sdata);
13924487981SJohannes Berg 
drv_config(struct ieee80211_local * local,u32 changed)14024487981SJohannes Berg static inline int drv_config(struct ieee80211_local *local, u32 changed)
14124487981SJohannes Berg {
142e1781ed3SKalle Valo 	int ret;
143e1781ed3SKalle Valo 
144e1781ed3SKalle Valo 	might_sleep();
145e1781ed3SKalle Valo 
1464efc76bdSJohannes Berg 	trace_drv_config(local, changed);
147e1781ed3SKalle Valo 	ret = local->ops->config(&local->hw, changed);
1484efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
1490a2b8bb2SJohannes Berg 	return ret;
15024487981SJohannes Berg }
15124487981SJohannes Berg 
drv_vif_cfg_changed(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,u64 changed)1527b7090b4SJohannes Berg static inline void drv_vif_cfg_changed(struct ieee80211_local *local,
15312375ef9SJohannes Berg 				       struct ieee80211_sub_if_data *sdata,
1547b7090b4SJohannes Berg 				       u64 changed)
1557b7090b4SJohannes Berg {
1567b7090b4SJohannes Berg 	might_sleep();
1577b7090b4SJohannes Berg 
1587b7090b4SJohannes Berg 	if (!check_sdata_in_driver(sdata))
1597b7090b4SJohannes Berg 		return;
1607b7090b4SJohannes Berg 
1617b7090b4SJohannes Berg 	trace_drv_vif_cfg_changed(local, sdata, changed);
1627b7090b4SJohannes Berg 	if (local->ops->vif_cfg_changed)
1637b7090b4SJohannes Berg 		local->ops->vif_cfg_changed(&local->hw, &sdata->vif, changed);
1647b7090b4SJohannes Berg 	else if (local->ops->bss_info_changed)
1657b7090b4SJohannes Berg 		local->ops->bss_info_changed(&local->hw, &sdata->vif,
1667b7090b4SJohannes Berg 					     &sdata->vif.bss_conf, changed);
1677b7090b4SJohannes Berg 	trace_drv_return_void(local);
1687b7090b4SJohannes Berg }
1697b7090b4SJohannes Berg 
170efe9c2bfSJohannes Berg void drv_link_info_changed(struct ieee80211_local *local,
1717b7090b4SJohannes Berg 			   struct ieee80211_sub_if_data *sdata,
172d8675a63SJohannes Berg 			   struct ieee80211_bss_conf *info,
173efe9c2bfSJohannes Berg 			   int link_id, u64 changed);
17424487981SJohannes Berg 
drv_prepare_multicast(struct ieee80211_local * local,struct netdev_hw_addr_list * mc_list)1753ac64beeSJohannes Berg static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
17622bedad3SJiri Pirko 					struct netdev_hw_addr_list *mc_list)
17724487981SJohannes Berg {
1783ac64beeSJohannes Berg 	u64 ret = 0;
1793ac64beeSJohannes Berg 
1804efc76bdSJohannes Berg 	trace_drv_prepare_multicast(local, mc_list->count);
1814efc76bdSJohannes Berg 
1823ac64beeSJohannes Berg 	if (local->ops->prepare_multicast)
18322bedad3SJiri Pirko 		ret = local->ops->prepare_multicast(&local->hw, mc_list);
1843ac64beeSJohannes Berg 
1854efc76bdSJohannes Berg 	trace_drv_return_u64(local, ret);
1863ac64beeSJohannes Berg 
1873ac64beeSJohannes Berg 	return ret;
1883ac64beeSJohannes Berg }
1893ac64beeSJohannes Berg 
drv_configure_filter(struct ieee80211_local * local,unsigned int changed_flags,unsigned int * total_flags,u64 multicast)1903ac64beeSJohannes Berg static inline void drv_configure_filter(struct ieee80211_local *local,
1913ac64beeSJohannes Berg 					unsigned int changed_flags,
1923ac64beeSJohannes Berg 					unsigned int *total_flags,
1933ac64beeSJohannes Berg 					u64 multicast)
1943ac64beeSJohannes Berg {
1953ac64beeSJohannes Berg 	might_sleep();
1963ac64beeSJohannes Berg 
1970a2b8bb2SJohannes Berg 	trace_drv_configure_filter(local, changed_flags, total_flags,
1983ac64beeSJohannes Berg 				   multicast);
1994efc76bdSJohannes Berg 	local->ops->configure_filter(&local->hw, changed_flags, total_flags,
2004efc76bdSJohannes Berg 				     multicast);
2014efc76bdSJohannes Berg 	trace_drv_return_void(local);
20224487981SJohannes Berg }
20324487981SJohannes Berg 
drv_config_iface_filter(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,unsigned int filter_flags,unsigned int changed_flags)2041b09b556SAndrei Otcheretianski static inline void drv_config_iface_filter(struct ieee80211_local *local,
2051b09b556SAndrei Otcheretianski 					   struct ieee80211_sub_if_data *sdata,
2061b09b556SAndrei Otcheretianski 					   unsigned int filter_flags,
2071b09b556SAndrei Otcheretianski 					   unsigned int changed_flags)
2081b09b556SAndrei Otcheretianski {
2091b09b556SAndrei Otcheretianski 	might_sleep();
2101b09b556SAndrei Otcheretianski 
2111b09b556SAndrei Otcheretianski 	trace_drv_config_iface_filter(local, sdata, filter_flags,
2121b09b556SAndrei Otcheretianski 				      changed_flags);
2131b09b556SAndrei Otcheretianski 	if (local->ops->config_iface_filter)
2141b09b556SAndrei Otcheretianski 		local->ops->config_iface_filter(&local->hw, &sdata->vif,
2151b09b556SAndrei Otcheretianski 						filter_flags,
2161b09b556SAndrei Otcheretianski 						changed_flags);
2171b09b556SAndrei Otcheretianski 	trace_drv_return_void(local);
2181b09b556SAndrei Otcheretianski }
2191b09b556SAndrei Otcheretianski 
drv_set_tim(struct ieee80211_local * local,struct ieee80211_sta * sta,bool set)22024487981SJohannes Berg static inline int drv_set_tim(struct ieee80211_local *local,
22124487981SJohannes Berg 			      struct ieee80211_sta *sta, bool set)
22224487981SJohannes Berg {
2230a2b8bb2SJohannes Berg 	int ret = 0;
2244efc76bdSJohannes Berg 	trace_drv_set_tim(local, sta, set);
22524487981SJohannes Berg 	if (local->ops->set_tim)
2260a2b8bb2SJohannes Berg 		ret = local->ops->set_tim(&local->hw, sta, set);
2274efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
2280a2b8bb2SJohannes Berg 	return ret;
22924487981SJohannes Berg }
23024487981SJohannes Berg 
231efe9c2bfSJohannes Berg int drv_set_key(struct ieee80211_local *local,
23212375ef9SJohannes Berg 		enum set_key_cmd cmd,
23312375ef9SJohannes Berg 		struct ieee80211_sub_if_data *sdata,
23424487981SJohannes Berg 		struct ieee80211_sta *sta,
235efe9c2bfSJohannes Berg 		struct ieee80211_key_conf *key);
23624487981SJohannes Berg 
drv_update_tkip_key(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_key_conf * conf,struct sta_info * sta,u32 iv32,u16 * phase1key)23724487981SJohannes Berg static inline void drv_update_tkip_key(struct ieee80211_local *local,
238b3fbdcf4SJohannes Berg 				       struct ieee80211_sub_if_data *sdata,
23924487981SJohannes Berg 				       struct ieee80211_key_conf *conf,
240b3fbdcf4SJohannes Berg 				       struct sta_info *sta, u32 iv32,
24124487981SJohannes Berg 				       u16 *phase1key)
24224487981SJohannes Berg {
243b3fbdcf4SJohannes Berg 	struct ieee80211_sta *ista = NULL;
244b3fbdcf4SJohannes Berg 
245b3fbdcf4SJohannes Berg 	if (sta)
246b3fbdcf4SJohannes Berg 		ista = &sta->sta;
247b3fbdcf4SJohannes Berg 
248077f4939SJohannes Berg 	sdata = get_bss_sdata(sdata);
249f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
250f6837ba8SJohannes Berg 		return;
2517b7eab6fSJohannes Berg 
2524efc76bdSJohannes Berg 	trace_drv_update_tkip_key(local, sdata, conf, ista, iv32);
25324487981SJohannes Berg 	if (local->ops->update_tkip_key)
254b3fbdcf4SJohannes Berg 		local->ops->update_tkip_key(&local->hw, &sdata->vif, conf,
255b3fbdcf4SJohannes Berg 					    ista, iv32, phase1key);
2564efc76bdSJohannes Berg 	trace_drv_return_void(local);
25724487981SJohannes Berg }
25824487981SJohannes Berg 
drv_hw_scan(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_scan_request * req)25924487981SJohannes Berg static inline int drv_hw_scan(struct ieee80211_local *local,
260a060bbfeSJohannes Berg 			      struct ieee80211_sub_if_data *sdata,
261c56ef672SDavid Spinadel 			      struct ieee80211_scan_request *req)
26224487981SJohannes Berg {
263e1781ed3SKalle Valo 	int ret;
264e1781ed3SKalle Valo 
265e1781ed3SKalle Valo 	might_sleep();
266e1781ed3SKalle Valo 
267f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
268f6837ba8SJohannes Berg 		return -EIO;
2697b7eab6fSJohannes Berg 
27079f460caSLuciano Coelho 	trace_drv_hw_scan(local, sdata);
271a060bbfeSJohannes Berg 	ret = local->ops->hw_scan(&local->hw, &sdata->vif, req);
2724efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
2730a2b8bb2SJohannes Berg 	return ret;
27424487981SJohannes Berg }
27524487981SJohannes Berg 
drv_cancel_hw_scan(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata)276b856439bSEliad Peller static inline void drv_cancel_hw_scan(struct ieee80211_local *local,
277b856439bSEliad Peller 				      struct ieee80211_sub_if_data *sdata)
278b856439bSEliad Peller {
279b856439bSEliad Peller 	might_sleep();
280b856439bSEliad Peller 
281f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
282f6837ba8SJohannes Berg 		return;
2837b7eab6fSJohannes Berg 
284b856439bSEliad Peller 	trace_drv_cancel_hw_scan(local, sdata);
285b856439bSEliad Peller 	local->ops->cancel_hw_scan(&local->hw, &sdata->vif);
286b856439bSEliad Peller 	trace_drv_return_void(local);
287b856439bSEliad Peller }
288b856439bSEliad Peller 
28979f460caSLuciano Coelho static inline int
drv_sched_scan_start(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct cfg80211_sched_scan_request * req,struct ieee80211_scan_ies * ies)29079f460caSLuciano Coelho drv_sched_scan_start(struct ieee80211_local *local,
29179f460caSLuciano Coelho 		     struct ieee80211_sub_if_data *sdata,
29279f460caSLuciano Coelho 		     struct cfg80211_sched_scan_request *req,
293633e2713SDavid Spinadel 		     struct ieee80211_scan_ies *ies)
29479f460caSLuciano Coelho {
29579f460caSLuciano Coelho 	int ret;
29679f460caSLuciano Coelho 
29779f460caSLuciano Coelho 	might_sleep();
29879f460caSLuciano Coelho 
299f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
300f6837ba8SJohannes Berg 		return -EIO;
3017b7eab6fSJohannes Berg 
30279f460caSLuciano Coelho 	trace_drv_sched_scan_start(local, sdata);
30379f460caSLuciano Coelho 	ret = local->ops->sched_scan_start(&local->hw, &sdata->vif,
30479f460caSLuciano Coelho 					      req, ies);
30579f460caSLuciano Coelho 	trace_drv_return_int(local, ret);
30679f460caSLuciano Coelho 	return ret;
30779f460caSLuciano Coelho }
30879f460caSLuciano Coelho 
drv_sched_scan_stop(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata)30937e3308cSJohannes Berg static inline int drv_sched_scan_stop(struct ieee80211_local *local,
31079f460caSLuciano Coelho 				      struct ieee80211_sub_if_data *sdata)
31179f460caSLuciano Coelho {
31237e3308cSJohannes Berg 	int ret;
31337e3308cSJohannes Berg 
31479f460caSLuciano Coelho 	might_sleep();
31579f460caSLuciano Coelho 
316f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
317f6837ba8SJohannes Berg 		return -EIO;
3187b7eab6fSJohannes Berg 
31979f460caSLuciano Coelho 	trace_drv_sched_scan_stop(local, sdata);
32037e3308cSJohannes Berg 	ret = local->ops->sched_scan_stop(&local->hw, &sdata->vif);
32137e3308cSJohannes Berg 	trace_drv_return_int(local, ret);
32237e3308cSJohannes Berg 
32337e3308cSJohannes Berg 	return ret;
32479f460caSLuciano Coelho }
32579f460caSLuciano Coelho 
drv_sw_scan_start(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,const u8 * mac_addr)326a344d677SJohannes Berg static inline void drv_sw_scan_start(struct ieee80211_local *local,
327a344d677SJohannes Berg 				     struct ieee80211_sub_if_data *sdata,
328a344d677SJohannes Berg 				     const u8 *mac_addr)
32924487981SJohannes Berg {
330e1781ed3SKalle Valo 	might_sleep();
331e1781ed3SKalle Valo 
332a344d677SJohannes Berg 	trace_drv_sw_scan_start(local, sdata, mac_addr);
33324487981SJohannes Berg 	if (local->ops->sw_scan_start)
334a344d677SJohannes Berg 		local->ops->sw_scan_start(&local->hw, &sdata->vif, mac_addr);
3354efc76bdSJohannes Berg 	trace_drv_return_void(local);
33624487981SJohannes Berg }
33724487981SJohannes Berg 
drv_sw_scan_complete(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata)338a344d677SJohannes Berg static inline void drv_sw_scan_complete(struct ieee80211_local *local,
339a344d677SJohannes Berg 					struct ieee80211_sub_if_data *sdata)
34024487981SJohannes Berg {
341e1781ed3SKalle Valo 	might_sleep();
342e1781ed3SKalle Valo 
343a344d677SJohannes Berg 	trace_drv_sw_scan_complete(local, sdata);
34424487981SJohannes Berg 	if (local->ops->sw_scan_complete)
345a344d677SJohannes Berg 		local->ops->sw_scan_complete(&local->hw, &sdata->vif);
3464efc76bdSJohannes Berg 	trace_drv_return_void(local);
34724487981SJohannes Berg }
34824487981SJohannes Berg 
drv_get_stats(struct ieee80211_local * local,struct ieee80211_low_level_stats * stats)34924487981SJohannes Berg static inline int drv_get_stats(struct ieee80211_local *local,
35024487981SJohannes Berg 				struct ieee80211_low_level_stats *stats)
35124487981SJohannes Berg {
3520a2b8bb2SJohannes Berg 	int ret = -EOPNOTSUPP;
3530a2b8bb2SJohannes Berg 
354e1781ed3SKalle Valo 	might_sleep();
355e1781ed3SKalle Valo 
3560a2b8bb2SJohannes Berg 	if (local->ops->get_stats)
3570a2b8bb2SJohannes Berg 		ret = local->ops->get_stats(&local->hw, stats);
3580a2b8bb2SJohannes Berg 	trace_drv_get_stats(local, stats, ret);
3590a2b8bb2SJohannes Berg 
3600a2b8bb2SJohannes Berg 	return ret;
36124487981SJohannes Berg }
36224487981SJohannes Berg 
drv_get_key_seq(struct ieee80211_local * local,struct ieee80211_key * key,struct ieee80211_key_seq * seq)3639352c19fSJohannes Berg static inline void drv_get_key_seq(struct ieee80211_local *local,
3649352c19fSJohannes Berg 				   struct ieee80211_key *key,
3659352c19fSJohannes Berg 				   struct ieee80211_key_seq *seq)
36624487981SJohannes Berg {
3679352c19fSJohannes Berg 	if (local->ops->get_key_seq)
3689352c19fSJohannes Berg 		local->ops->get_key_seq(&local->hw, &key->conf, seq);
3699352c19fSJohannes Berg 	trace_drv_get_key_seq(local, &key->conf);
37024487981SJohannes Berg }
37124487981SJohannes Berg 
drv_set_frag_threshold(struct ieee80211_local * local,u32 value)372f23a4780SArik Nemtsov static inline int drv_set_frag_threshold(struct ieee80211_local *local,
373f23a4780SArik Nemtsov 					u32 value)
374f23a4780SArik Nemtsov {
375f23a4780SArik Nemtsov 	int ret = 0;
376f23a4780SArik Nemtsov 
377f23a4780SArik Nemtsov 	might_sleep();
378f23a4780SArik Nemtsov 
379f23a4780SArik Nemtsov 	trace_drv_set_frag_threshold(local, value);
380f23a4780SArik Nemtsov 	if (local->ops->set_frag_threshold)
381f23a4780SArik Nemtsov 		ret = local->ops->set_frag_threshold(&local->hw, value);
382f23a4780SArik Nemtsov 	trace_drv_return_int(local, ret);
383f23a4780SArik Nemtsov 	return ret;
384f23a4780SArik Nemtsov }
385f23a4780SArik Nemtsov 
drv_set_rts_threshold(struct ieee80211_local * local,u32 value)38624487981SJohannes Berg static inline int drv_set_rts_threshold(struct ieee80211_local *local,
38724487981SJohannes Berg 					u32 value)
38824487981SJohannes Berg {
3890a2b8bb2SJohannes Berg 	int ret = 0;
390e1781ed3SKalle Valo 
391e1781ed3SKalle Valo 	might_sleep();
392e1781ed3SKalle Valo 
3934efc76bdSJohannes Berg 	trace_drv_set_rts_threshold(local, value);
39424487981SJohannes Berg 	if (local->ops->set_rts_threshold)
3950a2b8bb2SJohannes Berg 		ret = local->ops->set_rts_threshold(&local->hw, value);
3964efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
3970a2b8bb2SJohannes Berg 	return ret;
39824487981SJohannes Berg }
39924487981SJohannes Berg 
drv_set_coverage_class(struct ieee80211_local * local,s16 value)400310bc676SLukáš Turek static inline int drv_set_coverage_class(struct ieee80211_local *local,
401a4bcaf55SLorenzo Bianconi 					 s16 value)
402310bc676SLukáš Turek {
403310bc676SLukáš Turek 	int ret = 0;
404310bc676SLukáš Turek 	might_sleep();
405310bc676SLukáš Turek 
4064efc76bdSJohannes Berg 	trace_drv_set_coverage_class(local, value);
407310bc676SLukáš Turek 	if (local->ops->set_coverage_class)
408310bc676SLukáš Turek 		local->ops->set_coverage_class(&local->hw, value);
409310bc676SLukáš Turek 	else
410310bc676SLukáš Turek 		ret = -EOPNOTSUPP;
411310bc676SLukáš Turek 
4124efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
413310bc676SLukáš Turek 	return ret;
414310bc676SLukáš Turek }
415310bc676SLukáš Turek 
drv_sta_notify(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,enum sta_notify_cmd cmd,struct ieee80211_sta * sta)41624487981SJohannes Berg static inline void drv_sta_notify(struct ieee80211_local *local,
41712375ef9SJohannes Berg 				  struct ieee80211_sub_if_data *sdata,
41824487981SJohannes Berg 				  enum sta_notify_cmd cmd,
41924487981SJohannes Berg 				  struct ieee80211_sta *sta)
42024487981SJohannes Berg {
421bc192f89SFelix Fietkau 	sdata = get_bss_sdata(sdata);
422f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
423f6837ba8SJohannes Berg 		return;
4247b7eab6fSJohannes Berg 
4254efc76bdSJohannes Berg 	trace_drv_sta_notify(local, sdata, cmd, sta);
42624487981SJohannes Berg 	if (local->ops->sta_notify)
42712375ef9SJohannes Berg 		local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta);
4284efc76bdSJohannes Berg 	trace_drv_return_void(local);
42924487981SJohannes Berg }
43024487981SJohannes Berg 
drv_sta_add(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_sta * sta)43134e89507SJohannes Berg static inline int drv_sta_add(struct ieee80211_local *local,
43234e89507SJohannes Berg 			      struct ieee80211_sub_if_data *sdata,
43334e89507SJohannes Berg 			      struct ieee80211_sta *sta)
43434e89507SJohannes Berg {
43534e89507SJohannes Berg 	int ret = 0;
43634e89507SJohannes Berg 
43734e89507SJohannes Berg 	might_sleep();
43834e89507SJohannes Berg 
439bc192f89SFelix Fietkau 	sdata = get_bss_sdata(sdata);
440f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
441f6837ba8SJohannes Berg 		return -EIO;
4427b7eab6fSJohannes Berg 
4434efc76bdSJohannes Berg 	trace_drv_sta_add(local, sdata, sta);
44434e89507SJohannes Berg 	if (local->ops->sta_add)
44534e89507SJohannes Berg 		ret = local->ops->sta_add(&local->hw, &sdata->vif, sta);
44634e89507SJohannes Berg 
4474efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
44834e89507SJohannes Berg 
44934e89507SJohannes Berg 	return ret;
45034e89507SJohannes Berg }
45134e89507SJohannes Berg 
drv_sta_remove(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_sta * sta)45234e89507SJohannes Berg static inline void drv_sta_remove(struct ieee80211_local *local,
45334e89507SJohannes Berg 				  struct ieee80211_sub_if_data *sdata,
45434e89507SJohannes Berg 				  struct ieee80211_sta *sta)
45534e89507SJohannes Berg {
45634e89507SJohannes Berg 	might_sleep();
45734e89507SJohannes Berg 
458bc192f89SFelix Fietkau 	sdata = get_bss_sdata(sdata);
459f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
460f6837ba8SJohannes Berg 		return;
4617b7eab6fSJohannes Berg 
4624efc76bdSJohannes Berg 	trace_drv_sta_remove(local, sdata, sta);
46334e89507SJohannes Berg 	if (local->ops->sta_remove)
46434e89507SJohannes Berg 		local->ops->sta_remove(&local->hw, &sdata->vif, sta);
46534e89507SJohannes Berg 
4664efc76bdSJohannes Berg 	trace_drv_return_void(local);
46734e89507SJohannes Berg }
46834e89507SJohannes Berg 
46977d2ece6SSujith Manoharan #ifdef CONFIG_MAC80211_DEBUGFS
drv_link_add_debugfs(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_bss_conf * link_conf,struct dentry * dir)470170cd6a6SBenjamin Berg static inline void drv_link_add_debugfs(struct ieee80211_local *local,
471170cd6a6SBenjamin Berg 					struct ieee80211_sub_if_data *sdata,
472170cd6a6SBenjamin Berg 					struct ieee80211_bss_conf *link_conf,
473170cd6a6SBenjamin Berg 					struct dentry *dir)
474170cd6a6SBenjamin Berg {
475170cd6a6SBenjamin Berg 	might_sleep();
476170cd6a6SBenjamin Berg 
477170cd6a6SBenjamin Berg 	sdata = get_bss_sdata(sdata);
478170cd6a6SBenjamin Berg 	if (!check_sdata_in_driver(sdata))
479170cd6a6SBenjamin Berg 		return;
480170cd6a6SBenjamin Berg 
481170cd6a6SBenjamin Berg 	if (local->ops->link_add_debugfs)
482170cd6a6SBenjamin Berg 		local->ops->link_add_debugfs(&local->hw, &sdata->vif,
483170cd6a6SBenjamin Berg 					     link_conf, dir);
484170cd6a6SBenjamin Berg }
485170cd6a6SBenjamin Berg 
drv_sta_add_debugfs(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_sta * sta,struct dentry * dir)48677d2ece6SSujith Manoharan static inline void drv_sta_add_debugfs(struct ieee80211_local *local,
48777d2ece6SSujith Manoharan 				       struct ieee80211_sub_if_data *sdata,
48877d2ece6SSujith Manoharan 				       struct ieee80211_sta *sta,
48977d2ece6SSujith Manoharan 				       struct dentry *dir)
49077d2ece6SSujith Manoharan {
49177d2ece6SSujith Manoharan 	might_sleep();
49277d2ece6SSujith Manoharan 
49377d2ece6SSujith Manoharan 	sdata = get_bss_sdata(sdata);
494f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
495f6837ba8SJohannes Berg 		return;
49677d2ece6SSujith Manoharan 
49777d2ece6SSujith Manoharan 	if (local->ops->sta_add_debugfs)
49877d2ece6SSujith Manoharan 		local->ops->sta_add_debugfs(&local->hw, &sdata->vif,
49977d2ece6SSujith Manoharan 					    sta, dir);
50077d2ece6SSujith Manoharan }
501d2caad52SBenjamin Berg 
drv_link_sta_add_debugfs(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_link_sta * link_sta,struct dentry * dir)502d2caad52SBenjamin Berg static inline void drv_link_sta_add_debugfs(struct ieee80211_local *local,
503d2caad52SBenjamin Berg 					    struct ieee80211_sub_if_data *sdata,
504d2caad52SBenjamin Berg 					    struct ieee80211_link_sta *link_sta,
505d2caad52SBenjamin Berg 					    struct dentry *dir)
506d2caad52SBenjamin Berg {
507d2caad52SBenjamin Berg 	might_sleep();
508d2caad52SBenjamin Berg 
509d2caad52SBenjamin Berg 	sdata = get_bss_sdata(sdata);
510d2caad52SBenjamin Berg 	if (!check_sdata_in_driver(sdata))
511d2caad52SBenjamin Berg 		return;
512d2caad52SBenjamin Berg 
513d2caad52SBenjamin Berg 	if (local->ops->link_sta_add_debugfs)
514d2caad52SBenjamin Berg 		local->ops->link_sta_add_debugfs(&local->hw, &sdata->vif,
515d2caad52SBenjamin Berg 						 link_sta, dir);
516d2caad52SBenjamin Berg }
51777d2ece6SSujith Manoharan #endif
51877d2ece6SSujith Manoharan 
drv_sta_pre_rcu_remove(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct sta_info * sta)5196a9d1b91SJohannes Berg static inline void drv_sta_pre_rcu_remove(struct ieee80211_local *local,
5206a9d1b91SJohannes Berg 					  struct ieee80211_sub_if_data *sdata,
5216a9d1b91SJohannes Berg 					  struct sta_info *sta)
5226a9d1b91SJohannes Berg {
5236a9d1b91SJohannes Berg 	might_sleep();
5246a9d1b91SJohannes Berg 
5256a9d1b91SJohannes Berg 	sdata = get_bss_sdata(sdata);
526f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
527f6837ba8SJohannes Berg 		return;
5286a9d1b91SJohannes Berg 
5296a9d1b91SJohannes Berg 	trace_drv_sta_pre_rcu_remove(local, sdata, &sta->sta);
5306a9d1b91SJohannes Berg 	if (local->ops->sta_pre_rcu_remove)
5316a9d1b91SJohannes Berg 		local->ops->sta_pre_rcu_remove(&local->hw, &sdata->vif,
5326a9d1b91SJohannes Berg 					       &sta->sta);
5336a9d1b91SJohannes Berg 	trace_drv_return_void(local);
5346a9d1b91SJohannes Berg }
5356a9d1b91SJohannes Berg 
536727da60bSDenys Vlasenko __must_check
537f09603a2SJohannes Berg int drv_sta_state(struct ieee80211_local *local,
538f09603a2SJohannes Berg 		  struct ieee80211_sub_if_data *sdata,
539f09603a2SJohannes Berg 		  struct sta_info *sta,
540f09603a2SJohannes Berg 		  enum ieee80211_sta_state old_state,
541727da60bSDenys Vlasenko 		  enum ieee80211_sta_state new_state);
542f09603a2SJohannes Berg 
543ba905bf4SAshok Raj Nagarajan __must_check
544ba905bf4SAshok Raj Nagarajan int drv_sta_set_txpwr(struct ieee80211_local *local,
545ba905bf4SAshok Raj Nagarajan 		      struct ieee80211_sub_if_data *sdata,
546ba905bf4SAshok Raj Nagarajan 		      struct sta_info *sta);
547ba905bf4SAshok Raj Nagarajan 
5484fbd572cSDenys Vlasenko void drv_sta_rc_update(struct ieee80211_local *local,
5498f727ef3SJohannes Berg 		       struct ieee80211_sub_if_data *sdata,
5504fbd572cSDenys Vlasenko 		       struct ieee80211_sta *sta, u32 changed);
5518f727ef3SJohannes Berg 
drv_sta_rate_tbl_update(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_sta * sta)552f815e2b3SJohannes Berg static inline void drv_sta_rate_tbl_update(struct ieee80211_local *local,
553f815e2b3SJohannes Berg 					   struct ieee80211_sub_if_data *sdata,
554f815e2b3SJohannes Berg 					   struct ieee80211_sta *sta)
555f815e2b3SJohannes Berg {
556f815e2b3SJohannes Berg 	sdata = get_bss_sdata(sdata);
557f815e2b3SJohannes Berg 	if (!check_sdata_in_driver(sdata))
558f815e2b3SJohannes Berg 		return;
559f815e2b3SJohannes Berg 
560f815e2b3SJohannes Berg 	trace_drv_sta_rate_tbl_update(local, sdata, sta);
561f815e2b3SJohannes Berg 	if (local->ops->sta_rate_tbl_update)
562f815e2b3SJohannes Berg 		local->ops->sta_rate_tbl_update(&local->hw, &sdata->vif, sta);
563f815e2b3SJohannes Berg 
564f815e2b3SJohannes Berg 	trace_drv_return_void(local);
565f815e2b3SJohannes Berg }
566f815e2b3SJohannes Berg 
drv_sta_statistics(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_sta * sta,struct station_info * sinfo)5672b9a7e1bSJohannes Berg static inline void drv_sta_statistics(struct ieee80211_local *local,
5682b9a7e1bSJohannes Berg 				      struct ieee80211_sub_if_data *sdata,
5692b9a7e1bSJohannes Berg 				      struct ieee80211_sta *sta,
5702b9a7e1bSJohannes Berg 				      struct station_info *sinfo)
5712b9a7e1bSJohannes Berg {
5722b9a7e1bSJohannes Berg 	sdata = get_bss_sdata(sdata);
5732b9a7e1bSJohannes Berg 	if (!check_sdata_in_driver(sdata))
5742b9a7e1bSJohannes Berg 		return;
5752b9a7e1bSJohannes Berg 
5762b9a7e1bSJohannes Berg 	trace_drv_sta_statistics(local, sdata, sta);
5772b9a7e1bSJohannes Berg 	if (local->ops->sta_statistics)
5782b9a7e1bSJohannes Berg 		local->ops->sta_statistics(&local->hw, &sdata->vif, sta, sinfo);
5792b9a7e1bSJohannes Berg 	trace_drv_return_void(local);
5802b9a7e1bSJohannes Berg }
5812b9a7e1bSJohannes Berg 
582b23dcd4aSDenys Vlasenko int drv_conf_tx(struct ieee80211_local *local,
583b3e2130bSJohannes Berg 		struct ieee80211_link_data *link, u16 ac,
584b23dcd4aSDenys Vlasenko 		const struct ieee80211_tx_queue_params *params);
58524487981SJohannes Berg 
586416eb9fcSDenys Vlasenko u64 drv_get_tsf(struct ieee80211_local *local,
587416eb9fcSDenys Vlasenko 		struct ieee80211_sub_if_data *sdata);
588416eb9fcSDenys Vlasenko void drv_set_tsf(struct ieee80211_local *local,
58937a41b4aSEliad Peller 		 struct ieee80211_sub_if_data *sdata,
590416eb9fcSDenys Vlasenko 		 u64 tsf);
591354d381bSPedersen, Thomas void drv_offset_tsf(struct ieee80211_local *local,
592354d381bSPedersen, Thomas 		    struct ieee80211_sub_if_data *sdata,
593354d381bSPedersen, Thomas 		    s64 offset);
594416eb9fcSDenys Vlasenko void drv_reset_tsf(struct ieee80211_local *local,
595416eb9fcSDenys Vlasenko 		   struct ieee80211_sub_if_data *sdata);
59624487981SJohannes Berg 
drv_tx_last_beacon(struct ieee80211_local * local)59724487981SJohannes Berg static inline int drv_tx_last_beacon(struct ieee80211_local *local)
59824487981SJohannes Berg {
59902582e9bSMasanari Iida 	int ret = 0; /* default unsupported op for less congestion */
600e1781ed3SKalle Valo 
601e1781ed3SKalle Valo 	might_sleep();
602e1781ed3SKalle Valo 
6034efc76bdSJohannes Berg 	trace_drv_tx_last_beacon(local);
60424487981SJohannes Berg 	if (local->ops->tx_last_beacon)
6050a2b8bb2SJohannes Berg 		ret = local->ops->tx_last_beacon(&local->hw);
6064efc76bdSJohannes Berg 	trace_drv_return_int(local, ret);
6070a2b8bb2SJohannes Berg 	return ret;
60824487981SJohannes Berg }
60924487981SJohannes Berg 
6106db96838SDenys Vlasenko int drv_ampdu_action(struct ieee80211_local *local,
61112375ef9SJohannes Berg 		     struct ieee80211_sub_if_data *sdata,
61250ea05efSSara Sharon 		     struct ieee80211_ampdu_params *params);
6131f87f7d3SJohannes Berg 
drv_get_survey(struct ieee80211_local * local,int idx,struct survey_info * survey)6141289723eSHolger Schurig static inline int drv_get_survey(struct ieee80211_local *local, int idx,
6151289723eSHolger Schurig 				struct survey_info *survey)
6161289723eSHolger Schurig {
6171289723eSHolger Schurig 	int ret = -EOPNOTSUPP;
618c466d4efSJohn W. Linville 
619c466d4efSJohn W. Linville 	trace_drv_get_survey(local, idx, survey);
620c466d4efSJohn W. Linville 
62135dd0509SHolger Schurig 	if (local->ops->get_survey)
6221289723eSHolger Schurig 		ret = local->ops->get_survey(&local->hw, idx, survey);
623c466d4efSJohn W. Linville 
624c466d4efSJohn W. Linville 	trace_drv_return_int(local, ret);
625c466d4efSJohn W. Linville 
6261289723eSHolger Schurig 	return ret;
6271289723eSHolger Schurig }
6281f87f7d3SJohannes Berg 
drv_rfkill_poll(struct ieee80211_local * local)6291f87f7d3SJohannes Berg static inline void drv_rfkill_poll(struct ieee80211_local *local)
6301f87f7d3SJohannes Berg {
631e1781ed3SKalle Valo 	might_sleep();
632e1781ed3SKalle Valo 
6331f87f7d3SJohannes Berg 	if (local->ops->rfkill_poll)
6341f87f7d3SJohannes Berg 		local->ops->rfkill_poll(&local->hw);
6351f87f7d3SJohannes Berg }
636a80f7c0bSJohannes Berg 
drv_flush(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,u32 queues,bool drop)63739ecc01dSJohannes Berg static inline void drv_flush(struct ieee80211_local *local,
63877be2c54SEmmanuel Grumbach 			     struct ieee80211_sub_if_data *sdata,
63939ecc01dSJohannes Berg 			     u32 queues, bool drop)
640a80f7c0bSJohannes Berg {
641*ee0db868SOldřich Jedlička 	struct ieee80211_vif *vif;
64277be2c54SEmmanuel Grumbach 
643e1781ed3SKalle Valo 	might_sleep();
644e1781ed3SKalle Valo 
645*ee0db868SOldřich Jedlička 	sdata = get_bss_sdata(sdata);
646*ee0db868SOldřich Jedlička 	vif = sdata ? &sdata->vif : NULL;
647*ee0db868SOldřich Jedlička 
648f6837ba8SJohannes Berg 	if (sdata && !check_sdata_in_driver(sdata))
649f6837ba8SJohannes Berg 		return;
65077be2c54SEmmanuel Grumbach 
65139ecc01dSJohannes Berg 	trace_drv_flush(local, queues, drop);
652a80f7c0bSJohannes Berg 	if (local->ops->flush)
65377be2c54SEmmanuel Grumbach 		local->ops->flush(&local->hw, vif, queues, drop);
6544efc76bdSJohannes Berg 	trace_drv_return_void(local);
655a80f7c0bSJohannes Berg }
6565ce6e438SJohannes Berg 
drv_flush_sta(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct sta_info * sta)657d00800a2SJohannes Berg static inline void drv_flush_sta(struct ieee80211_local *local,
658d00800a2SJohannes Berg 				 struct ieee80211_sub_if_data *sdata,
659d00800a2SJohannes Berg 				 struct sta_info *sta)
660d00800a2SJohannes Berg {
661d00800a2SJohannes Berg 	might_sleep();
662d00800a2SJohannes Berg 
663*ee0db868SOldřich Jedlička 	sdata = get_bss_sdata(sdata);
664*ee0db868SOldřich Jedlička 
665d00800a2SJohannes Berg 	if (sdata && !check_sdata_in_driver(sdata))
666d00800a2SJohannes Berg 		return;
667d00800a2SJohannes Berg 
668d00800a2SJohannes Berg 	trace_drv_flush_sta(local, sdata, &sta->sta);
669d00800a2SJohannes Berg 	if (local->ops->flush_sta)
670d00800a2SJohannes Berg 		local->ops->flush_sta(&local->hw, &sdata->vif, &sta->sta);
671d00800a2SJohannes Berg 	trace_drv_return_void(local);
672d00800a2SJohannes Berg }
673d00800a2SJohannes Berg 
drv_channel_switch(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_channel_switch * ch_switch)6745ce6e438SJohannes Berg static inline void drv_channel_switch(struct ieee80211_local *local,
6750f791eb4SLuciano Coelho 				      struct ieee80211_sub_if_data *sdata,
6765ce6e438SJohannes Berg 				      struct ieee80211_channel_switch *ch_switch)
6775ce6e438SJohannes Berg {
6785ce6e438SJohannes Berg 	might_sleep();
6795ce6e438SJohannes Berg 
6800f791eb4SLuciano Coelho 	trace_drv_channel_switch(local, sdata, ch_switch);
6810f791eb4SLuciano Coelho 	local->ops->channel_switch(&local->hw, &sdata->vif, ch_switch);
6824efc76bdSJohannes Berg 	trace_drv_return_void(local);
6835ce6e438SJohannes Berg }
6845ce6e438SJohannes Berg 
68515d96753SBruno Randolf 
drv_set_antenna(struct ieee80211_local * local,u32 tx_ant,u32 rx_ant)68615d96753SBruno Randolf static inline int drv_set_antenna(struct ieee80211_local *local,
68715d96753SBruno Randolf 				  u32 tx_ant, u32 rx_ant)
68815d96753SBruno Randolf {
68915d96753SBruno Randolf 	int ret = -EOPNOTSUPP;
69015d96753SBruno Randolf 	might_sleep();
69115d96753SBruno Randolf 	if (local->ops->set_antenna)
69215d96753SBruno Randolf 		ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant);
69315d96753SBruno Randolf 	trace_drv_set_antenna(local, tx_ant, rx_ant, ret);
69415d96753SBruno Randolf 	return ret;
69515d96753SBruno Randolf }
69615d96753SBruno Randolf 
drv_get_antenna(struct ieee80211_local * local,u32 * tx_ant,u32 * rx_ant)69715d96753SBruno Randolf static inline int drv_get_antenna(struct ieee80211_local *local,
69815d96753SBruno Randolf 				  u32 *tx_ant, u32 *rx_ant)
69915d96753SBruno Randolf {
70015d96753SBruno Randolf 	int ret = -EOPNOTSUPP;
70115d96753SBruno Randolf 	might_sleep();
70215d96753SBruno Randolf 	if (local->ops->get_antenna)
70315d96753SBruno Randolf 		ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant);
70415d96753SBruno Randolf 	trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret);
70515d96753SBruno Randolf 	return ret;
70615d96753SBruno Randolf }
70715d96753SBruno Randolf 
drv_remain_on_channel(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_channel * chan,unsigned int duration,enum ieee80211_roc_type type)70821f83589SJohannes Berg static inline int drv_remain_on_channel(struct ieee80211_local *local,
70949884568SEliad Peller 					struct ieee80211_sub_if_data *sdata,
71021f83589SJohannes Berg 					struct ieee80211_channel *chan,
711d339d5caSIlan Peer 					unsigned int duration,
712d339d5caSIlan Peer 					enum ieee80211_roc_type type)
71321f83589SJohannes Berg {
71421f83589SJohannes Berg 	int ret;
71521f83589SJohannes Berg 
71621f83589SJohannes Berg 	might_sleep();
71721f83589SJohannes Berg 
718d339d5caSIlan Peer 	trace_drv_remain_on_channel(local, sdata, chan, duration, type);
71949884568SEliad Peller 	ret = local->ops->remain_on_channel(&local->hw, &sdata->vif,
720d339d5caSIlan Peer 					    chan, duration, type);
72121f83589SJohannes Berg 	trace_drv_return_int(local, ret);
72221f83589SJohannes Berg 
72321f83589SJohannes Berg 	return ret;
72421f83589SJohannes Berg }
72521f83589SJohannes Berg 
7265db4c4b9SEmmanuel Grumbach static inline int
drv_cancel_remain_on_channel(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata)7275db4c4b9SEmmanuel Grumbach drv_cancel_remain_on_channel(struct ieee80211_local *local,
7285db4c4b9SEmmanuel Grumbach 			     struct ieee80211_sub_if_data *sdata)
72921f83589SJohannes Berg {
73021f83589SJohannes Berg 	int ret;
73121f83589SJohannes Berg 
73221f83589SJohannes Berg 	might_sleep();
73321f83589SJohannes Berg 
7345db4c4b9SEmmanuel Grumbach 	trace_drv_cancel_remain_on_channel(local, sdata);
7355db4c4b9SEmmanuel Grumbach 	ret = local->ops->cancel_remain_on_channel(&local->hw, &sdata->vif);
73621f83589SJohannes Berg 	trace_drv_return_int(local, ret);
73721f83589SJohannes Berg 
73821f83589SJohannes Berg 	return ret;
73921f83589SJohannes Berg }
74021f83589SJohannes Berg 
drv_set_ringparam(struct ieee80211_local * local,u32 tx,u32 rx)74138c09159SJohn W. Linville static inline int drv_set_ringparam(struct ieee80211_local *local,
74238c09159SJohn W. Linville 				    u32 tx, u32 rx)
74338c09159SJohn W. Linville {
74438c09159SJohn W. Linville 	int ret = -ENOTSUPP;
74538c09159SJohn W. Linville 
74638c09159SJohn W. Linville 	might_sleep();
74738c09159SJohn W. Linville 
74838c09159SJohn W. Linville 	trace_drv_set_ringparam(local, tx, rx);
74938c09159SJohn W. Linville 	if (local->ops->set_ringparam)
75038c09159SJohn W. Linville 		ret = local->ops->set_ringparam(&local->hw, tx, rx);
75138c09159SJohn W. Linville 	trace_drv_return_int(local, ret);
75238c09159SJohn W. Linville 
75338c09159SJohn W. Linville 	return ret;
75438c09159SJohn W. Linville }
75538c09159SJohn W. Linville 
drv_get_ringparam(struct ieee80211_local * local,u32 * tx,u32 * tx_max,u32 * rx,u32 * rx_max)75638c09159SJohn W. Linville static inline void drv_get_ringparam(struct ieee80211_local *local,
75738c09159SJohn W. Linville 				     u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
75838c09159SJohn W. Linville {
75938c09159SJohn W. Linville 	might_sleep();
76038c09159SJohn W. Linville 
76138c09159SJohn W. Linville 	trace_drv_get_ringparam(local, tx, tx_max, rx, rx_max);
76238c09159SJohn W. Linville 	if (local->ops->get_ringparam)
76338c09159SJohn W. Linville 		local->ops->get_ringparam(&local->hw, tx, tx_max, rx, rx_max);
76438c09159SJohn W. Linville 	trace_drv_return_void(local);
76538c09159SJohn W. Linville }
76638c09159SJohn W. Linville 
drv_tx_frames_pending(struct ieee80211_local * local)767e8306f98SVivek Natarajan static inline bool drv_tx_frames_pending(struct ieee80211_local *local)
768e8306f98SVivek Natarajan {
769e8306f98SVivek Natarajan 	bool ret = false;
770e8306f98SVivek Natarajan 
771e8306f98SVivek Natarajan 	might_sleep();
772e8306f98SVivek Natarajan 
773e8306f98SVivek Natarajan 	trace_drv_tx_frames_pending(local);
774e8306f98SVivek Natarajan 	if (local->ops->tx_frames_pending)
775e8306f98SVivek Natarajan 		ret = local->ops->tx_frames_pending(&local->hw);
776e8306f98SVivek Natarajan 	trace_drv_return_bool(local, ret);
777e8306f98SVivek Natarajan 
778e8306f98SVivek Natarajan 	return ret;
779e8306f98SVivek Natarajan }
780bdbfd6b5SSujith Manoharan 
drv_set_bitrate_mask(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,const struct cfg80211_bitrate_mask * mask)781bdbfd6b5SSujith Manoharan static inline int drv_set_bitrate_mask(struct ieee80211_local *local,
782bdbfd6b5SSujith Manoharan 				       struct ieee80211_sub_if_data *sdata,
783bdbfd6b5SSujith Manoharan 				       const struct cfg80211_bitrate_mask *mask)
784bdbfd6b5SSujith Manoharan {
785bdbfd6b5SSujith Manoharan 	int ret = -EOPNOTSUPP;
786bdbfd6b5SSujith Manoharan 
787bdbfd6b5SSujith Manoharan 	might_sleep();
788bdbfd6b5SSujith Manoharan 
789f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
790f6837ba8SJohannes Berg 		return -EIO;
7917b7eab6fSJohannes Berg 
792bdbfd6b5SSujith Manoharan 	trace_drv_set_bitrate_mask(local, sdata, mask);
793bdbfd6b5SSujith Manoharan 	if (local->ops->set_bitrate_mask)
794bdbfd6b5SSujith Manoharan 		ret = local->ops->set_bitrate_mask(&local->hw,
795bdbfd6b5SSujith Manoharan 						   &sdata->vif, mask);
796bdbfd6b5SSujith Manoharan 	trace_drv_return_int(local, ret);
797bdbfd6b5SSujith Manoharan 
798bdbfd6b5SSujith Manoharan 	return ret;
799bdbfd6b5SSujith Manoharan }
800bdbfd6b5SSujith Manoharan 
drv_set_rekey_data(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct cfg80211_gtk_rekey_data * data)801c68f4b89SJohannes Berg static inline void drv_set_rekey_data(struct ieee80211_local *local,
802c68f4b89SJohannes Berg 				      struct ieee80211_sub_if_data *sdata,
803c68f4b89SJohannes Berg 				      struct cfg80211_gtk_rekey_data *data)
804c68f4b89SJohannes Berg {
805f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
806f6837ba8SJohannes Berg 		return;
8077b7eab6fSJohannes Berg 
808c68f4b89SJohannes Berg 	trace_drv_set_rekey_data(local, sdata, data);
809c68f4b89SJohannes Berg 	if (local->ops->set_rekey_data)
810c68f4b89SJohannes Berg 		local->ops->set_rekey_data(&local->hw, &sdata->vif, data);
811c68f4b89SJohannes Berg 	trace_drv_return_void(local);
812c68f4b89SJohannes Berg }
813c68f4b89SJohannes Berg 
drv_event_callback(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,const struct ieee80211_event * event)814a8182929SEmmanuel Grumbach static inline void drv_event_callback(struct ieee80211_local *local,
815887da917SEmmanuel Grumbach 				      struct ieee80211_sub_if_data *sdata,
816a8182929SEmmanuel Grumbach 				      const struct ieee80211_event *event)
817615f7b9bSMeenakshi Venkataraman {
818a8182929SEmmanuel Grumbach 	trace_drv_event_callback(local, sdata, event);
819a8182929SEmmanuel Grumbach 	if (local->ops->event_callback)
820a8182929SEmmanuel Grumbach 		local->ops->event_callback(&local->hw, &sdata->vif, event);
821615f7b9bSMeenakshi Venkataraman 	trace_drv_return_void(local);
822615f7b9bSMeenakshi Venkataraman }
8234049e09aSJohannes Berg 
8244049e09aSJohannes Berg static inline void
drv_release_buffered_frames(struct ieee80211_local * local,struct sta_info * sta,u16 tids,int num_frames,enum ieee80211_frame_release_type reason,bool more_data)8254049e09aSJohannes Berg drv_release_buffered_frames(struct ieee80211_local *local,
8264049e09aSJohannes Berg 			    struct sta_info *sta, u16 tids, int num_frames,
8274049e09aSJohannes Berg 			    enum ieee80211_frame_release_type reason,
8284049e09aSJohannes Berg 			    bool more_data)
8294049e09aSJohannes Berg {
8304049e09aSJohannes Berg 	trace_drv_release_buffered_frames(local, &sta->sta, tids, num_frames,
8314049e09aSJohannes Berg 					  reason, more_data);
8324049e09aSJohannes Berg 	if (local->ops->release_buffered_frames)
8334049e09aSJohannes Berg 		local->ops->release_buffered_frames(&local->hw, &sta->sta, tids,
8344049e09aSJohannes Berg 						    num_frames, reason,
8354049e09aSJohannes Berg 						    more_data);
8364049e09aSJohannes Berg 	trace_drv_return_void(local);
8374049e09aSJohannes Berg }
83840b96408SJohannes Berg 
83940b96408SJohannes Berg static inline void
drv_allow_buffered_frames(struct ieee80211_local * local,struct sta_info * sta,u16 tids,int num_frames,enum ieee80211_frame_release_type reason,bool more_data)84040b96408SJohannes Berg drv_allow_buffered_frames(struct ieee80211_local *local,
84140b96408SJohannes Berg 			  struct sta_info *sta, u16 tids, int num_frames,
84240b96408SJohannes Berg 			  enum ieee80211_frame_release_type reason,
84340b96408SJohannes Berg 			  bool more_data)
84440b96408SJohannes Berg {
84540b96408SJohannes Berg 	trace_drv_allow_buffered_frames(local, &sta->sta, tids, num_frames,
84640b96408SJohannes Berg 					reason, more_data);
84740b96408SJohannes Berg 	if (local->ops->allow_buffered_frames)
84840b96408SJohannes Berg 		local->ops->allow_buffered_frames(&local->hw, &sta->sta,
84940b96408SJohannes Berg 						  tids, num_frames, reason,
85040b96408SJohannes Berg 						  more_data);
85140b96408SJohannes Berg 	trace_drv_return_void(local);
85240b96408SJohannes Berg }
85366572cfcSVictor Goldenshtein 
drv_mgd_prepare_tx(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_prep_tx_info * info)854a1845fc7SJohannes Berg static inline void drv_mgd_prepare_tx(struct ieee80211_local *local,
855d4e36e55SIlan Peer 				      struct ieee80211_sub_if_data *sdata,
85615fae341SJohannes Berg 				      struct ieee80211_prep_tx_info *info)
857a1845fc7SJohannes Berg {
858a1845fc7SJohannes Berg 	might_sleep();
859a1845fc7SJohannes Berg 
860f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
861f6837ba8SJohannes Berg 		return;
862a1845fc7SJohannes Berg 	WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
863a1845fc7SJohannes Berg 
86415fae341SJohannes Berg 	trace_drv_mgd_prepare_tx(local, sdata, info->duration,
86515fae341SJohannes Berg 				 info->subtype, info->success);
866a1845fc7SJohannes Berg 	if (local->ops->mgd_prepare_tx)
86715fae341SJohannes Berg 		local->ops->mgd_prepare_tx(&local->hw, &sdata->vif, info);
86815fae341SJohannes Berg 	trace_drv_return_void(local);
86915fae341SJohannes Berg }
87015fae341SJohannes Berg 
drv_mgd_complete_tx(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_prep_tx_info * info)87115fae341SJohannes Berg static inline void drv_mgd_complete_tx(struct ieee80211_local *local,
87215fae341SJohannes Berg 				       struct ieee80211_sub_if_data *sdata,
87315fae341SJohannes Berg 				       struct ieee80211_prep_tx_info *info)
87415fae341SJohannes Berg {
87515fae341SJohannes Berg 	might_sleep();
87615fae341SJohannes Berg 
87715fae341SJohannes Berg 	if (!check_sdata_in_driver(sdata))
87815fae341SJohannes Berg 		return;
87915fae341SJohannes Berg 	WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
88015fae341SJohannes Berg 
88115fae341SJohannes Berg 	trace_drv_mgd_complete_tx(local, sdata, info->duration,
88215fae341SJohannes Berg 				  info->subtype, info->success);
88315fae341SJohannes Berg 	if (local->ops->mgd_complete_tx)
88415fae341SJohannes Berg 		local->ops->mgd_complete_tx(&local->hw, &sdata->vif, info);
885a1845fc7SJohannes Berg 	trace_drv_return_void(local);
886a1845fc7SJohannes Berg }
887c3645eacSMichal Kazior 
888ee10f2c7SArik Nemtsov static inline void
drv_mgd_protect_tdls_discover(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata)889ee10f2c7SArik Nemtsov drv_mgd_protect_tdls_discover(struct ieee80211_local *local,
890ee10f2c7SArik Nemtsov 			      struct ieee80211_sub_if_data *sdata)
891ee10f2c7SArik Nemtsov {
892ee10f2c7SArik Nemtsov 	might_sleep();
893ee10f2c7SArik Nemtsov 
894ee10f2c7SArik Nemtsov 	if (!check_sdata_in_driver(sdata))
895ee10f2c7SArik Nemtsov 		return;
896ee10f2c7SArik Nemtsov 	WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
897ee10f2c7SArik Nemtsov 
898ee10f2c7SArik Nemtsov 	trace_drv_mgd_protect_tdls_discover(local, sdata);
899ee10f2c7SArik Nemtsov 	if (local->ops->mgd_protect_tdls_discover)
900ee10f2c7SArik Nemtsov 		local->ops->mgd_protect_tdls_discover(&local->hw, &sdata->vif);
901ee10f2c7SArik Nemtsov 	trace_drv_return_void(local);
902ee10f2c7SArik Nemtsov }
903ee10f2c7SArik Nemtsov 
drv_add_chanctx(struct ieee80211_local * local,struct ieee80211_chanctx * ctx)904c3645eacSMichal Kazior static inline int drv_add_chanctx(struct ieee80211_local *local,
905c3645eacSMichal Kazior 				  struct ieee80211_chanctx *ctx)
906c3645eacSMichal Kazior {
907c3645eacSMichal Kazior 	int ret = -EOPNOTSUPP;
908c3645eacSMichal Kazior 
909dcae9e02SChaitanya T K 	might_sleep();
910dcae9e02SChaitanya T K 
911c3645eacSMichal Kazior 	trace_drv_add_chanctx(local, ctx);
912c3645eacSMichal Kazior 	if (local->ops->add_chanctx)
913c3645eacSMichal Kazior 		ret = local->ops->add_chanctx(&local->hw, &ctx->conf);
914c3645eacSMichal Kazior 	trace_drv_return_int(local, ret);
9158a61af65SJohannes Berg 	if (!ret)
9168a61af65SJohannes Berg 		ctx->driver_present = true;
917c3645eacSMichal Kazior 
918c3645eacSMichal Kazior 	return ret;
919c3645eacSMichal Kazior }
920c3645eacSMichal Kazior 
drv_remove_chanctx(struct ieee80211_local * local,struct ieee80211_chanctx * ctx)921c3645eacSMichal Kazior static inline void drv_remove_chanctx(struct ieee80211_local *local,
922c3645eacSMichal Kazior 				      struct ieee80211_chanctx *ctx)
923c3645eacSMichal Kazior {
924dcae9e02SChaitanya T K 	might_sleep();
925dcae9e02SChaitanya T K 
926f6837ba8SJohannes Berg 	if (WARN_ON(!ctx->driver_present))
927f6837ba8SJohannes Berg 		return;
928f6837ba8SJohannes Berg 
929c3645eacSMichal Kazior 	trace_drv_remove_chanctx(local, ctx);
930c3645eacSMichal Kazior 	if (local->ops->remove_chanctx)
931c3645eacSMichal Kazior 		local->ops->remove_chanctx(&local->hw, &ctx->conf);
932c3645eacSMichal Kazior 	trace_drv_return_void(local);
9338a61af65SJohannes Berg 	ctx->driver_present = false;
934c3645eacSMichal Kazior }
935c3645eacSMichal Kazior 
drv_change_chanctx(struct ieee80211_local * local,struct ieee80211_chanctx * ctx,u32 changed)936c3645eacSMichal Kazior static inline void drv_change_chanctx(struct ieee80211_local *local,
937c3645eacSMichal Kazior 				      struct ieee80211_chanctx *ctx,
938c3645eacSMichal Kazior 				      u32 changed)
939c3645eacSMichal Kazior {
940dcae9e02SChaitanya T K 	might_sleep();
941dcae9e02SChaitanya T K 
942c3645eacSMichal Kazior 	trace_drv_change_chanctx(local, ctx, changed);
9438a61af65SJohannes Berg 	if (local->ops->change_chanctx) {
9448a61af65SJohannes Berg 		WARN_ON_ONCE(!ctx->driver_present);
945c3645eacSMichal Kazior 		local->ops->change_chanctx(&local->hw, &ctx->conf, changed);
9468a61af65SJohannes Berg 	}
947c3645eacSMichal Kazior 	trace_drv_return_void(local);
948c3645eacSMichal Kazior }
949c3645eacSMichal Kazior 
drv_verify_link_exists(struct ieee80211_sub_if_data * sdata,struct ieee80211_bss_conf * link_conf)950727eff4dSGregory Greenman static inline void drv_verify_link_exists(struct ieee80211_sub_if_data *sdata,
951727eff4dSGregory Greenman 					  struct ieee80211_bss_conf *link_conf)
952727eff4dSGregory Greenman {
953727eff4dSGregory Greenman 	/* deflink always exists, so need to check only for other links */
954727eff4dSGregory Greenman 	if (sdata->deflink.conf != link_conf)
955727eff4dSGregory Greenman 		sdata_assert_lock(sdata);
956727eff4dSGregory Greenman }
957727eff4dSGregory Greenman 
958efe9c2bfSJohannes Berg int drv_assign_vif_chanctx(struct ieee80211_local *local,
959c3645eacSMichal Kazior 			   struct ieee80211_sub_if_data *sdata,
960727eff4dSGregory Greenman 			   struct ieee80211_bss_conf *link_conf,
961efe9c2bfSJohannes Berg 			   struct ieee80211_chanctx *ctx);
962efe9c2bfSJohannes Berg void drv_unassign_vif_chanctx(struct ieee80211_local *local,
963c3645eacSMichal Kazior 			      struct ieee80211_sub_if_data *sdata,
964727eff4dSGregory Greenman 			      struct ieee80211_bss_conf *link_conf,
965efe9c2bfSJohannes Berg 			      struct ieee80211_chanctx *ctx);
96642677ed3SDenys Vlasenko int drv_switch_vif_chanctx(struct ieee80211_local *local,
9671a5f0c13SLuciano Coelho 			   struct ieee80211_vif_chanctx_switch *vifs,
96842677ed3SDenys Vlasenko 			   int n_vifs, enum ieee80211_chanctx_switch_mode mode);
9691a5f0c13SLuciano Coelho 
drv_start_ap(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_bss_conf * link_conf)9701041638fSJohannes Berg static inline int drv_start_ap(struct ieee80211_local *local,
971ae7ba17bSShaul Triebitz 			       struct ieee80211_sub_if_data *sdata,
972b327c84cSGregory Greenman 			       struct ieee80211_bss_conf *link_conf)
9731041638fSJohannes Berg {
9741041638fSJohannes Berg 	int ret = 0;
9751041638fSJohannes Berg 
976b327c84cSGregory Greenman 	/* make sure link_conf is protected */
977727eff4dSGregory Greenman 	drv_verify_link_exists(sdata, link_conf);
978b327c84cSGregory Greenman 
979dcae9e02SChaitanya T K 	might_sleep();
980dcae9e02SChaitanya T K 
981f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
982f6837ba8SJohannes Berg 		return -EIO;
9831041638fSJohannes Berg 
984b327c84cSGregory Greenman 	trace_drv_start_ap(local, sdata, link_conf);
9851041638fSJohannes Berg 	if (local->ops->start_ap)
986b327c84cSGregory Greenman 		ret = local->ops->start_ap(&local->hw, &sdata->vif, link_conf);
9871041638fSJohannes Berg 	trace_drv_return_int(local, ret);
9881041638fSJohannes Berg 	return ret;
9891041638fSJohannes Berg }
9901041638fSJohannes Berg 
drv_stop_ap(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_bss_conf * link_conf)9911041638fSJohannes Berg static inline void drv_stop_ap(struct ieee80211_local *local,
992ae7ba17bSShaul Triebitz 			       struct ieee80211_sub_if_data *sdata,
993b327c84cSGregory Greenman 			       struct ieee80211_bss_conf *link_conf)
9941041638fSJohannes Berg {
995b327c84cSGregory Greenman 	/* make sure link_conf is protected */
996727eff4dSGregory Greenman 	drv_verify_link_exists(sdata, link_conf);
997b327c84cSGregory Greenman 
998f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
999f6837ba8SJohannes Berg 		return;
10001041638fSJohannes Berg 
1001b327c84cSGregory Greenman 	trace_drv_stop_ap(local, sdata, link_conf);
10021041638fSJohannes Berg 	if (local->ops->stop_ap)
1003b327c84cSGregory Greenman 		local->ops->stop_ap(&local->hw, &sdata->vif, link_conf);
10041041638fSJohannes Berg 	trace_drv_return_void(local);
10051041638fSJohannes Berg }
10061041638fSJohannes Berg 
1007cf2c92d8SEliad Peller static inline void
drv_reconfig_complete(struct ieee80211_local * local,enum ieee80211_reconfig_type reconfig_type)1008cf2c92d8SEliad Peller drv_reconfig_complete(struct ieee80211_local *local,
1009cf2c92d8SEliad Peller 		      enum ieee80211_reconfig_type reconfig_type)
10109214ad7fSJohannes Berg {
10119214ad7fSJohannes Berg 	might_sleep();
10129214ad7fSJohannes Berg 
1013cf2c92d8SEliad Peller 	trace_drv_reconfig_complete(local, reconfig_type);
1014cf2c92d8SEliad Peller 	if (local->ops->reconfig_complete)
1015cf2c92d8SEliad Peller 		local->ops->reconfig_complete(&local->hw, reconfig_type);
10169214ad7fSJohannes Berg 	trace_drv_return_void(local);
10179214ad7fSJohannes Berg }
10189214ad7fSJohannes Berg 
1019de5fad81SYoni Divinsky static inline void
drv_set_default_unicast_key(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,int key_idx)1020de5fad81SYoni Divinsky drv_set_default_unicast_key(struct ieee80211_local *local,
1021de5fad81SYoni Divinsky 			    struct ieee80211_sub_if_data *sdata,
1022de5fad81SYoni Divinsky 			    int key_idx)
1023de5fad81SYoni Divinsky {
1024f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
1025f6837ba8SJohannes Berg 		return;
1026de5fad81SYoni Divinsky 
1027de5fad81SYoni Divinsky 	WARN_ON_ONCE(key_idx < -1 || key_idx > 3);
1028de5fad81SYoni Divinsky 
1029de5fad81SYoni Divinsky 	trace_drv_set_default_unicast_key(local, sdata, key_idx);
1030de5fad81SYoni Divinsky 	if (local->ops->set_default_unicast_key)
1031de5fad81SYoni Divinsky 		local->ops->set_default_unicast_key(&local->hw, &sdata->vif,
1032de5fad81SYoni Divinsky 						    key_idx);
1033de5fad81SYoni Divinsky 	trace_drv_return_void(local);
1034de5fad81SYoni Divinsky }
1035de5fad81SYoni Divinsky 
1036a65240c1SJohannes Berg #if IS_ENABLED(CONFIG_IPV6)
drv_ipv6_addr_change(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct inet6_dev * idev)1037a65240c1SJohannes Berg static inline void drv_ipv6_addr_change(struct ieee80211_local *local,
1038a65240c1SJohannes Berg 					struct ieee80211_sub_if_data *sdata,
1039a65240c1SJohannes Berg 					struct inet6_dev *idev)
1040a65240c1SJohannes Berg {
1041a65240c1SJohannes Berg 	trace_drv_ipv6_addr_change(local, sdata);
1042a65240c1SJohannes Berg 	if (local->ops->ipv6_addr_change)
1043a65240c1SJohannes Berg 		local->ops->ipv6_addr_change(&local->hw, &sdata->vif, idev);
1044a65240c1SJohannes Berg 	trace_drv_return_void(local);
1045a65240c1SJohannes Berg }
1046a65240c1SJohannes Berg #endif
1047a65240c1SJohannes Berg 
104873da7d5bSSimon Wunderlich static inline void
drv_channel_switch_beacon(struct ieee80211_sub_if_data * sdata,struct cfg80211_chan_def * chandef)104973da7d5bSSimon Wunderlich drv_channel_switch_beacon(struct ieee80211_sub_if_data *sdata,
105073da7d5bSSimon Wunderlich 			  struct cfg80211_chan_def *chandef)
105173da7d5bSSimon Wunderlich {
105273da7d5bSSimon Wunderlich 	struct ieee80211_local *local = sdata->local;
105373da7d5bSSimon Wunderlich 
105473da7d5bSSimon Wunderlich 	if (local->ops->channel_switch_beacon) {
105573da7d5bSSimon Wunderlich 		trace_drv_channel_switch_beacon(local, sdata, chandef);
105673da7d5bSSimon Wunderlich 		local->ops->channel_switch_beacon(&local->hw, &sdata->vif,
105773da7d5bSSimon Wunderlich 						  chandef);
105873da7d5bSSimon Wunderlich 	}
105973da7d5bSSimon Wunderlich }
106073da7d5bSSimon Wunderlich 
10616d027bccSLuciano Coelho static inline int
drv_pre_channel_switch(struct ieee80211_sub_if_data * sdata,struct ieee80211_channel_switch * ch_switch)10626d027bccSLuciano Coelho drv_pre_channel_switch(struct ieee80211_sub_if_data *sdata,
10636d027bccSLuciano Coelho 		       struct ieee80211_channel_switch *ch_switch)
10646d027bccSLuciano Coelho {
10656d027bccSLuciano Coelho 	struct ieee80211_local *local = sdata->local;
10666d027bccSLuciano Coelho 	int ret = 0;
10676d027bccSLuciano Coelho 
10686d027bccSLuciano Coelho 	if (!check_sdata_in_driver(sdata))
10696d027bccSLuciano Coelho 		return -EIO;
10706d027bccSLuciano Coelho 
10716d027bccSLuciano Coelho 	trace_drv_pre_channel_switch(local, sdata, ch_switch);
10726d027bccSLuciano Coelho 	if (local->ops->pre_channel_switch)
10736d027bccSLuciano Coelho 		ret = local->ops->pre_channel_switch(&local->hw, &sdata->vif,
10746d027bccSLuciano Coelho 						     ch_switch);
10756d027bccSLuciano Coelho 	trace_drv_return_int(local, ret);
10766d027bccSLuciano Coelho 	return ret;
10776d027bccSLuciano Coelho }
10786d027bccSLuciano Coelho 
1079f1d65583SLuciano Coelho static inline int
drv_post_channel_switch(struct ieee80211_sub_if_data * sdata)1080f1d65583SLuciano Coelho drv_post_channel_switch(struct ieee80211_sub_if_data *sdata)
1081f1d65583SLuciano Coelho {
1082f1d65583SLuciano Coelho 	struct ieee80211_local *local = sdata->local;
1083f1d65583SLuciano Coelho 	int ret = 0;
1084f1d65583SLuciano Coelho 
1085f1d65583SLuciano Coelho 	if (!check_sdata_in_driver(sdata))
1086f1d65583SLuciano Coelho 		return -EIO;
1087f1d65583SLuciano Coelho 
1088f1d65583SLuciano Coelho 	trace_drv_post_channel_switch(local, sdata);
1089f1d65583SLuciano Coelho 	if (local->ops->post_channel_switch)
1090f1d65583SLuciano Coelho 		ret = local->ops->post_channel_switch(&local->hw, &sdata->vif);
1091f1d65583SLuciano Coelho 	trace_drv_return_int(local, ret);
1092f1d65583SLuciano Coelho 	return ret;
1093f1d65583SLuciano Coelho }
1094f1d65583SLuciano Coelho 
1095b9cc81d8SSara Sharon static inline void
drv_abort_channel_switch(struct ieee80211_sub_if_data * sdata)1096b9cc81d8SSara Sharon drv_abort_channel_switch(struct ieee80211_sub_if_data *sdata)
1097b9cc81d8SSara Sharon {
1098b9cc81d8SSara Sharon 	struct ieee80211_local *local = sdata->local;
1099b9cc81d8SSara Sharon 
1100b9cc81d8SSara Sharon 	if (!check_sdata_in_driver(sdata))
1101b9cc81d8SSara Sharon 		return;
1102b9cc81d8SSara Sharon 
1103b9cc81d8SSara Sharon 	trace_drv_abort_channel_switch(local, sdata);
1104b9cc81d8SSara Sharon 
1105b9cc81d8SSara Sharon 	if (local->ops->abort_channel_switch)
1106b9cc81d8SSara Sharon 		local->ops->abort_channel_switch(&local->hw, &sdata->vif);
1107b9cc81d8SSara Sharon }
1108b9cc81d8SSara Sharon 
1109fafd2bceSSara Sharon static inline void
drv_channel_switch_rx_beacon(struct ieee80211_sub_if_data * sdata,struct ieee80211_channel_switch * ch_switch)1110fafd2bceSSara Sharon drv_channel_switch_rx_beacon(struct ieee80211_sub_if_data *sdata,
1111fafd2bceSSara Sharon 			     struct ieee80211_channel_switch *ch_switch)
1112fafd2bceSSara Sharon {
1113fafd2bceSSara Sharon 	struct ieee80211_local *local = sdata->local;
1114fafd2bceSSara Sharon 
1115fafd2bceSSara Sharon 	if (!check_sdata_in_driver(sdata))
1116fafd2bceSSara Sharon 		return;
1117fafd2bceSSara Sharon 
1118fafd2bceSSara Sharon 	trace_drv_channel_switch_rx_beacon(local, sdata, ch_switch);
1119fafd2bceSSara Sharon 	if (local->ops->channel_switch_rx_beacon)
1120fafd2bceSSara Sharon 		local->ops->channel_switch_rx_beacon(&local->hw, &sdata->vif,
1121fafd2bceSSara Sharon 						     ch_switch);
1122fafd2bceSSara Sharon }
1123fafd2bceSSara Sharon 
drv_join_ibss(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata)112455fff501SJohannes Berg static inline int drv_join_ibss(struct ieee80211_local *local,
112555fff501SJohannes Berg 				struct ieee80211_sub_if_data *sdata)
112655fff501SJohannes Berg {
112755fff501SJohannes Berg 	int ret = 0;
112855fff501SJohannes Berg 
112955fff501SJohannes Berg 	might_sleep();
1130f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
1131f6837ba8SJohannes Berg 		return -EIO;
113255fff501SJohannes Berg 
113355fff501SJohannes Berg 	trace_drv_join_ibss(local, sdata, &sdata->vif.bss_conf);
113455fff501SJohannes Berg 	if (local->ops->join_ibss)
113555fff501SJohannes Berg 		ret = local->ops->join_ibss(&local->hw, &sdata->vif);
113655fff501SJohannes Berg 	trace_drv_return_int(local, ret);
113755fff501SJohannes Berg 	return ret;
113855fff501SJohannes Berg }
113955fff501SJohannes Berg 
drv_leave_ibss(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata)114055fff501SJohannes Berg static inline void drv_leave_ibss(struct ieee80211_local *local,
114155fff501SJohannes Berg 				  struct ieee80211_sub_if_data *sdata)
114255fff501SJohannes Berg {
114355fff501SJohannes Berg 	might_sleep();
1144f6837ba8SJohannes Berg 	if (!check_sdata_in_driver(sdata))
1145f6837ba8SJohannes Berg 		return;
114655fff501SJohannes Berg 
114755fff501SJohannes Berg 	trace_drv_leave_ibss(local, sdata);
114855fff501SJohannes Berg 	if (local->ops->leave_ibss)
114955fff501SJohannes Berg 		local->ops->leave_ibss(&local->hw, &sdata->vif);
115055fff501SJohannes Berg 	trace_drv_return_void(local);
115155fff501SJohannes Berg }
115255fff501SJohannes Berg 
drv_get_expected_throughput(struct ieee80211_local * local,struct sta_info * sta)1153cca674d4SAntonio Quartulli static inline u32 drv_get_expected_throughput(struct ieee80211_local *local,
11544fdbc67aSMaxim Altshul 					      struct sta_info *sta)
1155cca674d4SAntonio Quartulli {
1156cca674d4SAntonio Quartulli 	u32 ret = 0;
1157cca674d4SAntonio Quartulli 
11584fdbc67aSMaxim Altshul 	trace_drv_get_expected_throughput(&sta->sta);
11594fdbc67aSMaxim Altshul 	if (local->ops->get_expected_throughput && sta->uploaded)
11604fdbc67aSMaxim Altshul 		ret = local->ops->get_expected_throughput(&local->hw, &sta->sta);
1161cca674d4SAntonio Quartulli 	trace_drv_return_u32(local, ret);
1162cca674d4SAntonio Quartulli 
1163cca674d4SAntonio Quartulli 	return ret;
1164cca674d4SAntonio Quartulli }
1165cca674d4SAntonio Quartulli 
drv_get_txpower(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,int * dbm)11665b3dc42bSFelix Fietkau static inline int drv_get_txpower(struct ieee80211_local *local,
11675b3dc42bSFelix Fietkau 				  struct ieee80211_sub_if_data *sdata, int *dbm)
11685b3dc42bSFelix Fietkau {
11695b3dc42bSFelix Fietkau 	int ret;
11705b3dc42bSFelix Fietkau 
11715b3dc42bSFelix Fietkau 	if (!local->ops->get_txpower)
11725b3dc42bSFelix Fietkau 		return -EOPNOTSUPP;
11735b3dc42bSFelix Fietkau 
11745b3dc42bSFelix Fietkau 	ret = local->ops->get_txpower(&local->hw, &sdata->vif, dbm);
11755b3dc42bSFelix Fietkau 	trace_drv_get_txpower(local, sdata, *dbm, ret);
11765b3dc42bSFelix Fietkau 
11775b3dc42bSFelix Fietkau 	return ret;
11785b3dc42bSFelix Fietkau }
11795b3dc42bSFelix Fietkau 
1180a7a6bdd0SArik Nemtsov static inline int
drv_tdls_channel_switch(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_sta * sta,u8 oper_class,struct cfg80211_chan_def * chandef,struct sk_buff * tmpl_skb,u32 ch_sw_tm_ie)1181a7a6bdd0SArik Nemtsov drv_tdls_channel_switch(struct ieee80211_local *local,
1182a7a6bdd0SArik Nemtsov 			struct ieee80211_sub_if_data *sdata,
1183a7a6bdd0SArik Nemtsov 			struct ieee80211_sta *sta, u8 oper_class,
1184a7a6bdd0SArik Nemtsov 			struct cfg80211_chan_def *chandef,
1185a7a6bdd0SArik Nemtsov 			struct sk_buff *tmpl_skb, u32 ch_sw_tm_ie)
1186a7a6bdd0SArik Nemtsov {
1187a7a6bdd0SArik Nemtsov 	int ret;
1188a7a6bdd0SArik Nemtsov 
1189a7a6bdd0SArik Nemtsov 	might_sleep();
1190a7a6bdd0SArik Nemtsov 	if (!check_sdata_in_driver(sdata))
1191a7a6bdd0SArik Nemtsov 		return -EIO;
1192a7a6bdd0SArik Nemtsov 
1193a7a6bdd0SArik Nemtsov 	if (!local->ops->tdls_channel_switch)
1194a7a6bdd0SArik Nemtsov 		return -EOPNOTSUPP;
1195a7a6bdd0SArik Nemtsov 
1196a7a6bdd0SArik Nemtsov 	trace_drv_tdls_channel_switch(local, sdata, sta, oper_class, chandef);
1197a7a6bdd0SArik Nemtsov 	ret = local->ops->tdls_channel_switch(&local->hw, &sdata->vif, sta,
1198a7a6bdd0SArik Nemtsov 					      oper_class, chandef, tmpl_skb,
1199a7a6bdd0SArik Nemtsov 					      ch_sw_tm_ie);
1200a7a6bdd0SArik Nemtsov 	trace_drv_return_int(local, ret);
1201a7a6bdd0SArik Nemtsov 	return ret;
1202a7a6bdd0SArik Nemtsov }
1203a7a6bdd0SArik Nemtsov 
1204a7a6bdd0SArik Nemtsov static inline void
drv_tdls_cancel_channel_switch(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_sta * sta)1205a7a6bdd0SArik Nemtsov drv_tdls_cancel_channel_switch(struct ieee80211_local *local,
1206a7a6bdd0SArik Nemtsov 			       struct ieee80211_sub_if_data *sdata,
1207a7a6bdd0SArik Nemtsov 			       struct ieee80211_sta *sta)
1208a7a6bdd0SArik Nemtsov {
1209a7a6bdd0SArik Nemtsov 	might_sleep();
1210a7a6bdd0SArik Nemtsov 	if (!check_sdata_in_driver(sdata))
1211a7a6bdd0SArik Nemtsov 		return;
1212a7a6bdd0SArik Nemtsov 
1213a7a6bdd0SArik Nemtsov 	if (!local->ops->tdls_cancel_channel_switch)
1214a7a6bdd0SArik Nemtsov 		return;
1215a7a6bdd0SArik Nemtsov 
1216a7a6bdd0SArik Nemtsov 	trace_drv_tdls_cancel_channel_switch(local, sdata, sta);
1217a7a6bdd0SArik Nemtsov 	local->ops->tdls_cancel_channel_switch(&local->hw, &sdata->vif, sta);
1218a7a6bdd0SArik Nemtsov 	trace_drv_return_void(local);
1219a7a6bdd0SArik Nemtsov }
1220a7a6bdd0SArik Nemtsov 
12218a4d32f3SArik Nemtsov static inline void
drv_tdls_recv_channel_switch(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_tdls_ch_sw_params * params)12228a4d32f3SArik Nemtsov drv_tdls_recv_channel_switch(struct ieee80211_local *local,
12238a4d32f3SArik Nemtsov 			     struct ieee80211_sub_if_data *sdata,
12248a4d32f3SArik Nemtsov 			     struct ieee80211_tdls_ch_sw_params *params)
12258a4d32f3SArik Nemtsov {
12268a4d32f3SArik Nemtsov 	trace_drv_tdls_recv_channel_switch(local, sdata, params);
12278a4d32f3SArik Nemtsov 	if (local->ops->tdls_recv_channel_switch)
12288a4d32f3SArik Nemtsov 		local->ops->tdls_recv_channel_switch(&local->hw, &sdata->vif,
12298a4d32f3SArik Nemtsov 						     params);
12308a4d32f3SArik Nemtsov 	trace_drv_return_void(local);
12318a4d32f3SArik Nemtsov }
12328a4d32f3SArik Nemtsov 
drv_wake_tx_queue(struct ieee80211_local * local,struct txq_info * txq)1233e7881bd5SJohannes Berg static inline void drv_wake_tx_queue(struct ieee80211_local *local,
1234e7881bd5SJohannes Berg 				     struct txq_info *txq)
1235ba8c3d6fSFelix Fietkau {
1236e7881bd5SJohannes Berg 	struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->txq.vif);
1237e7881bd5SJohannes Berg 
1238db7205afSJohannes Berg 	/* In reconfig don't transmit now, but mark for waking later */
1239db7205afSJohannes Berg 	if (local->in_reconfig) {
12404444bc21SAlexander Wetzel 		set_bit(IEEE80211_TXQ_DIRTY, &txq->flags);
12414856bfd2SFelix Fietkau 		return;
1242db7205afSJohannes Berg 	}
12434856bfd2SFelix Fietkau 
1244e7881bd5SJohannes Berg 	if (!check_sdata_in_driver(sdata))
1245e7881bd5SJohannes Berg 		return;
1246e7881bd5SJohannes Berg 
1247e7881bd5SJohannes Berg 	trace_drv_wake_tx_queue(local, sdata, txq);
1248e7881bd5SJohannes Berg 	local->ops->wake_tx_queue(&local->hw, &txq->txq);
1249ba8c3d6fSFelix Fietkau }
1250ba8c3d6fSFelix Fietkau 
schedule_and_wake_txq(struct ieee80211_local * local,struct txq_info * txqi)125118667600SToke Høiland-Jørgensen static inline void schedule_and_wake_txq(struct ieee80211_local *local,
125218667600SToke Høiland-Jørgensen 					 struct txq_info *txqi)
125318667600SToke Høiland-Jørgensen {
1254390298e8SToke Høiland-Jørgensen 	ieee80211_schedule_txq(&local->hw, &txqi->txq);
125518667600SToke Høiland-Jørgensen 	drv_wake_tx_queue(local, txqi);
125618667600SToke Høiland-Jørgensen }
125718667600SToke Høiland-Jørgensen 
drv_can_aggregate_in_amsdu(struct ieee80211_local * local,struct sk_buff * head,struct sk_buff * skb)12589739fe29SSara Sharon static inline int drv_can_aggregate_in_amsdu(struct ieee80211_local *local,
12599739fe29SSara Sharon 					     struct sk_buff *head,
12609739fe29SSara Sharon 					     struct sk_buff *skb)
12619739fe29SSara Sharon {
12629739fe29SSara Sharon 	if (!local->ops->can_aggregate_in_amsdu)
12639739fe29SSara Sharon 		return true;
12649739fe29SSara Sharon 
12659739fe29SSara Sharon 	return local->ops->can_aggregate_in_amsdu(&local->hw, head, skb);
12669739fe29SSara Sharon }
12679739fe29SSara Sharon 
1268bc847970SPradeep Kumar Chitrapu static inline int
drv_get_ftm_responder_stats(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct cfg80211_ftm_responder_stats * ftm_stats)1269bc847970SPradeep Kumar Chitrapu drv_get_ftm_responder_stats(struct ieee80211_local *local,
1270bc847970SPradeep Kumar Chitrapu 			    struct ieee80211_sub_if_data *sdata,
1271bc847970SPradeep Kumar Chitrapu 			    struct cfg80211_ftm_responder_stats *ftm_stats)
1272bc847970SPradeep Kumar Chitrapu {
1273bc847970SPradeep Kumar Chitrapu 	u32 ret = -EOPNOTSUPP;
1274bc847970SPradeep Kumar Chitrapu 
1275bc847970SPradeep Kumar Chitrapu 	if (local->ops->get_ftm_responder_stats)
1276bc847970SPradeep Kumar Chitrapu 		ret = local->ops->get_ftm_responder_stats(&local->hw,
1277bc847970SPradeep Kumar Chitrapu 							 &sdata->vif,
1278bc847970SPradeep Kumar Chitrapu 							 ftm_stats);
1279bc847970SPradeep Kumar Chitrapu 	trace_drv_get_ftm_responder_stats(local, sdata, ftm_stats);
1280bc847970SPradeep Kumar Chitrapu 
1281bc847970SPradeep Kumar Chitrapu 	return ret;
1282bc847970SPradeep Kumar Chitrapu }
1283bc847970SPradeep Kumar Chitrapu 
drv_start_pmsr(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct cfg80211_pmsr_request * request)1284cee7013bSJohannes Berg static inline int drv_start_pmsr(struct ieee80211_local *local,
1285cee7013bSJohannes Berg 				 struct ieee80211_sub_if_data *sdata,
1286cee7013bSJohannes Berg 				 struct cfg80211_pmsr_request *request)
1287cee7013bSJohannes Berg {
1288cee7013bSJohannes Berg 	int ret = -EOPNOTSUPP;
1289cee7013bSJohannes Berg 
1290cee7013bSJohannes Berg 	might_sleep();
1291cee7013bSJohannes Berg 	if (!check_sdata_in_driver(sdata))
1292cee7013bSJohannes Berg 		return -EIO;
1293cee7013bSJohannes Berg 
1294cee7013bSJohannes Berg 	trace_drv_start_pmsr(local, sdata);
1295cee7013bSJohannes Berg 
1296cee7013bSJohannes Berg 	if (local->ops->start_pmsr)
1297cee7013bSJohannes Berg 		ret = local->ops->start_pmsr(&local->hw, &sdata->vif, request);
1298cee7013bSJohannes Berg 	trace_drv_return_int(local, ret);
1299cee7013bSJohannes Berg 
1300cee7013bSJohannes Berg 	return ret;
1301cee7013bSJohannes Berg }
1302cee7013bSJohannes Berg 
drv_abort_pmsr(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct cfg80211_pmsr_request * request)1303cee7013bSJohannes Berg static inline void drv_abort_pmsr(struct ieee80211_local *local,
1304cee7013bSJohannes Berg 				  struct ieee80211_sub_if_data *sdata,
1305cee7013bSJohannes Berg 				  struct cfg80211_pmsr_request *request)
1306cee7013bSJohannes Berg {
1307cee7013bSJohannes Berg 	trace_drv_abort_pmsr(local, sdata);
1308cee7013bSJohannes Berg 
1309cee7013bSJohannes Berg 	might_sleep();
1310cee7013bSJohannes Berg 	if (!check_sdata_in_driver(sdata))
1311cee7013bSJohannes Berg 		return;
1312cee7013bSJohannes Berg 
1313cee7013bSJohannes Berg 	if (local->ops->abort_pmsr)
1314cee7013bSJohannes Berg 		local->ops->abort_pmsr(&local->hw, &sdata->vif, request);
1315cee7013bSJohannes Berg 	trace_drv_return_void(local);
1316cee7013bSJohannes Berg }
1317cee7013bSJohannes Berg 
drv_start_nan(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct cfg80211_nan_conf * conf)1318708d50edSAyala Beker static inline int drv_start_nan(struct ieee80211_local *local,
1319708d50edSAyala Beker 				struct ieee80211_sub_if_data *sdata,
1320708d50edSAyala Beker 				struct cfg80211_nan_conf *conf)
1321708d50edSAyala Beker {
1322708d50edSAyala Beker 	int ret;
1323708d50edSAyala Beker 
1324708d50edSAyala Beker 	might_sleep();
1325708d50edSAyala Beker 	check_sdata_in_driver(sdata);
1326708d50edSAyala Beker 
1327708d50edSAyala Beker 	trace_drv_start_nan(local, sdata, conf);
1328708d50edSAyala Beker 	ret = local->ops->start_nan(&local->hw, &sdata->vif, conf);
1329708d50edSAyala Beker 	trace_drv_return_int(local, ret);
1330708d50edSAyala Beker 	return ret;
1331708d50edSAyala Beker }
1332708d50edSAyala Beker 
drv_stop_nan(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata)1333708d50edSAyala Beker static inline void drv_stop_nan(struct ieee80211_local *local,
1334708d50edSAyala Beker 				struct ieee80211_sub_if_data *sdata)
1335708d50edSAyala Beker {
1336708d50edSAyala Beker 	might_sleep();
1337708d50edSAyala Beker 	check_sdata_in_driver(sdata);
1338708d50edSAyala Beker 
1339708d50edSAyala Beker 	trace_drv_stop_nan(local, sdata);
1340708d50edSAyala Beker 	local->ops->stop_nan(&local->hw, &sdata->vif);
1341708d50edSAyala Beker 	trace_drv_return_void(local);
1342708d50edSAyala Beker }
1343708d50edSAyala Beker 
drv_nan_change_conf(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct cfg80211_nan_conf * conf,u32 changes)13445953ff6dSAyala Beker static inline int drv_nan_change_conf(struct ieee80211_local *local,
13455953ff6dSAyala Beker 				       struct ieee80211_sub_if_data *sdata,
13465953ff6dSAyala Beker 				       struct cfg80211_nan_conf *conf,
13475953ff6dSAyala Beker 				       u32 changes)
13485953ff6dSAyala Beker {
13495953ff6dSAyala Beker 	int ret;
13505953ff6dSAyala Beker 
13515953ff6dSAyala Beker 	might_sleep();
13525953ff6dSAyala Beker 	check_sdata_in_driver(sdata);
13535953ff6dSAyala Beker 
13545953ff6dSAyala Beker 	if (!local->ops->nan_change_conf)
13555953ff6dSAyala Beker 		return -EOPNOTSUPP;
13565953ff6dSAyala Beker 
13575953ff6dSAyala Beker 	trace_drv_nan_change_conf(local, sdata, conf, changes);
13585953ff6dSAyala Beker 	ret = local->ops->nan_change_conf(&local->hw, &sdata->vif, conf,
13595953ff6dSAyala Beker 					  changes);
13605953ff6dSAyala Beker 	trace_drv_return_int(local, ret);
13615953ff6dSAyala Beker 
13625953ff6dSAyala Beker 	return ret;
13635953ff6dSAyala Beker }
13645953ff6dSAyala Beker 
drv_add_nan_func(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,const struct cfg80211_nan_func * nan_func)1365167e33f4SAyala Beker static inline int drv_add_nan_func(struct ieee80211_local *local,
1366167e33f4SAyala Beker 				   struct ieee80211_sub_if_data *sdata,
1367167e33f4SAyala Beker 				   const struct cfg80211_nan_func *nan_func)
1368167e33f4SAyala Beker {
1369167e33f4SAyala Beker 	int ret;
1370167e33f4SAyala Beker 
1371167e33f4SAyala Beker 	might_sleep();
1372167e33f4SAyala Beker 	check_sdata_in_driver(sdata);
1373167e33f4SAyala Beker 
1374167e33f4SAyala Beker 	if (!local->ops->add_nan_func)
1375167e33f4SAyala Beker 		return -EOPNOTSUPP;
1376167e33f4SAyala Beker 
1377167e33f4SAyala Beker 	trace_drv_add_nan_func(local, sdata, nan_func);
1378167e33f4SAyala Beker 	ret = local->ops->add_nan_func(&local->hw, &sdata->vif, nan_func);
1379167e33f4SAyala Beker 	trace_drv_return_int(local, ret);
1380167e33f4SAyala Beker 
1381167e33f4SAyala Beker 	return ret;
1382167e33f4SAyala Beker }
1383167e33f4SAyala Beker 
drv_del_nan_func(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,u8 instance_id)1384167e33f4SAyala Beker static inline void drv_del_nan_func(struct ieee80211_local *local,
1385167e33f4SAyala Beker 				   struct ieee80211_sub_if_data *sdata,
1386167e33f4SAyala Beker 				   u8 instance_id)
1387167e33f4SAyala Beker {
1388167e33f4SAyala Beker 	might_sleep();
1389167e33f4SAyala Beker 	check_sdata_in_driver(sdata);
1390167e33f4SAyala Beker 
1391167e33f4SAyala Beker 	trace_drv_del_nan_func(local, sdata, instance_id);
1392167e33f4SAyala Beker 	if (local->ops->del_nan_func)
1393167e33f4SAyala Beker 		local->ops->del_nan_func(&local->hw, &sdata->vif, instance_id);
1394167e33f4SAyala Beker 	trace_drv_return_void(local);
1395167e33f4SAyala Beker }
1396167e33f4SAyala Beker 
drv_set_tid_config(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_sta * sta,struct cfg80211_tid_config * tid_conf)1397370f51d5STamizh chelvam static inline int drv_set_tid_config(struct ieee80211_local *local,
1398370f51d5STamizh chelvam 				     struct ieee80211_sub_if_data *sdata,
1399370f51d5STamizh chelvam 				     struct ieee80211_sta *sta,
1400370f51d5STamizh chelvam 				     struct cfg80211_tid_config *tid_conf)
1401370f51d5STamizh chelvam {
1402370f51d5STamizh chelvam 	int ret;
1403370f51d5STamizh chelvam 
1404370f51d5STamizh chelvam 	might_sleep();
1405370f51d5STamizh chelvam 	ret = local->ops->set_tid_config(&local->hw, &sdata->vif, sta,
1406370f51d5STamizh chelvam 					 tid_conf);
1407370f51d5STamizh chelvam 	trace_drv_return_int(local, ret);
1408370f51d5STamizh chelvam 
1409370f51d5STamizh chelvam 	return ret;
1410370f51d5STamizh chelvam }
1411370f51d5STamizh chelvam 
drv_reset_tid_config(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_sta * sta,u8 tids)1412370f51d5STamizh chelvam static inline int drv_reset_tid_config(struct ieee80211_local *local,
1413370f51d5STamizh chelvam 				       struct ieee80211_sub_if_data *sdata,
141460c2ef0eSSergey Matyukevich 				       struct ieee80211_sta *sta, u8 tids)
1415370f51d5STamizh chelvam {
1416370f51d5STamizh chelvam 	int ret;
1417370f51d5STamizh chelvam 
1418370f51d5STamizh chelvam 	might_sleep();
141960c2ef0eSSergey Matyukevich 	ret = local->ops->reset_tid_config(&local->hw, &sdata->vif, sta, tids);
1420370f51d5STamizh chelvam 	trace_drv_return_int(local, ret);
1421370f51d5STamizh chelvam 
1422370f51d5STamizh chelvam 	return ret;
1423370f51d5STamizh chelvam }
14246aea26ceSFelix Fietkau 
drv_update_vif_offload(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata)14256aea26ceSFelix Fietkau static inline void drv_update_vif_offload(struct ieee80211_local *local,
14266aea26ceSFelix Fietkau 					  struct ieee80211_sub_if_data *sdata)
14276aea26ceSFelix Fietkau {
14286aea26ceSFelix Fietkau 	might_sleep();
14296aea26ceSFelix Fietkau 	check_sdata_in_driver(sdata);
14306aea26ceSFelix Fietkau 
14316aea26ceSFelix Fietkau 	if (!local->ops->update_vif_offload)
14326aea26ceSFelix Fietkau 		return;
14336aea26ceSFelix Fietkau 
14346aea26ceSFelix Fietkau 	trace_drv_update_vif_offload(local, sdata);
14356aea26ceSFelix Fietkau 	local->ops->update_vif_offload(&local->hw, &sdata->vif);
14366aea26ceSFelix Fietkau 	trace_drv_return_void(local);
14376aea26ceSFelix Fietkau }
14386aea26ceSFelix Fietkau 
drv_sta_set_4addr(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_sta * sta,bool enabled)14391ff4e8f2SFelix Fietkau static inline void drv_sta_set_4addr(struct ieee80211_local *local,
14401ff4e8f2SFelix Fietkau 				     struct ieee80211_sub_if_data *sdata,
14411ff4e8f2SFelix Fietkau 				     struct ieee80211_sta *sta, bool enabled)
14421ff4e8f2SFelix Fietkau {
14431ff4e8f2SFelix Fietkau 	sdata = get_bss_sdata(sdata);
14441ff4e8f2SFelix Fietkau 	if (!check_sdata_in_driver(sdata))
14451ff4e8f2SFelix Fietkau 		return;
14461ff4e8f2SFelix Fietkau 
14471ff4e8f2SFelix Fietkau 	trace_drv_sta_set_4addr(local, sdata, sta, enabled);
14481ff4e8f2SFelix Fietkau 	if (local->ops->sta_set_4addr)
14491ff4e8f2SFelix Fietkau 		local->ops->sta_set_4addr(&local->hw, &sdata->vif, sta, enabled);
14501ff4e8f2SFelix Fietkau 	trace_drv_return_void(local);
14511ff4e8f2SFelix Fietkau }
14521ff4e8f2SFelix Fietkau 
drv_sta_set_decap_offload(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_sta * sta,bool enabled)145380a915ecSFelix Fietkau static inline void drv_sta_set_decap_offload(struct ieee80211_local *local,
145480a915ecSFelix Fietkau 					     struct ieee80211_sub_if_data *sdata,
145580a915ecSFelix Fietkau 					     struct ieee80211_sta *sta,
145680a915ecSFelix Fietkau 					     bool enabled)
145780a915ecSFelix Fietkau {
145880a915ecSFelix Fietkau 	sdata = get_bss_sdata(sdata);
145980a915ecSFelix Fietkau 	if (!check_sdata_in_driver(sdata))
146080a915ecSFelix Fietkau 		return;
146180a915ecSFelix Fietkau 
146280a915ecSFelix Fietkau 	trace_drv_sta_set_decap_offload(local, sdata, sta, enabled);
146380a915ecSFelix Fietkau 	if (local->ops->sta_set_decap_offload)
146480a915ecSFelix Fietkau 		local->ops->sta_set_decap_offload(&local->hw, &sdata->vif, sta,
146580a915ecSFelix Fietkau 						  enabled);
146680a915ecSFelix Fietkau 	trace_drv_return_void(local);
146780a915ecSFelix Fietkau }
146880a915ecSFelix Fietkau 
drv_add_twt_setup(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_sta * sta,struct ieee80211_twt_setup * twt)1469f5a4c24eSLorenzo Bianconi static inline void drv_add_twt_setup(struct ieee80211_local *local,
1470f5a4c24eSLorenzo Bianconi 				     struct ieee80211_sub_if_data *sdata,
1471f5a4c24eSLorenzo Bianconi 				     struct ieee80211_sta *sta,
1472f5a4c24eSLorenzo Bianconi 				     struct ieee80211_twt_setup *twt)
1473f5a4c24eSLorenzo Bianconi {
1474f5a4c24eSLorenzo Bianconi 	struct ieee80211_twt_params *twt_agrt;
1475f5a4c24eSLorenzo Bianconi 
1476f5a4c24eSLorenzo Bianconi 	might_sleep();
1477f5a4c24eSLorenzo Bianconi 
1478f5a4c24eSLorenzo Bianconi 	if (!check_sdata_in_driver(sdata))
1479f5a4c24eSLorenzo Bianconi 		return;
1480f5a4c24eSLorenzo Bianconi 
1481f5a4c24eSLorenzo Bianconi 	twt_agrt = (void *)twt->params;
1482f5a4c24eSLorenzo Bianconi 
1483f5a4c24eSLorenzo Bianconi 	trace_drv_add_twt_setup(local, sta, twt, twt_agrt);
1484f5a4c24eSLorenzo Bianconi 	local->ops->add_twt_setup(&local->hw, sta, twt);
1485f5a4c24eSLorenzo Bianconi 	trace_drv_return_void(local);
1486f5a4c24eSLorenzo Bianconi }
1487f5a4c24eSLorenzo Bianconi 
drv_twt_teardown_request(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_sta * sta,u8 flowid)1488f5a4c24eSLorenzo Bianconi static inline void drv_twt_teardown_request(struct ieee80211_local *local,
1489f5a4c24eSLorenzo Bianconi 					    struct ieee80211_sub_if_data *sdata,
1490f5a4c24eSLorenzo Bianconi 					    struct ieee80211_sta *sta,
1491f5a4c24eSLorenzo Bianconi 					    u8 flowid)
1492f5a4c24eSLorenzo Bianconi {
1493f5a4c24eSLorenzo Bianconi 	might_sleep();
1494f5a4c24eSLorenzo Bianconi 	if (!check_sdata_in_driver(sdata))
1495f5a4c24eSLorenzo Bianconi 		return;
1496f5a4c24eSLorenzo Bianconi 
1497f5a4c24eSLorenzo Bianconi 	if (!local->ops->twt_teardown_request)
1498f5a4c24eSLorenzo Bianconi 		return;
1499f5a4c24eSLorenzo Bianconi 
1500f5a4c24eSLorenzo Bianconi 	trace_drv_twt_teardown_request(local, sta, flowid);
1501f5a4c24eSLorenzo Bianconi 	local->ops->twt_teardown_request(&local->hw, sta, flowid);
1502f5a4c24eSLorenzo Bianconi 	trace_drv_return_void(local);
1503f5a4c24eSLorenzo Bianconi }
1504f5a4c24eSLorenzo Bianconi 
drv_net_fill_forward_path(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct ieee80211_sta * sta,struct net_device_path_ctx * ctx,struct net_device_path * path)1505d787a3e3SFelix Fietkau static inline int drv_net_fill_forward_path(struct ieee80211_local *local,
1506d787a3e3SFelix Fietkau 					    struct ieee80211_sub_if_data *sdata,
1507d787a3e3SFelix Fietkau 					    struct ieee80211_sta *sta,
1508d787a3e3SFelix Fietkau 					    struct net_device_path_ctx *ctx,
1509d787a3e3SFelix Fietkau 					    struct net_device_path *path)
1510d787a3e3SFelix Fietkau {
1511d787a3e3SFelix Fietkau 	int ret = -EOPNOTSUPP;
1512d787a3e3SFelix Fietkau 
1513d787a3e3SFelix Fietkau 	sdata = get_bss_sdata(sdata);
1514d787a3e3SFelix Fietkau 	if (!check_sdata_in_driver(sdata))
1515d787a3e3SFelix Fietkau 		return -EIO;
1516d787a3e3SFelix Fietkau 
1517d787a3e3SFelix Fietkau 	trace_drv_net_fill_forward_path(local, sdata, sta);
1518d787a3e3SFelix Fietkau 	if (local->ops->net_fill_forward_path)
1519d787a3e3SFelix Fietkau 		ret = local->ops->net_fill_forward_path(&local->hw,
1520d787a3e3SFelix Fietkau 							&sdata->vif, sta,
1521d787a3e3SFelix Fietkau 							ctx, path);
1522d787a3e3SFelix Fietkau 	trace_drv_return_int(local, ret);
1523d787a3e3SFelix Fietkau 
1524d787a3e3SFelix Fietkau 	return ret;
1525d787a3e3SFelix Fietkau }
1526d787a3e3SFelix Fietkau 
drv_net_setup_tc(struct ieee80211_local * local,struct ieee80211_sub_if_data * sdata,struct net_device * dev,enum tc_setup_type type,void * type_data)152761587f15SFelix Fietkau static inline int drv_net_setup_tc(struct ieee80211_local *local,
152861587f15SFelix Fietkau 				   struct ieee80211_sub_if_data *sdata,
152961587f15SFelix Fietkau 				   struct net_device *dev,
153061587f15SFelix Fietkau 				   enum tc_setup_type type, void *type_data)
153161587f15SFelix Fietkau {
153261587f15SFelix Fietkau 	int ret = -EOPNOTSUPP;
153361587f15SFelix Fietkau 
153461587f15SFelix Fietkau 	sdata = get_bss_sdata(sdata);
153561587f15SFelix Fietkau 	trace_drv_net_setup_tc(local, sdata, type);
153661587f15SFelix Fietkau 	if (local->ops->net_setup_tc)
153761587f15SFelix Fietkau 		ret = local->ops->net_setup_tc(&local->hw, &sdata->vif, dev,
153861587f15SFelix Fietkau 					       type, type_data);
153961587f15SFelix Fietkau 	trace_drv_return_int(local, ret);
154061587f15SFelix Fietkau 
154161587f15SFelix Fietkau 	return ret;
154261587f15SFelix Fietkau }
154361587f15SFelix Fietkau 
1544efe9c2bfSJohannes Berg int drv_change_vif_links(struct ieee80211_local *local,
1545d8787ec6SJohannes Berg 			 struct ieee80211_sub_if_data *sdata,
1546d8787ec6SJohannes Berg 			 u16 old_links, u16 new_links,
1547efe9c2bfSJohannes Berg 			 struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS]);
1548efe9c2bfSJohannes Berg int drv_change_sta_links(struct ieee80211_local *local,
1549cb71f1d1SJohannes Berg 			 struct ieee80211_sub_if_data *sdata,
1550cb71f1d1SJohannes Berg 			 struct ieee80211_sta *sta,
1551efe9c2bfSJohannes Berg 			 u16 old_links, u16 new_links);
1552cb71f1d1SJohannes Berg 
155324487981SJohannes Berg #endif /* __MAC80211_DRIVER_OPS */
1554