forked from Icenowy/xradio
-
Notifications
You must be signed in to change notification settings - Fork 50
/
xradio.h
578 lines (502 loc) · 15.1 KB
/
xradio.h
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
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
/*
* Common define of private data for XRadio drivers
*
* Copyright (c) 2013, XRadio
* Author: XRadio
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef XRADIO_H
#define XRADIO_H
#include <linux/version.h>
#include <linux/wait.h>
#include <linux/mutex.h>
#include <linux/workqueue.h>
#include <linux/sched.h>
#include <linux/atomic.h>
#include <net/mac80211.h>
//Macroses for Driver parameters.
#define XRWL_MAX_QUEUE_SZ (128)
#define AC_QUEUE_NUM 4
#define XRWL_MAX_VIFS (2)
#define XRWL_GENERIC_IF_ID (2)
#define XRWL_HOST_VIF0_11N_THROTTLE (58) //(XRWL_MAX_QUEUE_SZ/(XRWL_MAX_VIFS-1))*0.9
#define XRWL_HOST_VIF1_11N_THROTTLE (58) //(XRWL_MAX_QUEUE_SZ/(XRWL_MAX_VIFS-1))*0.9
#define XRWL_HOST_VIF0_11BG_THROTTLE (35) //XRWL_HOST_VIF0_11N_THROTTLE*0.6 = 35
#define XRWL_HOST_VIF1_11BG_THROTTLE (35) //XRWL_HOST_VIF0_11N_THROTTLE*0.6 = 35
#if 0
#define XRWL_FW_VIF0_THROTTLE (15)
#define XRWL_FW_VIF1_THROTTLE (15)
#endif
#define IEEE80211_FCTL_WEP 0x4000
#define IEEE80211_QOS_DATAGRP 0x0080
#define WSM_KEY_MAX_IDX 20
#include "queue.h"
#include "wsm.h"
#include "scan.h"
#include "tx.h"
#include "ht.h"
#include "pm.h"
#include "fwio.h"
/* #define ROC_DEBUG */
/* hidden ssid is only supported when separate probe resp IE
configuration is supported */
#ifdef PROBE_RESP_EXTRA_IE
#define HIDDEN_SSID 1
#endif
#define XRADIO_MAX_CTRL_FRAME_LEN (0x1000)
#define MAX_STA_IN_AP_MODE (14)
#define WLAN_LINK_ID_MAX (MAX_STA_IN_AP_MODE + 3)
#define XRADIO_MAX_STA_IN_AP_MODE (5)
#define XRADIO_MAX_REQUEUE_ATTEMPTS (5)
#define XRADIO_LINK_ID_UNMAPPED (15)
#define XRADIO_MAX_TID (8)
#define XRADIO_TX_BLOCK_ACK_ENABLED_FOR_ALL_TID (0x3F)
#define XRADIO_RX_BLOCK_ACK_ENABLED_FOR_ALL_TID (0x3F)
#define XRADIO_RX_BLOCK_ACK_ENABLED_FOR_BE_TID \
(XRADIO_TX_BLOCK_ACK_ENABLED_FOR_ALL_TID & 0x01)
#define XRADIO_TX_BLOCK_ACK_DISABLED_FOR_ALL_TID (0)
#define XRADIO_RX_BLOCK_ACK_DISABLED_FOR_ALL_TID (0)
#define XRADIO_BLOCK_ACK_CNT (30)
#define XRADIO_BLOCK_ACK_THLD (800)
#define XRADIO_BLOCK_ACK_HIST (3)
#define XRADIO_BLOCK_ACK_INTERVAL (1 * HZ / XRADIO_BLOCK_ACK_HIST)
#define XRWL_ALL_IFS (-1)
#ifdef ROAM_OFFLOAD
#define XRADIO_SCAN_TYPE_ACTIVE 0x1000
#define XRADIO_SCAN_BAND_5G 0x2000
#endif /*ROAM_OFFLOAD*/
#define IEEE80211_FCTL_WEP 0x4000
#define IEEE80211_QOS_DATAGRP 0x0080
#ifdef MCAST_FWDING
#define WSM_MAX_BUF 30
#endif
#define MAX_RATES_STAGE 8 //
#define MAX_RATES_RETRY 7
#define XRADIO_WORKQUEUE "xradio_wq"
#define WIFI_CONF_PATH "/data/xr_wifi.conf"
/* extern */ struct task_struct;
/* extern */ struct xradio_debug_priv;
/* extern */ struct xradio_debug_common;
/* extern */ struct firmware;
/* Please keep order */
enum xradio_join_status {
XRADIO_JOIN_STATUS_PASSIVE = 0,
XRADIO_JOIN_STATUS_MONITOR,
XRADIO_JOIN_STATUS_STA,
XRADIO_JOIN_STATUS_AP,
};
enum xradio_link_status {
XRADIO_LINK_OFF,
XRADIO_LINK_RESERVE,
XRADIO_LINK_SOFT,
XRADIO_LINK_HARD,
#if defined(CONFIG_XRADIO_USE_EXTENSIONS)
XRADIO_LINK_RESET,
XRADIO_LINK_RESET_REMAP,
#endif
};
enum xradio_bss_loss_status {
XRADIO_BSS_LOSS_NONE,
XRADIO_BSS_LOSS_CHECKING,
XRADIO_BSS_LOSS_CONFIRMING,
XRADIO_BSS_LOSS_CONFIRMED,
};
struct xradio_link_entry {
unsigned long timestamp;
enum xradio_link_status status;
#if defined(CONFIG_XRADIO_USE_EXTENSIONS)
enum xradio_link_status prev_status;
#endif
u8 mac[ETH_ALEN];
u8 buffered[XRADIO_MAX_TID];
struct sk_buff_head rx_queue;
};
#if defined(ROAM_OFFLOAD)
struct xradio_testframe {
u8 len;
u8 *data;
};
#endif
struct xradio_common {
struct xradio_debug_common *debug;
struct xradio_queue tx_queue[AC_QUEUE_NUM];
struct xradio_queue_stats tx_queue_stats;
struct ieee80211_hw *hw;
struct mac_address addresses[XRWL_MAX_VIFS];
/*Will be a pointer to a list of VIFs - Dynamically allocated */
struct ieee80211_vif *vif_list[XRWL_MAX_VIFS];
atomic_t num_vifs;
spinlock_t vif_list_lock;
u32 if_id_slot;
struct device *pdev;
struct workqueue_struct *workqueue;
struct mutex conf_mutex;
struct sdio_func *sdio_func;
int driver_ready;
/* HW/FW type (HIF_...) */
int hw_type;
int hw_revision;
int fw_revision;
/* firmware/hardware info */
unsigned int tx_hdr_len;
/* Radio data */
int output_power;
int noise;
/* calibration, output power limit and rssi<->dBm conversation data */
/* BBP/MAC state */
const struct firmware *sdd;
struct ieee80211_rate *rates;
struct ieee80211_rate *mcs_rates;
u8 mac_addr[ETH_ALEN];
/*TODO:COMBO: To be made per VIFF after mac80211 support */
struct ieee80211_channel *channel;
int channel_switch_in_progress;
wait_queue_head_t channel_switch_done;
u8 channel_changed; //add by yangfh 2015-5-15 16:57:38.
u8 long_frame_max_tx_count;
u8 short_frame_max_tx_count;
/* TODO:COMBO: According to Hong aggregation will happen per VIFF.
* Keeping in common structure for the time being. Will be moved to VIFF
* after the mechanism is clear */
u8 ba_tid_mask;
int ba_acc; /*TODO: Same as above */
int ba_cnt; /*TODO: Same as above */
int ba_cnt_rx; /*TODO: Same as above */
int ba_acc_rx; /*TODO: Same as above */
int ba_hist; /*TODO: Same as above */
struct timer_list ba_timer;/*TODO: Same as above */
spinlock_t ba_lock; /*TODO: Same as above */
bool ba_ena; /*TODO: Same as above */
struct work_struct ba_work; /*TODO: Same as above */
struct xradio_pm_state pm_state;
bool is_BT_Present;
bool is_go_thru_go_neg;
u8 conf_listen_interval;
/* BH */
atomic_t bh_tx;
atomic_t bh_term;
atomic_t bh_suspend;
struct task_struct *bh_thread;
int bh_error;
wait_queue_head_t bh_wq;
wait_queue_head_t bh_evt_wq;
int buf_id_tx; /* byte */
int buf_id_rx; /* byte */
int wsm_rx_seq; /* byte */
int wsm_tx_seq; /* byte */
int hw_bufs_used;
int hw_bufs_used_vif[XRWL_MAX_VIFS];
struct sk_buff *skb_cache;
struct sk_buff *skb_reserved;
int skb_resv_len;
bool powersave_enabled;
bool device_can_sleep;
/* Keep xradio awake (WUP = 1) 1 second after each scan to avoid
* FW issue with sleeping/waking up. */
atomic_t recent_scan;
long connet_time[XRWL_MAX_VIFS];
#ifdef CONFIG_XRADIO_SUSPEND_POWER_OFF
atomic_t suspend_state;
#endif
/* WSM */
struct wsm_caps wsm_caps;
struct mutex wsm_cmd_mux;
struct wsm_buf wsm_cmd_buf;
struct wsm_cmd wsm_cmd;
wait_queue_head_t wsm_cmd_wq;
wait_queue_head_t wsm_startup_done;
struct semaphore tx_lock_sem;
atomic_t tx_lock;
u32 pending_frame_id;
/* WSM debug */
u32 query_packetID;
atomic_t query_cnt;
struct work_struct query_work; /* for query packet */
/* Scan status */
struct xradio_scan scan;
/* TX/RX */
unsigned long rx_timestamp;
/* WSM events */
spinlock_t event_queue_lock;
struct list_head event_queue;
struct work_struct event_handler;
/* TX rate policy cache */
struct tx_policy_cache tx_policy_cache;
struct work_struct tx_policy_upload_work;
atomic_t upload_count;
/* cryptographic engine information */
/* bit field of glowing LEDs */
u16 softled_state;
/* statistics */
struct ieee80211_low_level_stats stats;
struct xradio_ht_oper ht_oper;
int tx_burst_idx;
struct ieee80211_iface_limit if_limits1[2];
struct ieee80211_iface_limit if_limits2[2];
struct ieee80211_iface_limit if_limits3[2];
struct ieee80211_iface_combination if_combs[3];
struct mutex wsm_oper_lock;
struct delayed_work rem_chan_timeout;
atomic_t remain_on_channel;
int roc_if_id;
u64 roc_cookie;
wait_queue_head_t offchannel_wq;
u16 offchannel_done;
u16 prev_channel;
int if_id_selected;
u32 key_map;
struct wsm_add_key keys[WSM_KEY_MAX_INDEX + 1];
#ifdef MCAST_FWDING
struct wsm_buf wsm_release_buf[WSM_MAX_BUF];
u8 buf_released;
#endif
#ifdef ROAM_OFFLOAD
u8 auto_scanning;
u8 frame_rcvd;
u8 num_scanchannels;
u8 num_2g_channels;
u8 num_5g_channels;
struct wsm_scan_ch scan_channels[48];
struct sk_buff *beacon;
struct sk_buff *beacon_bkp;
struct xradio_testframe testframe;
#endif /*ROAM_OFFLOAD*/
u8 connected_sta_cnt;
u16 vif0_throttle;
u16 vif1_throttle;
};
/* Virtual Interface State. One copy per VIF */
struct xradio_vif {
atomic_t enabled;
spinlock_t vif_lock;
int if_id;
/*TODO: Split into Common and VIF parts */
struct xradio_debug_priv *debug;
/* BBP/MAC state */
u8 bssid[ETH_ALEN];
struct wsm_edca_params edca;
struct wsm_tx_queue_params tx_queue_params;
struct wsm_association_mode association_mode;
struct wsm_set_bss_params bss_params;
struct wsm_set_pm powersave_mode;
struct wsm_set_pm firmware_ps_mode;
int power_set_true;
int user_power_set_true;
u8 user_pm_mode;
int cqm_rssi_thold;
unsigned cqm_rssi_hyst;
unsigned cqm_tx_failure_thold;
unsigned cqm_tx_failure_count;
bool cqm_use_rssi;
int cqm_link_loss_count;
int cqm_beacon_loss_count;
int mode;
bool enable_beacon;
int beacon_int;
size_t ssid_length;
u8 ssid[IEEE80211_MAX_SSID_LEN];
#ifdef HIDDEN_SSID
bool hidden_ssid;
#endif
bool listening;
struct wsm_rx_filter rx_filter;
struct wsm_beacon_filter_table bf_table;
struct wsm_beacon_filter_control bf_control;
struct wsm_multicast_filter multicast_filter;
bool has_multicast_subscription;
struct wsm_broadcast_addr_filter broadcast_filter;
bool disable_beacon_filter;
struct wsm_arp_ipv4_filter filter4;
struct work_struct update_filtering_work;
struct work_struct set_beacon_wakeup_period_work;
struct xradio_pm_state_vif pm_state_vif;
/*TODO: Add support in mac80211 for psmode info per VIF */
struct wsm_p2p_ps_modeinfo p2p_ps_modeinfo;
struct wsm_uapsd_info uapsd_info;
bool setbssparams_done;
u32 listen_interval;
u32 erp_info;
bool powersave_enabled;
/* WSM Join */
enum xradio_join_status join_status;
u8 join_bssid[ETH_ALEN];
struct work_struct join_work;
struct delayed_work join_timeout;
struct work_struct unjoin_work;
struct work_struct offchannel_work;
int join_dtim_period;
atomic_t delayed_unjoin;
/* Security */
s8 wep_default_key_id;
struct work_struct wep_key_work;
unsigned long rx_timestamp;
u32 cipherType;
/* AP powersave */
u32 link_id_map;
u32 max_sta_ap_mode;
u32 link_id_after_dtim;
u32 link_id_uapsd;
u32 link_id_max;
u32 wsm_key_max_idx;
struct xradio_link_entry link_id_db[MAX_STA_IN_AP_MODE];
struct work_struct link_id_work;
struct delayed_work link_id_gc_work;
u32 sta_asleep_mask;
u32 pspoll_mask;
bool aid0_bit_set;
spinlock_t ps_state_lock;
bool buffered_multicasts;
bool tx_multicast;
u8 last_tim[8]; //for softap dtim, add by yangfh
struct work_struct set_tim_work;
struct delayed_work set_cts_work;
struct work_struct multicast_start_work;
struct work_struct multicast_stop_work;
struct timer_list mcast_timeout;
/* CQM Implementation */
struct delayed_work bss_loss_work;
struct delayed_work connection_loss_work;
struct work_struct tx_failure_work;
int delayed_link_loss;
spinlock_t bss_loss_lock;
int bss_loss_status;
int bss_loss_confirm_id;
struct ieee80211_vif *vif;
struct xradio_common *hw_priv;
struct ieee80211_hw *hw;
/* ROC implementation */
struct delayed_work pending_offchanneltx_work;
#if defined(CONFIG_XRADIO_USE_EXTENSIONS)
/* Workaround for WFD testcase 6.1.10*/
struct work_struct linkid_reset_work;
u8 action_frame_sa[ETH_ALEN];
u8 action_linkid;
#endif
bool htcap;
#ifdef AP_HT_CAP_UPDATE
u16 ht_oper;
struct work_struct ht_oper_update_work;
#endif
#ifdef AP_HT_COMPAT_FIX
u16 ht_compat_cnt;
u16 ht_compat_det;
#endif
};
struct xradio_sta_priv {
int link_id;
struct xradio_vif *priv;
};
enum xradio_data_filterid {
IPV4ADDR_FILTER_ID = 0,
};
/* Datastructure for LLC-SNAP HDR */
#define P80211_OUI_LEN 3
struct ieee80211_snap_hdr {
u8 dsap; /* always 0xAA */
u8 ssap; /* always 0xAA */
u8 ctrl; /* always 0x03 */
u8 oui[P80211_OUI_LEN]; /* organizational universal id */
} __packed;
#ifdef TES_P2P_0002_ROC_RESTART
extern s32 TES_P2P_0002_roc_dur;
extern s32 TES_P2P_0002_roc_sec;
extern s32 TES_P2P_0002_roc_usec;
extern u32 TES_P2P_0002_packet_id;
extern u32 TES_P2P_0002_state;
#define TES_P2P_0002_STATE_IDLE 0x00
#define TES_P2P_0002_STATE_SEND_RESP 0x01
#define TES_P2P_0002_STATE_GET_PKTID 0x02
#endif
/* debug.h must be here because refer to struct xradio_vif and
struct xradio_common.*/
#include "debug.h"
/*******************************************************
interfaces for operations of vif.
********************************************************/
static inline
struct xradio_common *xrwl_vifpriv_to_hwpriv(struct xradio_vif *priv)
{
return priv->hw_priv;
}
static inline
struct xradio_vif *xrwl_get_vif_from_ieee80211(struct ieee80211_vif *vif)
{
return (struct xradio_vif *)vif->drv_priv;
}
static inline
struct xradio_vif *xrwl_hwpriv_to_vifpriv(struct xradio_common *hw_priv,
int if_id)
{
struct xradio_vif *vif;
if (WARN_ON((-1 == if_id) || (if_id > XRWL_MAX_VIFS)))
return NULL;
/* TODO:COMBO: During scanning frames can be received
* on interface ID 3 */
spin_lock(&hw_priv->vif_list_lock);
if (!hw_priv->vif_list[if_id]) {
spin_unlock(&hw_priv->vif_list_lock);
return NULL;
}
vif = xrwl_get_vif_from_ieee80211(hw_priv->vif_list[if_id]);
WARN_ON(!vif);
if (vif)
spin_lock(&vif->vif_lock);
spin_unlock(&hw_priv->vif_list_lock);
return vif;
}
static inline
struct xradio_vif *__xrwl_hwpriv_to_vifpriv(struct xradio_common *hw_priv,
int if_id)
{
WARN_ON((-1 == if_id) || (if_id > XRWL_MAX_VIFS));
/* TODO:COMBO: During scanning frames can be received
* on interface ID 3 */
if (!hw_priv->vif_list[if_id]) {
return NULL;
}
return xrwl_get_vif_from_ieee80211(hw_priv->vif_list[if_id]);
}
static inline
struct xradio_vif *xrwl_get_activevif(struct xradio_common *hw_priv)
{
return xrwl_hwpriv_to_vifpriv(hw_priv, ffs(hw_priv->if_id_slot)-1);
}
static inline bool is_hardware_xradio(struct xradio_common *hw_priv)
{
return (hw_priv->hw_revision == XR819_HW_REV0);
}
static inline int xrwl_get_nr_hw_ifaces(struct xradio_common *hw_priv)
{
switch(hw_priv->hw_revision) {
case XR819_HW_REV0:
default:
return 1;
}
}
#define xradio_for_each_vif(_hw_priv, _priv, _i) \
for( \
_i = 0; \
(_i < XRWL_MAX_VIFS) \
&& ((_priv = _hw_priv->vif_list[_i] ? \
xrwl_get_vif_from_ieee80211(_hw_priv->vif_list[_i]) : NULL),1); \
_i++ \
)
/*******************************************************
interfaces for operations of queue.
********************************************************/
static inline void xradio_tx_queues_lock(struct xradio_common *hw_priv)
{
int i;
for (i = 0; i < 4; ++i)
xradio_queue_lock(&hw_priv->tx_queue[i]);
}
static inline void xradio_tx_queues_unlock(struct xradio_common *hw_priv)
{
int i;
for (i = 0; i < 4; ++i)
xradio_queue_unlock(&hw_priv->tx_queue[i]);
}
#endif /* XRADIO_H */