hc
2024-08-16 62c46c9150c4afde7e5b25436263fddf79d66f0b
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
/*
 * Copyright (C) 2015 Spreadtrum Communications Inc.
 *
 * Authors    :
 * Keguang Zhang <keguang.zhang@spreadtrum.com>
 * Jingxiang Li <Jingxiang.li@spreadtrum.com>
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
 
#ifndef __SPRDWL_H__
#define __SPRDWL_H__
 
#include <linux/module.h>
#include <linux/init.h>
#include <linux/ieee80211.h>
#include <linux/etherdevice.h>
#include <net/cfg80211.h>
#include <linux/inetdevice.h>
#include <linux/wireless.h>
#include <linux/workqueue.h>
#include <linux/timer.h>
#include <linux/atomic.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <net/if_inet6.h>
#include <net/addrconf.h>
#include <linux/dcache.h>
#include <linux/udp.h>
#include <linux/version.h>
#include "wcn_wrapper.h"
 
#include "cfg80211.h"
#include "cmdevt.h"
#include "intf.h"
#include "vendor.h"
#include "tcp_ack.h"
#include "rtt.h"
#include "version.h"
#include "tracer.h"
 
#define SPRDWL_UNALIAGN        1
#ifdef SPRDWL_UNALIAGN
#define SPRDWL_PUT_LE16(val, addr)    put_unaligned_le16((val), (&addr))
#define SPRDWL_PUT_LE32(val, addr)    put_unaligned_le32((val), (&addr))
#define SPRDWL_GET_LE16(addr)        get_unaligned_le16(&addr)
#define SPRDWL_GET_LE32(addr)        get_unaligned_le32(&addr)
#define SPRDWL_GET_LE64(addr)        get_unaligned_le64(&addr)
#else
#define SPRDWL_PUT_LE16(val, addr)    cpu_to_le16((val), (addr))
#define SPRDWL_PUT_LE32(val, addr)    cpu_to_le32((val), (addr))
#define SPRDWL_GET_LE16(addr)        le16_to_cpu((addr))
#define SPRDWL_GET_LE32(addr)        le32_to_cpu((addr))
#endif
 
/* the max length between data_head and net data */
#define SPRDWL_SKB_HEAD_RESERV_LEN    16
#define SPRDWL_COUNTRY_CODE_LEN        2
#define ETHER_TYPE_IP 0x0800           /* IP */
#define ETHER_TYPE_IPV6 0x86dd             /* IPv6 */
#define WAPI_TYPE                 0x88B4
 
#ifdef OTT_UWE
#define FOUR_BYTES_ALIGN_OFFSET 3
#endif
 
struct sprdwl_mc_filter {
   bool mc_change;
   u8 subtype;
   u8 mac_num;
   u8 mac_addr[0];
};
 
struct android_wifi_priv_cmd {
   char *buf;
   int used_len;
   int total_len;
};
 
struct scan_result {
   struct list_head list;
   int signal;
   unsigned char bssid[6];
};
 
struct sprdwl_vif {
   struct net_device *ndev;    /* Linux net device */
   struct wireless_dev wdev;    /* Linux wireless device */
   struct sprdwl_priv *priv;
 
   char name[IFNAMSIZ];
   enum sprdwl_mode mode;
   struct list_head vif_node;    /* node for virtual interface list */
   int ref;
 
   /* multicast filter stuff */
   struct sprdwl_mc_filter *mc_filter;
 
   /* common stuff */
   enum sm_state sm_state;
   unsigned char mac[ETH_ALEN];
   int ssid_len;
   u8 ssid[IEEE80211_MAX_SSID_LEN];
   u8 bssid[ETH_ALEN];
   unsigned char beacon_loss;
   bool local_mac_flag;
 
   /* encryption stuff */
   u8 prwise_crypto;
   u8 grp_crypto;
   u8 key_index[2];
   u8 key[2][4][WLAN_MAX_KEY_LEN];
   u8 key_len[2][4];
   unsigned long mgmt_reg;
 
   /* P2P stuff */
   struct ieee80211_channel listen_channel;
   u64 listen_cookie;
   u8 ctx_id;
   struct  list_head  scan_head_ptr;
#ifdef ACS_SUPPORT
   /* ACS stuff */
   struct list_head survey_info_list;
#endif /* ACS_SUPPORT*/
#ifdef DFS_MASTER
   /* dfs master mode */
   struct workqueue_struct *dfs_cac_workqueue;
   struct delayed_work dfs_cac_work;
   struct workqueue_struct *dfs_chan_sw_workqueue;
   struct delayed_work dfs_chan_sw_work;
   struct cfg80211_chan_def dfs_chandef;
#endif
   u8 wps_flag;
#ifdef SYNC_DISCONNECT
   atomic_t sync_disconnect_event;
   u16 disconnect_event_code;
   wait_queue_head_t disconnect_wq;
#endif
   bool has_rand_mac;
   u8 random_mac[ETH_ALEN];
};
 
