// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2008, 2009 open80211s Ltd. * Copyright (C) 2019, 2021-2024 Intel Corporation * Author: Luis Carlos Cobo <[email protected]> */ #include <linux/gfp.h> #include <linux/kernel.h> #include <linux/random.h> #include <linux/rculist.h> #include "ieee80211_i.h" #include "rate.h" #include "mesh.h" #define PLINK_CNF_AID(mgmt) … #define PLINK_GET_LLID(p) … #define PLINK_GET_PLID(p) … #define mod_plink_timer(s, t) … enum plink_event { … }; static const char * const mplstates[] = …; static const char * const mplevents[] = …; /* We only need a valid sta if user configured a minimum rssi_threshold. */ static bool rssi_threshold_check(struct ieee80211_sub_if_data *sdata, struct sta_info *sta) { … } /** * mesh_plink_fsm_restart - restart a mesh peer link finite state machine * * @sta: mesh peer link to restart * * Locking: this function must be called holding sta->mesh->plink_lock */ static inline void mesh_plink_fsm_restart(struct sta_info *sta) { … } /* * mesh_set_short_slot_time - enable / disable ERP short slot time. * * The standard indirectly mandates mesh STAs to turn off short slot time by * disallowing advertising this (802.11-2012 8.4.1.4), but that doesn't mean we * can't be sneaky about it. Enable short slot time if all mesh STAs in the * MBSS support ERP rates. * * Returns BSS_CHANGED_ERP_SLOT or 0 for no change. */ static u64 mesh_set_short_slot_time(struct ieee80211_sub_if_data *sdata) { … } /** * mesh_set_ht_prot_mode - set correct HT protection mode * @sdata: the (mesh) interface to handle * * Section 9.23.3.5 of IEEE 80211-2012 describes the protection rules for HT * mesh STA in a MBSS. Three HT protection modes are supported for now, non-HT * mixed mode, 20MHz-protection and no-protection mode. non-HT mixed mode is * selected if any non-HT peers are present in our MBSS. 20MHz-protection mode * is selected if all peers in our 20/40MHz MBSS support HT and at least one * HT20 peer is present. Otherwise no-protection mode is selected. * * Returns: BSS_CHANGED_HT or 0 for no change */ static u64 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata) { … } static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, enum ieee80211_self_protected_actioncode action, u8 *da, u16 llid, u16 plid, u16 reason) { … } /** * __mesh_plink_deactivate - deactivate mesh peer link * * @sta: mesh peer link to deactivate * * Mesh paths with this peer as next hop should be flushed * by the caller outside of plink_lock. * * Returns: beacon changed flag if the beacon content changed. * * Locking: the caller must hold sta->mesh->plink_lock */ static u64 __mesh_plink_deactivate(struct sta_info *sta) { … } /** * mesh_plink_deactivate - deactivate mesh peer link * * @sta: mesh peer link to deactivate * * All mesh paths with this peer as next hop will be flushed * * Returns: beacon changed flag if the beacon content changed. */ u64 mesh_plink_deactivate(struct sta_info *sta) { … } static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, struct ieee802_11_elems *elems) { … } static int mesh_allocate_aid(struct ieee80211_sub_if_data *sdata) { … } static struct sta_info * __mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *hw_addr) { … } static struct sta_info * mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *addr, struct ieee802_11_elems *elems, struct ieee80211_rx_status *rx_status) { … } /* * mesh_sta_info_get - return mesh sta info entry for @addr. * * @sdata: local meshif * @addr: peer's address * @elems: IEs from beacon or mesh peering frame. * @rx_status: rx status for the frame for signal reporting * * Return existing or newly allocated sta_info under RCU read lock. * (re)initialize with given IEs. */ static struct sta_info * mesh_sta_info_get(struct ieee80211_sub_if_data *sdata, u8 *addr, struct ieee802_11_elems *elems, struct ieee80211_rx_status *rx_status) __acquires(RCU) { … } /* * mesh_neighbour_update - update or initialize new mesh neighbor. * * @sdata: local meshif * @addr: peer's address * @elems: IEs from beacon or mesh peering frame * @rx_status: rx status for the frame for signal reporting * * Initiates peering if appropriate. */ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata, u8 *hw_addr, struct ieee802_11_elems *elems, struct ieee80211_rx_status *rx_status) { … } void mesh_plink_timer(struct timer_list *t) { … } static inline void mesh_plink_timer_set(struct sta_info *sta, u32 timeout) { … } static bool llid_in_use(struct ieee80211_sub_if_data *sdata, u16 llid) { … } static u16 mesh_get_new_llid(struct ieee80211_sub_if_data *sdata) { … } u64 mesh_plink_open(struct sta_info *sta) { … } u64 mesh_plink_block(struct sta_info *sta) { … } static void mesh_plink_close(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, enum plink_event event) { … } static u64 mesh_plink_establish(struct ieee80211_sub_if_data *sdata, struct sta_info *sta) { … } /** * mesh_plink_fsm - step @sta MPM based on @event * * @sdata: interface * @sta: mesh neighbor * @event: peering event * * Return: changed MBSS flags */ static u64 mesh_plink_fsm(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, enum plink_event event) { … } /* * mesh_plink_get_event - get correct MPM event * * @sdata: interface * @sta: peer, leave NULL if processing a frame from a new suitable peer * @elems: peering management IEs * @ftype: frame type * @llid: peer's peer link ID * @plid: peer's local link ID * * Return: new peering event for @sta, but PLINK_UNDEFINED should be treated as * an error. */ static enum plink_event mesh_plink_get_event(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, struct ieee802_11_elems *elems, enum ieee80211_self_protected_actioncode ftype, u16 llid, u16 plid) { … } static void mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, struct ieee802_11_elems *elems, struct ieee80211_rx_status *rx_status) { … } void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, size_t len, struct ieee80211_rx_status *rx_status) { … }