1 /* SPDX-License-Identifier: GPL-2.0 */
3 * Portions of this file
4 * Copyright(c) 2016 Intel Deutschland GmbH
5 * Copyright (C) 2018 - 2019, 2021 Intel Corporation
8 #ifndef __MAC80211_DRIVER_OPS
9 #define __MAC80211_DRIVER_OPS
11 #include <net/mac80211.h>
12 #include "ieee80211_i.h"
15 #define check_sdata_in_driver(sdata) ({ \
16 !WARN_ONCE(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER), \
17 "%s: Failed check-sdata-in-driver check, flags: 0x%x\n", \
18 sdata->dev ? sdata->dev->name : sdata->name, sdata->flags); \
21 static inline struct ieee80211_sub_if_data *
22 get_bss_sdata(struct ieee80211_sub_if_data *sdata)
24 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
25 sdata = container_of(sdata->bss, struct ieee80211_sub_if_data,
31 static inline void drv_tx(struct ieee80211_local *local,
32 struct ieee80211_tx_control *control,
35 local->ops->tx(&local->hw, control, skb);
38 static inline void drv_sync_rx_queues(struct ieee80211_local *local,
41 if (local->ops->sync_rx_queues) {
42 trace_drv_sync_rx_queues(local, sta->sdata, &sta->sta);
43 local->ops->sync_rx_queues(&local->hw);
44 trace_drv_return_void(local);
48 static inline void drv_get_et_strings(struct ieee80211_sub_if_data *sdata,
51 struct ieee80211_local *local = sdata->local;
52 if (local->ops->get_et_strings) {
53 trace_drv_get_et_strings(local, sset);
54 local->ops->get_et_strings(&local->hw, &sdata->vif, sset, data);
55 trace_drv_return_void(local);
59 static inline void drv_get_et_stats(struct ieee80211_sub_if_data *sdata,
60 struct ethtool_stats *stats,
63 struct ieee80211_local *local = sdata->local;
64 if (local->ops->get_et_stats) {
65 trace_drv_get_et_stats(local);
66 local->ops->get_et_stats(&local->hw, &sdata->vif, stats, data);
67 trace_drv_return_void(local);
71 static inline int drv_get_et_sset_count(struct ieee80211_sub_if_data *sdata,
74 struct ieee80211_local *local = sdata->local;
76 if (local->ops->get_et_sset_count) {
77 trace_drv_get_et_sset_count(local, sset);
78 rv = local->ops->get_et_sset_count(&local->hw, &sdata->vif,
80 trace_drv_return_int(local, rv);
85 int drv_start(struct ieee80211_local *local);
86 void drv_stop(struct ieee80211_local *local);
89 static inline int drv_suspend(struct ieee80211_local *local,
90 struct cfg80211_wowlan *wowlan)
96 trace_drv_suspend(local);
97 ret = local->ops->suspend(&local->hw, wowlan);
98 trace_drv_return_int(local, ret);
102 static inline int drv_resume(struct ieee80211_local *local)
108 trace_drv_resume(local);
109 ret = local->ops->resume(&local->hw);
110 trace_drv_return_int(local, ret);
114 static inline void drv_set_wakeup(struct ieee80211_local *local,
119 if (!local->ops->set_wakeup)
122 trace_drv_set_wakeup(local, enabled);
123 local->ops->set_wakeup(&local->hw, enabled);
124 trace_drv_return_void(local);
128 int drv_add_interface(struct ieee80211_local *local,
129 struct ieee80211_sub_if_data *sdata);
131 int drv_change_interface(struct ieee80211_local *local,
132 struct ieee80211_sub_if_data *sdata,
133 enum nl80211_iftype type, bool p2p);
135 void drv_remove_interface(struct ieee80211_local *local,
136 struct ieee80211_sub_if_data *sdata);
138 static inline int drv_config(struct ieee80211_local *local, u32 changed)
144 trace_drv_config(local, changed);
145 ret = local->ops->config(&local->hw, changed);
146 trace_drv_return_int(local, ret);
150 static inline void drv_vif_cfg_changed(struct ieee80211_local *local,
151 struct ieee80211_sub_if_data *sdata,
156 if (!check_sdata_in_driver(sdata))
159 trace_drv_vif_cfg_changed(local, sdata, changed);
160 if (local->ops->vif_cfg_changed)
161 local->ops->vif_cfg_changed(&local->hw, &sdata->vif, changed);
162 else if (local->ops->bss_info_changed)
163 local->ops->bss_info_changed(&local->hw, &sdata->vif,
164 &sdata->vif.bss_conf, changed);
165 trace_drv_return_void(local);
168 static inline void drv_link_info_changed(struct ieee80211_local *local,
169 struct ieee80211_sub_if_data *sdata,
170 struct ieee80211_bss_conf *info,
171 int link_id, u64 changed)
175 if (WARN_ON_ONCE(changed & (BSS_CHANGED_BEACON |
176 BSS_CHANGED_BEACON_ENABLED) &&
177 sdata->vif.type != NL80211_IFTYPE_AP &&
178 sdata->vif.type != NL80211_IFTYPE_ADHOC &&
179 sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
180 sdata->vif.type != NL80211_IFTYPE_OCB))
183 if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE ||
184 sdata->vif.type == NL80211_IFTYPE_NAN ||
185 (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
186 !sdata->vif.bss_conf.mu_mimo_owner &&
187 !(changed & BSS_CHANGED_TXPOWER))))
190 if (!check_sdata_in_driver(sdata))
193 trace_drv_link_info_changed(local, sdata, info, changed);
194 if (local->ops->link_info_changed)
195 local->ops->link_info_changed(&local->hw, &sdata->vif,
197 else if (local->ops->bss_info_changed)
198 local->ops->bss_info_changed(&local->hw, &sdata->vif,
200 trace_drv_return_void(local);
203 static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
204 struct netdev_hw_addr_list *mc_list)
208 trace_drv_prepare_multicast(local, mc_list->count);
210 if (local->ops->prepare_multicast)
211 ret = local->ops->prepare_multicast(&local->hw, mc_list);
213 trace_drv_return_u64(local, ret);
218 static inline void drv_configure_filter(struct ieee80211_local *local,
219 unsigned int changed_flags,
220 unsigned int *total_flags,
225 trace_drv_configure_filter(local, changed_flags, total_flags,
227 local->ops->configure_filter(&local->hw, changed_flags, total_flags,
229 trace_drv_return_void(local);
232 static inline void drv_config_iface_filter(struct ieee80211_local *local,
233 struct ieee80211_sub_if_data *sdata,
234 unsigned int filter_flags,
235 unsigned int changed_flags)
239 trace_drv_config_iface_filter(local, sdata, filter_flags,
241 if (local->ops->config_iface_filter)
242 local->ops->config_iface_filter(&local->hw, &sdata->vif,
245 trace_drv_return_void(local);
248 static inline int drv_set_tim(struct ieee80211_local *local,
249 struct ieee80211_sta *sta, bool set)
252 trace_drv_set_tim(local, sta, set);
253 if (local->ops->set_tim)
254 ret = local->ops->set_tim(&local->hw, sta, set);
255 trace_drv_return_int(local, ret);
259 static inline int drv_set_key(struct ieee80211_local *local,
260 enum set_key_cmd cmd,
261 struct ieee80211_sub_if_data *sdata,
262 struct ieee80211_sta *sta,
263 struct ieee80211_key_conf *key)
269 sdata = get_bss_sdata(sdata);
270 if (!check_sdata_in_driver(sdata))
273 trace_drv_set_key(local, cmd, sdata, sta, key);
274 ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key);
275 trace_drv_return_int(local, ret);
279 static inline void drv_update_tkip_key(struct ieee80211_local *local,
280 struct ieee80211_sub_if_data *sdata,
281 struct ieee80211_key_conf *conf,
282 struct sta_info *sta, u32 iv32,
285 struct ieee80211_sta *ista = NULL;
290 sdata = get_bss_sdata(sdata);
291 if (!check_sdata_in_driver(sdata))
294 trace_drv_update_tkip_key(local, sdata, conf, ista, iv32);
295 if (local->ops->update_tkip_key)
296 local->ops->update_tkip_key(&local->hw, &sdata->vif, conf,
297 ista, iv32, phase1key);
298 trace_drv_return_void(local);
301 static inline int drv_hw_scan(struct ieee80211_local *local,
302 struct ieee80211_sub_if_data *sdata,
303 struct ieee80211_scan_request *req)
309 if (!check_sdata_in_driver(sdata))
312 trace_drv_hw_scan(local, sdata);
313 ret = local->ops->hw_scan(&local->hw, &sdata->vif, req);
314 trace_drv_return_int(local, ret);
318 static inline void drv_cancel_hw_scan(struct ieee80211_local *local,
319 struct ieee80211_sub_if_data *sdata)
323 if (!check_sdata_in_driver(sdata))
326 trace_drv_cancel_hw_scan(local, sdata);
327 local->ops->cancel_hw_scan(&local->hw, &sdata->vif);
328 trace_drv_return_void(local);
332 drv_sched_scan_start(struct ieee80211_local *local,
333 struct ieee80211_sub_if_data *sdata,
334 struct cfg80211_sched_scan_request *req,
335 struct ieee80211_scan_ies *ies)
341 if (!check_sdata_in_driver(sdata))
344 trace_drv_sched_scan_start(local, sdata);
345 ret = local->ops->sched_scan_start(&local->hw, &sdata->vif,
347 trace_drv_return_int(local, ret);
351 static inline int drv_sched_scan_stop(struct ieee80211_local *local,
352 struct ieee80211_sub_if_data *sdata)
358 if (!check_sdata_in_driver(sdata))
361 trace_drv_sched_scan_stop(local, sdata);
362 ret = local->ops->sched_scan_stop(&local->hw, &sdata->vif);
363 trace_drv_return_int(local, ret);
368 static inline void drv_sw_scan_start(struct ieee80211_local *local,
369 struct ieee80211_sub_if_data *sdata,
374 trace_drv_sw_scan_start(local, sdata, mac_addr);
375 if (local->ops->sw_scan_start)
376 local->ops->sw_scan_start(&local->hw, &sdata->vif, mac_addr);
377 trace_drv_return_void(local);
380 static inline void drv_sw_scan_complete(struct ieee80211_local *local,
381 struct ieee80211_sub_if_data *sdata)
385 trace_drv_sw_scan_complete(local, sdata);
386 if (local->ops->sw_scan_complete)
387 local->ops->sw_scan_complete(&local->hw, &sdata->vif);
388 trace_drv_return_void(local);
391 static inline int drv_get_stats(struct ieee80211_local *local,
392 struct ieee80211_low_level_stats *stats)
394 int ret = -EOPNOTSUPP;
398 if (local->ops->get_stats)
399 ret = local->ops->get_stats(&local->hw, stats);
400 trace_drv_get_stats(local, stats, ret);
405 static inline void drv_get_key_seq(struct ieee80211_local *local,
406 struct ieee80211_key *key,
407 struct ieee80211_key_seq *seq)
409 if (local->ops->get_key_seq)
410 local->ops->get_key_seq(&local->hw, &key->conf, seq);
411 trace_drv_get_key_seq(local, &key->conf);
414 static inline int drv_set_frag_threshold(struct ieee80211_local *local,
421 trace_drv_set_frag_threshold(local, value);
422 if (local->ops->set_frag_threshold)
423 ret = local->ops->set_frag_threshold(&local->hw, value);
424 trace_drv_return_int(local, ret);
428 static inline int drv_set_rts_threshold(struct ieee80211_local *local,
435 trace_drv_set_rts_threshold(local, value);
436 if (local->ops->set_rts_threshold)
437 ret = local->ops->set_rts_threshold(&local->hw, value);
438 trace_drv_return_int(local, ret);
442 static inline int drv_set_coverage_class(struct ieee80211_local *local,
448 trace_drv_set_coverage_class(local, value);
449 if (local->ops->set_coverage_class)
450 local->ops->set_coverage_class(&local->hw, value);
454 trace_drv_return_int(local, ret);
458 static inline void drv_sta_notify(struct ieee80211_local *local,
459 struct ieee80211_sub_if_data *sdata,
460 enum sta_notify_cmd cmd,
461 struct ieee80211_sta *sta)
463 sdata = get_bss_sdata(sdata);
464 if (!check_sdata_in_driver(sdata))
467 trace_drv_sta_notify(local, sdata, cmd, sta);
468 if (local->ops->sta_notify)
469 local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta);
470 trace_drv_return_void(local);
473 static inline int drv_sta_add(struct ieee80211_local *local,
474 struct ieee80211_sub_if_data *sdata,
475 struct ieee80211_sta *sta)
481 sdata = get_bss_sdata(sdata);
482 if (!check_sdata_in_driver(sdata))
485 trace_drv_sta_add(local, sdata, sta);
486 if (local->ops->sta_add)
487 ret = local->ops->sta_add(&local->hw, &sdata->vif, sta);
489 trace_drv_return_int(local, ret);
494 static inline void drv_sta_remove(struct ieee80211_local *local,
495 struct ieee80211_sub_if_data *sdata,
496 struct ieee80211_sta *sta)
500 sdata = get_bss_sdata(sdata);
501 if (!check_sdata_in_driver(sdata))
504 trace_drv_sta_remove(local, sdata, sta);
505 if (local->ops->sta_remove)
506 local->ops->sta_remove(&local->hw, &sdata->vif, sta);
508 trace_drv_return_void(local);
511 #ifdef CONFIG_MAC80211_DEBUGFS
512 static inline void drv_sta_add_debugfs(struct ieee80211_local *local,
513 struct ieee80211_sub_if_data *sdata,
514 struct ieee80211_sta *sta,
519 sdata = get_bss_sdata(sdata);
520 if (!check_sdata_in_driver(sdata))
523 if (local->ops->sta_add_debugfs)
524 local->ops->sta_add_debugfs(&local->hw, &sdata->vif,
529 static inline void drv_sta_pre_rcu_remove(struct ieee80211_local *local,
530 struct ieee80211_sub_if_data *sdata,
531 struct sta_info *sta)
535 sdata = get_bss_sdata(sdata);
536 if (!check_sdata_in_driver(sdata))
539 trace_drv_sta_pre_rcu_remove(local, sdata, &sta->sta);
540 if (local->ops->sta_pre_rcu_remove)
541 local->ops->sta_pre_rcu_remove(&local->hw, &sdata->vif,
543 trace_drv_return_void(local);
547 int drv_sta_state(struct ieee80211_local *local,
548 struct ieee80211_sub_if_data *sdata,
549 struct sta_info *sta,
550 enum ieee80211_sta_state old_state,
551 enum ieee80211_sta_state new_state);
554 int drv_sta_set_txpwr(struct ieee80211_local *local,
555 struct ieee80211_sub_if_data *sdata,
556 struct sta_info *sta);
558 void drv_sta_rc_update(struct ieee80211_local *local,
559 struct ieee80211_sub_if_data *sdata,
560 struct ieee80211_sta *sta, u32 changed);
562 static inline void drv_sta_rate_tbl_update(struct ieee80211_local *local,
563 struct ieee80211_sub_if_data *sdata,
564 struct ieee80211_sta *sta)
566 sdata = get_bss_sdata(sdata);
567 if (!check_sdata_in_driver(sdata))
570 trace_drv_sta_rate_tbl_update(local, sdata, sta);
571 if (local->ops->sta_rate_tbl_update)
572 local->ops->sta_rate_tbl_update(&local->hw, &sdata->vif, sta);
574 trace_drv_return_void(local);
577 static inline void drv_sta_statistics(struct ieee80211_local *local,
578 struct ieee80211_sub_if_data *sdata,
579 struct ieee80211_sta *sta,
580 struct station_info *sinfo)
582 sdata = get_bss_sdata(sdata);
583 if (!check_sdata_in_driver(sdata))
586 trace_drv_sta_statistics(local, sdata, sta);
587 if (local->ops->sta_statistics)
588 local->ops->sta_statistics(&local->hw, &sdata->vif, sta, sinfo);
589 trace_drv_return_void(local);
592 int drv_conf_tx(struct ieee80211_local *local,
593 struct ieee80211_link_data *link, u16 ac,
594 const struct ieee80211_tx_queue_params *params);
596 u64 drv_get_tsf(struct ieee80211_local *local,
597 struct ieee80211_sub_if_data *sdata);
598 void drv_set_tsf(struct ieee80211_local *local,
599 struct ieee80211_sub_if_data *sdata,
601 void drv_offset_tsf(struct ieee80211_local *local,
602 struct ieee80211_sub_if_data *sdata,
604 void drv_reset_tsf(struct ieee80211_local *local,
605 struct ieee80211_sub_if_data *sdata);
607 static inline int drv_tx_last_beacon(struct ieee80211_local *local)
609 int ret = 0; /* default unsupported op for less congestion */
613 trace_drv_tx_last_beacon(local);
614 if (local->ops->tx_last_beacon)
615 ret = local->ops->tx_last_beacon(&local->hw);
616 trace_drv_return_int(local, ret);
620 int drv_ampdu_action(struct ieee80211_local *local,
621 struct ieee80211_sub_if_data *sdata,
622 struct ieee80211_ampdu_params *params);
624 static inline int drv_get_survey(struct ieee80211_local *local, int idx,
625 struct survey_info *survey)
627 int ret = -EOPNOTSUPP;
629 trace_drv_get_survey(local, idx, survey);
631 if (local->ops->get_survey)
632 ret = local->ops->get_survey(&local->hw, idx, survey);
634 trace_drv_return_int(local, ret);
639 static inline void drv_rfkill_poll(struct ieee80211_local *local)
643 if (local->ops->rfkill_poll)
644 local->ops->rfkill_poll(&local->hw);
647 static inline void drv_flush(struct ieee80211_local *local,
648 struct ieee80211_sub_if_data *sdata,
649 u32 queues, bool drop)
651 struct ieee80211_vif *vif = sdata ? &sdata->vif : NULL;
655 if (sdata && !check_sdata_in_driver(sdata))
658 trace_drv_flush(local, queues, drop);
659 if (local->ops->flush)
660 local->ops->flush(&local->hw, vif, queues, drop);
661 trace_drv_return_void(local);
664 static inline void drv_channel_switch(struct ieee80211_local *local,
665 struct ieee80211_sub_if_data *sdata,
666 struct ieee80211_channel_switch *ch_switch)
670 trace_drv_channel_switch(local, sdata, ch_switch);
671 local->ops->channel_switch(&local->hw, &sdata->vif, ch_switch);
672 trace_drv_return_void(local);
676 static inline int drv_set_antenna(struct ieee80211_local *local,
677 u32 tx_ant, u32 rx_ant)
679 int ret = -EOPNOTSUPP;
681 if (local->ops->set_antenna)
682 ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant);
683 trace_drv_set_antenna(local, tx_ant, rx_ant, ret);
687 static inline int drv_get_antenna(struct ieee80211_local *local,
688 u32 *tx_ant, u32 *rx_ant)
690 int ret = -EOPNOTSUPP;
692 if (local->ops->get_antenna)
693 ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant);
694 trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret);
698 static inline int drv_remain_on_channel(struct ieee80211_local *local,
699 struct ieee80211_sub_if_data *sdata,
700 struct ieee80211_channel *chan,
701 unsigned int duration,
702 enum ieee80211_roc_type type)
708 trace_drv_remain_on_channel(local, sdata, chan, duration, type);
709 ret = local->ops->remain_on_channel(&local->hw, &sdata->vif,
710 chan, duration, type);
711 trace_drv_return_int(local, ret);
717 drv_cancel_remain_on_channel(struct ieee80211_local *local,
718 struct ieee80211_sub_if_data *sdata)
724 trace_drv_cancel_remain_on_channel(local, sdata);
725 ret = local->ops->cancel_remain_on_channel(&local->hw, &sdata->vif);
726 trace_drv_return_int(local, ret);
731 static inline int drv_set_ringparam(struct ieee80211_local *local,
738 trace_drv_set_ringparam(local, tx, rx);
739 if (local->ops->set_ringparam)
740 ret = local->ops->set_ringparam(&local->hw, tx, rx);
741 trace_drv_return_int(local, ret);
746 static inline void drv_get_ringparam(struct ieee80211_local *local,
747 u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
751 trace_drv_get_ringparam(local, tx, tx_max, rx, rx_max);
752 if (local->ops->get_ringparam)
753 local->ops->get_ringparam(&local->hw, tx, tx_max, rx, rx_max);
754 trace_drv_return_void(local);
757 static inline bool drv_tx_frames_pending(struct ieee80211_local *local)
763 trace_drv_tx_frames_pending(local);
764 if (local->ops->tx_frames_pending)
765 ret = local->ops->tx_frames_pending(&local->hw);
766 trace_drv_return_bool(local, ret);
771 static inline int drv_set_bitrate_mask(struct ieee80211_local *local,
772 struct ieee80211_sub_if_data *sdata,
773 const struct cfg80211_bitrate_mask *mask)
775 int ret = -EOPNOTSUPP;
779 if (!check_sdata_in_driver(sdata))
782 trace_drv_set_bitrate_mask(local, sdata, mask);
783 if (local->ops->set_bitrate_mask)
784 ret = local->ops->set_bitrate_mask(&local->hw,
786 trace_drv_return_int(local, ret);
791 static inline void drv_set_rekey_data(struct ieee80211_local *local,
792 struct ieee80211_sub_if_data *sdata,
793 struct cfg80211_gtk_rekey_data *data)
795 if (!check_sdata_in_driver(sdata))
798 trace_drv_set_rekey_data(local, sdata, data);
799 if (local->ops->set_rekey_data)
800 local->ops->set_rekey_data(&local->hw, &sdata->vif, data);
801 trace_drv_return_void(local);
804 static inline void drv_event_callback(struct ieee80211_local *local,
805 struct ieee80211_sub_if_data *sdata,
806 const struct ieee80211_event *event)
808 trace_drv_event_callback(local, sdata, event);
809 if (local->ops->event_callback)
810 local->ops->event_callback(&local->hw, &sdata->vif, event);
811 trace_drv_return_void(local);
815 drv_release_buffered_frames(struct ieee80211_local *local,
816 struct sta_info *sta, u16 tids, int num_frames,
817 enum ieee80211_frame_release_type reason,
820 trace_drv_release_buffered_frames(local, &sta->sta, tids, num_frames,
822 if (local->ops->release_buffered_frames)
823 local->ops->release_buffered_frames(&local->hw, &sta->sta, tids,
826 trace_drv_return_void(local);
830 drv_allow_buffered_frames(struct ieee80211_local *local,
831 struct sta_info *sta, u16 tids, int num_frames,
832 enum ieee80211_frame_release_type reason,
835 trace_drv_allow_buffered_frames(local, &sta->sta, tids, num_frames,
837 if (local->ops->allow_buffered_frames)
838 local->ops->allow_buffered_frames(&local->hw, &sta->sta,
839 tids, num_frames, reason,
841 trace_drv_return_void(local);
844 static inline void drv_mgd_prepare_tx(struct ieee80211_local *local,
845 struct ieee80211_sub_if_data *sdata,
846 struct ieee80211_prep_tx_info *info)
850 if (!check_sdata_in_driver(sdata))
852 WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
854 trace_drv_mgd_prepare_tx(local, sdata, info->duration,
855 info->subtype, info->success);
856 if (local->ops->mgd_prepare_tx)
857 local->ops->mgd_prepare_tx(&local->hw, &sdata->vif, info);
858 trace_drv_return_void(local);
861 static inline void drv_mgd_complete_tx(struct ieee80211_local *local,
862 struct ieee80211_sub_if_data *sdata,
863 struct ieee80211_prep_tx_info *info)
867 if (!check_sdata_in_driver(sdata))
869 WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
871 trace_drv_mgd_complete_tx(local, sdata, info->duration,
872 info->subtype, info->success);
873 if (local->ops->mgd_complete_tx)
874 local->ops->mgd_complete_tx(&local->hw, &sdata->vif, info);
875 trace_drv_return_void(local);
879 drv_mgd_protect_tdls_discover(struct ieee80211_local *local,
880 struct ieee80211_sub_if_data *sdata)
884 if (!check_sdata_in_driver(sdata))
886 WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION);
888 trace_drv_mgd_protect_tdls_discover(local, sdata);
889 if (local->ops->mgd_protect_tdls_discover)
890 local->ops->mgd_protect_tdls_discover(&local->hw, &sdata->vif);
891 trace_drv_return_void(local);
894 static inline int drv_add_chanctx(struct ieee80211_local *local,
895 struct ieee80211_chanctx *ctx)
897 int ret = -EOPNOTSUPP;
901 trace_drv_add_chanctx(local, ctx);
902 if (local->ops->add_chanctx)
903 ret = local->ops->add_chanctx(&local->hw, &ctx->conf);
904 trace_drv_return_int(local, ret);
906 ctx->driver_present = true;
911 static inline void drv_remove_chanctx(struct ieee80211_local *local,
912 struct ieee80211_chanctx *ctx)
916 if (WARN_ON(!ctx->driver_present))
919 trace_drv_remove_chanctx(local, ctx);
920 if (local->ops->remove_chanctx)
921 local->ops->remove_chanctx(&local->hw, &ctx->conf);
922 trace_drv_return_void(local);
923 ctx->driver_present = false;
926 static inline void drv_change_chanctx(struct ieee80211_local *local,
927 struct ieee80211_chanctx *ctx,
932 trace_drv_change_chanctx(local, ctx, changed);
933 if (local->ops->change_chanctx) {
934 WARN_ON_ONCE(!ctx->driver_present);
935 local->ops->change_chanctx(&local->hw, &ctx->conf, changed);
937 trace_drv_return_void(local);
940 static inline void drv_verify_link_exists(struct ieee80211_sub_if_data *sdata,
941 struct ieee80211_bss_conf *link_conf)
943 /* deflink always exists, so need to check only for other links */
944 if (sdata->deflink.conf != link_conf)
945 sdata_assert_lock(sdata);
948 static inline int drv_assign_vif_chanctx(struct ieee80211_local *local,
949 struct ieee80211_sub_if_data *sdata,
950 struct ieee80211_bss_conf *link_conf,
951 struct ieee80211_chanctx *ctx)
955 drv_verify_link_exists(sdata, link_conf);
956 if (!check_sdata_in_driver(sdata))
959 trace_drv_assign_vif_chanctx(local, sdata, link_conf, ctx);
960 if (local->ops->assign_vif_chanctx) {
961 WARN_ON_ONCE(!ctx->driver_present);
962 ret = local->ops->assign_vif_chanctx(&local->hw,
967 trace_drv_return_int(local, ret);
972 static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local,
973 struct ieee80211_sub_if_data *sdata,
974 struct ieee80211_bss_conf *link_conf,
975 struct ieee80211_chanctx *ctx)
979 drv_verify_link_exists(sdata, link_conf);
980 if (!check_sdata_in_driver(sdata))
983 trace_drv_unassign_vif_chanctx(local, sdata, link_conf, ctx);
984 if (local->ops->unassign_vif_chanctx) {
985 WARN_ON_ONCE(!ctx->driver_present);
986 local->ops->unassign_vif_chanctx(&local->hw,
991 trace_drv_return_void(local);
994 int drv_switch_vif_chanctx(struct ieee80211_local *local,
995 struct ieee80211_vif_chanctx_switch *vifs,
996 int n_vifs, enum ieee80211_chanctx_switch_mode mode);
998 static inline int drv_start_ap(struct ieee80211_local *local,
999 struct ieee80211_sub_if_data *sdata,
1000 struct ieee80211_bss_conf *link_conf)
1004 /* make sure link_conf is protected */
1005 drv_verify_link_exists(sdata, link_conf);
1009 if (!check_sdata_in_driver(sdata))
1012 trace_drv_start_ap(local, sdata, link_conf);
1013 if (local->ops->start_ap)
1014 ret = local->ops->start_ap(&local->hw, &sdata->vif, link_conf);
1015 trace_drv_return_int(local, ret);
1019 static inline void drv_stop_ap(struct ieee80211_local *local,
1020 struct ieee80211_sub_if_data *sdata,
1021 struct ieee80211_bss_conf *link_conf)
1023 /* make sure link_conf is protected */
1024 drv_verify_link_exists(sdata, link_conf);
1026 if (!check_sdata_in_driver(sdata))
1029 trace_drv_stop_ap(local, sdata, link_conf);
1030 if (local->ops->stop_ap)
1031 local->ops->stop_ap(&local->hw, &sdata->vif, link_conf);
1032 trace_drv_return_void(local);
1036 drv_reconfig_complete(struct ieee80211_local *local,
1037 enum ieee80211_reconfig_type reconfig_type)
1041 trace_drv_reconfig_complete(local, reconfig_type);
1042 if (local->ops->reconfig_complete)
1043 local->ops->reconfig_complete(&local->hw, reconfig_type);
1044 trace_drv_return_void(local);
1048 drv_set_default_unicast_key(struct ieee80211_local *local,
1049 struct ieee80211_sub_if_data *sdata,
1052 if (!check_sdata_in_driver(sdata))
1055 WARN_ON_ONCE(key_idx < -1 || key_idx > 3);
1057 trace_drv_set_default_unicast_key(local, sdata, key_idx);
1058 if (local->ops->set_default_unicast_key)
1059 local->ops->set_default_unicast_key(&local->hw, &sdata->vif,
1061 trace_drv_return_void(local);
1064 #if IS_ENABLED(CONFIG_IPV6)
1065 static inline void drv_ipv6_addr_change(struct ieee80211_local *local,
1066 struct ieee80211_sub_if_data *sdata,
1067 struct inet6_dev *idev)
1069 trace_drv_ipv6_addr_change(local, sdata);
1070 if (local->ops->ipv6_addr_change)
1071 local->ops->ipv6_addr_change(&local->hw, &sdata->vif, idev);
1072 trace_drv_return_void(local);
1077 drv_channel_switch_beacon(struct ieee80211_sub_if_data *sdata,
1078 struct cfg80211_chan_def *chandef)
1080 struct ieee80211_local *local = sdata->local;
1082 if (local->ops->channel_switch_beacon) {
1083 trace_drv_channel_switch_beacon(local, sdata, chandef);
1084 local->ops->channel_switch_beacon(&local->hw, &sdata->vif,
1090 drv_pre_channel_switch(struct ieee80211_sub_if_data *sdata,
1091 struct ieee80211_channel_switch *ch_switch)
1093 struct ieee80211_local *local = sdata->local;
1096 if (!check_sdata_in_driver(sdata))
1099 trace_drv_pre_channel_switch(local, sdata, ch_switch);
1100 if (local->ops->pre_channel_switch)
1101 ret = local->ops->pre_channel_switch(&local->hw, &sdata->vif,
1103 trace_drv_return_int(local, ret);
1108 drv_post_channel_switch(struct ieee80211_sub_if_data *sdata)
1110 struct ieee80211_local *local = sdata->local;
1113 if (!check_sdata_in_driver(sdata))
1116 trace_drv_post_channel_switch(local, sdata);
1117 if (local->ops->post_channel_switch)
1118 ret = local->ops->post_channel_switch(&local->hw, &sdata->vif);
1119 trace_drv_return_int(local, ret);
1124 drv_abort_channel_switch(struct ieee80211_sub_if_data *sdata)
1126 struct ieee80211_local *local = sdata->local;
1128 if (!check_sdata_in_driver(sdata))
1131 trace_drv_abort_channel_switch(local, sdata);
1133 if (local->ops->abort_channel_switch)
1134 local->ops->abort_channel_switch(&local->hw, &sdata->vif);
1138 drv_channel_switch_rx_beacon(struct ieee80211_sub_if_data *sdata,
1139 struct ieee80211_channel_switch *ch_switch)
1141 struct ieee80211_local *local = sdata->local;
1143 if (!check_sdata_in_driver(sdata))
1146 trace_drv_channel_switch_rx_beacon(local, sdata, ch_switch);
1147 if (local->ops->channel_switch_rx_beacon)
1148 local->ops->channel_switch_rx_beacon(&local->hw, &sdata->vif,
1152 static inline int drv_join_ibss(struct ieee80211_local *local,
1153 struct ieee80211_sub_if_data *sdata)
1158 if (!check_sdata_in_driver(sdata))
1161 trace_drv_join_ibss(local, sdata, &sdata->vif.bss_conf);
1162 if (local->ops->join_ibss)
1163 ret = local->ops->join_ibss(&local->hw, &sdata->vif);
1164 trace_drv_return_int(local, ret);
1168 static inline void drv_leave_ibss(struct ieee80211_local *local,
1169 struct ieee80211_sub_if_data *sdata)
1172 if (!check_sdata_in_driver(sdata))
1175 trace_drv_leave_ibss(local, sdata);
1176 if (local->ops->leave_ibss)
1177 local->ops->leave_ibss(&local->hw, &sdata->vif);
1178 trace_drv_return_void(local);
1181 static inline u32 drv_get_expected_throughput(struct ieee80211_local *local,
1182 struct sta_info *sta)
1186 trace_drv_get_expected_throughput(&sta->sta);
1187 if (local->ops->get_expected_throughput && sta->uploaded)
1188 ret = local->ops->get_expected_throughput(&local->hw, &sta->sta);
1189 trace_drv_return_u32(local, ret);
1194 static inline int drv_get_txpower(struct ieee80211_local *local,
1195 struct ieee80211_sub_if_data *sdata, int *dbm)
1199 if (!local->ops->get_txpower)
1202 ret = local->ops->get_txpower(&local->hw, &sdata->vif, dbm);
1203 trace_drv_get_txpower(local, sdata, *dbm, ret);
1209 drv_tdls_channel_switch(struct ieee80211_local *local,
1210 struct ieee80211_sub_if_data *sdata,
1211 struct ieee80211_sta *sta, u8 oper_class,
1212 struct cfg80211_chan_def *chandef,
1213 struct sk_buff *tmpl_skb, u32 ch_sw_tm_ie)
1218 if (!check_sdata_in_driver(sdata))
1221 if (!local->ops->tdls_channel_switch)
1224 trace_drv_tdls_channel_switch(local, sdata, sta, oper_class, chandef);
1225 ret = local->ops->tdls_channel_switch(&local->hw, &sdata->vif, sta,
1226 oper_class, chandef, tmpl_skb,
1228 trace_drv_return_int(local, ret);
1233 drv_tdls_cancel_channel_switch(struct ieee80211_local *local,
1234 struct ieee80211_sub_if_data *sdata,
1235 struct ieee80211_sta *sta)
1238 if (!check_sdata_in_driver(sdata))
1241 if (!local->ops->tdls_cancel_channel_switch)
1244 trace_drv_tdls_cancel_channel_switch(local, sdata, sta);
1245 local->ops->tdls_cancel_channel_switch(&local->hw, &sdata->vif, sta);
1246 trace_drv_return_void(local);
1250 drv_tdls_recv_channel_switch(struct ieee80211_local *local,
1251 struct ieee80211_sub_if_data *sdata,
1252 struct ieee80211_tdls_ch_sw_params *params)
1254 trace_drv_tdls_recv_channel_switch(local, sdata, params);
1255 if (local->ops->tdls_recv_channel_switch)
1256 local->ops->tdls_recv_channel_switch(&local->hw, &sdata->vif,
1258 trace_drv_return_void(local);
1261 static inline void drv_wake_tx_queue(struct ieee80211_local *local,
1262 struct txq_info *txq)
1264 struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->txq.vif);
1266 /* In reconfig don't transmit now, but mark for waking later */
1267 if (local->in_reconfig) {
1268 set_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txq->flags);
1272 if (!check_sdata_in_driver(sdata))
1275 trace_drv_wake_tx_queue(local, sdata, txq);
1276 local->ops->wake_tx_queue(&local->hw, &txq->txq);
1279 static inline void schedule_and_wake_txq(struct ieee80211_local *local,
1280 struct txq_info *txqi)
1282 ieee80211_schedule_txq(&local->hw, &txqi->txq);
1283 drv_wake_tx_queue(local, txqi);
1286 static inline int drv_can_aggregate_in_amsdu(struct ieee80211_local *local,
1287 struct sk_buff *head,
1288 struct sk_buff *skb)
1290 if (!local->ops->can_aggregate_in_amsdu)
1293 return local->ops->can_aggregate_in_amsdu(&local->hw, head, skb);
1297 drv_get_ftm_responder_stats(struct ieee80211_local *local,
1298 struct ieee80211_sub_if_data *sdata,
1299 struct cfg80211_ftm_responder_stats *ftm_stats)
1301 u32 ret = -EOPNOTSUPP;
1303 if (local->ops->get_ftm_responder_stats)
1304 ret = local->ops->get_ftm_responder_stats(&local->hw,
1307 trace_drv_get_ftm_responder_stats(local, sdata, ftm_stats);
1312 static inline int drv_start_pmsr(struct ieee80211_local *local,
1313 struct ieee80211_sub_if_data *sdata,
1314 struct cfg80211_pmsr_request *request)
1316 int ret = -EOPNOTSUPP;
1319 if (!check_sdata_in_driver(sdata))
1322 trace_drv_start_pmsr(local, sdata);
1324 if (local->ops->start_pmsr)
1325 ret = local->ops->start_pmsr(&local->hw, &sdata->vif, request);
1326 trace_drv_return_int(local, ret);
1331 static inline void drv_abort_pmsr(struct ieee80211_local *local,
1332 struct ieee80211_sub_if_data *sdata,
1333 struct cfg80211_pmsr_request *request)
1335 trace_drv_abort_pmsr(local, sdata);
1338 if (!check_sdata_in_driver(sdata))
1341 if (local->ops->abort_pmsr)
1342 local->ops->abort_pmsr(&local->hw, &sdata->vif, request);
1343 trace_drv_return_void(local);
1346 static inline int drv_start_nan(struct ieee80211_local *local,
1347 struct ieee80211_sub_if_data *sdata,
1348 struct cfg80211_nan_conf *conf)
1353 check_sdata_in_driver(sdata);
1355 trace_drv_start_nan(local, sdata, conf);
1356 ret = local->ops->start_nan(&local->hw, &sdata->vif, conf);
1357 trace_drv_return_int(local, ret);
1361 static inline void drv_stop_nan(struct ieee80211_local *local,
1362 struct ieee80211_sub_if_data *sdata)
1365 check_sdata_in_driver(sdata);
1367 trace_drv_stop_nan(local, sdata);
1368 local->ops->stop_nan(&local->hw, &sdata->vif);
1369 trace_drv_return_void(local);
1372 static inline int drv_nan_change_conf(struct ieee80211_local *local,
1373 struct ieee80211_sub_if_data *sdata,
1374 struct cfg80211_nan_conf *conf,
1380 check_sdata_in_driver(sdata);
1382 if (!local->ops->nan_change_conf)
1385 trace_drv_nan_change_conf(local, sdata, conf, changes);
1386 ret = local->ops->nan_change_conf(&local->hw, &sdata->vif, conf,
1388 trace_drv_return_int(local, ret);
1393 static inline int drv_add_nan_func(struct ieee80211_local *local,
1394 struct ieee80211_sub_if_data *sdata,
1395 const struct cfg80211_nan_func *nan_func)
1400 check_sdata_in_driver(sdata);
1402 if (!local->ops->add_nan_func)
1405 trace_drv_add_nan_func(local, sdata, nan_func);
1406 ret = local->ops->add_nan_func(&local->hw, &sdata->vif, nan_func);
1407 trace_drv_return_int(local, ret);
1412 static inline void drv_del_nan_func(struct ieee80211_local *local,
1413 struct ieee80211_sub_if_data *sdata,
1417 check_sdata_in_driver(sdata);
1419 trace_drv_del_nan_func(local, sdata, instance_id);
1420 if (local->ops->del_nan_func)
1421 local->ops->del_nan_func(&local->hw, &sdata->vif, instance_id);
1422 trace_drv_return_void(local);
1425 static inline int drv_set_tid_config(struct ieee80211_local *local,
1426 struct ieee80211_sub_if_data *sdata,
1427 struct ieee80211_sta *sta,
1428 struct cfg80211_tid_config *tid_conf)
1433 ret = local->ops->set_tid_config(&local->hw, &sdata->vif, sta,
1435 trace_drv_return_int(local, ret);
1440 static inline int drv_reset_tid_config(struct ieee80211_local *local,
1441 struct ieee80211_sub_if_data *sdata,
1442 struct ieee80211_sta *sta, u8 tids)
1447 ret = local->ops->reset_tid_config(&local->hw, &sdata->vif, sta, tids);
1448 trace_drv_return_int(local, ret);
1453 static inline void drv_update_vif_offload(struct ieee80211_local *local,
1454 struct ieee80211_sub_if_data *sdata)
1457 check_sdata_in_driver(sdata);
1459 if (!local->ops->update_vif_offload)
1462 trace_drv_update_vif_offload(local, sdata);
1463 local->ops->update_vif_offload(&local->hw, &sdata->vif);
1464 trace_drv_return_void(local);
1467 static inline void drv_sta_set_4addr(struct ieee80211_local *local,
1468 struct ieee80211_sub_if_data *sdata,
1469 struct ieee80211_sta *sta, bool enabled)
1471 sdata = get_bss_sdata(sdata);
1472 if (!check_sdata_in_driver(sdata))
1475 trace_drv_sta_set_4addr(local, sdata, sta, enabled);
1476 if (local->ops->sta_set_4addr)
1477 local->ops->sta_set_4addr(&local->hw, &sdata->vif, sta, enabled);
1478 trace_drv_return_void(local);
1481 static inline void drv_sta_set_decap_offload(struct ieee80211_local *local,
1482 struct ieee80211_sub_if_data *sdata,
1483 struct ieee80211_sta *sta,
1486 sdata = get_bss_sdata(sdata);
1487 if (!check_sdata_in_driver(sdata))
1490 trace_drv_sta_set_decap_offload(local, sdata, sta, enabled);
1491 if (local->ops->sta_set_decap_offload)
1492 local->ops->sta_set_decap_offload(&local->hw, &sdata->vif, sta,
1494 trace_drv_return_void(local);
1497 static inline void drv_add_twt_setup(struct ieee80211_local *local,
1498 struct ieee80211_sub_if_data *sdata,
1499 struct ieee80211_sta *sta,
1500 struct ieee80211_twt_setup *twt)
1502 struct ieee80211_twt_params *twt_agrt;
1506 if (!check_sdata_in_driver(sdata))
1509 twt_agrt = (void *)twt->params;
1511 trace_drv_add_twt_setup(local, sta, twt, twt_agrt);
1512 local->ops->add_twt_setup(&local->hw, sta, twt);
1513 trace_drv_return_void(local);
1516 static inline void drv_twt_teardown_request(struct ieee80211_local *local,
1517 struct ieee80211_sub_if_data *sdata,
1518 struct ieee80211_sta *sta,
1522 if (!check_sdata_in_driver(sdata))
1525 if (!local->ops->twt_teardown_request)
1528 trace_drv_twt_teardown_request(local, sta, flowid);
1529 local->ops->twt_teardown_request(&local->hw, sta, flowid);
1530 trace_drv_return_void(local);
1533 static inline int drv_net_fill_forward_path(struct ieee80211_local *local,
1534 struct ieee80211_sub_if_data *sdata,
1535 struct ieee80211_sta *sta,
1536 struct net_device_path_ctx *ctx,
1537 struct net_device_path *path)
1539 int ret = -EOPNOTSUPP;
1541 sdata = get_bss_sdata(sdata);
1542 if (!check_sdata_in_driver(sdata))
1545 trace_drv_net_fill_forward_path(local, sdata, sta);
1546 if (local->ops->net_fill_forward_path)
1547 ret = local->ops->net_fill_forward_path(&local->hw,
1550 trace_drv_return_int(local, ret);
1555 static inline int drv_change_vif_links(struct ieee80211_local *local,
1556 struct ieee80211_sub_if_data *sdata,
1557 u16 old_links, u16 new_links,
1558 struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS])
1560 int ret = -EOPNOTSUPP;
1564 if (!check_sdata_in_driver(sdata))
1567 trace_drv_change_vif_links(local, sdata, old_links, new_links);
1568 if (local->ops->change_vif_links)
1569 ret = local->ops->change_vif_links(&local->hw, &sdata->vif,
1570 old_links, new_links, old);
1571 trace_drv_return_int(local, ret);
1576 static inline int drv_change_sta_links(struct ieee80211_local *local,
1577 struct ieee80211_sub_if_data *sdata,
1578 struct ieee80211_sta *sta,
1579 u16 old_links, u16 new_links)
1581 int ret = -EOPNOTSUPP;
1585 if (!check_sdata_in_driver(sdata))
1588 trace_drv_change_sta_links(local, sdata, sta, old_links, new_links);
1589 if (local->ops->change_sta_links)
1590 ret = local->ops->change_sta_links(&local->hw, &sdata->vif, sta,
1591 old_links, new_links);
1592 trace_drv_return_int(local, ret);
1597 #endif /* __MAC80211_DRIVER_OPS */