aboutsummaryrefslogtreecommitdiffstats
path: root/driver/modules/hostap_ap.h
blob: afbfce9cfaeba25b2db1230f99f2cf4955c44979 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
#ifndef HOSTAP_AP_H
#define HOSTAP_AP_H

/* AP data structures for STAs */

/* maximum number of frames to buffer per STA */
#define STA_MAX_TX_BUFFER 32

/* Flags used in skb->cb[6] to control how the packet is handled in TX path.
 * skb->cb[0..5] must contain magic value 'hostap' to indicate that cb[6] is
 * used. */
#define AP_SKB_CB_MAGIC "hostap"
#define AP_SKB_CB_MAGIC_LEN 6
#define AP_SKB_CB_BUFFERED_FRAME BIT(0)
#define AP_SKB_CB_ADD_MOREDATA BIT(1)


/* STA flags */
#define WLAN_STA_AUTH BIT(0)
#define WLAN_STA_ASSOC BIT(1)
#define WLAN_STA_PS BIT(2)
#define WLAN_STA_TIM BIT(3) /* TIM bit is on for PS stations */
#define WLAN_STA_PERM BIT(4) /* permanent; do not remove entry on expiration */
#define WLAN_STA_AUTHORIZED BIT(5) /* If 802.1X is used, this flag is
				    * controlling whether STA is authorized to
				    * send and receive non-IEEE 802.1X frames
				    */
#define WLAN_STA_PENDING_POLL BIT(6) /* pending activity poll not ACKed */

#define WLAN_RATE_1M BIT(0)
#define WLAN_RATE_2M BIT(1)
#define WLAN_RATE_5M5 BIT(2)
#define WLAN_RATE_11M BIT(3)
#define WLAN_RATE_COUNT 4

/* Maximum size of Supported Rates info element. IEEE 802.11 has a limit of 8,
 * but some pre-standard IEEE 802.11g products use longer elements. */
#define WLAN_SUPP_RATES_MAX 32

/* Try to increase TX rate after # successfully sent consecutive packets */
#define WLAN_RATE_UPDATE_COUNT 50

/* Decrease TX rate after # consecutive dropped packets */
#define WLAN_RATE_DECREASE_THRESHOLD 2

struct sta_info {
	struct list_head list;
	struct sta_info *hnext; /* next entry in hash table list */
	atomic_t users; /* number of users (do not remove if > 0) */
	struct proc_dir_entry *proc;

	u8 addr[6];
	u16 aid; /* STA's unique AID (1 .. 2007) or 0 if not yet assigned */
	u32 flags;
	u16 capability;
	u16 listen_interval; /* or beacon_int for APs */
	u8 supported_rates[WLAN_SUPP_RATES_MAX];

	unsigned long last_auth;
	unsigned long last_assoc;
	unsigned long last_rx;
	unsigned long last_tx;
	unsigned long rx_packets, tx_packets;
	unsigned long rx_bytes, tx_bytes;
	struct sk_buff_head tx_buf;
	/* FIX: timeout buffers with an expiry time somehow derived from
	 * listen_interval */

	u8 last_rx_silence;
	u8 last_rx_signal;
	u8 last_rx_rate;
	u8 last_rx_updated; /* IWSPY's struct iw_quality::updated */

	u8 tx_supp_rates; /* bit field of supported TX rates */
	u8 tx_rate; /* current TX rate (in 0.1 Mbps) */
	u8 tx_rate_idx; /* current TX rate (WLAN_RATE_*) */
	u8 tx_max_rate; /* max TX rate (WLAN_RATE_*) */
	u32 tx_count[WLAN_RATE_COUNT]; /* number of frames sent (per rate) */
	u32 rx_count[WLAN_RATE_COUNT]; /* number of frames received (per rate)
					*/
	u32 tx_since_last_failure;
	u32 tx_consecutive_exc;

	struct prism2_crypt_data *crypt;

	int ap; /* whether this station is an AP */

	local_info_t *local;

#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
	union {
		struct {
			char *challenge; /* shared key authentication
					  * challenge */
		} sta;
		struct {
			int ssid_len;
			unsigned char ssid[MAX_SSID_LEN + 1]; /* AP's ssid */
			int channel;
			unsigned long last_beacon; /* last RX beacon time */
		} ap;
	} u;

	struct timer_list timer;
	enum { STA_NULLFUNC = 0, STA_DISASSOC, STA_DEAUTH } timeout_next;
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
};


#define MAX_STA_COUNT 1024

/* Maximum number of AIDs to use for STAs; must be 2007 or lower
 * (8802.11 limitation) */
#define MAX_AID_TABLE_SIZE 128

#define STA_HASH_SIZE 256
#define STA_HASH(sta) (sta[5])


/* Default value for maximum station inactivity. After AP_MAX_INACTIVITY has
 * passed since last received frame from the station, a nullfunc data frame is
 * sent to the station. If this frame is not acknowledged and no other frames
 * have been received, the station will be disassociated after
 * AP_DISASSOC_DELAY. Similarily, a the station will be deauthenticated after
 * AP_DEAUTH_DELAY. AP_TIMEOUT_RESOLUTION is the resolution that is used with
 * max inactivity timer. */
#define AP_MAX_INACTIVITY (5 * 60 * HZ)
#define AP_DISASSOC_DELAY (HZ)
#define AP_DEAUTH_DELAY (HZ)