enum sprdwl_hw_type {
   SPRDWL_HW_SIPC,
   SPRDWL_HW_SDIO,
   SPRDWL_HW_PCIE,
   SPRDWL_HW_USB
};
 
#ifdef WMMAC_WFA_CERTIFICATION
struct wmm_ac_params {
   u8 aci_aifsn; /* AIFSN, ACM, ACI */
   u8 cw; /* ECWmin, ECWmax (CW = 2^ECW - 1) */
   u16 txop_limit;
};
 
struct wmm_params_element {
   /* Element ID: 221 (0xdd); Length: 24 */
   /* required fields for WMM version 1 */
   u8 oui[3]; /* 00:50:f2 */
   u8 oui_type; /* 2 */
   u8 oui_subtype; /* 1 */
   u8 version; /* 1 for WMM version 1.0 */
   u8 qos_info; /* AP/STA specific QoS info */
   u8 reserved; /* 0 */
   struct wmm_ac_params ac[4]; /* AC_BE, AC_BK, AC_VI, AC_VO */
};
 
struct sprdwl_wmmac_params {
   struct wmm_ac_params ac[4];
   struct timer_list wmmac_edcaf_timer;
   struct timer_list wmmac_vo_timer;
   struct timer_list wmmac_vi_timer;
};
#endif
 
struct sprdwl_channel_list {
   int num_channels;
   int channels[TOTAL_2G_5G_CHANNEL_NUM];
};
 
#ifdef CP2_RESET_SUPPORT
struct sprlwl_drv_cp_sync {
   char country[2];
   unsigned char fw_stat[SPRDWL_MODE_MAX];
   bool scan_not_allowed;
   bool cmd_not_allowed;
   struct regulatory_request request;
 
};
#endif
 
struct sprdwl_priv {
   struct wiphy *wiphy;
   /* virtual interface list */
   spinlock_t list_lock;
   struct list_head vif_list;
 
   /* necessary info from fw */
   u32 chip_model;
   u32 chip_ver;
   u32 fw_ver;
   u32 fw_std;
   u32 fw_capa;
   struct sprdwl_ver wl_ver;
   u8 max_ap_assoc_sta;
   u8 max_acl_mac_addrs;
   u8 max_mc_mac_addrs;
   u8 mac_addr[ETH_ALEN];
   u8 wnm_ft_support;
   u32 wiphy_sec2_flag;
   struct wiphy_sec2_t wiphy_sec2;
   struct sync_api_verion_t sync_api;
   unsigned short skb_head_len;
   enum sprdwl_hw_type hw_type;
   void *hw_priv;
   int hw_offset;
   struct sprdwl_if_ops *if_ops;
   u16 beacon_period;
 
   /* scan */
   spinlock_t scan_lock;
   struct sprdwl_vif *scan_vif;
   struct cfg80211_scan_request *scan_request;
   struct timer_list scan_timer;
 
   /* schedule scan */
   spinlock_t sched_scan_lock;
   struct sprdwl_vif *sched_scan_vif;
   struct cfg80211_sched_scan_request *sched_scan_request;
 
   /*gscan*/
   u8 gscan_buckets_num;
   struct sprdwl_gscan_cached_results *gscan_res;
 
   struct sprdwl_gscan_hotlist_results *hotlist_res;
 
   int gscan_req_id;
   struct sprdwl_significant_change_result *significant_res;
   struct sprdwl_roam_capa roam_capa;
   /*ll status*/
   struct sprdwl_llstat_radio pre_radio;
 
   /* default MAC addr*/
   unsigned char default_mac[ETH_ALEN];
#define SPRDWL_INTF_CLOSE    (0)
#define SPRDWL_INTF_OPEN    (1)
#define SPRDWL_INTF_CLOSING    (2)
   unsigned char fw_stat[SPRDWL_MODE_MAX];
 
   /* delayed work */
   spinlock_t work_lock;
   struct work_struct work;
   struct list_head work_list;
   struct workqueue_struct *common_workq;
 
   struct dentry *debugfs;
 
   /* tcp ack management */
   struct sprdwl_tcp_ack_manage ack_m;
 
   /* FTM */
   struct sprdwl_ftm_priv ftm;
   struct wakeup_trace wakeup_tracer;
#ifdef WMMAC_WFA_CERTIFICATION
   /*wmmac*/
   struct sprdwl_wmmac_params wmmac;
#endif
   struct sprdwl_channel_list ch_2g4_info;
   struct sprdwl_channel_list ch_5g_without_dfs_info;
   struct sprdwl_channel_list ch_5g_dfs_info;
   /* with credit or without credit */
#define TX_WITH_CREDIT    (0)
#define TX_NO_CREDIT    (1)
   unsigned char credit_capa;
   int is_suspending;
 
