18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef HOSTAP_AP_H
38c2ecf20Sopenharmony_ci#define HOSTAP_AP_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#include "hostap_80211.h"
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci/* AP data structures for STAs */
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci/* maximum number of frames to buffer per STA */
108c2ecf20Sopenharmony_ci#define STA_MAX_TX_BUFFER 32
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci/* STA flags */
138c2ecf20Sopenharmony_ci#define WLAN_STA_AUTH BIT(0)
148c2ecf20Sopenharmony_ci#define WLAN_STA_ASSOC BIT(1)
158c2ecf20Sopenharmony_ci#define WLAN_STA_PS BIT(2)
168c2ecf20Sopenharmony_ci#define WLAN_STA_TIM BIT(3) /* TIM bit is on for PS stations */
178c2ecf20Sopenharmony_ci#define WLAN_STA_PERM BIT(4) /* permanent; do not remove entry on expiration */
188c2ecf20Sopenharmony_ci#define WLAN_STA_AUTHORIZED BIT(5) /* If 802.1X is used, this flag is
198c2ecf20Sopenharmony_ci				    * controlling whether STA is authorized to
208c2ecf20Sopenharmony_ci				    * send and receive non-IEEE 802.1X frames
218c2ecf20Sopenharmony_ci				    */
228c2ecf20Sopenharmony_ci#define WLAN_STA_PENDING_POLL BIT(6) /* pending activity poll not ACKed */
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci#define WLAN_RATE_1M BIT(0)
258c2ecf20Sopenharmony_ci#define WLAN_RATE_2M BIT(1)
268c2ecf20Sopenharmony_ci#define WLAN_RATE_5M5 BIT(2)
278c2ecf20Sopenharmony_ci#define WLAN_RATE_11M BIT(3)
288c2ecf20Sopenharmony_ci#define WLAN_RATE_COUNT 4
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci/* Maximum size of Supported Rates info element. IEEE 802.11 has a limit of 8,
318c2ecf20Sopenharmony_ci * but some pre-standard IEEE 802.11g products use longer elements. */
328c2ecf20Sopenharmony_ci#define WLAN_SUPP_RATES_MAX 32
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci/* Try to increase TX rate after # successfully sent consecutive packets */
358c2ecf20Sopenharmony_ci#define WLAN_RATE_UPDATE_COUNT 50
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci/* Decrease TX rate after # consecutive dropped packets */
388c2ecf20Sopenharmony_ci#define WLAN_RATE_DECREASE_THRESHOLD 2
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_cistruct sta_info {
418c2ecf20Sopenharmony_ci	struct list_head list;
428c2ecf20Sopenharmony_ci	struct sta_info *hnext; /* next entry in hash table list */
438c2ecf20Sopenharmony_ci	atomic_t users; /* number of users (do not remove if > 0) */
448c2ecf20Sopenharmony_ci	struct proc_dir_entry *proc;
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	u8 addr[6];
478c2ecf20Sopenharmony_ci	u16 aid; /* STA's unique AID (1 .. 2007) or 0 if not yet assigned */
488c2ecf20Sopenharmony_ci	u32 flags;
498c2ecf20Sopenharmony_ci	u16 capability;
508c2ecf20Sopenharmony_ci	u16 listen_interval; /* or beacon_int for APs */
518c2ecf20Sopenharmony_ci	u8 supported_rates[WLAN_SUPP_RATES_MAX];
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci	unsigned long last_auth;
548c2ecf20Sopenharmony_ci	unsigned long last_assoc;
558c2ecf20Sopenharmony_ci	unsigned long last_rx;
568c2ecf20Sopenharmony_ci	unsigned long last_tx;
578c2ecf20Sopenharmony_ci	unsigned long rx_packets, tx_packets;
588c2ecf20Sopenharmony_ci	unsigned long rx_bytes, tx_bytes;
598c2ecf20Sopenharmony_ci	struct sk_buff_head tx_buf;
608c2ecf20Sopenharmony_ci	/* FIX: timeout buffers with an expiry time somehow derived from
618c2ecf20Sopenharmony_ci	 * listen_interval */
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci	s8 last_rx_silence; /* Noise in dBm */
648c2ecf20Sopenharmony_ci	s8 last_rx_signal; /* Signal strength in dBm */
658c2ecf20Sopenharmony_ci	u8 last_rx_rate; /* TX rate in 0.1 Mbps */
668c2ecf20Sopenharmony_ci	u8 last_rx_updated; /* IWSPY's struct iw_quality::updated */
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	u8 tx_supp_rates; /* bit field of supported TX rates */
698c2ecf20Sopenharmony_ci	u8 tx_rate; /* current TX rate (in 0.1 Mbps) */
708c2ecf20Sopenharmony_ci	u8 tx_rate_idx; /* current TX rate (WLAN_RATE_*) */
718c2ecf20Sopenharmony_ci	u8 tx_max_rate; /* max TX rate (WLAN_RATE_*) */
728c2ecf20Sopenharmony_ci	u32 tx_count[WLAN_RATE_COUNT]; /* number of frames sent (per rate) */
738c2ecf20Sopenharmony_ci	u32 rx_count[WLAN_RATE_COUNT]; /* number of frames received (per rate)
748c2ecf20Sopenharmony_ci					*/
758c2ecf20Sopenharmony_ci	u32 tx_since_last_failure;
768c2ecf20Sopenharmony_ci	u32 tx_consecutive_exc;
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci	struct lib80211_crypt_data *crypt;
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci	int ap; /* whether this station is an AP */
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci	local_info_t *local;
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
858c2ecf20Sopenharmony_ci	union {
868c2ecf20Sopenharmony_ci		struct {
878c2ecf20Sopenharmony_ci			char *challenge; /* shared key authentication
888c2ecf20Sopenharmony_ci					  * challenge */
898c2ecf20Sopenharmony_ci		} sta;
908c2ecf20Sopenharmony_ci		struct {
918c2ecf20Sopenharmony_ci			int ssid_len;
928c2ecf20Sopenharmony_ci			unsigned char ssid[MAX_SSID_LEN + 1]; /* AP's ssid */
938c2ecf20Sopenharmony_ci			int channel;
948c2ecf20Sopenharmony_ci			unsigned long last_beacon; /* last RX beacon time */
958c2ecf20Sopenharmony_ci		} ap;
968c2ecf20Sopenharmony_ci	} u;
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci	struct timer_list timer;
998c2ecf20Sopenharmony_ci	enum { STA_NULLFUNC = 0, STA_DISASSOC, STA_DEAUTH } timeout_next;
1008c2ecf20Sopenharmony_ci#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
1018c2ecf20Sopenharmony_ci};
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci#define MAX_STA_COUNT 1024
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci/* Maximum number of AIDs to use for STAs; must be 2007 or lower
1078c2ecf20Sopenharmony_ci * (8802.11 limitation) */
1088c2ecf20Sopenharmony_ci#define MAX_AID_TABLE_SIZE 128
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci#define STA_HASH_SIZE 256
1118c2ecf20Sopenharmony_ci#define STA_HASH(sta) (sta[5])
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci/* Default value for maximum station inactivity. After AP_MAX_INACTIVITY_SEC
1158c2ecf20Sopenharmony_ci * has passed since last received frame from the station, a nullfunc data
1168c2ecf20Sopenharmony_ci * frame is sent to the station. If this frame is not acknowledged and no other
1178c2ecf20Sopenharmony_ci * frames have been received, the station will be disassociated after
1188c2ecf20Sopenharmony_ci * AP_DISASSOC_DELAY. Similarly, a the station will be deauthenticated after
1198c2ecf20Sopenharmony_ci * AP_DEAUTH_DELAY. AP_TIMEOUT_RESOLUTION is the resolution that is used with
1208c2ecf20Sopenharmony_ci * max inactivity timer. */
1218c2ecf20Sopenharmony_ci#define AP_MAX_INACTIVITY_SEC (5 * 60)
1228c2ecf20Sopenharmony_ci#define AP_DISASSOC_DELAY (HZ)
1238c2ecf20Sopenharmony_ci#define AP_DEAUTH_DELAY (HZ)
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci/* ap_policy: whether to accept frames to/from other APs/IBSS */
1268c2ecf20Sopenharmony_citypedef enum {
1278c2ecf20Sopenharmony_ci	AP_OTHER_AP_SKIP_ALL = 0,
1288c2ecf20Sopenharmony_ci	AP_OTHER_AP_SAME_SSID = 1,
1298c2ecf20Sopenharmony_ci	AP_OTHER_AP_ALL = 2,
1308c2ecf20Sopenharmony_ci	AP_OTHER_AP_EVEN_IBSS = 3
1318c2ecf20Sopenharmony_ci} ap_policy_enum;
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci#define PRISM2_AUTH_OPEN BIT(0)
1348c2ecf20Sopenharmony_ci#define PRISM2_AUTH_SHARED_KEY BIT(1)
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci/* MAC address-based restrictions */
1388c2ecf20Sopenharmony_cistruct mac_entry {
1398c2ecf20Sopenharmony_ci	struct list_head list;
1408c2ecf20Sopenharmony_ci	u8 addr[6];
1418c2ecf20Sopenharmony_ci};
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_cistruct mac_restrictions {
1448c2ecf20Sopenharmony_ci	enum { MAC_POLICY_OPEN = 0, MAC_POLICY_ALLOW, MAC_POLICY_DENY } policy;
1458c2ecf20Sopenharmony_ci	unsigned int entries;
1468c2ecf20Sopenharmony_ci	struct list_head mac_list;
1478c2ecf20Sopenharmony_ci	spinlock_t lock;
1488c2ecf20Sopenharmony_ci};
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_cistruct add_sta_proc_data {
1528c2ecf20Sopenharmony_ci	u8 addr[ETH_ALEN];
1538c2ecf20Sopenharmony_ci	struct add_sta_proc_data *next;
1548c2ecf20Sopenharmony_ci};
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_citypedef enum { WDS_ADD, WDS_DEL } wds_oper_type;
1588c2ecf20Sopenharmony_cistruct wds_oper_data {
1598c2ecf20Sopenharmony_ci	wds_oper_type type;
1608c2ecf20Sopenharmony_ci	u8 addr[ETH_ALEN];
1618c2ecf20Sopenharmony_ci	struct wds_oper_data *next;
1628c2ecf20Sopenharmony_ci};
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_cistruct ap_data {
1668c2ecf20Sopenharmony_ci	int initialized; /* whether ap_data has been initialized */
1678c2ecf20Sopenharmony_ci	local_info_t *local;
1688c2ecf20Sopenharmony_ci	int bridge_packets; /* send packet to associated STAs directly to the
1698c2ecf20Sopenharmony_ci			     * wireless media instead of higher layers in the
1708c2ecf20Sopenharmony_ci			     * kernel */
1718c2ecf20Sopenharmony_ci	unsigned int bridged_unicast; /* number of unicast frames bridged on
1728c2ecf20Sopenharmony_ci				       * wireless media */
1738c2ecf20Sopenharmony_ci	unsigned int bridged_multicast; /* number of non-unicast frames
1748c2ecf20Sopenharmony_ci					 * bridged on wireless media */
1758c2ecf20Sopenharmony_ci	unsigned int tx_drop_nonassoc; /* number of unicast TX packets dropped
1768c2ecf20Sopenharmony_ci					* because they were to an address that
1778c2ecf20Sopenharmony_ci					* was not associated */
1788c2ecf20Sopenharmony_ci	int nullfunc_ack; /* use workaround for nullfunc frame ACKs */
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci	spinlock_t sta_table_lock;
1818c2ecf20Sopenharmony_ci	int num_sta; /* number of entries in sta_list */
1828c2ecf20Sopenharmony_ci	struct list_head sta_list; /* STA info list head */
1838c2ecf20Sopenharmony_ci	struct sta_info *sta_hash[STA_HASH_SIZE];
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ci	struct proc_dir_entry *proc;
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci	ap_policy_enum ap_policy;
1888c2ecf20Sopenharmony_ci	unsigned int max_inactivity;
1898c2ecf20Sopenharmony_ci	int autom_ap_wds;
1908c2ecf20Sopenharmony_ci
1918c2ecf20Sopenharmony_ci	struct mac_restrictions mac_restrictions; /* MAC-based auth */
1928c2ecf20Sopenharmony_ci	int last_tx_rate;
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_ci	struct work_struct add_sta_proc_queue;
1958c2ecf20Sopenharmony_ci	struct add_sta_proc_data *add_sta_proc_entries;
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_ci	struct work_struct wds_oper_queue;
1988c2ecf20Sopenharmony_ci	struct wds_oper_data *wds_oper_entries;
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci	u16 tx_callback_idx;
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_ci#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
2038c2ecf20Sopenharmony_ci	/* pointers to STA info; based on allocated AID or NULL if AID free
2048c2ecf20Sopenharmony_ci	 * AID is in the range 1-2007, so sta_aid[0] corresponders to AID 1
2058c2ecf20Sopenharmony_ci	 * and so on
2068c2ecf20Sopenharmony_ci	 */
2078c2ecf20Sopenharmony_ci	struct sta_info *sta_aid[MAX_AID_TABLE_SIZE];
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_ci	u16 tx_callback_auth, tx_callback_assoc, tx_callback_poll;
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci	/* WEP operations for generating challenges to be used with shared key
2128c2ecf20Sopenharmony_ci	 * authentication */
2138c2ecf20Sopenharmony_ci	struct lib80211_crypto_ops *crypt;
2148c2ecf20Sopenharmony_ci	void *crypt_priv;
2158c2ecf20Sopenharmony_ci#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
2168c2ecf20Sopenharmony_ci};
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_civoid hostap_rx(struct net_device *dev, struct sk_buff *skb,
2208c2ecf20Sopenharmony_ci	       struct hostap_80211_rx_status *rx_stats);
2218c2ecf20Sopenharmony_civoid hostap_init_data(local_info_t *local);
2228c2ecf20Sopenharmony_civoid hostap_init_ap_proc(local_info_t *local);
2238c2ecf20Sopenharmony_civoid hostap_free_data(struct ap_data *ap);
2248c2ecf20Sopenharmony_civoid hostap_check_sta_fw_version(struct ap_data *ap, int sta_fw_ver);
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_citypedef enum {
2278c2ecf20Sopenharmony_ci	AP_TX_CONTINUE, AP_TX_DROP, AP_TX_RETRY, AP_TX_BUFFERED,
2288c2ecf20Sopenharmony_ci	AP_TX_CONTINUE_NOT_AUTHORIZED
2298c2ecf20Sopenharmony_ci} ap_tx_ret;
2308c2ecf20Sopenharmony_cistruct hostap_tx_data {
2318c2ecf20Sopenharmony_ci	struct sk_buff *skb;
2328c2ecf20Sopenharmony_ci	int host_encrypt;
2338c2ecf20Sopenharmony_ci	struct lib80211_crypt_data *crypt;
2348c2ecf20Sopenharmony_ci	void *sta_ptr;
2358c2ecf20Sopenharmony_ci};
2368c2ecf20Sopenharmony_ciap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx);
2378c2ecf20Sopenharmony_civoid hostap_handle_sta_release(void *ptr);
2388c2ecf20Sopenharmony_civoid hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb);
2398c2ecf20Sopenharmony_ciint hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr);
2408c2ecf20Sopenharmony_citypedef enum {
2418c2ecf20Sopenharmony_ci	AP_RX_CONTINUE, AP_RX_DROP, AP_RX_EXIT, AP_RX_CONTINUE_NOT_AUTHORIZED
2428c2ecf20Sopenharmony_ci} ap_rx_ret;
2438c2ecf20Sopenharmony_ciap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
2448c2ecf20Sopenharmony_ci			       struct sk_buff *skb,
2458c2ecf20Sopenharmony_ci			       struct hostap_80211_rx_status *rx_stats,
2468c2ecf20Sopenharmony_ci			       int wds);
2478c2ecf20Sopenharmony_ciint hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr *hdr,
2488c2ecf20Sopenharmony_ci			     struct lib80211_crypt_data **crypt,
2498c2ecf20Sopenharmony_ci			     void **sta_ptr);
2508c2ecf20Sopenharmony_ciint hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr);
2518c2ecf20Sopenharmony_ciint hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr);
2528c2ecf20Sopenharmony_ciint hostap_add_sta(struct ap_data *ap, u8 *sta_addr);
2538c2ecf20Sopenharmony_ciint hostap_update_rx_stats(struct ap_data *ap, struct ieee80211_hdr *hdr,
2548c2ecf20Sopenharmony_ci			   struct hostap_80211_rx_status *rx_stats);
2558c2ecf20Sopenharmony_civoid hostap_update_rates(local_info_t *local);
2568c2ecf20Sopenharmony_civoid hostap_add_wds_links(local_info_t *local);
2578c2ecf20Sopenharmony_civoid hostap_wds_link_oper(local_info_t *local, u8 *addr, wds_oper_type type);
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_ci#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
2608c2ecf20Sopenharmony_civoid hostap_deauth_all_stas(struct net_device *dev, struct ap_data *ap,
2618c2ecf20Sopenharmony_ci			    int resend);
2628c2ecf20Sopenharmony_ci#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_ci#endif /* HOSTAP_AP_H */
265