/* ap_policy: whether to accept frames to/from other APs/IBSS */
typedef enum {
	AP_OTHER_AP_SKIP_ALL = 0,
	AP_OTHER_AP_SAME_SSID = 1,
	AP_OTHER_AP_ALL = 2,
	AP_OTHER_AP_EVEN_IBSS = 3
} ap_policy_enum;

#define PRISM2_AUTH_OPEN BIT(0)
#define PRISM2_AUTH_SHARED_KEY BIT(1)


/* MAC address-based restrictions */
struct mac_entry {
	struct list_head list;
	u8 addr[6];
};

struct mac_restrictions {
	enum { MAC_POLICY_OPEN = 0, MAC_POLICY_ALLOW, MAC_POLICY_DENY } policy;
	unsigned int entries;
	struct list_head mac_list;
	spinlock_t lock;
};


struct add_sta_proc_data {
	u8 addr[ETH_ALEN];
	struct add_sta_proc_data *next;
};


struct add_wds_data {
	u8 addr[ETH_ALEN];
	struct add_wds_data *next;
};


struct ap_data {
	int initialized; /* whether ap_data has been initialized */
	local_info_t *local;
	int bridge_packets; /* send packet to associated STAs directly to the
			     * wireless media instead of higher layers in the
			     * kernel */
	unsigned int bridged_unicast; /* number of unicast frames bridged on
				       * wireless media */
	unsigned int bridged_multicast; /* number of non-unicast frames
					 * bridged on wireless media */
	int nullfunc_ack; /* use workaround for nullfunc frame ACKs */

	spinlock_t sta_table_lock;
	int num_sta; /* number of entries in sta_list */
	struct list_head sta_list; /* STA info list head */
	struct sta_info *sta_hash[STA_HASH_SIZE];

	struct proc_dir_entry *proc;

	ap_policy_enum ap_policy;
	unsigned int max_inactivity;
	int autom_ap_wds;
	int auth_algs; /* PRISM2_AUTH_ flags */

	struct mac_restrictions mac_restrictions; /* MAC-based auth */
	int last_tx_rate;

	HOSTAP_QUEUE set_tim_queue;
	struct list_head set_tim_list;
	spinlock_t set_tim_lock;

	HOSTAP_QUEUE add_sta_proc_queue;
	struct add_sta_proc_data *add_sta_proc_entries;

	HOSTAP_QUEUE add_wds_queue;
	struct add_wds_data *add_wds_entries;

	u16 tx_callback_idx;

#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
	/* pointers to STA info; based on allocated AID or NULL if AID free
	 * AID is in the range 1-2007, so sta_aid[0] corresponders to AID 1
	 * and so on
	 */
	struct sta_info *sta_aid[MAX_AID_TABLE_SIZE];

	u16 tx_callback_auth, tx_callback_assoc, tx_callback_poll;

	/* WEP operations for generating challenges to be used with shared key
	 * authentication */
	struct hostap_crypto_ops *crypt;
	void *crypt_priv;
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
};


void hostap_rx(struct net_device *dev, struct sk_buff *skb,
	       struct hostap_80211_rx_status *rx_stats);
void hostap_init_data(local_info_t *local);
void hostap_free_data(struct ap_data *ap);
void hostap_check_sta_fw_version(struct ap_data *ap, int variant, int major,
				 int minor);

typedef enum {
	AP_TX_CONTINUE, AP_TX_DROP, AP_TX_RETRY, AP_TX_BUFFERED,
	AP_TX_CONTINUE_NOT_AUTHORIZED
} ap_tx_ret;
ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct sk_buff *skb,
			       struct hfa384x_tx_frame *txdesc, int wds,
			       int host_encrypt,
			       struct prism2_crypt_data **crypt,
			       void **sta_ptr);
void hostap_handle_sta_release(void *ptr);
void hostap_handle_sta_tx_exc(local_info_t *local,
			      struct hfa384x_tx_frame *txdesc);
int hostap_update_sta_ps(local_info_t *local,
			 struct hostap_ieee80211_hdr *hdr);
typedef enum {
	AP_RX_CONTINUE, AP_RX_DROP, AP_RX_EXIT, AP_RX_CONTINUE_NOT_AUTHORIZED
} ap_rx_ret;
ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
			       struct sk_buff *skb,
			       struct hostap_80211_rx_status *rx_stats,
			       int wds);
int hostap_handle_sta_crypto(local_info_t *local,
			     struct hostap_ieee80211_hdr *hdr,
			     struct prism2_crypt_data **crypt, void **sta_ptr);
int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr);
int hostap_add_sta(struct ap_data *ap, u8 *sta_addr);
int hostap_update_rx_stats(struct ap_data *ap,
			   struct hostap_ieee80211_hdr *hdr,
			   struct hostap_80211_rx_status *rx_stats);
void hostap_update_rates(local_info_t *local);
void hostap_add_wds_links(local_info_t *local);
void hostap_add_wds_link(local_info_t *local, u8 *addr);
void hostap_ap_update_sq(struct sta_info *sta,
			 struct hostap_80211_rx_status *rx_stats);

#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
void hostap_deauth_all_stas(struct net_device *dev, struct ap_data *ap,
			    int resend);
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */

#endif /* HOSTAP_AP_H */