Commit | Line | Data |
---|---|---|
ec470a07 TK |
1 | /***************************************************************************** |
2 | * | |
85aa0fce | 3 | * Copyright (c) 2012 - 2019 Samsung Electronics Co., Ltd. All rights reserved |
ec470a07 TK |
4 | * |
5 | ****************************************************************************/ | |
6 | ||
7 | #ifndef __SLSI_DEVICE_H__ | |
8 | #define __SLSI_DEVICE_H__ | |
9 | ||
10 | #include <linux/init.h> | |
11 | #include <linux/device.h> | |
12 | #include <linux/inetdevice.h> | |
13 | #include <net/addrconf.h> | |
14 | ||
15 | #include <linux/version.h> | |
16 | #include <linux/module.h> | |
17 | #include <linux/string.h> | |
18 | #include <linux/kernel.h> | |
19 | #include <linux/netdevice.h> | |
20 | #include <linux/etherdevice.h> | |
21 | #include <linux/ratelimit.h> | |
22 | #include <linux/ip.h> | |
23 | ||
24 | #include <linux/completion.h> | |
25 | #include <linux/workqueue.h> | |
26 | #include <linux/time.h> | |
27 | #include <linux/sched.h> | |
28 | ||
29 | #include <linux/nl80211.h> | |
30 | #include <linux/wireless.h> | |
31 | #include <linux/proc_fs.h> | |
32 | #include <linux/ieee80211.h> | |
33 | #include <net/cfg80211.h> | |
34 | #include <linux/nl80211.h> | |
35 | ||
36 | #include <scsc/scsc_mx.h> | |
37 | ||
38 | #include "fapi.h" | |
39 | #include "const.h" | |
40 | #include "utils.h" | |
41 | #include "hip.h" | |
42 | #include "log_clients.h" | |
43 | #include "src_sink.h" | |
44 | #include "scsc_wifi_fcq.h" | |
45 | #include "scsc_wifi_cm_if.h" | |
46 | #include "hip4.h" | |
47 | #include "nl80211_vendor.h" | |
48 | #include "traffic_monitor.h" | |
49 | ||
7c9842a5 AC |
50 | #define FAPI_MAJOR_VERSION(v) (((v) >> 8) & 0xFF) |
51 | #define FAPI_MINOR_VERSION(v) ((v) & 0xFF) | |
52 | ||
ec470a07 TK |
53 | /* Modes for CMDGETBSSINFO and CMDGETSTAINFO */ |
54 | #define SLSI_80211_MODE_11B 0 | |
55 | #define SLSI_80211_MODE_11G 1 | |
56 | #define SLSI_80211_MODE_11N 2 | |
57 | #define SLSI_80211_MODE_11A 3 | |
58 | #define SLSI_80211_MODE_11AC 4 | |
59 | ||
5fcd17b3 PK |
60 | #define SLSI_FW_API_RATE_HT_SELECTOR_FIELD 0xc000 |
61 | #define SLSI_FW_API_RATE_NON_HT_SELECTED 0x4000 | |
62 | #define SLSI_FW_API_RATE_HT_SELECTED 0x8000 | |
63 | #define SLSI_FW_API_RATE_VHT_SELECTED 0xc000 | |
64 | ||
65 | #define SLSI_FW_API_RATE_VHT_MCS_FIELD 0x000F | |
66 | #define SLSI_FW_API_RATE_HT_MCS_FIELD 0x003F | |
67 | #define SLSI_FW_API_RATE_INDEX_FIELD 0x1fff | |
68 | #define SLSI_FW_API_RATE_VHT_NSS_FIELD 0x0070 | |
69 | #define SLSI_FW_API_RATE_HT_NSS_FIELD 0x0040 | |
70 | ||
71 | #define SLSI_FW_API_RATE_BW_FIELD 0x0600 | |
72 | #define SLSI_FW_API_RATE_BW_40MHZ 0x0200 | |
73 | #define SLSI_FW_API_RATE_BW_20MHZ 0x0000 | |
74 | ||
75 | #define SLSI_FW_API_RATE_SGI 0x0100 | |
76 | #define SLSI_FW_API_RATE_GF 0x0080 | |
77 | ||
78 | /* indices: 3= BW20->idx_0, BW40->idx_1, BW80->idx_2. | |
79 | * 2= noSGI->idx_0, SGI->idx_1 | |
80 | * 10= mcs index | |
81 | * rate units 100kbps | |
82 | * This table for single stream Nss=1and does not include 160MHz BW and 80+80MHz BW. | |
83 | */ | |
84 | static const u16 slsi_rates_table[3][2][10] = { | |
85 | { /* BW20 */ | |
86 | { /* no SGI */ | |
87 | 65, 130, 195, 260, 390, 520, 585, 650, 780, 0 | |
88 | }, | |
89 | { /* SGI */ | |
90 | 72, 144, 217, 289, 433, 578, 650, 722, 867, 0 | |
91 | } | |
92 | }, | |
93 | { /* BW40 */ | |
94 | { /* no SGI */ | |
95 | 135, 270, 405, 540, 810, 1080, 1215, 1350, 1620, 1800 | |
96 | }, | |
97 | { /* SGI */ | |
98 | 150, 300, 450, 600, 900, 1200, 1350, 1500, 1800, 2000 | |
99 | } | |
100 | }, | |
101 | { /* BW80 */ | |
102 | { /* no SGI */ | |
103 | 293, 585, 878, 1170, 1755, 2340, 2633, 2925, 3510, 3900 | |
104 | }, | |
105 | { /* SGI */ | |
106 | 325, 650, 975, 1300, 1950, 2600, 2925, 3250, 3900, 4333 | |
107 | } | |
108 | } | |
109 | }; | |
ec470a07 TK |
110 | /* MSDU subframe Header */ |
111 | struct msduhdr { | |
112 | unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ | |
113 | unsigned char h_source[ETH_ALEN]; /* source ether addr */ | |
114 | __be16 len; /* MSDU Subframe length */ | |
115 | unsigned char dsap; /* DSAP field - SNAP 0xaa */ | |
116 | unsigned char ssap; /* SSAP field - SNAP 0xaa */ | |
117 | unsigned char ui; /* Control field: U, func UI - 0x03 */ | |
118 | unsigned char oui[3]; /* Organization Code - 0x000000 */ | |
119 | __be16 type; /* Type - 0x0800 (IPv4)*/ | |
120 | } __attribute__((packed)); | |
121 | ||
122 | static inline void ethr_ii_to_subframe_msdu(struct sk_buff *skb) | |
123 | { | |
124 | struct ethhdr *ehdr; | |
125 | struct msduhdr msduh; | |
126 | ||
127 | ehdr = eth_hdr(skb); | |
128 | ether_addr_copy(msduh.h_dest, ehdr->h_dest); | |
129 | ether_addr_copy(msduh.h_source, ehdr->h_source); | |
130 | /* adjust packet length */ | |
131 | msduh.len = cpu_to_be16(skb->len - 6); | |
132 | msduh.dsap = 0xaa; | |
133 | msduh.ssap = 0xaa; | |
134 | msduh.ui = 0x03; | |
135 | memset(msduh.oui, 0x0, 3); | |
136 | msduh.type = ehdr->h_proto; | |
137 | (void)skb_push(skb, sizeof(struct msduhdr) - sizeof(struct ethhdr)); | |
77c81e22 DP |
138 | /* update SKB mac_header to point to start of MSDU header */ |
139 | skb->mac_header -= (sizeof(struct msduhdr) - sizeof(struct ethhdr)); | |
ec470a07 TK |
140 | memcpy(skb->data, &msduh, sizeof(struct msduhdr)); |
141 | } | |
142 | ||
143 | #define SLSI_TX_PROCESS_ID_MIN (0xC001) | |
144 | #define SLSI_TX_PROCESS_ID_MAX (0xCF00) | |
145 | #define SLSI_TX_PROCESS_ID_UDI_MIN (0xCF01) | |
146 | #define SLSI_TX_PROCESS_ID_UDI_MAX (0xCFFE) | |
147 | ||
148 | /* There are no wakelocks in kernel/supplicant/hostapd. | |
149 | * So keep the platform active for some time after receiving any data packet. | |
150 | * This timeout value can be fine-tuned based on the test results. | |
151 | */ | |
152 | #define SLSI_RX_WAKELOCK_TIME (200) | |
153 | #define MAX_BA_BUFFER_SIZE 64 | |
154 | #define NUM_BA_SESSIONS_PER_PEER 8 | |
155 | #define MAX_CHANNEL_LIST 20 | |
156 | #define SLSI_MAX_RX_BA_SESSIONS (8) | |
5fcd17b3 | 157 | #define SLSI_STA_ACTION_FRAME_BITMAP (SLSI_ACTION_FRAME_PUBLIC | SLSI_ACTION_FRAME_WMM | SLSI_ACTION_FRAME_WNM |\ |
85aa0fce Y |
158 | SLSI_ACTION_FRAME_QOS | SLSI_ACTION_FRAME_PROTECTED_DUAL |\ |
159 | SLSI_ACTION_FRAME_RADIO_MEASUREMENT) | |
ec470a07 TK |
160 | |
161 | /* Default value for MIB SLSI_PSID_UNIFI_DISCONNECT_TIMEOUT + 1 sec*/ | |
162 | #define SLSI_DEFAULT_AP_DISCONNECT_IND_TIMEOUT 3000 | |
163 | ||
164 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)) | |
165 | #define WLAN_EID_VHT_CAPABILITY 191 | |
166 | #define WLAN_EID_VHT_OPERATION 192 | |
167 | #endif | |
168 | ||
169 | #define NUM_COUNTRY (300) | |
170 | ||
171 | #ifdef CONFIG_SCSC_WLAN_MUTEX_DEBUG | |
172 | #define SLSI_MUTEX_INIT(slsi_mutex__) \ | |
173 | { \ | |
174 | (slsi_mutex__).owner = NULL; \ | |
175 | mutex_init(&(slsi_mutex__).mutex); \ | |
176 | (slsi_mutex__).valid = true; \ | |
177 | } | |
178 | ||
179 | #define SLSI_MUTEX_LOCK(slsi_mutex_to_lock) \ | |
180 | { \ | |
181 | (slsi_mutex_to_lock).line_no_before = __LINE__; \ | |
182 | (slsi_mutex_to_lock).file_name_before = __FILE__; \ | |
183 | mutex_lock(&(slsi_mutex_to_lock).mutex); \ | |
184 | (slsi_mutex_to_lock).owner = current; \ | |
185 | (slsi_mutex_to_lock).line_no_after = __LINE__; \ | |
186 | (slsi_mutex_to_lock).file_name_after = __FILE__; \ | |
187 | (slsi_mutex_to_lock).function = __func__; \ | |
188 | } | |
189 | ||
190 | #define SLSI_MUTEX_UNLOCK(slsi_mutex_to_unlock) \ | |
191 | { \ | |
192 | (slsi_mutex_to_unlock).owner = NULL; \ | |
193 | mutex_unlock(&(slsi_mutex_to_unlock).mutex); \ | |
194 | } | |
195 | #define SLSI_MUTEX_IS_LOCKED(slsi_mutex__) mutex_is_locked(&(slsi_mutex__).mutex) | |
196 | ||
197 | struct slsi_mutex { | |
198 | bool valid; | |
199 | u32 line_no_before; | |
200 | const u8 *file_name_before; | |
201 | /* a std mutex */ | |
202 | struct mutex mutex; | |
203 | u32 line_no_after; | |
204 | const u8 *file_name_after; | |
205 | const u8 *function; | |
206 | struct task_struct *owner; | |
207 | }; | |
208 | ||
209 | #else | |
210 | #define SLSI_MUTEX_INIT(mutex__) mutex_init(&(mutex__)) | |
211 | #define SLSI_MUTEX_LOCK(mutex_to_lock) mutex_lock(&(mutex_to_lock)) | |
212 | #define SLSI_MUTEX_UNLOCK(mutex_to_unlock) mutex_unlock(&(mutex_to_unlock)) | |
213 | #define SLSI_MUTEX_IS_LOCKED(mutex__) mutex_is_locked(&(mutex__)) | |
214 | #endif | |
215 | ||
216 | #define OS_UNUSED_PARAMETER(x) ((void)(x)) | |
217 | ||
218 | #define SLSI_HOST_TAG_TRAFFIC_QUEUE(htag) (htag & 0x00000003) | |
219 | ||
220 | /* For each mlme-req a mlme-cfm is expected to be received from the | |
221 | * firmware. The host is not allowed to send another mlme-req until | |
222 | * the mlme-cfm is received. | |
223 | * | |
224 | * However there are also instances where we need to wait for an mlme-ind | |
225 | * following a mlme-req/cfm exchange. One example of this is the disconnect | |
226 | * sequence: | |
227 | * mlme-disconnect-req - host requests disconnection | |
228 | * mlme-disconnect-cfm - firmware accepts disconnection request but hasn't | |
229 | * disconnected yet. | |
230 | * mlme-disconnect-ind - firmware reports final result of disconnection | |
231 | * | |
232 | * Assuming that waiting for the mlme-ind following on from the mlme-req/cfm | |
233 | * is ok. | |
234 | */ | |
235 | struct slsi_sig_send { | |
236 | /* a std spinlock */ | |
237 | spinlock_t send_signal_lock; | |
238 | #ifdef CONFIG_SCSC_WLAN_MUTEX_DEBUG | |
239 | struct slsi_mutex mutex; | |
240 | #else | |
241 | /* a std mutex */ | |
242 | struct mutex mutex; | |
243 | #endif | |
244 | struct completion completion; | |
245 | ||
246 | u16 process_id; | |
247 | u16 req_id; | |
248 | u16 cfm_id; | |
249 | u16 ind_id; | |
250 | struct sk_buff *cfm; | |
251 | struct sk_buff *ind; | |
252 | struct sk_buff *mib_error; | |
253 | }; | |
254 | ||
255 | static inline void slsi_sig_send_init(struct slsi_sig_send *sig_send) | |
256 | { | |
257 | spin_lock_init(&sig_send->send_signal_lock); | |
258 | sig_send->req_id = 0; | |
259 | sig_send->cfm_id = 0; | |
260 | sig_send->process_id = SLSI_TX_PROCESS_ID_MIN; | |
261 | SLSI_MUTEX_INIT(sig_send->mutex); | |
262 | init_completion(&sig_send->completion); | |
263 | } | |
264 | ||
265 | struct slsi_ba_frame_desc { | |
266 | bool active; | |
267 | struct sk_buff *signal; | |
268 | u16 sn; | |
269 | }; | |
270 | ||
271 | struct slsi_ba_session_rx { | |
272 | bool active; | |
273 | bool used; | |
274 | void *vif; | |
275 | struct slsi_ba_frame_desc buffer[MAX_BA_BUFFER_SIZE]; | |
276 | u16 buffer_size; | |
277 | u16 occupied_slots; | |
278 | u16 expected_sn; | |
279 | u16 start_sn; | |
280 | u16 highest_received_sn; | |
281 | bool trigger_ba_after_ssn; | |
282 | u8 tid; | |
283 | ||
284 | /* Aging timer parameters */ | |
285 | bool timer_on; | |
286 | struct timer_list ba_age_timer; | |
287 | struct slsi_spinlock ba_lock; | |
288 | struct net_device *dev; | |
289 | }; | |
290 | ||
291 | #define SLSI_TID_MAX (16) | |
292 | #define SLSI_AMPDU_F_INITIATED (0x0001) | |
293 | #define SLSI_AMPDU_F_CREATED (0x0002) | |
294 | #define SLSI_AMPDU_F_OPERATIONAL (0x0004) | |
295 | ||
ec470a07 TK |
296 | #define SLSI_SCAN_HW_ID 0 |
297 | #define SLSI_SCAN_SCHED_ID 1 | |
298 | #define SLSI_SCAN_MAX 3 | |
299 | ||
300 | #define SLSI_SCAN_SSID_MAP_MAX 10 /* Arbitrary value */ | |
301 | #define SLSI_SCAN_SSID_MAP_EXPIRY_AGE 2 /* If hidden bss not found these many scan cycles, remove map. Arbitrary value*/ | |
302 | #define SLSI_FW_SCAN_DONE_TIMEOUT_MSEC (15 * 1000) | |
303 | ||
304 | struct slsi_scan_result { | |
305 | u8 bssid[ETH_ALEN]; | |
306 | u8 hidden; | |
307 | int rssi; | |
308 | struct sk_buff *probe_resp; | |
309 | struct sk_buff *beacon; | |
310 | struct slsi_scan_result *next; | |
311 | }; | |
312 | ||
313 | /* Per Interface Scan Data | |
314 | * Access protected by: cfg80211_lock | |
315 | */ | |
316 | struct slsi_scan { | |
317 | /* When a Scan is running this not NULL. */ | |
318 | struct cfg80211_scan_request *scan_req; | |
ccc5c12c | 319 | struct slsi_acs_request *acs_request; |
ec470a07 TK |
320 | struct cfg80211_sched_scan_request *sched_req; |
321 | bool requeue_timeout_work; | |
322 | ||
323 | /* Indicates if the scan req is blocking. i.e, waiting until scan_done_ind received */ | |
324 | bool is_blocking_scan; | |
325 | ||
326 | struct slsi_scan_result *scan_results; /* head for scan_results list*/ | |
327 | }; | |
328 | ||
329 | struct slsi_ssid_map { | |
330 | u8 bssid[ETH_ALEN]; | |
331 | u8 ssid[32]; | |
332 | u8 ssid_len; | |
333 | u8 age; | |
334 | }; | |
335 | ||
336 | struct slsi_peer { | |
337 | /* Flag MUST be set last when creating a record and immediately when removing. | |
338 | * Otherwise another process could test the flag and start using the data. | |
339 | */ | |
340 | bool valid; | |
341 | u8 address[ETH_ALEN]; | |
342 | ||
343 | /* Presently connected_state is used only for AP/GO mode*/ | |
344 | u8 connected_state; | |
345 | u16 aid; | |
346 | /* Presently is_wps is used only in P2P GO mode */ | |
347 | bool is_wps; | |
348 | u16 capabilities; | |
349 | bool qos_enabled; | |
350 | u8 queueset; | |
351 | struct scsc_wifi_fcq_data_qset data_qs; | |
352 | struct scsc_wifi_fcq_ctrl_q ctrl_q; | |
353 | ||
354 | bool authorized; | |
355 | bool pairwise_key_set; | |
356 | ||
357 | /* Needed for STA/AP VIF */ | |
358 | struct sk_buff *assoc_ie; | |
359 | struct sk_buff_head buffered_frames; | |
360 | /* Needed for STA VIF */ | |
361 | struct sk_buff *assoc_resp_ie; | |
362 | ||
363 | /* bitmask that keeps the status of acm bit for each AC | |
364 | * bit 7 6 5 4 3 2 1 0 | |
365 | * | | | | | | | | | |
366 | * vo vo vi vi be bk bk be | |
367 | */ | |
368 | u8 wmm_acm; | |
369 | /* bitmask that keeps the status of tspec establishment for each priority | |
370 | * bit 7 6 5 4 3 2 1 0 | |
371 | * | | | | | | | | | |
372 | * p7 p6 p5 p4 p3 p2 p1 p0 | |
373 | */ | |
374 | u8 tspec_established; | |
375 | u8 uapsd; | |
376 | ||
377 | /* TODO_HARDMAC: | |
378 | * Q: Can we obtain stats from the firmware? | |
379 | * Yes - then this is NOT needed and we can just get from the firmware when requested. | |
380 | * No - How much can we get from the PSCHED? | |
381 | */ | |
382 | struct station_info sinfo; | |
383 | /* rate limit for peer sinfo mib reads */ | |
384 | struct ratelimit_state sinfo_mib_get_rs; | |
385 | struct slsi_ba_session_rx *ba_session_rx[NUM_BA_SESSIONS_PER_PEER]; | |
386 | ||
387 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) | |
388 | /* qos map configured at peer end*/ | |
389 | bool qos_map_set; | |
390 | struct cfg80211_qos_map qos_map; | |
391 | #endif | |
392 | }; | |
393 | ||
394 | /* Used to update vif type on vif deactivation indicating vif is no longer available */ | |
395 | #define SLSI_VIFTYPE_UNSPECIFIED 0xFFFF | |
396 | ||
397 | struct slsi_vif_mgmt_tx { | |
398 | u64 cookie; /* Cookie assigned by Host for the tx mgmt frame */ | |
399 | u16 host_tag; /* Host tag for the tx mgmt frame */ | |
400 | const u8 *buf; /* Buffer - Mgmt frame requested for tx */ | |
401 | size_t buf_len; /* Buffer length */ | |
402 | u8 exp_frame; /* Next expected Public action frame subtype from peer */ | |
403 | }; | |
404 | ||
405 | struct slsi_wmm_ac { | |
406 | u8 aci_aifsn; | |
407 | u8 ecw; | |
408 | u16 txop_limit; | |
409 | } __packed; | |
410 | ||
411 | /* struct slsi_wmm_parameter_element | |
412 | * | |
413 | * eid - Vendor Specific | |
414 | * len - Remaining Length of IE | |
415 | * oui - Microsoft OUI | |
416 | * oui_type - WMM | |
417 | * oui_subtype - Param IE | |
418 | * version - 1 | |
419 | * qos_info - Qos | |
420 | * reserved - | |
421 | * ac - BE,BK,VI,VO | |
422 | */ | |
423 | struct slsi_wmm_parameter_element { | |
424 | u8 eid; | |
425 | u8 len; | |
426 | u8 oui[3]; | |
427 | u8 oui_type; | |
428 | u8 oui_subtype; | |
429 | u8 version; | |
430 | u8 qos_info; | |
431 | u8 reserved; | |
432 | struct slsi_wmm_ac ac[4]; | |
433 | } __packed; | |
434 | ||
435 | #define SLSI_MIN_FILTER_ID 0x80 /* Start of filter range reserved for host */ | |
436 | ||
437 | /* for AP */ | |
438 | #define SLSI_AP_ALL_IPV6_PKTS_FILTER_ID 0x80 | |
439 | ||
440 | /* filter IDs for filters installed by driver */ | |
441 | #ifdef CONFIG_SCSC_WLAN_BLOCK_IPV6 | |
442 | ||
443 | enum slsi_filter_id { | |
444 | SLSI_LOCAL_ARP_FILTER_ID = SLSI_MIN_FILTER_ID, /* 0x80 */ | |
445 | SLSI_ALL_BC_MC_FILTER_ID, /* 0x81 */ | |
446 | SLSI_PROXY_ARP_FILTER_ID, /* 0x82 */ | |
447 | SLSI_ALL_IPV6_PKTS_FILTER_ID, /* 0x83 */ | |
448 | #ifndef CONFIG_SCSC_WLAN_DISABLE_NAT_KA | |
449 | SLSI_NAT_IPSEC_FILTER_ID, /* 0x84 */ | |
450 | #endif | |
59c50e41 | 451 | #ifdef CONFIG_SCSC_WLAN_ENHANCED_PKT_FILTER |
452 | SLSI_OPT_OUT_ALL_FILTER_ID, /* 0x85 */ | |
453 | SLSI_OPT_IN_TCP4_FILTER_ID, /* 0x86 */ | |
454 | SLSI_OPT_IN_TCP6_FILTER_ID, /* 0x87 */ | |
455 | #endif | |
456 | SLSI_REGD_MC_FILTER_ID, /* 0x88 */ | |
ec470a07 TK |
457 | }; |
458 | #else | |
459 | ||
460 | /* for STA */ | |
461 | enum slsi_filter_id { | |
462 | SLSI_LOCAL_ARP_FILTER_ID = SLSI_MIN_FILTER_ID, /* 0x80 */ | |
463 | SLSI_ALL_BC_MC_FILTER_ID, /* 0x81 */ | |
464 | SLSI_PROXY_ARP_FILTER_ID, /* 0x82 */ | |
465 | SLSI_LOCAL_NS_FILTER_ID, /* 0x83 */ | |
466 | SLSI_PROXY_ARP_NA_FILTER_ID, /* 0x84 */ | |
467 | #ifndef CONFIG_SCSC_WLAN_DISABLE_NAT_KA | |
468 | SLSI_NAT_IPSEC_FILTER_ID, /* 0x85 */ | |
469 | #endif | |
59c50e41 | 470 | #ifdef CONFIG_SCSC_WLAN_ENHANCED_PKT_FILTER |
471 | SLSI_OPT_OUT_ALL_FILTER_ID, /* 0x86 */ | |
472 | SLSI_OPT_IN_TCP4_FILTER_ID, /* 0x87 */ | |
473 | SLSI_OPT_IN_TCP6_FILTER_ID, /* 0x88 */ | |
474 | #endif | |
475 | SLSI_REGD_MC_FILTER_ID, /* 0x89 */ | |
ec470a07 TK |
476 | }; |
477 | ||
478 | #endif | |
479 | ||
480 | #define SLSI_MAX_PKT_FILTERS 16 | |
481 | ||
482 | #ifndef CONFIG_SCSC_WLAN_DISABLE_NAT_KA | |
483 | /* default config */ | |
484 | #define SLSI_MC_ADDR_ENTRY_MAX (SLSI_MIN_FILTER_ID + SLSI_MAX_PKT_FILTERS - SLSI_REGD_MC_FILTER_ID) | |
485 | #else | |
486 | #define SLSI_MC_ADDR_ENTRY_MAX (SLSI_MIN_FILTER_ID + SLSI_MAX_PKT_FILTERS - SLSI_REGD_MC_FILTER_ID + 1) | |
487 | #endif | |
488 | ||
489 | /* Values for vif_status field | |
490 | * | |
491 | * Used to indicate the status of an activated VIF, to help resolve | |
492 | * conflicting activities with indications from the firmware eg. | |
493 | * cfg80211 triggers a disconnection before a STA completes its | |
494 | * connection to an AP. | |
495 | */ | |
496 | #define SLSI_VIF_STATUS_UNSPECIFIED 0 | |
497 | #define SLSI_VIF_STATUS_CONNECTING 1 | |
498 | #define SLSI_VIF_STATUS_CONNECTED 2 | |
499 | #define SLSI_VIF_STATUS_DISCONNECTING 3 | |
500 | ||
501 | /*From wifi_offload.h (N_AVAIL_ID=3)*/ | |
502 | #define SLSI_MAX_KEEPALIVE_ID 3 | |
503 | ||
504 | struct slsi_last_connected_bss { | |
505 | u8 address[ETH_ALEN]; | |
506 | int antenna_mode; | |
507 | int rssi; | |
508 | int mode; | |
509 | int passpoint_version; | |
510 | int snr; | |
511 | int noise_level; | |
512 | u16 bandwidth; | |
513 | u16 roaming_count; | |
514 | u16 channel_freq; | |
515 | u16 tx_data_rate; | |
516 | u8 roaming_akm; | |
517 | u8 kv; | |
518 | u32 kvie; | |
519 | bool mimo_used; | |
520 | }; | |
521 | ||
522 | struct slsi_vif_sta { | |
523 | /* Only valid when the VIF is activated */ | |
524 | u8 vif_status; | |
525 | bool is_wps; | |
526 | u16 eap_hosttag; | |
527 | u16 m4_host_tag; | |
528 | u16 keepalive_host_tag[SLSI_MAX_KEEPALIVE_ID]; | |
529 | ||
530 | struct sk_buff *roam_mlme_procedure_started_ind; | |
531 | ||
532 | /* This id is used to find out which response (connect resp/roamed resp/reassoc resp) | |
533 | * is to be sent once M4 is transmitted successfully | |
534 | */ | |
535 | u16 resp_id; | |
536 | bool gratuitous_arp_needed; | |
537 | ||
538 | /* regd multicast address*/ | |
539 | u8 regd_mc_addr_count; | |
540 | u8 regd_mc_addr[SLSI_MC_ADDR_ENTRY_MAX][ETH_ALEN]; | |
541 | bool group_key_set; | |
542 | struct sk_buff *mlme_scan_ind_skb; | |
543 | bool roam_in_progress; | |
544 | int tdls_peer_sta_records; | |
545 | bool tdls_enabled; | |
546 | struct cfg80211_bss *sta_bss; | |
547 | u8 *assoc_req_add_info_elem; | |
548 | u8 assoc_req_add_info_elem_len; | |
549 | ||
550 | /* List of seen ESS and Freq associated with them */ | |
551 | struct list_head network_map; | |
552 | ||
553 | struct slsi_wmm_ac wmm_ac[4]; | |
554 | bool nd_offload_enabled; | |
555 | ||
556 | /*This structure is used to store last disconnected bss info and valid even when vif is deactivated. */ | |
557 | struct slsi_last_connected_bss last_connected_bss; | |
9b5afb62 | 558 | struct cfg80211_crypto_settings crypto; |
ec470a07 TK |
559 | }; |
560 | ||
561 | struct slsi_vif_unsync { | |
562 | struct delayed_work roc_expiry_work; /* Work on ROC duration expiry */ | |
563 | struct delayed_work del_vif_work; /* Work on unsync vif retention timeout */ | |
564 | struct delayed_work hs2_del_vif_work; /* Work on HS2 unsync vif retention timeout */ | |
9bd951ae | 565 | struct delayed_work unset_channel_expiry_work; /*unset channel after a timer */ |
ec470a07 TK |
566 | u64 roc_cookie; /* Cookie id for ROC */ |
567 | u8 *probe_rsp_ies; /* Probe response IEs to be configured in firmware */ | |
568 | size_t probe_rsp_ies_len; /* Probe response IE length */ | |
569 | bool ies_changed; /* To indicate if Probe Response IEs have changed from that previously stored */ | |
570 | bool listen_offload; /* To indicate if Listen Offload is started */ | |
9bd951ae | 571 | bool slsi_p2p_continuous_fullscan; |
ec470a07 TK |
572 | }; |
573 | ||
574 | struct slsi_last_disconnected_sta { | |
575 | u8 address[ETH_ALEN]; | |
d7f52c77 Y |
576 | u32 rx_retry_packets; |
577 | u32 rx_bc_mc_packets; | |
578 | u16 capabilities; | |
ec470a07 TK |
579 | int bandwidth; |
580 | int antenna_mode; | |
581 | int rssi; | |
582 | int mode; | |
583 | u16 tx_data_rate; | |
584 | bool mimo_used; | |
585 | u16 reason; | |
3cefd7b3 | 586 | int support_mode; |
ec470a07 TK |
587 | }; |
588 | ||
589 | struct slsi_vif_ap { | |
590 | struct slsi_wmm_parameter_element wmm_ie; | |
591 | struct slsi_last_disconnected_sta last_disconnected_sta; | |
592 | u8 *cache_wmm_ie; | |
593 | u8 *cache_wpa_ie; | |
594 | u8 *add_info_ies; | |
595 | size_t wmm_ie_len; | |
596 | size_t wpa_ie_len; | |
597 | size_t add_info_ies_len; | |
598 | bool p2p_gc_keys_set; /* Used in GO mode to identify that a CLI has connected after WPA2 handshake */ | |
599 | bool privacy; /* Used for port enabling based on the open/secured AP configuration */ | |
600 | bool qos_enabled; | |
601 | int beacon_interval; /* Beacon interval in AP/GO mode */ | |
602 | int mode; | |
603 | bool non_ht_bss_present; /* Non HT BSS observed in HT20 OBSS scan */ | |
604 | struct scsc_wifi_fcq_data_qset group_data_qs; | |
605 | u32 cipher; | |
606 | u16 channel_freq; | |
607 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | |
608 | u8 ssid_len; | |
609 | }; | |
610 | ||
6189f2b5 JPS |
611 | #define SLSI_NAN_MAX_PUBLISH_ID 16 |
612 | #define SLSI_NAN_MAX_SUBSCRIBE_ID 16 | |
613 | ||
614 | struct slsi_vif_nan { | |
615 | u32 publish_id_map; | |
616 | u32 subscribe_id_map; | |
617 | }; | |
618 | ||
ec470a07 TK |
619 | #define TCP_ACK_SUPPRESSION_RECORDS_MAX 16 |
620 | #define TCP_ACK_SUPPRESSION_RECORD_UNUSED_TIMEOUT 10 /* in seconds */ | |
621 | ||
622 | #define TCP_ACK_SUPPRESSION_OPTIONS_OFFSET 20 | |
623 | #define TCP_ACK_SUPPRESSION_OPTION_EOL 0 | |
624 | #define TCP_ACK_SUPPRESSION_OPTION_NOP 1 | |
625 | #define TCP_ACK_SUPPRESSION_OPTION_MSS 2 | |
626 | #define TCP_ACK_SUPPRESSION_OPTION_WINDOW 3 | |
627 | #define TCP_ACK_SUPPRESSION_OPTION_SACK 5 | |
628 | ||
629 | #define SLSI_IS_VIF_CHANNEL_5G(ndev_vif) (((ndev_vif)->chan) ? ((ndev_vif)->chan->hw_value > 14) : 0) | |
630 | ||
631 | struct slsi_tcp_ack_s { | |
632 | u32 daddr; | |
633 | u32 dport; | |
634 | u32 saddr; | |
635 | u32 sport; | |
636 | struct sk_buff_head list; | |
637 | u8 window_multiplier; | |
638 | u16 mss; | |
639 | u32 ack_seq; | |
640 | u16 slow_start_count; | |
641 | u8 count; | |
642 | u8 max; | |
643 | u8 age; | |
644 | struct timer_list timer; | |
645 | struct slsi_spinlock lock; | |
646 | bool state; | |
647 | ktime_t last_sent; | |
648 | bool tcp_slow_start; | |
649 | ||
650 | /* TCP session throughput monitor */ | |
651 | u16 hysteresis; | |
652 | u32 last_tcp_rate; | |
653 | ktime_t last_sample_time; | |
654 | u32 last_ack_seq; | |
655 | u64 num_bytes; | |
ec470a07 TK |
656 | #ifdef CONFIG_SCSC_WLAN_HIP4_PROFILING |
657 | u8 stream_id; | |
658 | u8 rx_window_scale; | |
659 | #endif | |
660 | }; | |
661 | ||
662 | struct slsi_tcp_ack_stats { | |
663 | u32 tack_acks; | |
664 | u32 tack_suppressed; | |
665 | u32 tack_sent; | |
666 | u32 tack_max; | |
667 | u32 tack_timeout; | |
668 | u32 tack_dacks; | |
669 | u32 tack_sacks; | |
670 | u32 tack_delay_acks; | |
671 | u32 tack_low_window; | |
672 | u32 tack_nocache; | |
673 | u32 tack_norecord; | |
674 | u32 tack_hasdata; | |
675 | u32 tack_psh; | |
676 | u32 tack_dropped; | |
677 | u32 tack_ktime; | |
678 | u32 tack_lastrecord; | |
679 | u32 tack_searchrecord; | |
680 | u32 tack_ece; | |
681 | }; | |
682 | ||
683 | struct netdev_vif { | |
684 | struct slsi_dev *sdev; | |
685 | struct wireless_dev wdev; | |
686 | atomic_t is_registered; /* Has the net dev been registered */ | |
687 | bool is_available; /* Has the net dev been opened AND is usable */ | |
688 | bool is_fw_test; /* Is the device in use as a test device via UDI */ | |
689 | ||
690 | /* Structure can be accessed by cfg80211 ops, procfs/ioctls and as a result | |
691 | * of receiving MLME indications e.g. MLME-CONNECT-IND that can affect the | |
692 | * status of the interface eg. STA connect failure will delete the VIF. | |
693 | */ | |
694 | #ifdef CONFIG_SCSC_WLAN_MUTEX_DEBUG | |
695 | struct slsi_mutex vif_mutex; | |
696 | #else | |
697 | /* a std mutex */ | |
698 | struct mutex vif_mutex; | |
699 | #endif | |
700 | struct slsi_sig_send sig_wait; | |
e04e03ea | 701 | |
ec470a07 | 702 | struct slsi_skb_work rx_data; |
5fcd17b3 | 703 | struct slsi_skb_work rx_mlme; |
ec470a07 TK |
704 | u16 ifnum; |
705 | enum nl80211_iftype iftype; | |
706 | enum nl80211_channel_type channel_type; | |
707 | struct ieee80211_channel *chan; | |
479ea86c IP |
708 | u16 driver_channel; |
709 | bool drv_in_p2p_procedure; | |
ec470a07 TK |
710 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9)) |
711 | struct cfg80211_chan_def *chandef; | |
712 | #endif | |
713 | ||
714 | /* NOTE: The Address is a __be32 | |
715 | * It needs converting to pass to the FW | |
716 | * But not for the Arp or trace %pI4 | |
717 | */ | |
718 | __be32 ipaddress; | |
719 | ||
720 | #ifndef CONFIG_SCSC_WLAN_BLOCK_IPV6 | |
721 | struct in6_addr ipv6address; | |
722 | struct slsi_spinlock ipv6addr_lock; | |
723 | #endif | |
724 | struct net_device_stats stats; | |
725 | u32 rx_packets[SLSI_LLS_AC_MAX]; | |
726 | u32 tx_packets[SLSI_LLS_AC_MAX]; | |
727 | u32 tx_no_ack[SLSI_LLS_AC_MAX]; | |
728 | #ifdef CONFIG_SCSC_WLAN_MUTEX_DEBUG | |
729 | struct slsi_mutex scan_mutex; | |
730 | struct slsi_mutex scan_result_mutex; | |
731 | #else | |
732 | /* a std mutex */ | |
733 | struct mutex scan_mutex; | |
734 | struct mutex scan_result_mutex; | |
735 | ||
736 | #endif | |
737 | struct slsi_scan scan[SLSI_SCAN_MAX]; | |
738 | ||
739 | struct slsi_src_sink_params src_sink_params; | |
740 | u16 power_mode; | |
741 | u16 set_power_mode; | |
742 | ||
743 | bool activated; /* VIF is created in firmware and ready to use */ | |
744 | u16 vif_type; | |
745 | struct slsi_spinlock peer_lock; | |
746 | int peer_sta_records; | |
747 | struct slsi_peer *peer_sta_record[SLSI_ADHOC_PEER_CONNECTIONS_MAX]; | |
748 | ||
749 | /* Used to populate the cfg80211 station_info structure generation variable. | |
750 | * This number should increase every time the list of stations changes | |
751 | * i.e. when a station is added or removed, so that userspace can tell | |
752 | * whether it got a consistent snapshot. | |
753 | */ | |
754 | int cfg80211_sinfo_generation; | |
755 | ||
756 | /* Block Ack MPDU Re-order */ | |
757 | struct sk_buff_head ba_complete; | |
758 | atomic_t ba_flush; | |
759 | ||
760 | u64 mgmt_tx_cookie; /* Cookie id for mgmt tx */ | |
761 | struct slsi_vif_mgmt_tx mgmt_tx_data; | |
762 | struct delayed_work scan_timeout_work; /* Work on scan timeout */ | |
763 | bool delete_probe_req_ies; /* Delete probe request stored at probe_req_ies, if | |
764 | * connected for WAP2 at mlme_del_vif or in all cases | |
765 | * if STA | |
766 | */ | |
767 | u8 *probe_req_ies; | |
768 | size_t probe_req_ie_len; | |
769 | ||
770 | struct slsi_vif_unsync unsync; | |
771 | struct slsi_vif_sta sta; | |
772 | struct slsi_vif_ap ap; | |
6189f2b5 | 773 | struct slsi_vif_nan nan; |
ec470a07 TK |
774 | |
775 | /* TCP ack suppression. */ | |
776 | struct slsi_tcp_ack_s *last_tcp_ack; | |
777 | struct slsi_tcp_ack_s ack_suppression[TCP_ACK_SUPPRESSION_RECORDS_MAX]; | |
778 | struct slsi_tcp_ack_stats tcp_ack_stats; | |
ec470a07 | 779 | /* traffic monitor */ |
25f4f399 DP |
780 | ktime_t last_timer_time; |
781 | u32 report_time; | |
782 | u32 num_bytes_tx_per_timer; | |
783 | u32 num_bytes_rx_per_timer; | |
784 | u32 num_bytes_tx_per_sec; | |
785 | u32 num_bytes_rx_per_sec; | |
ec470a07 TK |
786 | u32 throughput_tx; |
787 | u32 throughput_rx; | |
25f4f399 DP |
788 | u32 throughput_tx_bps; |
789 | u32 throughput_rx_bps; | |
ec470a07 TK |
790 | }; |
791 | ||
792 | struct slsi_802_11d_reg_domain { | |
ec470a07 TK |
793 | u8 *countrylist; |
794 | struct ieee80211_regdomain *regdomain; | |
795 | int country_len; | |
796 | }; | |
797 | ||
798 | #ifdef CONFIG_SCSC_WLAN_WES_NCHO | |
799 | struct slsi_wes_mode_roam_scan_channels { | |
800 | int n; | |
801 | u8 channels[MAX_CHANNEL_LIST]; | |
802 | }; | |
803 | #endif | |
804 | ||
805 | struct slsi_dev_config { | |
806 | /* Supported Freq Band (Dynamic) | |
807 | * Set via the freq_band procfs | |
808 | */ | |
809 | #define SLSI_FREQ_BAND_AUTO 0 | |
810 | #define SLSI_FREQ_BAND_5GHZ 1 | |
811 | #define SLSI_FREQ_BAND_2GHZ 2 | |
812 | int supported_band; | |
813 | ||
814 | struct ieee80211_supported_band *band_5G; | |
815 | struct ieee80211_supported_band *band_2G; | |
816 | ||
817 | /* current user suspend mode | |
818 | * Set via the suspend_mode procfs | |
819 | * 0 : not suspended | |
820 | * 1 : suspended | |
821 | */ | |
822 | int user_suspend_mode; | |
823 | ||
824 | /* Rx filtering rule | |
825 | * Set via the rx_filter_num procfs | |
826 | * 0: Unicast, 1: Broadcast, 2:Multicast IPv4, 3: Multicast IPv6 | |
827 | */ | |
828 | int rx_filter_num; | |
829 | ||
830 | /* Rx filter rule enabled | |
831 | * Set via the rx_filter_start & rx_filter_stop procfs | |
832 | */ | |
833 | bool rx_filter_rule_started; | |
834 | ||
835 | /* AP Auto channel Selection */ | |
836 | #define SLSI_NO_OF_SCAN_CHANLS_FOR_AUTO_CHAN_MAX 14 | |
837 | int ap_auto_chan; | |
838 | ||
839 | /*QoS capability for a non-AP Station*/ | |
840 | int qos_info; | |
841 | #ifdef CONFIG_SCSC_WLAN_WES_NCHO | |
842 | /* NCHO OKC mode */ | |
843 | int okc_mode; | |
844 | ||
845 | /*NCHO WES mode */ | |
846 | int wes_mode; | |
847 | ||
848 | int roam_scan_mode; | |
849 | ||
850 | /*WES mode roam scan channels*/ | |
851 | struct slsi_wes_mode_roam_scan_channels wes_roam_scan_list; | |
852 | #endif | |
853 | struct slsi_802_11d_reg_domain domain_info; | |
854 | ||
855 | int ap_disconnect_ind_timeout; | |
856 | ||
857 | u8 host_state; | |
858 | ||
859 | int rssi_boost_5g; | |
860 | int rssi_boost_2g; | |
cfe11a24 | 861 | bool disable_ch12_ch13; |
ec470a07 TK |
862 | }; |
863 | ||
864 | #define SLSI_DEVICE_STATE_ATTACHING 0 | |
865 | #define SLSI_DEVICE_STATE_STOPPED 1 | |
866 | #define SLSI_DEVICE_STATE_STARTING 2 | |
867 | #define SLSI_DEVICE_STATE_STARTED 3 | |
868 | #define SLSI_DEVICE_STATE_STOPPING 4 | |
869 | ||
870 | #define SLSI_NET_INDEX_WLAN 1 | |
871 | #define SLSI_NET_INDEX_P2P 2 | |
872 | #define SLSI_NET_INDEX_P2PX_SWLAN 3 | |
6189f2b5 | 873 | #define SLSI_NET_INDEX_NAN 4 |
ec470a07 TK |
874 | |
875 | /* States used during P2P operations */ | |
876 | enum slsi_p2p_states { | |
877 | P2P_IDLE_NO_VIF, /* Initial state - Unsync vif is not present */ | |
878 | P2P_IDLE_VIF_ACTIVE, /* Unsync vif is present but no P2P procedure in progress */ | |
879 | P2P_SCANNING, /* P2P SOCIAL channel (1,6,11) scan in progress. Not used for P2P full scan */ | |
880 | P2P_LISTENING, /* P2P Listen (ROC) in progress */ | |
881 | P2P_ACTION_FRAME_TX_RX, /* P2P Action frame Tx in progress or waiting for a peer action frame Rx (i.e. in response to the Tx frame) */ | |
882 | P2P_GROUP_FORMED_CLI, /* P2P Group Formed - CLI role */ | |
883 | P2P_GROUP_FORMED_GO, /* P2P Group Formed - GO role */ | |
884 | /* NOTE: In P2P_LISTENING state if frame transmission is requested to driver then a peer response is ideally NOT expected. | |
885 | * This is an assumption based on the fact that FIND would be stopped prior to group formation/connection. | |
886 | * If driver were to receive a peer frame in P2P_LISTENING state then it would most probably be a REQUEST frame and the supplicant would respond to it. | |
887 | * Hence the driver should get only RESPONSE frames for transmission in P2P_LISTENING state. | |
888 | */ | |
889 | }; | |
890 | ||
5fcd17b3 PK |
891 | enum slsi_wlan_state { |
892 | WLAN_UNSYNC_NO_VIF = 0, /* Initial state - Unsync vif is not present */ | |
893 | WLAN_UNSYNC_VIF_ACTIVE, /* Unsync vif is activated but no wlan procedure in progress */ | |
894 | WLAN_UNSYNC_VIF_TX /* Unsync vif is activated and wlan procedure in progress */ | |
ec470a07 TK |
895 | }; |
896 | ||
897 | /* Wakelock timeouts */ | |
898 | #define SLSI_WAKELOCK_TIME_MSEC_EAPOL (1000) | |
899 | ||
900 | struct slsi_chip_info_mib { | |
901 | u16 chip_version; | |
902 | }; | |
903 | ||
904 | struct slsi_plat_info_mib { | |
905 | u16 plat_build; | |
906 | }; | |
907 | ||
908 | /* P2P States in text format for debug purposes */ | |
909 | static inline char *slsi_p2p_state_text(u8 state) | |
910 | { | |
911 | switch (state) { | |
912 | case P2P_IDLE_NO_VIF: | |
913 | return "P2P_IDLE_NO_VIF"; | |
914 | case P2P_IDLE_VIF_ACTIVE: | |
915 | return "P2P_IDLE_VIF_ACTIVE"; | |
916 | case P2P_SCANNING: | |
917 | return "P2P_SCANNING"; | |
918 | case P2P_LISTENING: | |
919 | return "P2P_LISTENING"; | |
920 | case P2P_ACTION_FRAME_TX_RX: | |
921 | return "P2P_ACTION_FRAME_TX_RX"; | |
922 | case P2P_GROUP_FORMED_CLI: | |
923 | return "P2P_GROUP_FORMED_CLI"; | |
924 | case P2P_GROUP_FORMED_GO: | |
925 | return "P2P_GROUP_FORMED_GO"; | |
926 | default: | |
927 | return "UNKNOWN"; | |
928 | } | |
929 | } | |
930 | ||
5fcd17b3 PK |
931 | #define SLSI_WLAN_MAX_HCF_PLATFORM_LEN (128) |
932 | ||
ec470a07 TK |
933 | struct slsi_dev_mib_info { |
934 | char *mib_file_name; | |
935 | unsigned int mib_hash; | |
936 | ||
937 | /* Cached File MIB Configuration values from User Space */ | |
938 | u8 *mib_data; | |
939 | u32 mib_len; | |
5fcd17b3 | 940 | char platform[SLSI_WLAN_MAX_HCF_PLATFORM_LEN]; |
ec470a07 TK |
941 | }; |
942 | ||
943 | #define SLSI_WLAN_MAX_MIB_FILE 2 /* Number of WLAN HCFs to load */ | |
944 | ||
479ea86c IP |
945 | #ifdef CONFIG_SCSC_LOG_COLLECTION |
946 | struct slsi_dev_mib_collect_file { | |
947 | char file_name[32]; | |
948 | u16 len; | |
949 | u8 *data; | |
950 | } __packed; | |
951 | ||
952 | struct slsi_dev_mib_collect { | |
953 | bool enabled; | |
954 | /* Serialize writers/readers */ | |
955 | spinlock_t in_collection; | |
956 | char num_files; | |
957 | /* +1 represents local_mib */ | |
958 | struct slsi_dev_mib_collect_file file[SLSI_WLAN_MAX_MIB_FILE + 1]; | |
959 | }; | |
960 | ||
961 | #endif | |
962 | ||
ec470a07 TK |
963 | struct slsi_dev { |
964 | /* Devices */ | |
965 | struct device *dev; | |
966 | struct wiphy *wiphy; | |
967 | ||
968 | struct slsi_hip hip; /* HIP bookkeeping block */ | |
969 | struct slsi_hip4 hip4_inst; /* The handler to parse to HIP */ | |
970 | ||
971 | struct scsc_wifi_cm_if cm_if; /* cm_if bookkeeping block */ | |
972 | struct scsc_mx *maxwell_core; | |
973 | struct scsc_service_client mx_wlan_client; | |
974 | struct scsc_service *service; | |
975 | struct slsi_chip_info_mib chip_info_mib; | |
976 | struct slsi_plat_info_mib plat_info_mib; | |
b47322da | 977 | u16 reg_dom_version; |
ec470a07 TK |
978 | |
979 | #ifdef CONFIG_SCSC_WLAN_MUTEX_DEBUG | |
980 | struct slsi_mutex netdev_add_remove_mutex; | |
981 | #else | |
982 | /* a std mutex */ | |
983 | struct mutex netdev_add_remove_mutex; | |
984 | #endif | |
85aa0fce Y |
985 | /* mutex to protect dynamic netdev removal */ |
986 | struct mutex netdev_remove_mutex; | |
ec470a07 TK |
987 | int netdev_up_count; |
988 | struct net_device __rcu *netdev[CONFIG_SCSC_WLAN_MAX_INTERFACES + 1]; /* 0 is reserved */ | |
d7f52c77 | 989 | struct net_device __rcu *netdev_ap; |
ec470a07 TK |
990 | u8 netdev_addresses[CONFIG_SCSC_WLAN_MAX_INTERFACES + 1][ETH_ALEN]; /* 0 is reserved */ |
991 | ||
992 | int device_state; | |
993 | ||
994 | /* BoT */ | |
995 | atomic_t in_pause_state; | |
996 | ||
997 | /* Locking used to control Starting and stopping the chip */ | |
998 | #ifdef CONFIG_SCSC_WLAN_MUTEX_DEBUG | |
999 | struct slsi_mutex start_stop_mutex; | |
1000 | #else | |
1001 | /* a std mutex */ | |
1002 | struct mutex start_stop_mutex; | |
1003 | #endif | |
1004 | /* UDI Logging */ | |
1005 | struct slsi_log_clients log_clients; | |
1006 | void *uf_cdev; | |
1007 | ||
1008 | /* ProcFS */ | |
1009 | int procfs_instance; | |
1010 | struct proc_dir_entry *procfs_dir; | |
1011 | ||
1012 | /* Configuration */ | |
1013 | u8 hw_addr[ETH_ALEN]; | |
1014 | struct slsi_dev_mib_info mib[SLSI_WLAN_MAX_MIB_FILE]; | |
1015 | struct slsi_dev_mib_info local_mib; | |
479ea86c IP |
1016 | #ifdef CONFIG_SCSC_LOG_COLLECTION |
1017 | struct slsi_dev_mib_collect collect_mib; | |
1018 | #endif | |
ec470a07 TK |
1019 | char *maddr_file_name; |
1020 | bool *term_udi_users; /* Try to terminate UDI users during unload */ | |
1021 | int *sig_wait_cfm_timeout; | |
1022 | ||
1023 | struct slsi_wake_lock wlan_wl; | |
1024 | struct slsi_wake_lock wlan_wl_mlme; | |
1025 | struct slsi_wake_lock wlan_wl_ma; | |
5fcd17b3 | 1026 | #if !defined SLSI_TEST_DEV && defined CONFIG_ANDROID |
ec470a07 TK |
1027 | struct wake_lock wlan_wl_roam; |
1028 | #endif | |
1029 | struct slsi_sig_send sig_wait; | |
1030 | struct slsi_skb_work rx_dbg_sap; | |
1031 | atomic_t tx_host_tag[SLSI_LLS_AC_MAX]; | |
1032 | #ifdef CONFIG_SCSC_WLAN_MUTEX_DEBUG | |
1033 | struct slsi_mutex device_config_mutex; | |
1034 | #else | |
1035 | /* a std mutex */ | |
1036 | struct mutex device_config_mutex; | |
1037 | #endif | |
1038 | struct slsi_dev_config device_config; | |
1039 | ||
1040 | struct notifier_block inetaddr_notifier; | |
1041 | #ifndef CONFIG_SCSC_WLAN_BLOCK_IPV6 | |
1042 | struct notifier_block inet6addr_notifier; | |
1043 | #endif | |
1044 | ||
1045 | struct workqueue_struct *device_wq; /* Driver Workqueue */ | |
1046 | enum slsi_p2p_states p2p_state; /* Store current P2P operation */ | |
1047 | ||
5fcd17b3 | 1048 | enum slsi_wlan_state wlan_unsync_vif_state; /* Store current sate of unsync wlan vif */ |
ec470a07 TK |
1049 | |
1050 | int current_tspec_id; | |
1051 | int tspec_error_code; | |
1052 | u8 p2p_group_exp_frame; /* Next expected Public action frame subtype from peer */ | |
1053 | bool initial_scan; | |
1054 | ||
1055 | #ifdef CONFIG_SCSC_WLAN_GSCAN_ENABLE | |
1056 | struct slsi_gscan *gscan; | |
1057 | struct slsi_gscan_result *gscan_hash_table[SLSI_GSCAN_HASH_TABLE_SIZE]; | |
1058 | int num_gscan_results; | |
1059 | int buffer_threshold; | |
1060 | int buffer_consumed; | |
1061 | struct slsi_bucket bucket[SLSI_GSCAN_MAX_BUCKETS]; | |
1062 | struct list_head hotlist_results; | |
1063 | bool epno_active; | |
1064 | #endif | |
5fcd17b3 PK |
1065 | #ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION |
1066 | u8 scan_mac_addr[6]; | |
1067 | bool scan_addr_set; | |
ec470a07 TK |
1068 | #endif |
1069 | #ifdef CONFIG_SCSC_WLAN_HIP4_PROFILING | |
1070 | int minor_prof; | |
1071 | #endif | |
1072 | struct slsi_ba_session_rx rx_ba_buffer_pool[SLSI_MAX_RX_BA_SESSIONS]; | |
1073 | struct slsi_spinlock rx_ba_buffer_pool_lock; | |
1074 | bool fail_reported; | |
1075 | bool p2p_certif; /* Set to true to idenitfy p2p_certification testing is going on*/ | |
1076 | bool mlme_blocked; /* When true do not send mlme signals to FW */ | |
1077 | atomic_t debug_inds; | |
1078 | int recovery_next_state; | |
1079 | struct completion recovery_remove_completion; | |
1080 | struct completion recovery_stop_completion; | |
1081 | struct completion recovery_completed; | |
1082 | int recovery_status; | |
1083 | struct slsi_ssid_map ssid_map[SLSI_SCAN_SSID_MAP_MAX]; | |
1084 | bool band_5g_supported; | |
1085 | int supported_2g_channels[14]; | |
1086 | int supported_5g_channels[25]; | |
1087 | int enabled_channel_count; | |
1088 | bool fw_ht_enabled; | |
1089 | u8 fw_ht_cap[4]; /* HT capabilities is 21 bytes but host is never intersted in last 17 bytes*/ | |
1090 | bool fw_vht_enabled; | |
1091 | u8 fw_vht_cap[4]; | |
1092 | #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING | |
1093 | u8 wifi_sharing_5ghz_channel[8]; | |
1094 | int valid_5g_freq[25]; | |
1095 | int wifi_sharing_5g_restricted_channels[25]; | |
1096 | int num_5g_restricted_channels; | |
1097 | #endif | |
1098 | bool fw_2g_40mhz_enabled; | |
6189f2b5 | 1099 | bool nan_enabled; |
ec470a07 TK |
1100 | u16 assoc_result_code; /* Status of latest association in STA mode */ |
1101 | bool allow_switch_40_mhz; /* Used in AP cert to disable HT40 when not configured */ | |
1102 | bool allow_switch_80_mhz; /* Used in AP cert to disable VHT when not configured */ | |
1103 | #ifdef CONFIG_SCSC_WLAN_AP_INFO_FILE | |
7e30b534 | 1104 | /* Parameters in '/data/vendor/conn/.softap.info' */ |
ec470a07 TK |
1105 | bool dualband_concurrency; |
1106 | u32 softap_max_client; | |
1107 | #endif | |
f985c5e0 | 1108 | u32 fw_dwell_time; |
ec470a07 TK |
1109 | int lls_num_radio; |
1110 | ||
ec470a07 TK |
1111 | #ifdef CONFIG_SCSC_WLAN_MUTEX_DEBUG |
1112 | struct slsi_mutex logger_mutex; | |
1113 | #else | |
1114 | /* a std mutex */ | |
1115 | struct mutex logger_mutex; | |
ec470a07 TK |
1116 | #endif |
1117 | struct slsi_traffic_mon_clients traffic_mon_clients; | |
5fcd17b3 PK |
1118 | /*Store vif index corresponding to rtt id for FTM*/ |
1119 | u16 rtt_vif[8]; | |
ccc5c12c | 1120 | bool acs_channel_switched; |
85aa0fce | 1121 | int recovery_timeout; /* ms autorecovery completion timeout */ |
82bed73d KV |
1122 | #ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION |
1123 | bool fw_mac_randomization_enabled; | |
1124 | #endif | |
ec470a07 TK |
1125 | }; |
1126 | ||
1127 | /* Compact representation of channels a ESS has been seen on | |
1128 | * This is sized correctly for the Channels we currently support, | |
1129 | * 2.4Ghz Channels 1 - 14 | |
1130 | * 5 Ghz Channels Uni1, Uni2 and Uni3 | |
1131 | */ | |
1132 | struct slsi_roaming_network_map_entry { | |
1133 | struct list_head list; | |
1134 | unsigned long last_seen_jiffies; /* Timestamp of the last time we saw this ESS */ | |
1135 | struct cfg80211_ssid ssid; /* SSID of the ESS */ | |
1136 | u8 initial_bssid[ETH_ALEN]; /* Bssid of the first ap seen in this ESS */ | |
1137 | bool only_one_ap_seen; /* Has more than one AP for this ESS been seen */ | |
1138 | u16 channels_24_ghz; /* 2.4 Ghz Channels Bit Map */ | |
1139 | /* 5 Ghz Channels Bit Map | |
1140 | * channels_5_ghz & 0x000000FF = 4 Uni1 Channels | |
1141 | * channels_5_ghz & 0x00FFFF00 = 15 Uni2 Channels | |
1142 | * channels_5_ghz & 0xFF000000 = 5 Uni3 Channels | |
1143 | */ | |
1144 | u32 channels_5_ghz; | |
1145 | }; | |
1146 | ||
1147 | #define LLC_SNAP_HDR_LEN 8 | |
1148 | struct llc_snap_hdr { | |
1149 | u8 llc_dsap; | |
1150 | u8 llc_ssap; | |
1151 | u8 llc_ctrl; | |
1152 | u8 snap_oui[3]; | |
1153 | u16 snap_type; | |
1154 | } __packed; | |
1155 | ||
31894d8f | 1156 | void slsi_rx_data_deliver_skb(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb, bool from_ba_timer); |
ec470a07 TK |
1157 | void slsi_rx_dbg_sap_work(struct work_struct *work); |
1158 | void slsi_rx_netdev_data_work(struct work_struct *work); | |
1159 | void slsi_rx_netdev_mlme_work(struct work_struct *work); | |
1160 | int slsi_rx_enqueue_netdev_mlme(struct slsi_dev *sdev, struct sk_buff *skb, u16 vif); | |
1161 | void slsi_rx_scan_pass_to_cfg80211(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb); | |
1162 | void slsi_rx_buffered_frames(struct slsi_dev *sdev, struct net_device *dev, struct slsi_peer *peer); | |
1163 | int slsi_rx_blocking_signals(struct slsi_dev *sdev, struct sk_buff *skb); | |
1164 | void slsi_scan_complete(struct slsi_dev *sdev, struct net_device *dev, u16 scan_id, bool aborted); | |
1165 | ||
1166 | void slsi_tx_pause_queues(struct slsi_dev *sdev); | |
1167 | void slsi_tx_unpause_queues(struct slsi_dev *sdev); | |
1168 | int slsi_tx_control(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb); | |
1169 | int slsi_tx_data(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb); | |
1170 | int slsi_tx_data_lower(struct slsi_dev *sdev, struct sk_buff *skb); | |
1171 | bool slsi_is_test_mode_enabled(void); | |
1172 | bool slsi_is_rf_test_mode_enabled(void); | |
1173 | int slsi_check_rf_test_mode(void); | |
1174 | void slsi_regd_deinit(struct slsi_dev *sdev); | |
1175 | void slsi_init_netdev_mac_addr(struct slsi_dev *sdev); | |
1176 | bool slsi_dev_lls_supported(void); | |
1177 | bool slsi_dev_gscan_supported(void); | |
1178 | bool slsi_dev_epno_supported(void); | |
1179 | bool slsi_dev_vo_vi_block_ack(void); | |
1180 | int slsi_dev_get_scan_result_count(void); | |
1181 | bool slsi_dev_llslogs_supported(void); | |
6189f2b5 | 1182 | int slsi_dev_nan_supported(struct slsi_dev *sdev); |
0db27ed8 | 1183 | void slsi_regd_init(struct slsi_dev *sdev); |
5fcd17b3 | 1184 | bool slsi_dev_rtt_supported(void); |
ec470a07 TK |
1185 | |
1186 | static inline u16 slsi_tx_host_tag(struct slsi_dev *sdev, enum slsi_traffic_q tq) | |
1187 | { | |
1188 | /* host_tag: | |
1189 | * bit 0,1 = trafficqueue identifier | |
1190 | * bit 2-15 = incremental number | |
1191 | * So increment by 4 to get bit 2-15 a incremental sequence | |
1192 | */ | |
1193 | return (u16)atomic_add_return(4, &sdev->tx_host_tag[tq]); | |
1194 | } | |
1195 | ||
1196 | static inline u16 slsi_tx_mgmt_host_tag(struct slsi_dev *sdev) | |
1197 | { | |
1198 | /* Doesn't matter which traffic queue host tag is selected.*/ | |
1199 | return slsi_tx_host_tag(sdev, 0); | |
1200 | } | |
1201 | ||
1202 | static inline struct net_device *slsi_get_netdev_rcu(struct slsi_dev *sdev, u16 ifnum) | |
1203 | { | |
1204 | WARN_ON(!rcu_read_lock_held()); | |
1205 | if (ifnum > CONFIG_SCSC_WLAN_MAX_INTERFACES) { | |
1206 | /* WARN(1, "ifnum:%d", ifnum); WARN() is used like this to avoid Coverity Error */ | |
1207 | return NULL; | |
1208 | } | |
1209 | return rcu_dereference(sdev->netdev[ifnum]); | |
1210 | } | |
1211 | ||
1212 | static inline struct net_device *slsi_get_netdev_locked(struct slsi_dev *sdev, u16 ifnum) | |
1213 | { | |
1214 | WARN_ON(!SLSI_MUTEX_IS_LOCKED(sdev->netdev_add_remove_mutex)); | |
1215 | if (ifnum > CONFIG_SCSC_WLAN_MAX_INTERFACES) { | |
1216 | WARN(1, "ifnum:%d", ifnum); /* WARN() is used like this to avoid Coverity Error */ | |
1217 | return NULL; | |
1218 | } | |
1219 | return sdev->netdev[ifnum]; | |
1220 | } | |
1221 | ||
1222 | static inline struct net_device *slsi_get_netdev(struct slsi_dev *sdev, u16 ifnum) | |
1223 | { | |
1224 | struct net_device *dev; | |
1225 | ||
1226 | SLSI_MUTEX_LOCK(sdev->netdev_add_remove_mutex); | |
1227 | dev = slsi_get_netdev_locked(sdev, ifnum); | |
1228 | SLSI_MUTEX_UNLOCK(sdev->netdev_add_remove_mutex); | |
1229 | ||
1230 | return dev; | |
1231 | } | |
1232 | ||
1233 | static inline int slsi_get_supported_mode(const u8 *peer_ie) | |
1234 | { | |
1235 | const u8 *peer_ie_data; | |
1236 | u8 peer_ie_len; | |
1237 | int i; | |
1238 | int supported_rate; | |
1239 | ||
1240 | peer_ie_len = peer_ie[1]; | |
1241 | peer_ie_data = &peer_ie[2]; | |
1242 | for (i = 0; i < peer_ie_len; i++) { | |
1243 | supported_rate = ((peer_ie_data[i] & 0x7F) / 2); | |
1244 | if (supported_rate > 11) | |
1245 | return SLSI_80211_MODE_11G; | |
1246 | } | |
1247 | return SLSI_80211_MODE_11B; | |
1248 | } | |
1249 | ||
d7f52c77 Y |
1250 | /* Names of full mode HCF files */ |
1251 | extern char *slsi_mib_file; | |
1252 | extern char *slsi_mib_file2; | |
1253 | ||
ec470a07 | 1254 | #endif |