1d2912cb1SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */ 2ccf80ddfSLuis Carlos Cobo /* 3264d9b7dSRui Paulo * Copyright (c) 2008, 2009 open80211s Ltd. 4*03145a1dSJohannes Berg * Copyright (C) 2023-2024 Intel Corporation 5ccf80ddfSLuis Carlos Cobo * Authors: Luis Carlos Cobo <luisca@cozybit.com> 6ccf80ddfSLuis Carlos Cobo * Javier Cardona <javier@cozybit.com> 7ccf80ddfSLuis Carlos Cobo */ 8ccf80ddfSLuis Carlos Cobo 9ccf80ddfSLuis Carlos Cobo #ifndef IEEE80211S_H 10ccf80ddfSLuis Carlos Cobo #define IEEE80211S_H 11ccf80ddfSLuis Carlos Cobo 12902acc78SJohannes Berg #include <linux/types.h> 13ccf80ddfSLuis Carlos Cobo #include <linux/jhash.h> 14902acc78SJohannes Berg #include "ieee80211_i.h" 15ccf80ddfSLuis Carlos Cobo 16ccf80ddfSLuis Carlos Cobo 17ccf80ddfSLuis Carlos Cobo /* Data structures */ 18ccf80ddfSLuis Carlos Cobo 19ccf80ddfSLuis Carlos Cobo /** 20ccf80ddfSLuis Carlos Cobo * enum mesh_path_flags - mac80211 mesh path flags 21ccf80ddfSLuis Carlos Cobo * 22eb80ed8dSRami Rosen * @MESH_PATH_ACTIVE: the mesh path can be used for forwarding 23eb80ed8dSRami Rosen * @MESH_PATH_RESOLVING: the discovery process is running for this mesh path 24d19b3bf6SRui Paulo * @MESH_PATH_SN_VALID: the mesh path contains a valid destination sequence 25ccf80ddfSLuis Carlos Cobo * number 26ccf80ddfSLuis Carlos Cobo * @MESH_PATH_FIXED: the mesh path has been manually set and should not be 27ccf80ddfSLuis Carlos Cobo * modified 28ccf80ddfSLuis Carlos Cobo * @MESH_PATH_RESOLVED: the mesh path can has been resolved 29f3011cf9SJavier Cardona * @MESH_PATH_REQ_QUEUED: there is an unsent path request for this destination 30f3011cf9SJavier Cardona * already queued up, waiting for the discovery process to start. 3174932959SBob Copeland * @MESH_PATH_DELETED: the mesh path has been deleted and should no longer 3274932959SBob Copeland * be used 33ccf80ddfSLuis Carlos Cobo * 34eb80ed8dSRami Rosen * MESH_PATH_RESOLVED is used by the mesh path timer to 35ccf80ddfSLuis Carlos Cobo * decide when to stop or cancel the mesh path discovery. 36ccf80ddfSLuis Carlos Cobo */ 37ccf80ddfSLuis Carlos Cobo enum mesh_path_flags { 38ccf80ddfSLuis Carlos Cobo MESH_PATH_ACTIVE = BIT(0), 39ccf80ddfSLuis Carlos Cobo MESH_PATH_RESOLVING = BIT(1), 40d19b3bf6SRui Paulo MESH_PATH_SN_VALID = BIT(2), 41ccf80ddfSLuis Carlos Cobo MESH_PATH_FIXED = BIT(3), 42ccf80ddfSLuis Carlos Cobo MESH_PATH_RESOLVED = BIT(4), 43f3011cf9SJavier Cardona MESH_PATH_REQ_QUEUED = BIT(5), 4474932959SBob Copeland MESH_PATH_DELETED = BIT(6), 45ccf80ddfSLuis Carlos Cobo }; 46ccf80ddfSLuis Carlos Cobo 47ccf80ddfSLuis Carlos Cobo /** 4818889231SJavier Cardona * enum mesh_deferred_task_flags - mac80211 mesh deferred tasks 4918889231SJavier Cardona * 5018889231SJavier Cardona * 5118889231SJavier Cardona * 5218889231SJavier Cardona * @MESH_WORK_HOUSEKEEPING: run the periodic mesh housekeeping tasks 53e304bfd3SRui Paulo * @MESH_WORK_ROOT: the mesh root station needs to send a frame 54dbf498fbSJavier Cardona * @MESH_WORK_DRIFT_ADJUST: time to compensate for clock drift relative to other 55dbf498fbSJavier Cardona * mesh nodes 56f81a9dedSThomas Pedersen * @MESH_WORK_MBSS_CHANGED: rebuild beacon and notify driver of BSS changes 5718889231SJavier Cardona */ 5818889231SJavier Cardona enum mesh_deferred_task_flags { 5918889231SJavier Cardona MESH_WORK_HOUSEKEEPING, 60e304bfd3SRui Paulo MESH_WORK_ROOT, 61dbf498fbSJavier Cardona MESH_WORK_DRIFT_ADJUST, 62f81a9dedSThomas Pedersen MESH_WORK_MBSS_CHANGED, 6318889231SJavier Cardona }; 6418889231SJavier Cardona 6518889231SJavier Cardona /** 66ccf80ddfSLuis Carlos Cobo * struct mesh_path - mac80211 mesh path structure 67ccf80ddfSLuis Carlos Cobo * 68ccf80ddfSLuis Carlos Cobo * @dst: mesh path destination mac address 6968bb54b4SBob Copeland * @mpp: mesh proxy mac address 7068bb54b4SBob Copeland * @rhash: rhashtable list pointer 71b4c3fbe6SHerbert Xu * @walk_list: linked list containing all mesh_path objects. 7268bb54b4SBob Copeland * @gate_list: list pointer for known gates list 73f698d856SJasper Bryant-Greene * @sdata: mesh subif 74ccf80ddfSLuis Carlos Cobo * @next_hop: mesh neighbor to which frames for this destination will be 75ccf80ddfSLuis Carlos Cobo * forwarded 76ccf80ddfSLuis Carlos Cobo * @timer: mesh path discovery timer 77ccf80ddfSLuis Carlos Cobo * @frame_queue: pending queue for frames sent to this destination while the 78ccf80ddfSLuis Carlos Cobo * path is unresolved 7968bb54b4SBob Copeland * @rcu: rcu head for freeing mesh path 80d19b3bf6SRui Paulo * @sn: target sequence number 81ccf80ddfSLuis Carlos Cobo * @metric: current metric to this destination 82ccf80ddfSLuis Carlos Cobo * @hop_count: hops to destination 83ccf80ddfSLuis Carlos Cobo * @exp_time: in jiffies, when the path will expire or when it expired 84ccf80ddfSLuis Carlos Cobo * @discovery_timeout: timeout (lapse in jiffies) used for the last discovery 85ccf80ddfSLuis Carlos Cobo * retry 86ccf80ddfSLuis Carlos Cobo * @discovery_retries: number of discovery retries 87ccf80ddfSLuis Carlos Cobo * @flags: mesh path flags, as specified on &enum mesh_path_flags 88f5e50cd0SJavier Cardona * @state_lock: mesh path state lock used to protect changes to the 89f5e50cd0SJavier Cardona * mpath itself. No need to take this lock when adding or removing 90f5e50cd0SJavier Cardona * an mpath to a hash bucket on a path table. 913d045a54SChun-Yeow Yeoh * @rann_snd_addr: the RANN sender address 92d2a079fdSChun-Yeow Yeoh * @rann_metric: the aggregated path metric towards the root node 93728b19e5SChun-Yeow Yeoh * @last_preq_to_root: Timestamp of last PREQ sent to root 943d045a54SChun-Yeow Yeoh * @is_root: the destination station of this path is a root node 955ee68e5bSJavier Cardona * @is_gate: the destination station of this path is a mesh gate 96540bbcb9SJulan Hsu * @path_change_count: the number of path changes to destination 97*03145a1dSJohannes Berg * @fast_tx_check: timestamp of last fast-xmit enable attempt 98ccf80ddfSLuis Carlos Cobo * 99ccf80ddfSLuis Carlos Cobo * 10068bb54b4SBob Copeland * The dst address is unique in the mesh path table. Since the mesh_path is 10168bb54b4SBob Copeland * protected by RCU, deleting the next_hop STA must remove / substitute the 10268bb54b4SBob Copeland * mesh_path structure and wait until that is no longer reachable before 10368bb54b4SBob Copeland * destroying the STA completely. 104ccf80ddfSLuis Carlos Cobo */ 105ccf80ddfSLuis Carlos Cobo struct mesh_path { 106ccf80ddfSLuis Carlos Cobo u8 dst[ETH_ALEN]; 10779617deeSYanBo u8 mpp[ETH_ALEN]; /* used for MPP or MAP */ 10860854fd9SBob Copeland struct rhash_head rhash; 109b4c3fbe6SHerbert Xu struct hlist_node walk_list; 110947c2a0eSBob Copeland struct hlist_node gate_list; 111f698d856SJasper Bryant-Greene struct ieee80211_sub_if_data *sdata; 11240b275b6SJohannes Berg struct sta_info __rcu *next_hop; 113ccf80ddfSLuis Carlos Cobo struct timer_list timer; 114ccf80ddfSLuis Carlos Cobo struct sk_buff_head frame_queue; 115ccf80ddfSLuis Carlos Cobo struct rcu_head rcu; 116d19b3bf6SRui Paulo u32 sn; 117ccf80ddfSLuis Carlos Cobo u32 metric; 118ccf80ddfSLuis Carlos Cobo u8 hop_count; 119ccf80ddfSLuis Carlos Cobo unsigned long exp_time; 120ccf80ddfSLuis Carlos Cobo u32 discovery_timeout; 121ccf80ddfSLuis Carlos Cobo u8 discovery_retries; 122ccf80ddfSLuis Carlos Cobo enum mesh_path_flags flags; 123ccf80ddfSLuis Carlos Cobo spinlock_t state_lock; 1243d045a54SChun-Yeow Yeoh u8 rann_snd_addr[ETH_ALEN]; 125d2a079fdSChun-Yeow Yeoh u32 rann_metric; 126728b19e5SChun-Yeow Yeoh unsigned long last_preq_to_root; 127d5edb9aeSFelix Fietkau unsigned long fast_tx_check; 1283d045a54SChun-Yeow Yeoh bool is_root; 1295ee68e5bSJavier Cardona bool is_gate; 130540bbcb9SJulan Hsu u32 path_change_count; 131ccf80ddfSLuis Carlos Cobo }; 132ccf80ddfSLuis Carlos Cobo 133d5edb9aeSFelix Fietkau #define MESH_FAST_TX_CACHE_MAX_SIZE 512 134d5edb9aeSFelix Fietkau #define MESH_FAST_TX_CACHE_THRESHOLD_SIZE 384 135d5edb9aeSFelix Fietkau #define MESH_FAST_TX_CACHE_TIMEOUT 8000 /* msecs */ 136d5edb9aeSFelix Fietkau 137d5edb9aeSFelix Fietkau /** 138d5edb9aeSFelix Fietkau * struct ieee80211_mesh_fast_tx - cached mesh fast tx entry 139d5edb9aeSFelix Fietkau * @rhash: rhashtable pointer 140d5edb9aeSFelix Fietkau * @addr_key: The Ethernet DA which is the key for this entry 141d5edb9aeSFelix Fietkau * @fast_tx: base fast_tx data 142d5edb9aeSFelix Fietkau * @hdr: cached mesh and rfc1042 headers 143d5edb9aeSFelix Fietkau * @hdrlen: length of mesh + rfc1042 144d5edb9aeSFelix Fietkau * @walk_list: list containing all the fast tx entries 145d5edb9aeSFelix Fietkau * @mpath: mesh path corresponding to the Mesh DA 146d5edb9aeSFelix Fietkau * @mppath: MPP entry corresponding to this DA 147d5edb9aeSFelix Fietkau * @timestamp: Last used time of this entry 148d5edb9aeSFelix Fietkau */ 149d5edb9aeSFelix Fietkau struct ieee80211_mesh_fast_tx { 150d5edb9aeSFelix Fietkau struct rhash_head rhash; 151d5edb9aeSFelix Fietkau u8 addr_key[ETH_ALEN] __aligned(2); 152d5edb9aeSFelix Fietkau 153d5edb9aeSFelix Fietkau struct ieee80211_fast_tx fast_tx; 154d5edb9aeSFelix Fietkau u8 hdr[sizeof(struct ieee80211s_hdr) + sizeof(rfc1042_header)]; 155d5edb9aeSFelix Fietkau u16 hdrlen; 156d5edb9aeSFelix Fietkau 157d5edb9aeSFelix Fietkau struct mesh_path *mpath, *mppath; 158d5edb9aeSFelix Fietkau struct hlist_node walk_list; 159d5edb9aeSFelix Fietkau unsigned long timestamp; 160d5edb9aeSFelix Fietkau }; 161d5edb9aeSFelix Fietkau 162ccf80ddfSLuis Carlos Cobo /* Recent multicast cache */ 163ccf80ddfSLuis Carlos Cobo /* RMC_BUCKETS must be a power of 2, maximum 256 */ 164ccf80ddfSLuis Carlos Cobo #define RMC_BUCKETS 256 165ccf80ddfSLuis Carlos Cobo #define RMC_QUEUE_MAX_LEN 4 166ccf80ddfSLuis Carlos Cobo #define RMC_TIMEOUT (3 * HZ) 167ccf80ddfSLuis Carlos Cobo 168ccf80ddfSLuis Carlos Cobo /** 169ccf80ddfSLuis Carlos Cobo * struct rmc_entry - entry in the Recent Multicast Cache 170ccf80ddfSLuis Carlos Cobo * 171ccf80ddfSLuis Carlos Cobo * @seqnum: mesh sequence number of the frame 172ccf80ddfSLuis Carlos Cobo * @exp_time: expiration time of the entry, in jiffies 173ccf80ddfSLuis Carlos Cobo * @sa: source address of the frame 17468bb54b4SBob Copeland * @list: hashtable list pointer 175ccf80ddfSLuis Carlos Cobo * 176ccf80ddfSLuis Carlos Cobo * The Recent Multicast Cache keeps track of the latest multicast frames that 177ccf80ddfSLuis Carlos Cobo * have been received by a mesh interface and discards received multicast frames 178ccf80ddfSLuis Carlos Cobo * that are found in the cache. 179ccf80ddfSLuis Carlos Cobo */ 180ccf80ddfSLuis Carlos Cobo struct rmc_entry { 18147a0489cSBob Copeland struct hlist_node list; 182ccf80ddfSLuis Carlos Cobo unsigned long exp_time; 1833257523bSBob Copeland u32 seqnum; 184ccf80ddfSLuis Carlos Cobo u8 sa[ETH_ALEN]; 185ccf80ddfSLuis Carlos Cobo }; 186ccf80ddfSLuis Carlos Cobo 187ccf80ddfSLuis Carlos Cobo struct mesh_rmc { 18847a0489cSBob Copeland struct hlist_head bucket[RMC_BUCKETS]; 18951ceddadSLuis Carlos Cobo u32 idx_mask; 190ccf80ddfSLuis Carlos Cobo }; 191ccf80ddfSLuis Carlos Cobo 19225d49e4dSThomas Pedersen #define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ) 193ccf80ddfSLuis Carlos Cobo 194ccf80ddfSLuis Carlos Cobo #define MESH_PATH_EXPIRE (600 * HZ) 195ccf80ddfSLuis Carlos Cobo 196ccf80ddfSLuis Carlos Cobo /* Default maximum number of plinks per interface */ 197ccf80ddfSLuis Carlos Cobo #define MESH_MAX_PLINKS 256 198ccf80ddfSLuis Carlos Cobo 199ccf80ddfSLuis Carlos Cobo /* Maximum number of paths per interface */ 200ccf80ddfSLuis Carlos Cobo #define MESH_MAX_MPATHS 1024 201ccf80ddfSLuis Carlos Cobo 2024bd4c2ddSThomas Pedersen /* Number of frames buffered per destination for unresolved destinations */ 2034bd4c2ddSThomas Pedersen #define MESH_FRAME_QUEUE_LEN 10 2044bd4c2ddSThomas Pedersen 205ccf80ddfSLuis Carlos Cobo /* Public interfaces */ 206ccf80ddfSLuis Carlos Cobo /* Various */ 2073c5772a5SJavier Cardona int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, 20815ff6365SJohannes Berg const u8 *da, const u8 *sa); 2095edfcee5SAndrzej Hajda unsigned int ieee80211_new_mesh_header(struct ieee80211_sub_if_data *sdata, 210bf7cd94dSJohannes Berg struct ieee80211s_hdr *meshhdr, 211bf7cd94dSJohannes Berg const char *addr4or5, const char *addr6); 212bf7cd94dSJohannes Berg int mesh_rmc_check(struct ieee80211_sub_if_data *sdata, 213bf7cd94dSJohannes Berg const u8 *addr, struct ieee80211s_hdr *mesh_hdr); 214f743ff49SThomas Pedersen bool mesh_matches_local(struct ieee80211_sub_if_data *sdata, 215f743ff49SThomas Pedersen struct ieee802_11_elems *ie); 216bf7cd94dSJohannes Berg int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata, 217bf7cd94dSJohannes Berg struct sk_buff *skb); 218bf7cd94dSJohannes Berg int mesh_add_meshid_ie(struct ieee80211_sub_if_data *sdata, 219bf7cd94dSJohannes Berg struct sk_buff *skb); 220bf7cd94dSJohannes Berg int mesh_add_rsn_ie(struct ieee80211_sub_if_data *sdata, 221bf7cd94dSJohannes Berg struct sk_buff *skb); 222bf7cd94dSJohannes Berg int mesh_add_vendor_ies(struct ieee80211_sub_if_data *sdata, 223bf7cd94dSJohannes Berg struct sk_buff *skb); 224bf7cd94dSJohannes Berg int mesh_add_ht_cap_ie(struct ieee80211_sub_if_data *sdata, 225bf7cd94dSJohannes Berg struct sk_buff *skb); 226bf7cd94dSJohannes Berg int mesh_add_ht_oper_ie(struct ieee80211_sub_if_data *sdata, 227bf7cd94dSJohannes Berg struct sk_buff *skb); 228c85fb53cSBob Copeland int mesh_add_vht_cap_ie(struct ieee80211_sub_if_data *sdata, 229c85fb53cSBob Copeland struct sk_buff *skb); 230c85fb53cSBob Copeland int mesh_add_vht_oper_ie(struct ieee80211_sub_if_data *sdata, 231c85fb53cSBob Copeland struct sk_buff *skb); 23260ad72daSSven Eckelmann int mesh_add_he_cap_ie(struct ieee80211_sub_if_data *sdata, 23360ad72daSSven Eckelmann struct sk_buff *skb, u8 ie_len); 23460ad72daSSven Eckelmann int mesh_add_he_oper_ie(struct ieee80211_sub_if_data *sdata, 23560ad72daSSven Eckelmann struct sk_buff *skb); 23624a2042cSRajkumar Manoharan int mesh_add_he_6ghz_cap_ie(struct ieee80211_sub_if_data *sdata, 23724a2042cSRajkumar Manoharan struct sk_buff *skb); 238df1875c4SRyder Lee int mesh_add_eht_cap_ie(struct ieee80211_sub_if_data *sdata, 239df1875c4SRyder Lee struct sk_buff *skb, u8 ie_len); 240df1875c4SRyder Lee int mesh_add_eht_oper_ie(struct ieee80211_sub_if_data *sdata, 241df1875c4SRyder Lee struct sk_buff *skb); 242f698d856SJasper Bryant-Greene void mesh_rmc_free(struct ieee80211_sub_if_data *sdata); 243f698d856SJasper Bryant-Greene int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); 244ccf80ddfSLuis Carlos Cobo void ieee80211s_init(void); 245bfc32e6aSJavier Cardona void ieee80211s_update_metric(struct ieee80211_local *local, 246c4205510SYuan-Chi Pang struct sta_info *sta, 247c4205510SYuan-Chi Pang struct ieee80211_tx_status *st); 248902acc78SJohannes Berg void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata); 2490371a08fSBob Copeland void ieee80211_mesh_teardown_sdata(struct ieee80211_sub_if_data *sdata); 2502b5e1967SThomas Pedersen int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata); 251472dbc45SJohannes Berg void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata); 25263c5723bSRui Paulo void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh); 2538ba7acf3SJohannes Berg const struct ieee80211_mesh_sync_ops *ieee80211_mesh_sync_ops_get(u8 method); 2542b5e1967SThomas Pedersen /* wrapper for ieee80211_bss_info_change_notify() */ 2552b5e1967SThomas Pedersen void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata, 25615ddba5fSAnjaneyulu u64 changed); 257902acc78SJohannes Berg 2583f52b7e3SMarco Porsch /* mesh power save */ 25915ddba5fSAnjaneyulu u64 ieee80211_mps_local_status_update(struct ieee80211_sub_if_data *sdata); 26015ddba5fSAnjaneyulu u64 ieee80211_mps_set_sta_local_pm(struct sta_info *sta, 2613f52b7e3SMarco Porsch enum nl80211_mesh_power_mode pm); 2623f52b7e3SMarco Porsch void ieee80211_mps_set_frame_flags(struct ieee80211_sub_if_data *sdata, 2633f52b7e3SMarco Porsch struct sta_info *sta, 2643f52b7e3SMarco Porsch struct ieee80211_hdr *hdr); 2653f52b7e3SMarco Porsch void ieee80211_mps_sta_status_update(struct sta_info *sta); 2663f52b7e3SMarco Porsch void ieee80211_mps_rx_h_sta_process(struct sta_info *sta, 2673f52b7e3SMarco Porsch struct ieee80211_hdr *hdr); 2683f52b7e3SMarco Porsch void ieee80211_mpsp_trigger_process(u8 *qc, struct sta_info *sta, 2693f52b7e3SMarco Porsch bool tx, bool acked); 2703f52b7e3SMarco Porsch void ieee80211_mps_frame_release(struct sta_info *sta, 2713f52b7e3SMarco Porsch struct ieee802_11_elems *elems); 2723f52b7e3SMarco Porsch 273ccf80ddfSLuis Carlos Cobo /* Mesh paths */ 274bf7cd94dSJohannes Berg int mesh_nexthop_lookup(struct ieee80211_sub_if_data *sdata, 275bf7cd94dSJohannes Berg struct sk_buff *skb); 276bf7cd94dSJohannes Berg int mesh_nexthop_resolve(struct ieee80211_sub_if_data *sdata, 277bf7cd94dSJohannes Berg struct sk_buff *skb); 278f698d856SJasper Bryant-Greene void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata); 279bf7cd94dSJohannes Berg struct mesh_path *mesh_path_lookup(struct ieee80211_sub_if_data *sdata, 280bf7cd94dSJohannes Berg const u8 *dst); 281bf7cd94dSJohannes Berg struct mesh_path *mpp_path_lookup(struct ieee80211_sub_if_data *sdata, 282bf7cd94dSJohannes Berg const u8 *dst); 283bf7cd94dSJohannes Berg int mpp_path_add(struct ieee80211_sub_if_data *sdata, 284bf7cd94dSJohannes Berg const u8 *dst, const u8 *mpp); 285bf7cd94dSJohannes Berg struct mesh_path * 286bf7cd94dSJohannes Berg mesh_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx); 287a2db2ed3SHenning Rogge struct mesh_path * 288a2db2ed3SHenning Rogge mpp_path_lookup_by_idx(struct ieee80211_sub_if_data *sdata, int idx); 289ccf80ddfSLuis Carlos Cobo void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop); 290f698d856SJasper Bryant-Greene void mesh_path_expire(struct ieee80211_sub_if_data *sdata); 291f698d856SJasper Bryant-Greene void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata, 292f698d856SJasper Bryant-Greene struct ieee80211_mgmt *mgmt, size_t len); 293ae76eef0SBob Copeland struct mesh_path * 294ae76eef0SBob Copeland mesh_path_add(struct ieee80211_sub_if_data *sdata, const u8 *dst); 2955ee68e5bSJavier Cardona 2965ee68e5bSJavier Cardona int mesh_path_add_gate(struct mesh_path *mpath); 2975ee68e5bSJavier Cardona int mesh_path_send_to_gates(struct mesh_path *mpath); 2985ee68e5bSJavier Cardona int mesh_gate_num(struct ieee80211_sub_if_data *sdata); 299ab60633cSNarayanraddi Masti u32 airtime_link_metric_get(struct ieee80211_local *local, 300ab60633cSNarayanraddi Masti struct sta_info *sta); 301bf7cd94dSJohannes Berg 302ccf80ddfSLuis Carlos Cobo /* Mesh plinks */ 303f743ff49SThomas Pedersen void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata, 304ecbc12adSBob Copeland u8 *hw_addr, struct ieee802_11_elems *ie, 305ecbc12adSBob Copeland struct ieee80211_rx_status *rx_status); 306f698d856SJasper Bryant-Greene bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie); 30715ddba5fSAnjaneyulu u64 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); 3084c02d62fSKees Cook void mesh_plink_timer(struct timer_list *t); 309ccf80ddfSLuis Carlos Cobo void mesh_plink_broken(struct sta_info *sta); 31015ddba5fSAnjaneyulu u64 mesh_plink_deactivate(struct sta_info *sta); 31115ddba5fSAnjaneyulu u64 mesh_plink_open(struct sta_info *sta); 31215ddba5fSAnjaneyulu u64 mesh_plink_block(struct sta_info *sta); 313f698d856SJasper Bryant-Greene void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, 314f698d856SJasper Bryant-Greene struct ieee80211_mgmt *mgmt, size_t len, 315f698d856SJasper Bryant-Greene struct ieee80211_rx_status *rx_status); 31645b5028eSThomas Pedersen void mesh_sta_cleanup(struct sta_info *sta); 317ccf80ddfSLuis Carlos Cobo 318ccf80ddfSLuis Carlos Cobo /* Private interfaces */ 319ccf80ddfSLuis Carlos Cobo /* Mesh paths */ 320bf7cd94dSJohannes Berg int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata, 321f63f8421SChun-Yeow Yeoh u8 ttl, const u8 *target, u32 target_sn, 322f63f8421SChun-Yeow Yeoh u16 target_rcode, const u8 *ra); 323ccf80ddfSLuis Carlos Cobo void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta); 324ccf80ddfSLuis Carlos Cobo void mesh_path_flush_pending(struct mesh_path *mpath); 325ccf80ddfSLuis Carlos Cobo void mesh_path_tx_pending(struct mesh_path *mpath); 3268b5cb7e4SPavel Skripkin void mesh_pathtbl_init(struct ieee80211_sub_if_data *sdata); 3272bdaf386SBob Copeland void mesh_pathtbl_unregister(struct ieee80211_sub_if_data *sdata); 328bf7cd94dSJohannes Berg int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr); 32934f11cd3SKees Cook void mesh_path_timer(struct timer_list *t); 330ccf80ddfSLuis Carlos Cobo void mesh_path_flush_by_nexthop(struct sta_info *sta); 331bf7cd94dSJohannes Berg void mesh_path_discard_frame(struct ieee80211_sub_if_data *sdata, 332bf7cd94dSJohannes Berg struct sk_buff *skb); 333e304bfd3SRui Paulo void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata); 334ccf80ddfSLuis Carlos Cobo 33525d49e4dSThomas Pedersen bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt); 336d5edb9aeSFelix Fietkau struct ieee80211_mesh_fast_tx * 337d5edb9aeSFelix Fietkau mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, const u8 *addr); 338d5edb9aeSFelix Fietkau bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata, 339d5edb9aeSFelix Fietkau struct sk_buff *skb, u32 ctrl_flags); 340d5edb9aeSFelix Fietkau void mesh_fast_tx_cache(struct ieee80211_sub_if_data *sdata, 341d5edb9aeSFelix Fietkau struct sk_buff *skb, struct mesh_path *mpath); 342d5edb9aeSFelix Fietkau void mesh_fast_tx_gc(struct ieee80211_sub_if_data *sdata); 343d5edb9aeSFelix Fietkau void mesh_fast_tx_flush_addr(struct ieee80211_sub_if_data *sdata, 344d5edb9aeSFelix Fietkau const u8 *addr); 345d5edb9aeSFelix Fietkau void mesh_fast_tx_flush_mpath(struct mesh_path *mpath); 346d5edb9aeSFelix Fietkau void mesh_fast_tx_flush_sta(struct ieee80211_sub_if_data *sdata, 347d5edb9aeSFelix Fietkau struct sta_info *sta); 348d5edb9aeSFelix Fietkau void mesh_path_refresh(struct ieee80211_sub_if_data *sdata, 349d5edb9aeSFelix Fietkau struct mesh_path *mpath, const u8 *addr); 350f5ea9120SJohannes Berg 351902acc78SJohannes Berg #ifdef CONFIG_MAC80211_MESH 3521617bab8SMarco Porsch static inline 35315ddba5fSAnjaneyulu u64 mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata) 3541617bab8SMarco Porsch { 3551617bab8SMarco Porsch atomic_inc(&sdata->u.mesh.estab_plinks); 356e05ecccdSJacob Minshall return mesh_accept_plinks_update(sdata) | BSS_CHANGED_BEACON; 3571617bab8SMarco Porsch } 3581617bab8SMarco Porsch 3591617bab8SMarco Porsch static inline 36015ddba5fSAnjaneyulu u64 mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata) 3611617bab8SMarco Porsch { 3621617bab8SMarco Porsch atomic_dec(&sdata->u.mesh.estab_plinks); 363e05ecccdSJacob Minshall return mesh_accept_plinks_update(sdata) | BSS_CHANGED_BEACON; 3641617bab8SMarco Porsch } 3651617bab8SMarco Porsch 366ccf80ddfSLuis Carlos Cobo static inline int mesh_plink_free_count(struct ieee80211_sub_if_data *sdata) 367ccf80ddfSLuis Carlos Cobo { 368472dbc45SJohannes Berg return sdata->u.mesh.mshcfg.dot11MeshMaxPeerLinks - 3691258d976SAshok Nagarajan atomic_read(&sdata->u.mesh.estab_plinks); 370ccf80ddfSLuis Carlos Cobo } 371ccf80ddfSLuis Carlos Cobo 372ccf80ddfSLuis Carlos Cobo static inline bool mesh_plink_availables(struct ieee80211_sub_if_data *sdata) 373ccf80ddfSLuis Carlos Cobo { 374d0709a65SJohannes Berg return (min_t(long, mesh_plink_free_count(sdata), 375ccf80ddfSLuis Carlos Cobo MESH_MAX_PLINKS - sdata->local->num_sta)) > 0; 376ccf80ddfSLuis Carlos Cobo } 377ccf80ddfSLuis Carlos Cobo 378ccf80ddfSLuis Carlos Cobo static inline void mesh_path_activate(struct mesh_path *mpath) 379ccf80ddfSLuis Carlos Cobo { 380ccf80ddfSLuis Carlos Cobo mpath->flags |= MESH_PATH_ACTIVE | MESH_PATH_RESOLVED; 381ccf80ddfSLuis Carlos Cobo } 382ccf80ddfSLuis Carlos Cobo 383c7108a71SJavier Cardona static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata) 384c7108a71SJavier Cardona { 385c7108a71SJavier Cardona return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP; 386c7108a71SJavier Cardona } 387c7108a71SJavier Cardona 38894c514feSAndrei Emeltchenko void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata); 389445cd452SMasashi Honma void mesh_sync_adjust_tsf(struct ieee80211_sub_if_data *sdata); 390bf7cd94dSJohannes Berg void ieee80211s_stop(void); 391902acc78SJohannes Berg #else 392c7108a71SJavier Cardona static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata) 393c7108a71SJavier Cardona { return false; } 39494c514feSAndrei Emeltchenko static inline void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata) 39594c514feSAndrei Emeltchenko {} 396bf7cd94dSJohannes Berg static inline void ieee80211s_stop(void) {} 397902acc78SJohannes Berg #endif 398902acc78SJohannes Berg 399ccf80ddfSLuis Carlos Cobo #endif /* IEEE80211S_H */ 400