   /* OTT support */
#define OTT_NO_SUPT    (0)
#define OTT_SUPT    (1)
   unsigned char ott_supt;
 
#ifdef CP2_RESET_SUPPORT
   struct sprlwl_drv_cp_sync sync;
#endif
};
 
struct sprdwl_eap_hdr {
   u8 version;
#define EAP_PACKET_TYPE        (0)
   u8 type;
   u16 len;
#define EAP_FAILURE_CODE    (4)
   u8 code;
   u8 id;
   u16 auth_proc_len;
   u8 auth_proc_type;
   u64 ex_id:24;
   u64 ex_type:32;
#define EAP_WSC_DONE    (5)
   u64 opcode:8;
};
 
enum sprdwl_debug {
   L_NONE = 0,
   L_ERR, /*LEVEL_ERR*/
   L_WARN, /*LEVEL_WARNING*/
   L_INFO,/*LEVEL_INFO*/
   L_DBG, /*LEVEL_DEBUG*/
};
 
extern int sprdwl_debug_level;
extern struct device *sprdwl_dev;
#define wl_debug(fmt, args...) \
   do { \
       if (sprdwl_debug_level >= L_DBG) { \
           pr_err("sprdwl:" fmt, ##args); \
       } \
   } while (0)
 
#define wl_err(fmt, args...) \
   do { \
       if (sprdwl_debug_level >= L_ERR) \
           pr_err("sprdwl:" fmt, ##args); \
   } while (0)
 
#define wl_warn(fmt, args...) \
   do { \
       if (sprdwl_debug_level >= L_WARN) \
           pr_err("sprdwl:" fmt, ##args); \
   } while (0)
 
#define wl_info(fmt, args...) \
   do { \
       if (sprdwl_debug_level >= L_INFO) { \
           pr_err("sprdwl:" fmt, ##args); \
       } \
   } while (0)
 
#define wl_err_ratelimited(fmt, args...) \
   do { \
       if (sprdwl_debug_level >= L_ERR) \
           printk_ratelimited("sprdwl:" fmt, ##args); \
   } while (0)
 
#define wl_ndev_log(level, ndev, fmt, args...) \
   do { \
       if (sprdwl_debug_level >= level) { \
           netdev_err(ndev, fmt, ##args); \
       } \
   } while (0)
 
#define wl_hex_dump(level, _str, _type, _row, _gp, _buf, _len, _ascii) \
   do { \
       if (sprdwl_debug_level >= level) { \
           print_hex_dump(KERN_ERR, _str, _type, _row, _gp, _buf, _len, _ascii); \
       } \
   } while (0)
 
#define wl_err_ratelimited(fmt, args...) \
   do { \
       if (sprdwl_debug_level >= L_ERR) \
           printk_ratelimited("sprdwl:" fmt, ##args); \
   } while (0)
 
#ifdef ACS_SUPPORT
struct sprdwl_bssid {
   unsigned char bssid[ETH_ALEN];
   struct list_head list;
};
 
struct sprdwl_survey_info {
   /* survey info */
   unsigned int cca_busy_time;
   char noise;
   struct ieee80211_channel *channel;
   struct list_head survey_list;
   /* channel info */
   unsigned short chan;
   unsigned short beacon_num;
   struct list_head bssid_list;
};
 
void clean_survey_info_list(struct sprdwl_vif *vif);
void transfer_survey_info(struct sprdwl_vif *vif);
void acs_scan_result(struct sprdwl_vif *vif, u16 chan,
            struct ieee80211_mgmt *mgmt);
#endif /* ACS_SUPPORT */
 
void init_scan_list(struct sprdwl_vif *vif);
void clean_scan_list(struct sprdwl_vif *vif);
extern struct sprdwl_priv *g_sprdwl_priv;
 
void sprdwl_netif_rx(struct sk_buff *skb, struct net_device *ndev);
void sprdwl_stop_net(struct sprdwl_vif *vif);
void sprdwl_net_flowcontrl(struct sprdwl_priv *priv,
              enum sprdwl_mode mode, bool state);
 
struct wireless_dev *sprdwl_add_iface(struct sprdwl_priv *priv,
                     const char *name,
                     enum nl80211_iftype type, u8 *addr);
int sprdwl_del_iface(struct sprdwl_priv *priv, struct sprdwl_vif *vif);
struct sprdwl_priv *sprdwl_core_create(enum sprdwl_hw_type type,
                      struct sprdwl_if_ops *ops);
void sprdwl_core_free(struct sprdwl_priv *priv);
int sprdwl_core_init(struct device *dev, struct sprdwl_priv *priv);
int sprdwl_core_deinit(struct sprdwl_priv *priv);
int marlin_reset_register_notify(void *callback_func, void *para);
int marlin_reset_unregister_notify(void);
#endif /* __SPRDWL_H__ */