blob: 97848e400288cc99141557fd85b8271cdfd67a6c [file] [log] [blame]
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001/*!
2 * @file wilc_wfi_cfgopertaions.c
3 * @brief CFG80211 Function Implementation functionality
4 * @author aabouzaeid
5 * mabubakr
6 * mdaftedar
7 * zsalah
8 * @sa wilc_wfi_cfgopertaions.h top level OS wrapper file
9 * @date 31 Aug 2010
10 * @version 1.0
11 */
12
13#include "wilc_wfi_cfgoperations.h"
Arnd Bergmann491880e2015-11-16 15:04:55 +010014#include "host_interface.h"
Leo Kim7ae43362015-09-16 18:35:59 +090015#include <linux/errno.h>
Johnny Kimc5c77ba2015-05-11 14:30:56 +090016
Arnd Bergmann15162fb2015-11-16 15:04:57 +010017/* The following macros describe the bitfield map used by the firmware to determine its 11i mode */
18#define NO_ENCRYPT 0
19#define ENCRYPT_ENABLED BIT(0)
20#define WEP BIT(1)
21#define WEP_EXTENDED BIT(2)
22#define WPA BIT(3)
23#define WPA2 BIT(4)
24#define AES BIT(5)
25#define TKIP BIT(6)
26
27/*Public action frame index IDs*/
28#define FRAME_TYPE_ID 0
29#define ACTION_CAT_ID 24
30#define ACTION_SUBTYPE_ID 25
31#define P2P_PUB_ACTION_SUBTYPE 30
32
33/*Public action frame Attribute IDs*/
34#define ACTION_FRAME 0xd0
35#define GO_INTENT_ATTR_ID 0x04
36#define CHANLIST_ATTR_ID 0x0b
37#define OPERCHAN_ATTR_ID 0x11
38#define PUB_ACTION_ATTR_ID 0x04
39#define P2PELEM_ATTR_ID 0xdd
40
41/*Public action subtype values*/
42#define GO_NEG_REQ 0x00
43#define GO_NEG_RSP 0x01
44#define GO_NEG_CONF 0x02
45#define P2P_INV_REQ 0x03
46#define P2P_INV_RSP 0x04
47#define PUBLIC_ACT_VENDORSPEC 0x09
48#define GAS_INTIAL_REQ 0x0a
49#define GAS_INTIAL_RSP 0x0b
50
51#define INVALID_CHANNEL 0
52
53#define nl80211_SCAN_RESULT_EXPIRE (3 * HZ)
54#define SCAN_RESULT_EXPIRE (40 * HZ)
55
56static const u32 cipher_suites[] = {
57 WLAN_CIPHER_SUITE_WEP40,
58 WLAN_CIPHER_SUITE_WEP104,
59 WLAN_CIPHER_SUITE_TKIP,
60 WLAN_CIPHER_SUITE_CCMP,
61 WLAN_CIPHER_SUITE_AES_CMAC,
62};
63
64static const struct ieee80211_txrx_stypes
65 wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = {
66 [NL80211_IFTYPE_STATION] = {
67 .tx = 0xffff,
68 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
69 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
70 },
71 [NL80211_IFTYPE_AP] = {
72 .tx = 0xffff,
73 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
74 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
75 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
76 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
77 BIT(IEEE80211_STYPE_AUTH >> 4) |
78 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
79 BIT(IEEE80211_STYPE_ACTION >> 4)
80 },
81 [NL80211_IFTYPE_P2P_CLIENT] = {
82 .tx = 0xffff,
83 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
84 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
85 BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
86 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
87 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
88 BIT(IEEE80211_STYPE_AUTH >> 4) |
89 BIT(IEEE80211_STYPE_DEAUTH >> 4)
90 }
91};
92
93/* Time to stay on the channel */
94#define WILC_WFI_DWELL_PASSIVE 100
95#define WILC_WFI_DWELL_ACTIVE 40
96
97#define TCP_ACK_FILTER_LINK_SPEED_THRESH 54
98#define DEFAULT_LINK_SPEED 72
99
100
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900101#define IS_MANAGMEMENT 0x100
102#define IS_MANAGMEMENT_CALLBACK 0x080
103#define IS_MGMT_STATUS_SUCCES 0x040
104#define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff)
105
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100106extern int wilc_mac_open(struct net_device *ndev);
107extern int wilc_mac_close(struct net_device *ndev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900108
Arnd Bergmann1608c402015-11-16 15:04:53 +0100109static tstrNetworkInfo astrLastScannedNtwrksShadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
Leo Kim771fbae2015-11-19 15:56:10 +0900110static u32 last_scanned_cnt;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100111struct timer_list wilc_during_ip_timer;
Arnd Bergmann1608c402015-11-16 15:04:53 +0100112static struct timer_list hAgingTimer;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900113static u8 op_ifcs;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900114
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100115u8 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900116
117#define CHAN2G(_channel, _freq, _flags) { \
118 .band = IEEE80211_BAND_2GHZ, \
119 .center_freq = (_freq), \
120 .hw_value = (_channel), \
121 .flags = (_flags), \
122 .max_antenna_gain = 0, \
123 .max_power = 30, \
124}
125
126/*Frequency range for channels*/
127static struct ieee80211_channel WILC_WFI_2ghz_channels[] = {
128 CHAN2G(1, 2412, 0),
129 CHAN2G(2, 2417, 0),
130 CHAN2G(3, 2422, 0),
131 CHAN2G(4, 2427, 0),
132 CHAN2G(5, 2432, 0),
133 CHAN2G(6, 2437, 0),
134 CHAN2G(7, 2442, 0),
135 CHAN2G(8, 2447, 0),
136 CHAN2G(9, 2452, 0),
137 CHAN2G(10, 2457, 0),
138 CHAN2G(11, 2462, 0),
139 CHAN2G(12, 2467, 0),
140 CHAN2G(13, 2472, 0),
141 CHAN2G(14, 2484, 0),
142};
143
144#define RATETAB_ENT(_rate, _hw_value, _flags) { \
145 .bitrate = (_rate), \
146 .hw_value = (_hw_value), \
147 .flags = (_flags), \
148}
149
150
151/* Table 6 in section 3.2.1.1 */
152static struct ieee80211_rate WILC_WFI_rates[] = {
153 RATETAB_ENT(10, 0, 0),
154 RATETAB_ENT(20, 1, 0),
155 RATETAB_ENT(55, 2, 0),
156 RATETAB_ENT(110, 3, 0),
157 RATETAB_ENT(60, 9, 0),
158 RATETAB_ENT(90, 6, 0),
159 RATETAB_ENT(120, 7, 0),
160 RATETAB_ENT(180, 8, 0),
161 RATETAB_ENT(240, 9, 0),
162 RATETAB_ENT(360, 10, 0),
163 RATETAB_ENT(480, 11, 0),
164 RATETAB_ENT(540, 12, 0),
165};
166
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900167struct p2p_mgmt_data {
168 int size;
169 u8 *buff;
170};
171
172/*Global variable used to state the current connected STA channel*/
Arnd Bergmann1608c402015-11-16 15:04:53 +0100173static u8 u8WLANChannel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900174
Arnd Bergmann1608c402015-11-16 15:04:53 +0100175static u8 curr_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900176
Arnd Bergmann1608c402015-11-16 15:04:53 +0100177static u8 u8P2P_oui[] = {0x50, 0x6f, 0x9A, 0x09};
178static u8 u8P2Plocalrandom = 0x01;
179static u8 u8P2Precvrandom = 0x00;
180static u8 u8P2P_vendorspec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
181static bool bWilc_ie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900182
183static struct ieee80211_supported_band WILC_WFI_band_2ghz = {
184 .channels = WILC_WFI_2ghz_channels,
185 .n_channels = ARRAY_SIZE(WILC_WFI_2ghz_channels),
186 .bitrates = WILC_WFI_rates,
187 .n_bitrates = ARRAY_SIZE(WILC_WFI_rates),
188};
189
190
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900191struct add_key_params {
192 u8 key_idx;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900193 bool pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900194 u8 *mac_addr;
195};
Arnd Bergmann1608c402015-11-16 15:04:53 +0100196static struct add_key_params g_add_gtk_key_params;
197static struct wilc_wfi_key g_key_gtk_params;
198static struct add_key_params g_add_ptk_key_params;
199static struct wilc_wfi_key g_key_ptk_params;
200static struct wilc_wfi_wep_key g_key_wep_params;
201static bool g_ptk_keys_saved;
202static bool g_gtk_keys_saved;
203static bool g_wep_keys_saved;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900204
205#define AGING_TIME (9 * 1000)
206#define duringIP_TIME 15000
207
Arnd Bergmann1608c402015-11-16 15:04:53 +0100208static void clear_shadow_scan(void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900209{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900210 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900211
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900212 if (op_ifcs == 0) {
Greg Kroah-Hartman4183e972015-08-14 20:11:16 -0700213 del_timer_sync(&hAgingTimer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900214 PRINT_INFO(CORECONFIG_DBG, "destroy aging timer\n");
215
Leo Kim771fbae2015-11-19 15:56:10 +0900216 for (i = 0; i < last_scanned_cnt; i++) {
217 if (astrLastScannedNtwrksShadow[last_scanned_cnt].pu8IEs != NULL) {
Chaehyun Lim49188af2015-08-11 10:32:41 +0900218 kfree(astrLastScannedNtwrksShadow[i].pu8IEs);
Leo Kim771fbae2015-11-19 15:56:10 +0900219 astrLastScannedNtwrksShadow[last_scanned_cnt].pu8IEs = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900220 }
221
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100222 wilc_free_join_params(astrLastScannedNtwrksShadow[i].pJoinParams);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900223 astrLastScannedNtwrksShadow[i].pJoinParams = NULL;
224 }
Leo Kim771fbae2015-11-19 15:56:10 +0900225 last_scanned_cnt = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900226 }
227
228}
229
Arnd Bergmann1608c402015-11-16 15:04:53 +0100230static u32 get_rssi_avg(tstrNetworkInfo *pstrNetworkInfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900231{
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900232 u8 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900233 int rssi_v = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900234 u8 num_rssi = (pstrNetworkInfo->strRssi.u8Full) ? NUM_RSSI : (pstrNetworkInfo->strRssi.u8Index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900235
236 for (i = 0; i < num_rssi; i++)
237 rssi_v += pstrNetworkInfo->strRssi.as8RSSI[i];
238
239 rssi_v /= num_rssi;
240 return rssi_v;
241}
242
Arnd Bergmann1608c402015-11-16 15:04:53 +0100243static void refresh_scan(void *pUserVoid, u8 all, bool bDirectScan)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900244{
Chaehyun Lim27268872015-09-15 14:06:13 +0900245 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900246 struct wiphy *wiphy;
247 struct cfg80211_bss *bss = NULL;
248 int i;
249 int rssi = 0;
250
Chaehyun Lim27268872015-09-15 14:06:13 +0900251 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900252 wiphy = priv->dev->ieee80211_ptr->wiphy;
253
Leo Kim771fbae2015-11-19 15:56:10 +0900254 for (i = 0; i < last_scanned_cnt; i++) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900255 tstrNetworkInfo *pstrNetworkInfo;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900256
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900257 pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]);
258
259
260 if ((!pstrNetworkInfo->u8Found) || all) {
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900261 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900262 struct ieee80211_channel *channel;
263
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900264 if (pstrNetworkInfo != NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900265
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900266 s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900267 channel = ieee80211_get_channel(wiphy, s32Freq);
268
269 rssi = get_rssi_avg(pstrNetworkInfo);
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900270 if (memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7) || bDirectScan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900271 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
272 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900273 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900274 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900275 }
276 }
277
278 }
279 }
280
281}
282
Arnd Bergmann1608c402015-11-16 15:04:53 +0100283static void reset_shadow_found(void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900284{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900285 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900286
Leo Kim771fbae2015-11-19 15:56:10 +0900287 for (i = 0; i < last_scanned_cnt; i++)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900288 astrLastScannedNtwrksShadow[i].u8Found = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900289}
290
Arnd Bergmann1608c402015-11-16 15:04:53 +0100291static void update_scan_time(void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900292{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900293 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900294
Leo Kim771fbae2015-11-19 15:56:10 +0900295 for (i = 0; i < last_scanned_cnt; i++)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900296 astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900297}
298
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700299static void remove_network_from_shadow(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900300{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900301 unsigned long now = jiffies;
302 int i, j;
303
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900304
Leo Kim771fbae2015-11-19 15:56:10 +0900305 for (i = 0; i < last_scanned_cnt; i++) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900306 if (time_after(now, astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530307 PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", astrLastScannedNtwrksShadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900308
Shraddha Barkecccfc392015-10-12 20:49:19 +0530309 kfree(astrLastScannedNtwrksShadow[i].pu8IEs);
310 astrLastScannedNtwrksShadow[i].pu8IEs = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900311
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100312 wilc_free_join_params(astrLastScannedNtwrksShadow[i].pJoinParams);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900313
Leo Kim771fbae2015-11-19 15:56:10 +0900314 for (j = i; (j < last_scanned_cnt - 1); j++)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900315 astrLastScannedNtwrksShadow[j] = astrLastScannedNtwrksShadow[j + 1];
Leo Kim771fbae2015-11-19 15:56:10 +0900316
317 last_scanned_cnt--;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900318 }
319 }
320
Leo Kim771fbae2015-11-19 15:56:10 +0900321 PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n",
322 last_scanned_cnt);
323 if (last_scanned_cnt != 0) {
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700324 hAgingTimer.data = arg;
325 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
326 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900327 PRINT_D(CFG80211_DBG, "No need to restart Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700328 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900329}
330
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700331static void clear_duringIP(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900332{
333 PRINT_D(GENERIC_DBG, "GO:IP Obtained , enable scan\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100334 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900335}
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900336
Arnd Bergmann1608c402015-11-16 15:04:53 +0100337static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900338{
Chaehyun Lima74cc6b2015-10-02 16:41:17 +0900339 int state = -1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900340 int i;
341
Leo Kim771fbae2015-11-19 15:56:10 +0900342 if (last_scanned_cnt == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900343 PRINT_D(CFG80211_DBG, "Starting Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700344 hAgingTimer.data = (unsigned long)pUserVoid;
345 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900346 state = -1;
347 } else {
348 /* Linear search for now */
Leo Kim771fbae2015-11-19 15:56:10 +0900349 for (i = 0; i < last_scanned_cnt; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900350 if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900351 pstrNetworkInfo->au8bssid, 6) == 0) {
352 state = i;
353 break;
354 }
355 }
356 }
357 return state;
358}
359
Arnd Bergmann1608c402015-11-16 15:04:53 +0100360static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900361{
Chaehyun Lima74cc6b2015-10-02 16:41:17 +0900362 int ap_found = is_network_in_shadow(pstrNetworkInfo, pUserVoid);
Chaehyun Limfbc2fe12015-09-15 14:06:16 +0900363 u32 ap_index = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900364 u8 rssi_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900365
Leo Kim771fbae2015-11-19 15:56:10 +0900366 if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900367 PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
368 return;
369 }
370 if (ap_found == -1) {
Leo Kim771fbae2015-11-19 15:56:10 +0900371 ap_index = last_scanned_cnt;
372 last_scanned_cnt++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900373
374 } else {
375 ap_index = ap_found;
376 }
377 rssi_index = astrLastScannedNtwrksShadow[ap_index].strRssi.u8Index;
378 astrLastScannedNtwrksShadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
379 if (rssi_index == NUM_RSSI) {
380 rssi_index = 0;
381 astrLastScannedNtwrksShadow[ap_index].strRssi.u8Full = 1;
382 }
383 astrLastScannedNtwrksShadow[ap_index].strRssi.u8Index = rssi_index;
384
385 astrLastScannedNtwrksShadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
386 astrLastScannedNtwrksShadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
387
388 astrLastScannedNtwrksShadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900389 memcpy(astrLastScannedNtwrksShadow[ap_index].au8ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900390 pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
391
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900392 memcpy(astrLastScannedNtwrksShadow[ap_index].au8bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900393 pstrNetworkInfo->au8bssid, ETH_ALEN);
394
395 astrLastScannedNtwrksShadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
396 astrLastScannedNtwrksShadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
397 astrLastScannedNtwrksShadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
398
399 astrLastScannedNtwrksShadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
400 astrLastScannedNtwrksShadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
401 if (ap_found != -1)
Chaehyun Lim49188af2015-08-11 10:32:41 +0900402 kfree(astrLastScannedNtwrksShadow[ap_index].pu8IEs);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900403 astrLastScannedNtwrksShadow[ap_index].pu8IEs =
Glen Leef3052582015-09-10 12:03:04 +0900404 kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL); /* will be deallocated by the WILC_WFI_CfgScan() function */
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900405 memcpy(astrLastScannedNtwrksShadow[ap_index].pu8IEs,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900406 pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
407
408 astrLastScannedNtwrksShadow[ap_index].u32TimeRcvdInScan = jiffies;
409 astrLastScannedNtwrksShadow[ap_index].u32TimeRcvdInScanCached = jiffies;
410 astrLastScannedNtwrksShadow[ap_index].u8Found = 1;
411 if (ap_found != -1)
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100412 wilc_free_join_params(astrLastScannedNtwrksShadow[ap_index].pJoinParams);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900413 astrLastScannedNtwrksShadow[ap_index].pJoinParams = pJoinParams;
414
415}
416
417
418/**
419 * @brief CfgScanResult
420 * @details Callback function which returns the scan results found
421 *
422 * @param[in] tenuScanEvent enuScanEvent: enum, indicating the scan event triggered, whether that is
423 * SCAN_EVENT_NETWORK_FOUND or SCAN_EVENT_DONE
424 * tstrNetworkInfo* pstrNetworkInfo: structure holding the scan results information
425 * void* pUserVoid: Private structure associated with the wireless interface
426 * @return NONE
427 * @author mabubakr
428 * @date
429 * @version 1.0
430 */
Leo Kim1ec38152015-10-12 16:55:59 +0900431static void CfgScanResult(enum scan_event enuScanEvent, tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900432{
Chaehyun Lim27268872015-09-15 14:06:13 +0900433 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900434 struct wiphy *wiphy;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900435 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900436 struct ieee80211_channel *channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900437 struct cfg80211_bss *bss = NULL;
438
Chaehyun Lim27268872015-09-15 14:06:13 +0900439 priv = (struct wilc_priv *)pUserVoid;
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100440 if (priv->bCfgScanning) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900441 if (enuScanEvent == SCAN_EVENT_NETWORK_FOUND) {
442 wiphy = priv->dev->ieee80211_ptr->wiphy;
Leo Kim7ae43362015-09-16 18:35:59 +0900443
444 if (!wiphy)
445 return;
446
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900447 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC
448 &&
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900449 ((((s32)pstrNetworkInfo->s8rssi) * 100) < 0
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900450 ||
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900451 (((s32)pstrNetworkInfo->s8rssi) * 100) > 100)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900452 ) {
Leo Kim24db7132015-09-16 18:36:01 +0900453 PRINT_ER("wiphy signal type fial\n");
454 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900455 }
456
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900457 if (pstrNetworkInfo != NULL) {
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900458 s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900459 channel = ieee80211_get_channel(wiphy, s32Freq);
460
Leo Kim7ae43362015-09-16 18:35:59 +0900461 if (!channel)
462 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900463
464 PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530465 "BeaconPeriod: %d\n", channel->center_freq, (((s32)pstrNetworkInfo->s8rssi) * 100),
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900466 pstrNetworkInfo->u16CapInfo, pstrNetworkInfo->u16BeaconPeriod);
467
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100468 if (pstrNetworkInfo->bNewNetwork) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900469 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
470 /* max_scan_ssids */
471 PRINT_D(CFG80211_DBG, "Network %s found\n", pstrNetworkInfo->au8ssid);
472
473
474 priv->u32RcvdChCount++;
475
476
477
478 if (pJoinParams == NULL) {
479 PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n");
480 }
481 add_network_to_shadow(pstrNetworkInfo, priv, pJoinParams);
482
483 /*P2P peers are sent to WPA supplicant and added to shadow table*/
484
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900485 if (!(memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900486 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
487 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900488 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)pstrNetworkInfo->s8rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900489 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900490 }
491
492
493 } else {
494 PRINT_ER("Discovered networks exceeded the max limit\n");
495 }
496 } else {
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900497 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900498 /* So this network is discovered before, we'll just update its RSSI */
499 for (i = 0; i < priv->u32RcvdChCount; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900500 if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid, pstrNetworkInfo->au8bssid, 6) == 0) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530501 PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", astrLastScannedNtwrksShadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900502
503 astrLastScannedNtwrksShadow[i].s8rssi = pstrNetworkInfo->s8rssi;
504 astrLastScannedNtwrksShadow[i].u32TimeRcvdInScan = jiffies;
505 break;
506 }
507 }
508 }
509 }
510 } else if (enuScanEvent == SCAN_EVENT_DONE) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530511 PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev);
512 PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n");
Dean Lee72ed4dc2015-06-12 14:11:44 +0900513 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900514
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530515 if (priv->u32RcvdChCount > 0)
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530516 PRINT_D(CFG80211_DBG, "%d Network(s) found\n", priv->u32RcvdChCount);
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530517 else
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530518 PRINT_D(CFG80211_DBG, "No networks found\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900519
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200520 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900521
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900522 if (priv->pstrScanReq != NULL) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900523 cfg80211_scan_done(priv->pstrScanReq, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900524 priv->u32RcvdChCount = 0;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900525 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900526 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900527 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200528 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900529
530 }
531 /*Aborting any scan operation during mac close*/
532 else if (enuScanEvent == SCAN_EVENT_ABORTED) {
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200533 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900534
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530535 PRINT_D(CFG80211_DBG, "Scan Aborted\n");
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900536 if (priv->pstrScanReq != NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900537
538 update_scan_time(priv);
Dean Lee72ed4dc2015-06-12 14:11:44 +0900539 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900540
Dean Lee72ed4dc2015-06-12 14:11:44 +0900541 cfg80211_scan_done(priv->pstrScanReq, false);
542 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900543 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900544 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200545 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900546 }
547 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900548}
549
550
551/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900552 * @brief CfgConnectResult
553 * @details
554 * @param[in] tenuConnDisconnEvent enuConnDisconnEvent: Type of connection response either
555 * connection response or disconnection notification.
556 * tstrConnectInfo* pstrConnectInfo: COnnection information.
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900557 * u8 u8MacStatus: Mac Status from firmware
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900558 * tstrDisconnectNotifInfo* pstrDisconnectNotifInfo: Disconnection Notification
559 * void* pUserVoid: Private data associated with wireless interface
560 * @return NONE
561 * @author mabubakr
562 * @date 01 MAR 2012
563 * @version 1.0
564 */
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100565int wilc_connecting;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900566
Leo Kimed3f0372015-10-12 16:56:01 +0900567static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900568 tstrConnectInfo *pstrConnectInfo,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900569 u8 u8MacStatus,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900570 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
571 void *pUserVoid)
572{
Chaehyun Lim27268872015-09-15 14:06:13 +0900573 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900574 struct net_device *dev;
Leo Kim441dc602015-10-12 16:55:35 +0900575 struct host_if_drv *pstrWFIDrv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900576 u8 NullBssid[ETH_ALEN] = {0};
Glen Leec1ec2c12015-10-20 17:13:58 +0900577 struct wilc *wl;
578 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900579
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100580 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900581
Chaehyun Lim27268872015-09-15 14:06:13 +0900582 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900583 dev = priv->dev;
Glen Leec1ec2c12015-10-20 17:13:58 +0900584 nic = netdev_priv(dev);
585 wl = nic->wilc;
Leo Kim441dc602015-10-12 16:55:35 +0900586 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900587
588 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
589 /*Initialization*/
Amitoj Kaur Chawlababa7c72015-10-15 13:48:29 +0530590 u16 u16ConnectStatus;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900591
592 u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
593
594 PRINT_D(CFG80211_DBG, " Connection response received = %d\n", u8MacStatus);
595
596 if ((u8MacStatus == MAC_DISCONNECTED) &&
597 (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
598 /* The case here is that our station was waiting for association response frame and has just received it containing status code
599 * = SUCCESSFUL_STATUSCODE, while mac status is MAC_DISCONNECTED (which means something wrong happened) */
600 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100601 wilc_wlan_set_bssid(priv->dev, NullBssid);
602 eth_zero_addr(wilc_connected_SSID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900603
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900604 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
Leo Kimab16ec02015-10-29 12:05:40 +0900605 if (!pstrWFIDrv->p2p_connect)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900606 u8WLANChannel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900607
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530608 PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d\n", u16ConnectStatus, u8MacStatus);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900609 }
610
611 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900612 bool bNeedScanRefresh = false;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900613 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900614
615 PRINT_INFO(CFG80211_DBG, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo->au8bssid[0],
616 pstrConnectInfo->au8bssid[1], pstrConnectInfo->au8bssid[2], pstrConnectInfo->au8bssid[3], pstrConnectInfo->au8bssid[4], pstrConnectInfo->au8bssid[5]);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900617 memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900618
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900619
Leo Kim771fbae2015-11-19 15:56:10 +0900620 for (i = 0; i < last_scanned_cnt; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900621 if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900622 pstrConnectInfo->au8bssid, ETH_ALEN) == 0) {
623 unsigned long now = jiffies;
624
625 if (time_after(now,
626 astrLastScannedNtwrksShadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900627 bNeedScanRefresh = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900628 }
629
630 break;
631 }
632 }
633
Abdul Hussain5a66bf22015-06-16 09:44:06 +0000634 if (bNeedScanRefresh) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900635 /*Also, refrsh DIRECT- results if */
Dean Lee72ed4dc2015-06-12 14:11:44 +0900636 refresh_scan(priv, 1, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900637
638 }
639
640 }
641
642
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530643 PRINT_D(CFG80211_DBG, "Association request info elements length = %zu\n", pstrConnectInfo->ReqIEsLen);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900644
645 PRINT_D(CFG80211_DBG, "Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen);
646
647 cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
648 pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
649 pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
650 u16ConnectStatus, GFP_KERNEL); /* TODO: mostafa: u16ConnectStatus to */
651 /* be replaced by pstrConnectInfo->u16ConnectStatus */
652 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100653 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900654 PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n",
655 pstrDisconnectNotifInfo->u16reason, priv->dev);
656 u8P2Plocalrandom = 0x01;
657 u8P2Precvrandom = 0x00;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900658 bWilc_ie = false;
Shraddha Barkebcf02652015-10-05 17:00:32 +0530659 eth_zero_addr(priv->au8AssociatedBss);
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100660 wilc_wlan_set_bssid(priv->dev, NullBssid);
661 eth_zero_addr(wilc_connected_SSID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900662
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900663 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
Leo Kimab16ec02015-10-29 12:05:40 +0900664 if (!pstrWFIDrv->p2p_connect)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900665 u8WLANChannel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900666 /*Incase "P2P CLIENT Connected" send deauthentication reason by 3 to force the WPA_SUPPLICANT to directly change
667 * virtual interface to station*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900668 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900669 pstrDisconnectNotifInfo->u16reason = 3;
670 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900671 /*Incase "P2P CLIENT during connection(not connected)" send deauthentication reason by 1 to force the WPA_SUPPLICANT
672 * to scan again and retry the connection*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900673 else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900674 pstrDisconnectNotifInfo->u16reason = 1;
675 }
676 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
Sudip Mukherjeee26bb712015-06-30 13:51:51 +0530677 pstrDisconnectNotifInfo->ie_len, false,
678 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900679
680 }
681
682}
683
684
685/**
Chaehyun Lim80785a92015-09-14 12:24:01 +0900686 * @brief set_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900687 * @details Set channel for a given wireless interface. Some devices
688 * may support multi-channel operation (by channel hopping) so cfg80211
689 * doesn't verify much. Note, however, that the passed netdev may be
690 * %NULL as well if the user requested changing the channel for the
691 * device itself, or for a monitor interface.
692 * @param[in]
693 * @return int : Return 0 on Success
694 * @author mdaftedar
695 * @date 01 MAR 2012
696 * @version 1.0
697 */
Chaehyun Lim80785a92015-09-14 12:24:01 +0900698static int set_channel(struct wiphy *wiphy,
699 struct cfg80211_chan_def *chandef)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900700{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900701 u32 channelnum = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +0900702 struct wilc_priv *priv;
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900703 int result = 0;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900704
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900705 priv = wiphy_priv(wiphy);
706
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900707 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
708 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900709
Chaehyun Lim866a2c22015-10-02 16:41:21 +0900710 curr_channel = channelnum;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100711 result = wilc_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900712
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900713 if (result != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900714 PRINT_ER("Error in setting channel %d\n", channelnum);
715
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900716 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900717}
718
719/**
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900720 * @brief scan
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900721 * @details Request to do a scan. If returning zero, the scan request is given
722 * the driver, and will be valid until passed to cfg80211_scan_done().
723 * For scan results, call cfg80211_inform_bss(); you can call this outside
724 * the scan/scan_done bracket too.
725 * @param[in]
726 * @return int : Return 0 on Success
727 * @author mabubakr
728 * @date 01 MAR 2012
729 * @version 1.0
730 */
731
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900732static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900733{
Chaehyun Lim27268872015-09-15 14:06:13 +0900734 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900735 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +0900736 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900737 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
Leo Kim607db442015-10-05 15:25:37 +0900738 struct hidden_network strHiddenNetwork;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900739
740 priv = wiphy_priv(wiphy);
741
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900742 priv->pstrScanReq = request;
743
744 priv->u32RcvdChCount = 0;
745
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100746 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900747
748
749 reset_shadow_found(priv);
750
Dean Lee72ed4dc2015-06-12 14:11:44 +0900751 priv->bCfgScanning = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900752 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
753 /* max_scan_ssids */
754 for (i = 0; i < request->n_channels; i++) {
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900755 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900756 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
757 }
758
759 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530760 PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900761
762 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
763
764 if (request->n_ssids >= 1) {
765
766
Leo Kim607db442015-10-05 15:25:37 +0900767 strHiddenNetwork.pstrHiddenNetworkInfo = kmalloc(request->n_ssids * sizeof(struct hidden_network), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900768 strHiddenNetwork.u8ssidnum = request->n_ssids;
769
770
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900771 for (i = 0; i < request->n_ssids; i++) {
772
773 if (request->ssids[i].ssid != NULL && request->ssids[i].ssid_len != 0) {
Glen Leef3052582015-09-10 12:03:04 +0900774 strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900775 memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900776 strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len;
777 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530778 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900779 strHiddenNetwork.u8ssidnum -= 1;
780 }
781 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530782 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100783 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900784 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900785 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900786 CfgScanResult, (void *)priv, &strHiddenNetwork);
787 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530788 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100789 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900790 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900791 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900792 CfgScanResult, (void *)priv, NULL);
793 }
794
795 } else {
796 PRINT_ER("Requested num of scanned channels is greater than the max, supported"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530797 " channels\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900798 }
799
Leo Kime6e12662015-09-16 18:36:03 +0900800 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900801 s32Error = -EBUSY;
802 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
803 }
804
805 return s32Error;
806}
807
808/**
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900809 * @brief connect
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900810 * @details Connect to the ESS with the specified parameters. When connected,
811 * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
812 * If the connection fails for some reason, call cfg80211_connect_result()
813 * with the status from the AP.
814 * @param[in]
815 * @return int : Return 0 on Success
816 * @author mabubakr
817 * @date 01 MAR 2012
818 * @version 1.0
819 */
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900820static int connect(struct wiphy *wiphy, struct net_device *dev,
821 struct cfg80211_connect_params *sme)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900822{
Leo Kime6e12662015-09-16 18:36:03 +0900823 s32 s32Error = 0;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900824 u32 i;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900825 u8 u8security = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +0900826 enum AUTHTYPE tenuAuth_type = ANY;
Dean Lee576917a2015-06-15 11:58:57 +0900827 char *pcgroup_encrypt_val = NULL;
828 char *pccipher_group = NULL;
829 char *pcwpa_version = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900830
Chaehyun Lim27268872015-09-15 14:06:13 +0900831 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +0900832 struct host_if_drv *pstrWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900833 tstrNetworkInfo *pstrNetworkInfo = NULL;
834
835
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100836 wilc_connecting = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900837 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +0900838 pstrWFIDrv = (struct host_if_drv *)(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900839
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100840 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900841
Johnny Kim8a143302015-06-10 17:06:46 +0900842 PRINT_D(CFG80211_DBG, "Connecting to SSID [%s] on netdev [%p] host if [%p]\n", sme->ssid, dev, priv->hWILCWFIDrv);
Chaehyun Lim3f882892015-08-10 11:33:17 +0900843 if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900844 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
Leo Kimab16ec02015-10-29 12:05:40 +0900845 pstrWFIDrv->p2p_connect = 1;
846 } else {
847 pstrWFIDrv->p2p_connect = 0;
848 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530849 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900850
Leo Kim771fbae2015-11-19 15:56:10 +0900851 for (i = 0; i < last_scanned_cnt; i++) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900852 if ((sme->ssid_len == astrLastScannedNtwrksShadow[i].u8SsidLen) &&
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900853 memcmp(astrLastScannedNtwrksShadow[i].au8ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900854 sme->ssid,
855 sme->ssid_len) == 0) {
856 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
857 if (sme->bssid == NULL) {
858 /* BSSID is not passed from the user, so decision of matching
859 * is done by SSID only */
860 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
861 break;
862 } else {
863 /* BSSID is also passed from the user, so decision of matching
864 * should consider also this passed BSSID */
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900865 if (memcmp(astrLastScannedNtwrksShadow[i].au8bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900866 sme->bssid,
867 ETH_ALEN) == 0) {
868 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
869 break;
870 }
871 }
872 }
873 }
874
Leo Kim771fbae2015-11-19 15:56:10 +0900875 if (i < last_scanned_cnt) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900876 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
877
878 pstrNetworkInfo = &(astrLastScannedNtwrksShadow[i]);
879
880 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
881 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
882 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
883 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
884 } else {
885 s32Error = -ENOENT;
Leo Kim771fbae2015-11-19 15:56:10 +0900886 if (last_scanned_cnt == 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900887 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
888 else
889 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
890
891 goto done;
892 }
893
894 priv->WILC_WFI_wep_default = 0;
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900895 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
896 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900897
898 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
899 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
900
901 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
902
903 if (INFO) {
904 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
905 PRINT_D(CORECONFIG_DBG, "sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]);
906 }
907
908 if (sme->crypto.cipher_group != NO_ENCRYPT) {
909 /* To determine the u8security value, first we check the group cipher suite then {in case of WPA or WPA2}
910 * we will add to it the pairwise cipher suite(s) */
911 pcwpa_version = "Default";
912 PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900913 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900914 u8security = ENCRYPT_ENABLED | WEP;
915 pcgroup_encrypt_val = "WEP40";
916 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
917 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
918
919 if (INFO) {
920 for (i = 0; i < sme->key_len; i++)
921 PRINT_D(CORECONFIG_DBG, "WEP Key Value[%d] = %d\n", i, sme->key[i]);
922 }
923 priv->WILC_WFI_wep_default = sme->key_idx;
924 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900925 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900926
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900927 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900928 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900929 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
930 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900931 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900932
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100933 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
934 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900935 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900936 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
937 pcgroup_encrypt_val = "WEP104";
938 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
939
940 priv->WILC_WFI_wep_default = sme->key_idx;
941 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900942 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900943
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900944 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900945 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900946 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
947 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900948 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900949
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100950 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
951 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900952 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900953 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900954 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
955 pcgroup_encrypt_val = "WPA2_TKIP";
956 pccipher_group = "TKIP";
957 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
958 /* tenuSecurity_t = WPA2_AES; */
959 u8security = ENCRYPT_ENABLED | WPA2 | AES;
960 pcgroup_encrypt_val = "WPA2_AES";
961 pccipher_group = "AES";
962 }
963 pcwpa_version = "WPA_VERSION_2";
964 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
965 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900966 u8security = ENCRYPT_ENABLED | WPA | TKIP;
967 pcgroup_encrypt_val = "WPA_TKIP";
968 pccipher_group = "TKIP";
969 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
970 /* tenuSecurity_t = WPA_AES; */
971 u8security = ENCRYPT_ENABLED | WPA | AES;
972 pcgroup_encrypt_val = "WPA_AES";
973 pccipher_group = "AES";
974
975 }
976 pcwpa_version = "WPA_VERSION_1";
977
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900978 } else {
979 s32Error = -ENOTSUPP;
980 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
981
982 goto done;
983 }
984
985 }
986
987 /* After we set the u8security value from checking the group cipher suite, {in case of WPA or WPA2} we will
988 * add to it the pairwise cipher suite(s) */
989 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
990 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
991 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
992 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
993 u8security = u8security | TKIP;
994 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
995 u8security = u8security | AES;
996 }
997 }
998 }
999
1000 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
1001
1002 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
1003 switch (sme->auth_type) {
1004 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1005 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
1006 tenuAuth_type = OPEN_SYSTEM;
1007 break;
1008
1009 case NL80211_AUTHTYPE_SHARED_KEY:
1010 tenuAuth_type = SHARED_KEY;
1011 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
1012 break;
1013
1014 default:
1015 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
1016 }
1017
1018
1019 /* ai: key_mgmt: enterprise case */
1020 if (sme->crypto.n_akm_suites) {
1021 switch (sme->crypto.akm_suites[0]) {
1022 case WLAN_AKM_SUITE_8021X:
1023 tenuAuth_type = IEEE8021;
1024 break;
1025
1026 default:
1027 break;
1028 }
1029 }
1030
1031
1032 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
1033
1034 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
1035 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
1036
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001037 curr_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001038
Leo Kimab16ec02015-10-29 12:05:40 +09001039 if (!pstrWFIDrv->p2p_connect)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001040 u8WLANChannel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001041
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001042 wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001043
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001044 s32Error = wilc_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001045 sme->ssid_len, sme->ie, sme->ie_len,
1046 CfgConnectResult, (void *)priv, u8security,
1047 tenuAuth_type, pstrNetworkInfo->u8channel,
1048 pstrNetworkInfo->pJoinParams);
Leo Kime6e12662015-09-16 18:36:03 +09001049 if (s32Error != 0) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001050 PRINT_ER("wilc_set_join_req(): Error(%d)\n", s32Error);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001051 s32Error = -ENOENT;
1052 goto done;
1053 }
1054
1055done:
1056
1057 return s32Error;
1058}
1059
1060
1061/**
Chaehyun Limb027cde2015-09-14 12:24:04 +09001062 * @brief disconnect
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001063 * @details Disconnect from the BSS/ESS.
1064 * @param[in]
1065 * @return int : Return 0 on Success
1066 * @author mdaftedar
1067 * @date 01 MAR 2012
1068 * @version 1.0
1069 */
Chaehyun Limb027cde2015-09-14 12:24:04 +09001070static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001071{
Leo Kime6e12662015-09-16 18:36:03 +09001072 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09001073 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09001074 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim51e825f2015-09-15 14:06:14 +09001075 u8 NullBssid[ETH_ALEN] = {0};
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001076
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001077 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001078 priv = wiphy_priv(wiphy);
1079
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001080 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
Leo Kim441dc602015-10-12 16:55:35 +09001081 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Leo Kimab16ec02015-10-29 12:05:40 +09001082 if (!pstrWFIDrv->p2p_connect)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001083 u8WLANChannel = INVALID_CHANNEL;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001084 wilc_wlan_set_bssid(priv->dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001085
1086 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
1087
1088 u8P2Plocalrandom = 0x01;
1089 u8P2Precvrandom = 0x00;
Dean Lee72ed4dc2015-06-12 14:11:44 +09001090 bWilc_ie = false;
Leo Kim1229b1a2015-10-29 12:05:39 +09001091 pstrWFIDrv->p2p_timeout = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001092
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001093 s32Error = wilc_disconnect(priv->hWILCWFIDrv, reason_code);
Leo Kime6e12662015-09-16 18:36:03 +09001094 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001095 PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
1096 s32Error = -EINVAL;
1097 }
1098
1099 return s32Error;
1100}
1101
1102/**
Chaehyun Lim953d4172015-09-14 12:24:05 +09001103 * @brief add_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001104 * @details Add a key with the given parameters. @mac_addr will be %NULL
1105 * when adding a group key.
1106 * @param[in] key : key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, 8-byte Rx Mic Key
1107 * @return int : Return 0 on Success
1108 * @author mdaftedar
1109 * @date 01 MAR 2012
1110 * @version 1.0
1111 */
Chaehyun Lim953d4172015-09-14 12:24:05 +09001112static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1113 bool pairwise,
1114 const u8 *mac_addr, struct key_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001115
1116{
Leo Kime6e12662015-09-16 18:36:03 +09001117 s32 s32Error = 0, KeyLen = params->key_len;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001118 u32 i;
Chaehyun Lim27268872015-09-15 14:06:13 +09001119 struct wilc_priv *priv;
Arnd Bergmann057d1e92015-06-01 21:06:44 +02001120 const u8 *pu8RxMic = NULL;
1121 const u8 *pu8TxMic = NULL;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001122 u8 u8mode = NO_ENCRYPT;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001123 u8 u8gmode = NO_ENCRYPT;
1124 u8 u8pmode = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +09001125 enum AUTHTYPE tenuAuth_type = ANY;
Glen Lee76469202015-10-20 17:13:59 +09001126 struct wilc *wl;
1127 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001128
1129 priv = wiphy_priv(wiphy);
Glen Lee76469202015-10-20 17:13:59 +09001130 nic = netdev_priv(netdev);
1131 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001132
1133 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
1134
Johnny Kim8a143302015-06-10 17:06:46 +09001135 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001136
1137 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
1138 params->key[1],
1139 params->key[2]);
1140
1141
1142 switch (params->cipher) {
1143 case WLAN_CIPHER_SUITE_WEP40:
1144 case WLAN_CIPHER_SUITE_WEP104:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001145 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
1146
1147 priv->WILC_WFI_wep_default = key_index;
1148 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001149 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001150
1151 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
1152 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
1153
1154 for (i = 0; i < params->key_len; i++)
1155 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
1156
1157 tenuAuth_type = OPEN_SYSTEM;
1158
1159 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
1160 u8mode = ENCRYPT_ENABLED | WEP;
1161 else
1162 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
1163
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001164 wilc_add_wep_key_bss_ap(priv->hWILCWFIDrv, params->key, params->key_len, key_index, u8mode, tenuAuth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001165 break;
1166 }
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001167 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001168 priv->WILC_WFI_wep_default = key_index;
1169 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001170 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001171
1172 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
1173 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
1174 if (INFO) {
1175 for (i = 0; i < params->key_len; i++)
1176 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
1177 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001178 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001179 }
1180
1181 break;
1182
1183 case WLAN_CIPHER_SUITE_TKIP:
1184 case WLAN_CIPHER_SUITE_CCMP:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001185 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
1186
1187 if (priv->wilc_gtk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001188 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001189 priv->wilc_gtk[key_index]->key = NULL;
1190 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001191
1192 }
1193 if (priv->wilc_ptk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001194 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001195 priv->wilc_ptk[key_index]->key = NULL;
1196 priv->wilc_ptk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001197 }
1198
1199
1200
Daniel Machon19132212015-08-05 08:18:31 +02001201 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001202 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1203 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1204 else
1205 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1206
1207 priv->wilc_groupkey = u8gmode;
1208
1209 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1210
1211 pu8TxMic = params->key + 24;
1212 pu8RxMic = params->key + 16;
1213 KeyLen = params->key_len - 16;
1214 }
1215 /* if there has been previous allocation for the same index through its key, free that memory and allocate again*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301216 kfree(priv->wilc_gtk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001217
Glen Leef3052582015-09-10 12:03:04 +09001218 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001219 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001220
1221 /* if there has been previous allocation for the same index through its seq, free that memory and allocate again*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301222 kfree(priv->wilc_gtk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001223
1224 if ((params->seq_len) > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001225 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001226 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001227 }
1228
1229 priv->wilc_gtk[key_index]->cipher = params->cipher;
1230 priv->wilc_gtk[key_index]->key_len = params->key_len;
1231 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1232
1233 if (INFO) {
1234 for (i = 0; i < params->key_len; i++)
1235 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1236 for (i = 0; i < params->seq_len; i++)
1237 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1238 }
1239
1240
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001241 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001242 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode);
1243
1244 } else {
1245 PRINT_INFO(CFG80211_DBG, "STA Address: %x%x%x%x%x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4]);
1246
1247 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1248 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1249 else
1250 u8pmode = priv->wilc_groupkey | AES;
1251
1252
1253 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1254
1255 pu8TxMic = params->key + 24;
1256 pu8RxMic = params->key + 16;
1257 KeyLen = params->key_len - 16;
1258 }
1259
Shraddha Barkecccfc392015-10-12 20:49:19 +05301260 kfree(priv->wilc_ptk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001261
Glen Leef3052582015-09-10 12:03:04 +09001262 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001263
Shraddha Barkecccfc392015-10-12 20:49:19 +05301264 kfree(priv->wilc_ptk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001265
1266 if ((params->seq_len) > 0)
Glen Leef3052582015-09-10 12:03:04 +09001267 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001268
1269 if (INFO) {
1270 for (i = 0; i < params->key_len; i++)
1271 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1272
1273 for (i = 0; i < params->seq_len; i++)
1274 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1275 }
1276
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001277 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001278
1279 if ((params->seq_len) > 0)
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001280 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001281
1282 priv->wilc_ptk[key_index]->cipher = params->cipher;
1283 priv->wilc_ptk[key_index]->key_len = params->key_len;
1284 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1285
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001286 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001287 pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index);
1288 }
1289 break;
1290 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001291
1292 {
1293 u8mode = 0;
Daniel Machon19132212015-08-05 08:18:31 +02001294 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001295 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1296 /* swap the tx mic by rx mic */
1297 pu8RxMic = params->key + 24;
1298 pu8TxMic = params->key + 16;
1299 KeyLen = params->key_len - 16;
1300 }
1301
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001302 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001303 if (!g_gtk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001304 g_add_gtk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001305 g_add_gtk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001306 if (!mac_addr) {
1307 g_add_gtk_key_params.mac_addr = NULL;
1308 } else {
Glen Leef3052582015-09-10 12:03:04 +09001309 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001310 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1311 }
1312 g_key_gtk_params.key_len = params->key_len;
1313 g_key_gtk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001314 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001315 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1316 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001317 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001318 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1319 }
1320 g_key_gtk_params.cipher = params->cipher;
1321
1322 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1323 g_key_gtk_params.key[1],
1324 g_key_gtk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001325 g_gtk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001326 }
1327
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001328 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001329 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001330 } else {
1331 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1332 /* swap the tx mic by rx mic */
1333 pu8RxMic = params->key + 24;
1334 pu8TxMic = params->key + 16;
1335 KeyLen = params->key_len - 16;
1336 }
1337
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001338 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001339 if (!g_ptk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001340 g_add_ptk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001341 g_add_ptk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001342 if (!mac_addr) {
1343 g_add_ptk_key_params.mac_addr = NULL;
1344 } else {
Glen Leef3052582015-09-10 12:03:04 +09001345 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001346 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1347 }
1348 g_key_ptk_params.key_len = params->key_len;
1349 g_key_ptk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001350 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001351 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1352 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001353 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001354 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1355 }
1356 g_key_ptk_params.cipher = params->cipher;
1357
1358 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1359 g_key_ptk_params.key[1],
1360 g_key_ptk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001361 g_ptk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001362 }
1363
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001364 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001365 pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index);
1366 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1367 if (INFO) {
1368 for (i = 0; i < params->key_len; i++)
1369 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1370 }
1371 }
1372 }
1373 break;
1374
1375 default:
1376 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
1377 s32Error = -ENOTSUPP;
1378
1379 }
1380
1381 return s32Error;
1382}
1383
1384/**
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001385 * @brief del_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001386 * @details Remove a key given the @mac_addr (%NULL for a group key)
1387 * and @key_index, return -ENOENT if the key doesn't exist.
1388 * @param[in]
1389 * @return int : Return 0 on Success
1390 * @author mdaftedar
1391 * @date 01 MAR 2012
1392 * @version 1.0
1393 */
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001394static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1395 u8 key_index,
1396 bool pairwise,
1397 const u8 *mac_addr)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001398{
Chaehyun Lim27268872015-09-15 14:06:13 +09001399 struct wilc_priv *priv;
Glen Lee692e2ac2015-10-20 17:14:00 +09001400 struct wilc *wl;
1401 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001402
1403 priv = wiphy_priv(wiphy);
Glen Lee692e2ac2015-10-20 17:14:00 +09001404 nic = netdev_priv(netdev);
1405 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001406
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001407 /*delete saved keys, if any*/
Glen Lee692e2ac2015-10-20 17:14:00 +09001408 if (netdev == wl->vif[0].ndev) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09001409 g_ptk_keys_saved = false;
1410 g_gtk_keys_saved = false;
1411 g_wep_keys_saved = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001412
1413 /*Delete saved WEP keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301414 kfree(g_key_wep_params.key);
1415 g_key_wep_params.key = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001416
1417 /*freeing memory allocated by "wilc_gtk" and "wilc_ptk" in "WILC_WIFI_ADD_KEY"*/
1418
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001419 if ((priv->wilc_gtk[key_index]) != NULL) {
1420
Shraddha Barkecccfc392015-10-12 20:49:19 +05301421 kfree(priv->wilc_gtk[key_index]->key);
1422 priv->wilc_gtk[key_index]->key = NULL;
1423 kfree(priv->wilc_gtk[key_index]->seq);
1424 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001425
Chaehyun Lim49188af2015-08-11 10:32:41 +09001426 kfree(priv->wilc_gtk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001427 priv->wilc_gtk[key_index] = NULL;
1428
1429 }
1430
1431 if ((priv->wilc_ptk[key_index]) != NULL) {
1432
Shraddha Barkecccfc392015-10-12 20:49:19 +05301433 kfree(priv->wilc_ptk[key_index]->key);
1434 priv->wilc_ptk[key_index]->key = NULL;
1435 kfree(priv->wilc_ptk[key_index]->seq);
1436 priv->wilc_ptk[key_index]->seq = NULL;
Chaehyun Lim49188af2015-08-11 10:32:41 +09001437 kfree(priv->wilc_ptk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001438 priv->wilc_ptk[key_index] = NULL;
1439 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001440
1441 /*Delete saved PTK and GTK keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301442 kfree(g_key_ptk_params.key);
1443 g_key_ptk_params.key = NULL;
1444 kfree(g_key_ptk_params.seq);
1445 g_key_ptk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001446
Shraddha Barkecccfc392015-10-12 20:49:19 +05301447 kfree(g_key_gtk_params.key);
1448 g_key_gtk_params.key = NULL;
1449 kfree(g_key_gtk_params.seq);
1450 g_key_gtk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001451
1452 /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001453 wilc_set_machw_change_vir_if(netdev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001454 }
1455
1456 if (key_index >= 0 && key_index <= 3) {
Chaehyun Lim2cc46832015-08-07 09:02:01 +09001457 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001458 priv->WILC_WFI_wep_key_len[key_index] = 0;
1459
1460 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001461 wilc_remove_wep_key(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001462 } else {
1463 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001464 wilc_remove_key(priv->hWILCWFIDrv, mac_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001465 }
1466
Leo Kimaaed3292015-10-12 16:55:38 +09001467 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001468}
1469
1470/**
Chaehyun Limf4893df2015-09-14 12:24:07 +09001471 * @brief get_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001472 * @details Get information about the key with the given parameters.
1473 * @mac_addr will be %NULL when requesting information for a group
1474 * key. All pointers given to the @callback function need not be valid
1475 * after it returns. This function should return an error if it is
1476 * not possible to retrieve the key, -ENOENT if it doesn't exist.
1477 * @param[in]
1478 * @return int : Return 0 on Success
1479 * @author mdaftedar
1480 * @date 01 MAR 2012
1481 * @version 1.0
1482 */
Chaehyun Limf4893df2015-09-14 12:24:07 +09001483static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1484 bool pairwise,
1485 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001486{
Chaehyun Lim27268872015-09-15 14:06:13 +09001487 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001488 struct key_params key_params;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001489 u32 i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001490
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001491 priv = wiphy_priv(wiphy);
1492
1493
Alison Schofield3604af52015-10-12 13:22:44 -07001494 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001495 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1496
1497 key_params.key = priv->wilc_gtk[key_index]->key;
1498 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1499 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1500 key_params.seq = priv->wilc_gtk[key_index]->seq;
1501 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1502 if (INFO) {
1503 for (i = 0; i < key_params.key_len; i++)
1504 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1505 }
1506 } else {
1507 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1508
1509 key_params.key = priv->wilc_ptk[key_index]->key;
1510 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1511 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1512 key_params.seq = priv->wilc_ptk[key_index]->seq;
1513 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1514 }
1515
1516 callback(cookie, &key_params);
1517
Leo Kimaaed3292015-10-12 16:55:38 +09001518 return 0; /* priv->wilc_gtk->key_len ?0 : -ENOENT; */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001519}
1520
1521/**
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001522 * @brief set_default_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001523 * @details Set the default management frame key on an interface
1524 * @param[in]
1525 * @return int : Return 0 on Success.
1526 * @author mdaftedar
1527 * @date 01 MAR 2012
1528 * @version 1.0
1529 */
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001530static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1531 bool unicast, bool multicast)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001532{
Chaehyun Lim27268872015-09-15 14:06:13 +09001533 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001534
1535
1536 priv = wiphy_priv(wiphy);
1537
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301538 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001539
1540 if (key_index != priv->WILC_WFI_wep_default) {
1541
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001542 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001543 }
1544
Leo Kimaaed3292015-10-12 16:55:38 +09001545 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001546}
1547
1548/**
Chaehyun Limf06f5622015-09-14 12:24:18 +09001549 * @brief get_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001550 * @details Get station information for the station identified by @mac
1551 * @param[in] NONE
1552 * @return int : Return 0 on Success.
1553 * @author mdaftedar
1554 * @date 01 MAR 2012
1555 * @version 1.0
1556 */
1557
Chaehyun Limf06f5622015-09-14 12:24:18 +09001558static int get_station(struct wiphy *wiphy, struct net_device *dev,
1559 const u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001560{
Chaehyun Lim27268872015-09-15 14:06:13 +09001561 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001562 perInterface_wlan_t *nic;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001563 u32 i = 0;
1564 u32 associatedsta = 0;
1565 u32 inactive_time = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001566 priv = wiphy_priv(wiphy);
1567 nic = netdev_priv(dev);
1568
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001569 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
1570 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1571
1572 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1573
1574 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1575
1576 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1577 associatedsta = i;
1578 break;
1579 }
1580
1581 }
1582
1583 if (associatedsta == -1) {
Leo Kimaaed3292015-10-12 16:55:38 +09001584 PRINT_ER("Station required is not associated\n");
1585 return -ENOENT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001586 }
1587
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001588 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001589
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001590 wilc_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001591 sinfo->inactive_time = 1000 * inactive_time;
1592 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
1593
1594 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001595
1596 if (nic->iftype == STATION_MODE) {
Leo Kim03e7b9c2015-10-12 16:55:58 +09001597 struct rf_info strStatistics;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001598
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001599 wilc_get_statistics(priv->hWILCWFIDrv, &strStatistics);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001600
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001601 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
Chandra S Gorentla62129902015-08-05 22:11:57 +05301602 BIT(NL80211_STA_INFO_RX_PACKETS) |
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001603 BIT(NL80211_STA_INFO_TX_PACKETS) |
1604 BIT(NL80211_STA_INFO_TX_FAILED) |
1605 BIT(NL80211_STA_INFO_TX_BITRATE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001606
Leo Kim00c8dfc2015-10-29 12:05:30 +09001607 sinfo->signal = strStatistics.rssi;
Leo Kim9b992742015-10-29 12:05:32 +09001608 sinfo->rx_packets = strStatistics.rx_cnt;
Leo Kim54160372015-10-29 12:05:33 +09001609 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1610 sinfo->tx_failed = strStatistics.tx_fail_cnt;
Leo Kim5babeec2015-10-29 12:05:29 +09001611 sinfo->txrate.legacy = strStatistics.link_speed * 10;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001612
Leo Kim5babeec2015-10-29 12:05:29 +09001613 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1614 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001615 wilc_enable_tcp_ack_filter(true);
Leo Kim5babeec2015-10-29 12:05:29 +09001616 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001617 wilc_enable_tcp_ack_filter(false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001618
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001619 PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
1620 sinfo->tx_failed, sinfo->txrate.legacy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001621 }
Leo Kimaaed3292015-10-12 16:55:38 +09001622 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001623}
1624
1625
1626/**
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001627 * @brief change_bss
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001628 * @details Modify parameters for a given BSS.
1629 * @param[in]
1630 * -use_cts_prot: Whether to use CTS protection
1631 * (0 = no, 1 = yes, -1 = do not change)
1632 * -use_short_preamble: Whether the use of short preambles is allowed
1633 * (0 = no, 1 = yes, -1 = do not change)
1634 * -use_short_slot_time: Whether the use of short slot time is allowed
1635 * (0 = no, 1 = yes, -1 = do not change)
1636 * -basic_rates: basic rates in IEEE 802.11 format
1637 * (or NULL for no change)
1638 * -basic_rates_len: number of basic rates
1639 * -ap_isolate: do not forward packets between connected stations
1640 * -ht_opmode: HT Operation mode
1641 * (u16 = opmode, -1 = do not change)
1642 * @return int : Return 0 on Success.
1643 * @author mdaftedar
1644 * @date 01 MAR 2012
1645 * @version 1.0
1646 */
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001647static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1648 struct bss_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001649{
1650 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1651 return 0;
1652}
1653
1654/**
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001655 * @brief set_wiphy_params
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001656 * @details Notify that wiphy parameters have changed;
1657 * @param[in] Changed bitfield (see &enum wiphy_params_flags) describes which values
1658 * have changed.
1659 * @return int : Return 0 on Success
1660 * @author mdaftedar
1661 * @date 01 MAR 2012
1662 * @version 1.0
1663 */
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001664static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001665{
Leo Kime6e12662015-09-16 18:36:03 +09001666 s32 s32Error = 0;
Leo Kim95296502015-10-05 15:25:46 +09001667 struct cfg_param_val pstrCfgParamVal;
Chaehyun Lim27268872015-09-15 14:06:13 +09001668 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001669
1670 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001671
Tony Cho87c05b22015-10-12 16:56:07 +09001672 pstrCfgParamVal.flag = 0;
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301673 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001674
1675 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1676 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1677 priv->dev->ieee80211_ptr->wiphy->retry_short);
Tony Cho87c05b22015-10-12 16:56:07 +09001678 pstrCfgParamVal.flag |= RETRY_SHORT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001679 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1680 }
1681 if (changed & WIPHY_PARAM_RETRY_LONG) {
1682
1683 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_LONG %d\n", priv->dev->ieee80211_ptr->wiphy->retry_long);
Tony Cho87c05b22015-10-12 16:56:07 +09001684 pstrCfgParamVal.flag |= RETRY_LONG;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001685 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1686
1687 }
1688 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1689 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->frag_threshold);
Tony Cho87c05b22015-10-12 16:56:07 +09001690 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001691 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1692
1693 }
1694
1695 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1696 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1697
Tony Cho87c05b22015-10-12 16:56:07 +09001698 pstrCfgParamVal.flag |= RTS_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001699 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1700
1701 }
1702
1703 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001704 s32Error = wilc_hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001705 if (s32Error)
1706 PRINT_ER("Error in setting WIPHY PARAMS\n");
1707
1708
1709 return s32Error;
1710}
Arnd Bergmanne5af0562015-05-29 22:52:12 +02001711
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001712/**
Chaehyun Lim4d466572015-09-14 12:24:22 +09001713 * @brief set_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001714 * @details Cache a PMKID for a BSSID. This is mostly useful for fullmac
1715 * devices running firmwares capable of generating the (re) association
1716 * RSN IE. It allows for faster roaming between WPA2 BSSIDs.
1717 * @param[in]
1718 * @return int : Return 0 on Success
1719 * @author mdaftedar
1720 * @date 01 MAR 2012
1721 * @version 1.0
1722 */
Chaehyun Lim4d466572015-09-14 12:24:22 +09001723static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1724 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001725{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001726 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001727 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001728 u8 flag = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001729
Chaehyun Lim27268872015-09-15 14:06:13 +09001730 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001731
1732 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1733
1734
1735 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001736 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001737 ETH_ALEN)) {
1738 /*If bssid already exists and pmkid value needs to reset*/
1739 flag = PMKID_FOUND;
1740 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1741 break;
1742 }
1743 }
1744 if (i < WILC_MAX_NUM_PMKIDS) {
1745 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001746 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001747 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001748 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001749 PMKID_LEN);
1750 if (!(flag == PMKID_FOUND))
1751 priv->pmkid_list.numpmkid++;
1752 } else {
1753 PRINT_ER("Invalid PMKID index\n");
1754 s32Error = -EINVAL;
1755 }
1756
1757 if (!s32Error) {
1758 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001759 s32Error = wilc_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001760 }
1761 return s32Error;
1762}
1763
1764/**
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001765 * @brief del_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001766 * @details Delete a cached PMKID.
1767 * @param[in]
1768 * @return int : Return 0 on Success
1769 * @author mdaftedar
1770 * @date 01 MAR 2012
1771 * @version 1.0
1772 */
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001773static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1774 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001775{
1776
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001777 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001778 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001779
Chaehyun Lim27268872015-09-15 14:06:13 +09001780 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001781
1782 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1783
1784 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001785 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001786 ETH_ALEN)) {
1787 /*If bssid is found, reset the values*/
1788 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
Leo Kimcd1e6cb2015-10-05 15:25:45 +09001789 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001790 break;
1791 }
1792 }
1793
1794 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1795 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001796 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001797 priv->pmkid_list.pmkidlist[i + 1].bssid,
1798 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001799 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001800 priv->pmkid_list.pmkidlist[i].pmkid,
1801 PMKID_LEN);
1802 }
1803 priv->pmkid_list.numpmkid--;
1804 } else {
1805 s32Error = -EINVAL;
1806 }
1807
1808 return s32Error;
1809}
1810
1811/**
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001812 * @brief flush_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001813 * @details Flush all cached PMKIDs.
1814 * @param[in]
1815 * @return int : Return 0 on Success
1816 * @author mdaftedar
1817 * @date 01 MAR 2012
1818 * @version 1.0
1819 */
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001820static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001821{
Chaehyun Lim27268872015-09-15 14:06:13 +09001822 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001823
1824 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
1825
1826 /*Get cashed Pmkids and set all with zeros*/
Leo Kima949f902015-10-05 15:25:44 +09001827 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001828
1829 return 0;
1830}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001831
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001832
1833/**
1834 * @brief WILC_WFI_CfgParseRxAction
1835 * @details Function parses the received frames and modifies the following attributes:
1836 * -GO Intent
1837 * -Channel list
1838 * -Operating Channel
1839 *
1840 * @param[in] u8* Buffer, u32 length
1841 * @return NONE.
1842 * @author mdaftedar
1843 * @date 12 DEC 2012
1844 * @version
1845 */
1846
Arnd Bergmann1608c402015-11-16 15:04:53 +01001847static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001848{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001849 u32 index = 0;
1850 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001851
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001852 u8 op_channel_attr_index = 0;
1853 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001854
1855 while (index < len) {
1856 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001857 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001858 }
1859
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301860 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001861 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301862 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001863 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001864 index += buf[index + 1] + 3; /* ID,Length byte */
1865 }
Alison Schofield3604af52015-10-12 13:22:44 -07001866 if (u8WLANChannel != INVALID_CHANNEL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001867
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001868 /*Modify channel list attribute*/
1869 if (channel_list_attr_index) {
1870 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1871 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1872 if (buf[i] == 0x51) {
1873 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
1874 buf[j] = u8WLANChannel;
1875 }
1876 break;
1877 }
1878 }
1879 }
1880 /*Modify operating channel attribute*/
1881 if (op_channel_attr_index) {
1882 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1883 buf[op_channel_attr_index + 6] = 0x51;
1884 buf[op_channel_attr_index + 7] = u8WLANChannel;
1885 }
1886 }
1887}
1888
1889/**
1890 * @brief WILC_WFI_CfgParseTxAction
1891 * @details Function parses the transmitted action frames and modifies the
1892 * GO Intent attribute
1893 * @param[in] u8* Buffer, u32 length, bool bOperChan, u8 iftype
1894 * @return NONE.
1895 * @author mdaftedar
1896 * @date 12 DEC 2012
1897 * @version
1898 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01001899static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001900{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001901 u32 index = 0;
1902 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001903
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001904 u8 op_channel_attr_index = 0;
1905 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001906
1907 while (index < len) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001908 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001909 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001910
1911 break;
1912 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001913
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301914 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001915 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301916 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001917 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001918 index += buf[index + 1] + 3; /* ID,Length byte */
1919 }
Alison Schofield3604af52015-10-12 13:22:44 -07001920 if (u8WLANChannel != INVALID_CHANNEL && bOperChan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001921
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001922 /*Modify channel list attribute*/
1923 if (channel_list_attr_index) {
1924 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1925 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1926 if (buf[i] == 0x51) {
1927 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
1928 buf[j] = u8WLANChannel;
1929 }
1930 break;
1931 }
1932 }
1933 }
1934 /*Modify operating channel attribute*/
1935 if (op_channel_attr_index) {
1936 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1937 buf[op_channel_attr_index + 6] = 0x51;
1938 buf[op_channel_attr_index + 7] = u8WLANChannel;
1939 }
1940 }
1941}
1942
1943/* @brief WILC_WFI_p2p_rx
1944 * @details
1945 * @param[in]
1946 *
1947 * @return None
1948 * @author Mai Daftedar
1949 * @date 2 JUN 2013
1950 * @version 1.0
1951 */
1952
Chaehyun Limfbc2fe12015-09-15 14:06:16 +09001953void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001954{
1955
Chaehyun Lim27268872015-09-15 14:06:13 +09001956 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001957 u32 header, pkt_offset;
Leo Kim441dc602015-10-12 16:55:35 +09001958 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001959 u32 i = 0;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001960 s32 s32Freq;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001961
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001962 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001963 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001964
1965 /* Get WILC header */
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001966 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001967
1968 /* The packet offset field conain info about what type of managment frame */
1969 /* we are dealing with and ack status */
1970 pkt_offset = GET_PKT_OFFSET(header);
1971
1972 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1973 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1974 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001975 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001976 return;
1977 } else {
1978 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
1979 PRINT_D(GENERIC_DBG, "Success Ack - Action frame category: %x Action Subtype: %d Dialog T: %x OR %x\n", buff[ACTION_CAT_ID], buff[ACTION_SUBTYPE_ID],
1980 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001981 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001982 } else {
1983 PRINT_D(GENERIC_DBG, "Fail Ack - Action frame category: %x Action Subtype: %d Dialog T: %x OR %x\n", buff[ACTION_CAT_ID], buff[ACTION_SUBTYPE_ID],
1984 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001985 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001986 }
1987 return;
1988 }
1989 } else {
1990
1991 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
1992
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001993 /*Upper layer is informed that the frame is received on this freq*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001994 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001995
1996 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1997 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
1998
Leo Kim1229b1a2015-10-29 12:05:39 +09001999 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002000 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
2001 return;
2002 }
2003 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
2004
2005 switch (buff[ACTION_SUBTYPE_ID]) {
2006 case GAS_INTIAL_REQ:
2007 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
2008 break;
2009
2010 case GAS_INTIAL_RSP:
2011 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
2012 break;
2013
2014 case PUBLIC_ACT_VENDORSPEC:
2015 /*Now we have a public action vendor specific action frame, check if its a p2p public action frame
2016 * based on the standard its should have the p2p_oui attribute with the following values 50 6f 9A 09*/
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002017 if (!memcmp(u8P2P_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002018 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
2019 if (!bWilc_ie) {
2020 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002021 if (!memcmp(u8P2P_vendorspec, &buff[i], 6)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002022 u8P2Precvrandom = buff[i + 6];
Dean Lee72ed4dc2015-06-12 14:11:44 +09002023 bWilc_ie = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002024 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", u8P2Precvrandom);
2025 break;
2026 }
2027 }
2028 }
2029 }
2030 if (u8P2Plocalrandom > u8P2Precvrandom) {
2031 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2032 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2033 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002034 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(u8P2P_oui, &buff[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002035 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
2036 break;
2037 }
2038 }
2039 }
2040 } else
2041 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2042 }
2043
2044
2045 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (bWilc_ie)) {
2046 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
2047 /* extra attribute for sig_dbm: signal strength in mBm, or 0 if unknown */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002048 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002049 return;
2050 }
2051 break;
2052
2053 default:
2054 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
2055 break;
2056 }
2057 }
2058 }
2059
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002060 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002061 }
2062}
2063
2064/**
2065 * @brief WILC_WFI_mgmt_tx_complete
2066 * @details Returns result of writing mgmt frame to VMM (Tx buffers are freed here)
2067 * @param[in] priv
2068 * transmitting status
2069 * @return None
2070 * @author Amr Abdelmoghny
2071 * @date 20 MAY 2013
2072 * @version 1.0
2073 */
2074static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
2075{
2076 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
2077
2078
2079 kfree(pv_data->buff);
2080 kfree(pv_data);
2081}
2082
2083/**
2084 * @brief WILC_WFI_RemainOnChannelReady
2085 * @details Callback function, called from handle_remain_on_channel on being ready on channel
2086 * @param
2087 * @return none
2088 * @author Amr abdelmoghny
2089 * @date 9 JUNE 2013
2090 * @version
2091 */
2092
2093static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
2094{
Chaehyun Lim27268872015-09-15 14:06:13 +09002095 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002096
Chaehyun Lim27268872015-09-15 14:06:13 +09002097 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002098
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302099 PRINT_D(HOSTINF_DBG, "Remain on channel ready\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002100
Dean Lee72ed4dc2015-06-12 14:11:44 +09002101 priv->bInP2PlistenState = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002102
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002103 cfg80211_ready_on_channel(priv->wdev,
2104 priv->strRemainOnChanParams.u64ListenCookie,
2105 priv->strRemainOnChanParams.pstrListenChan,
2106 priv->strRemainOnChanParams.u32ListenDuration,
2107 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002108}
2109
2110/**
2111 * @brief WILC_WFI_RemainOnChannelExpired
2112 * @details Callback function, called on expiration of remain-on-channel duration
2113 * @param
2114 * @return none
2115 * @author Amr abdelmoghny
2116 * @date 15 MAY 2013
2117 * @version
2118 */
2119
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002120static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002121{
Chaehyun Lim27268872015-09-15 14:06:13 +09002122 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002123
Chaehyun Lim27268872015-09-15 14:06:13 +09002124 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002125
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002126 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302127 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002128
Dean Lee72ed4dc2015-06-12 14:11:44 +09002129 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002130
2131 /*Inform wpas of remain-on-channel expiration*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002132 cfg80211_remain_on_channel_expired(priv->wdev,
2133 priv->strRemainOnChanParams.u64ListenCookie,
2134 priv->strRemainOnChanParams.pstrListenChan,
2135 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002136 } else {
2137 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
2138 , priv->strRemainOnChanParams.u32ListenSessionID);
2139 }
2140}
2141
2142
2143/**
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002144 * @brief remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002145 * @details Request the driver to remain awake on the specified
2146 * channel for the specified duration to complete an off-channel
2147 * operation (e.g., public action frame exchange). When the driver is
2148 * ready on the requested channel, it must indicate this with an event
2149 * notification by calling cfg80211_ready_on_channel().
2150 * @param[in]
2151 * @return int : Return 0 on Success
2152 * @author mdaftedar
2153 * @date 01 MAR 2012
2154 * @version 1.0
2155 */
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002156static int remain_on_channel(struct wiphy *wiphy,
2157 struct wireless_dev *wdev,
2158 struct ieee80211_channel *chan,
2159 unsigned int duration, u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002160{
Leo Kime6e12662015-09-16 18:36:03 +09002161 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002162 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002163
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002164 priv = wiphy_priv(wiphy);
2165
2166 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
2167
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002168
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002169 if (wdev->iftype == NL80211_IFTYPE_AP) {
2170 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
2171 return s32Error;
2172 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002173
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002174 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002175
2176 /*Setting params needed by WILC_WFI_RemainOnChannelExpired()*/
2177 priv->strRemainOnChanParams.pstrListenChan = chan;
2178 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002179 priv->strRemainOnChanParams.u32ListenDuration = duration;
2180 priv->strRemainOnChanParams.u32ListenSessionID++;
2181
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002182 s32Error = wilc_remain_on_channel(priv->hWILCWFIDrv
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002183 , priv->strRemainOnChanParams.u32ListenSessionID
2184 , duration
2185 , chan->hw_value
2186 , WILC_WFI_RemainOnChannelExpired
2187 , WILC_WFI_RemainOnChannelReady
2188 , (void *)priv);
2189
2190 return s32Error;
2191}
2192
2193/**
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002194 * @brief cancel_remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002195 * @details Cancel an on-going remain-on-channel operation.
2196 * This allows the operation to be terminated prior to timeout based on
2197 * the duration value.
2198 * @param[in] struct wiphy *wiphy,
2199 * @param[in] struct net_device *dev
2200 * @param[in] u64 cookie,
2201 * @return int : Return 0 on Success
2202 * @author mdaftedar
2203 * @date 01 MAR 2012
2204 * @version 1.0
2205 */
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002206static int cancel_remain_on_channel(struct wiphy *wiphy,
2207 struct wireless_dev *wdev,
2208 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002209{
Leo Kime6e12662015-09-16 18:36:03 +09002210 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002211 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002212
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002213 priv = wiphy_priv(wiphy);
2214
2215 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
2216
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002217 s32Error = wilc_listen_state_expired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002218 return s32Error;
2219}
2220/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002221 * @brief WILC_WFI_mgmt_tx_frame
2222 * @details
2223 *
2224 * @param[in]
2225 * @return NONE.
2226 * @author mdaftedar
2227 * @date 01 JUL 2012
2228 * @version
2229 */
Chaehyun Limc1560322015-09-22 18:34:51 +09002230static int mgmt_tx(struct wiphy *wiphy,
2231 struct wireless_dev *wdev,
2232 struct cfg80211_mgmt_tx_params *params,
2233 u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002234{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002235 struct ieee80211_channel *chan = params->chan;
2236 unsigned int wait = params->wait;
2237 const u8 *buf = params->buf;
2238 size_t len = params->len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002239 const struct ieee80211_mgmt *mgmt;
2240 struct p2p_mgmt_data *mgmt_tx;
Chaehyun Lim27268872015-09-15 14:06:13 +09002241 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002242 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002243 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002244 perInterface_wlan_t *nic;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002245 u32 buf_len = len + sizeof(u8P2P_vendorspec) + sizeof(u8P2Plocalrandom);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002246
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002247 nic = netdev_priv(wdev->netdev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002248 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002249 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002250
2251 *cookie = (unsigned long)buf;
2252 priv->u64tx_cookie = *cookie;
2253 mgmt = (const struct ieee80211_mgmt *) buf;
2254
2255 if (ieee80211_is_mgmt(mgmt->frame_control)) {
2256
2257 /*mgmt frame allocation*/
Glen Leef3052582015-09-10 12:03:04 +09002258 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002259 if (mgmt_tx == NULL) {
2260 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
Leo Kime6e12662015-09-16 18:36:03 +09002261 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002262 }
Glen Leef3052582015-09-10 12:03:04 +09002263 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002264 if (mgmt_tx->buff == NULL) {
2265 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
Tony Chof638dd32015-09-07 19:09:31 +09002266 kfree(mgmt_tx);
Leo Kime6e12662015-09-16 18:36:03 +09002267 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002268 }
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09002269 memcpy(mgmt_tx->buff, buf, len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002270 mgmt_tx->size = len;
2271
2272
2273 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
2274 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
2275 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002276 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002277 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002278 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002279 } else if (ieee80211_is_action(mgmt->frame_control)) {
Chaehyun Limd85f5322015-06-11 14:35:54 +09002280 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002281
2282
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002283 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002284 /*Only set the channel, if not a negotiation confirmation frame
2285 * (If Negotiation confirmation frame, force it
2286 * to be transmitted on the same negotiation channel)*/
2287
2288 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
2289 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
2290 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002291 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002292 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002293 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002294 }
2295 switch (buf[ACTION_SUBTYPE_ID]) {
2296 case GAS_INTIAL_REQ:
2297 {
2298 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
2299 break;
2300 }
2301
2302 case GAS_INTIAL_RSP:
2303 {
2304 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
2305 break;
2306 }
2307
2308 case PUBLIC_ACT_VENDORSPEC:
2309 {
2310 /*Now we have a public action vendor specific action frame, check if its a p2p public action frame
2311 * based on the standard its should have the p2p_oui attribute with the following values 50 6f 9A 09*/
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002312 if (!memcmp(u8P2P_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002313 /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/
2314 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
2315 if (u8P2Plocalrandom == 1 && u8P2Precvrandom < u8P2Plocalrandom) {
2316 get_random_bytes(&u8P2Plocalrandom, 1);
2317 /*Increment the number to prevent if its 0*/
2318 u8P2Plocalrandom++;
2319 }
2320 }
2321
2322 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2323 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2324 if (u8P2Plocalrandom > u8P2Precvrandom) {
2325 PRINT_D(GENERIC_DBG, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2326
2327 /*Search for the p2p information information element , after the Public action subtype theres a byte for teh dialog token, skip that*/
2328 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002329 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(u8P2P_oui, &buf[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002330 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
Dean Lee72ed4dc2015-06-12 14:11:44 +09002331 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002332
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002333 /*If using supplicant go intent, no need at all*/
2334 /*to parse transmitted negotiation frames*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002335 else
Dean Lee72ed4dc2015-06-12 14:11:44 +09002336 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002337 break;
2338 }
2339 }
2340
2341 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
Shivani Bhardwajd8060fc2015-10-29 00:30:01 +05302342 /*
2343 * Adding WILC information element to allow two WILC devices to
2344 * identify each other and connect
2345 */
2346 memcpy(&mgmt_tx->buff[len], u8P2P_vendorspec, sizeof(u8P2P_vendorspec));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002347 mgmt_tx->buff[len + sizeof(u8P2P_vendorspec)] = u8P2Plocalrandom;
2348 mgmt_tx->size = buf_len;
2349 }
2350 } else
2351 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2352 }
2353
2354 } else {
2355 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
2356 }
2357
2358 break;
2359 }
2360
2361 default:
2362 {
2363 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
2364 break;
2365 }
2366 }
2367
2368 }
2369
2370 PRINT_D(GENERIC_DBG, "TX: ACTION FRAME Type:%x : Chan:%d\n", buf[ACTION_SUBTYPE_ID], chan->hw_value);
Leo Kim1229b1a2015-10-29 12:05:39 +09002371 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002372
Leo Kim1229b1a2015-10-29 12:05:39 +09002373 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n",
2374 jiffies, pstrWFIDrv->p2p_timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002375 }
2376
Glen Lee829c4772015-10-29 12:18:44 +09002377 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
2378 mgmt_tx->buff, mgmt_tx->size,
Glen Leec9d48342015-10-01 16:03:43 +09002379 WILC_WFI_mgmt_tx_complete);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002380 } else {
2381 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
2382 }
Leo Kimaaed3292015-10-12 16:55:38 +09002383 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002384}
2385
Chaehyun Lim85c587a2015-09-22 18:34:50 +09002386static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
2387 struct wireless_dev *wdev,
2388 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002389{
Chaehyun Lim27268872015-09-15 14:06:13 +09002390 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002391 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002392
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002393 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002394 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002395
2396
2397 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
Leo Kim1229b1a2015-10-29 12:05:39 +09002398 pstrWFIDrv->p2p_timeout = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002399
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +01002400 if (!priv->bInP2PlistenState) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002401 cfg80211_remain_on_channel_expired(priv->wdev,
2402 priv->strRemainOnChanParams.u64ListenCookie,
2403 priv->strRemainOnChanParams.pstrListenChan,
2404 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002405 }
2406
2407 return 0;
2408}
2409
2410/**
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002411 * @brief wilc_mgmt_frame_register
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002412 * @details Notify driver that a management frame type was
2413 * registered. Note that this callback may not sleep, and cannot run
2414 * concurrently with itself.
2415 * @param[in]
2416 * @return NONE.
2417 * @author mdaftedar
2418 * @date 01 JUL 2012
2419 * @version
2420 */
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002421void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
2422 u16 frame_type, bool reg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002423{
2424
Chaehyun Lim27268872015-09-15 14:06:13 +09002425 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002426 perInterface_wlan_t *nic;
Glen Lee1b869352015-10-20 17:14:01 +09002427 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002428
2429 priv = wiphy_priv(wiphy);
2430 nic = netdev_priv(priv->wdev->netdev);
Glen Lee1b869352015-10-20 17:14:01 +09002431 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002432
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002433 if (!frame_type)
2434 return;
2435
2436 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
2437 switch (frame_type) {
2438 case PROBE_REQ:
2439 {
2440 nic->g_struct_frame_reg[0].frame_type = frame_type;
2441 nic->g_struct_frame_reg[0].reg = reg;
2442 }
2443 break;
2444
2445 case ACTION:
2446 {
2447 nic->g_struct_frame_reg[1].frame_type = frame_type;
2448 nic->g_struct_frame_reg[1].reg = reg;
2449 }
2450 break;
2451
2452 default:
2453 {
2454 break;
2455 }
2456
2457 }
2458 /*If mac is closed, then return*/
Glen Lee1b869352015-10-20 17:14:01 +09002459 if (!wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002460 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
2461 return;
2462 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002463 wilc_frame_register(priv->hWILCWFIDrv, frame_type, reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002464
2465
2466}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002467
2468/**
Chaehyun Lima8047e22015-09-22 18:34:48 +09002469 * @brief set_cqm_rssi_config
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002470 * @details Configure connection quality monitor RSSI threshold.
2471 * @param[in] struct wiphy *wiphy:
2472 * @param[in] struct net_device *dev:
2473 * @param[in] s32 rssi_thold:
2474 * @param[in] u32 rssi_hyst:
2475 * @return int : Return 0 on Success
2476 * @author mdaftedar
2477 * @date 01 MAR 2012
2478 * @version 1.0
2479 */
Chaehyun Lima8047e22015-09-22 18:34:48 +09002480static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
2481 s32 rssi_thold, u32 rssi_hyst)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002482{
2483 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2484 return 0;
2485
2486}
2487/**
Chaehyun Limbdb63382015-09-14 12:24:19 +09002488 * @brief dump_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002489 * @details Configure connection quality monitor RSSI threshold.
2490 * @param[in] struct wiphy *wiphy:
2491 * @param[in] struct net_device *dev
2492 * @param[in] int idx
2493 * @param[in] u8 *mac
2494 * @param[in] struct station_info *sinfo
2495 * @return int : Return 0 on Success
2496 * @author mdaftedar
2497 * @date 01 MAR 2012
2498 * @version 1.0
2499 */
Chaehyun Limbdb63382015-09-14 12:24:19 +09002500static int dump_station(struct wiphy *wiphy, struct net_device *dev,
2501 int idx, u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002502{
Chaehyun Lim27268872015-09-15 14:06:13 +09002503 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002504
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002505 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2506
2507 if (idx != 0)
2508 return -ENOENT;
2509
2510 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002511
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002512 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002513
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002514 wilc_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002515
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002516 return 0;
2517
2518}
2519
2520
2521/**
Chaehyun Lim46530672015-09-22 18:34:46 +09002522 * @brief set_power_mgmt
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002523 * @details
2524 * @param[in]
2525 * @return int : Return 0 on Success.
2526 * @author mdaftedar
2527 * @date 01 JUL 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09002528 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002529 */
Chaehyun Lim46530672015-09-22 18:34:46 +09002530static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2531 bool enabled, int timeout)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002532{
Chaehyun Lim27268872015-09-15 14:06:13 +09002533 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002534
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002535 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2536
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002537 if (wiphy == NULL)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002538 return -ENOENT;
2539
2540 priv = wiphy_priv(wiphy);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002541 if (priv->hWILCWFIDrv == NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002542 PRINT_ER("Driver is NULL\n");
2543 return -EIO;
2544 }
2545
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002546 if (wilc_enable_ps)
2547 wilc_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002548
2549
Leo Kime6e12662015-09-16 18:36:03 +09002550 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002551
2552}
Glen Lee108b3432015-09-16 18:53:20 +09002553
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002554/**
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002555 * @brief change_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002556 * @details Change type/configuration of virtual interface,
2557 * keep the struct wireless_dev's iftype updated.
2558 * @param[in] NONE
2559 * @return int : Return 0 on Success.
2560 * @author mdaftedar
2561 * @date 01 MAR 2012
2562 * @version 1.0
2563 */
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002564static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2565 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002566{
Chaehyun Lim27268872015-09-15 14:06:13 +09002567 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002568 perInterface_wlan_t *nic;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002569 u8 interface_type;
Chaehyun Limd85f5322015-06-11 14:35:54 +09002570 u16 TID = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002571 u8 i;
Glen Lee299382c2015-10-20 17:13:56 +09002572 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002573
2574 nic = netdev_priv(dev);
2575 priv = wiphy_priv(wiphy);
Glen Lee299382c2015-10-20 17:13:56 +09002576 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002577
2578 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2579 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
2580 u8P2Plocalrandom = 0x01;
2581 u8P2Precvrandom = 0x00;
2582
Dean Lee72ed4dc2015-06-12 14:11:44 +09002583 bWilc_ie = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002584
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002585 wilc_optaining_ip = false;
2586 del_timer(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002587 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002588 /*Set WILC_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/
2589 if (g_ptk_keys_saved && g_gtk_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002590 wilc_set_machw_change_vir_if(dev, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002591 }
2592
2593 switch (type) {
2594 case NL80211_IFTYPE_STATION:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002595 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002596 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002597
2598 /* send delba over wlan interface */
2599
2600
2601 dev->ieee80211_ptr->iftype = type;
2602 priv->wdev->iftype = type;
2603 nic->monitor_flag = 0;
2604 nic->iftype = STATION_MODE;
2605
2606 /*Remove the enteries of the previously connected clients*/
2607 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002608 interface_type = nic->iftype;
2609 nic->iftype = STATION_MODE;
2610
Glen Lee299382c2015-10-20 17:13:56 +09002611 if (wl->initialized) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002612 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2613 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002614 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002615 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002616
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002617 /*Eliminate host interface blocking state*/
Glen Lee299382c2015-10-20 17:13:56 +09002618 up(&wl->cfg_event);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002619
Glen Lee53dc0cf2015-10-20 17:13:57 +09002620 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002621 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002622 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002623 nic->iftype = interface_type;
2624
2625 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002626 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2627 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002628 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002629 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002630
2631 /*Add saved WEP keys, if any*/
2632 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002633 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002634 g_key_wep_params.key_idx);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002635 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002636 g_key_wep_params.key,
2637 g_key_wep_params.key_len,
2638 g_key_wep_params.key_idx);
2639 }
2640
2641 /*No matter the driver handler passed here, it will be overwriiten*/
2642 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002643 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002644
2645 /*Add saved PTK and GTK keys, if any*/
2646 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2647 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2648 g_key_ptk_params.key[1],
2649 g_key_ptk_params.key[2]);
2650 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2651 g_key_gtk_params.key[1],
2652 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002653 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2654 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002655 g_add_ptk_key_params.key_idx,
2656 g_add_ptk_key_params.pairwise,
2657 g_add_ptk_key_params.mac_addr,
2658 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002659
Glen Lee299382c2015-10-20 17:13:56 +09002660 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2661 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002662 g_add_gtk_key_params.key_idx,
2663 g_add_gtk_key_params.pairwise,
2664 g_add_gtk_key_params.mac_addr,
2665 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002666 }
2667
Glen Lee299382c2015-10-20 17:13:56 +09002668 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002669 for (i = 0; i < num_reg_frame; i++) {
2670 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2671 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002672 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002673 nic->g_struct_frame_reg[i].frame_type,
2674 nic->g_struct_frame_reg[i].reg);
2675 }
2676 }
2677
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002678 wilc_enable_ps = true;
2679 wilc_set_power_mgmt(priv->hWILCWFIDrv, 1, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002680 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002681 break;
2682
2683 case NL80211_IFTYPE_P2P_CLIENT:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002684 wilc_enable_ps = false;
2685 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
2686 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002687 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002688
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002689 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2690 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002691
2692 dev->ieee80211_ptr->iftype = type;
2693 priv->wdev->iftype = type;
2694 nic->monitor_flag = 0;
2695
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002696 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2697 nic->iftype = CLIENT_MODE;
2698
2699
Glen Lee299382c2015-10-20 17:13:56 +09002700 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002701 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002702 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002703
Glen Lee53dc0cf2015-10-20 17:13:57 +09002704 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002705 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002706 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002707
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002708 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2709 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002710 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002711 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002712
2713 /*Add saved WEP keys, if any*/
2714 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002715 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2716 g_key_wep_params.key_idx);
2717 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
2718 g_key_wep_params.key,
2719 g_key_wep_params.key_len,
2720 g_key_wep_params.key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002721 }
2722
2723 /*No matter the driver handler passed here, it will be overwriiten*/
2724 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002725 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002726
2727 /*Add saved PTK and GTK keys, if any*/
2728 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2729 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2730 g_key_ptk_params.key[1],
2731 g_key_ptk_params.key[2]);
2732 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2733 g_key_gtk_params.key[1],
2734 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002735 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2736 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002737 g_add_ptk_key_params.key_idx,
2738 g_add_ptk_key_params.pairwise,
2739 g_add_ptk_key_params.mac_addr,
2740 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002741
Glen Lee299382c2015-10-20 17:13:56 +09002742 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2743 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002744 g_add_gtk_key_params.key_idx,
2745 g_add_gtk_key_params.pairwise,
2746 g_add_gtk_key_params.mac_addr,
2747 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002748 }
2749
2750 /*Refresh scan, to refresh the scan results to the wpa_supplicant. Set MachHw to false to enable further key installments*/
Dean Lee72ed4dc2015-06-12 14:11:44 +09002751 refresh_scan(priv, 1, true);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002752 wilc_set_machw_change_vir_if(dev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002753
Glen Lee299382c2015-10-20 17:13:56 +09002754 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002755 for (i = 0; i < num_reg_frame; i++) {
2756 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2757 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002758 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002759 nic->g_struct_frame_reg[i].frame_type,
2760 nic->g_struct_frame_reg[i].reg);
2761 }
2762 }
2763 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002764 break;
2765
2766 case NL80211_IFTYPE_AP:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002767 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002768 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002769 dev->ieee80211_ptr->iftype = type;
2770 priv->wdev->iftype = type;
2771 nic->iftype = AP_MODE;
Johnny Kim8a143302015-06-10 17:06:46 +09002772 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002773
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002774 PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002775 wilc_wlan_get_firmware(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002776 /*If wilc is running, then close-open to actually get new firmware running (serves P2P)*/
Glen Lee299382c2015-10-20 17:13:56 +09002777 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002778 nic->iftype = AP_MODE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002779 wilc_mac_close(dev);
2780 wilc_mac_open(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002781
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002782 for (i = 0; i < num_reg_frame; i++) {
2783 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2784 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002785 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002786 nic->g_struct_frame_reg[i].frame_type,
2787 nic->g_struct_frame_reg[i].reg);
2788 }
2789 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002790 break;
2791
2792 case NL80211_IFTYPE_P2P_GO:
2793 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
2794
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002795 wilc_optaining_ip = true;
2796 mod_timer(&wilc_during_ip_timer, jiffies + msecs_to_jiffies(duringIP_TIME));
2797 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002798 /*Delete block ack has to be the latest config packet*/
2799 /*sent before downloading new FW. This is because it blocks on*/
2800 /*hWaitResponse semaphore, which allows previous config*/
2801 /*packets to actually take action on old FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002802 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2803 wl->vif[0].bssid, TID);
2804 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002805 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002806 dev->ieee80211_ptr->iftype = type;
2807 priv->wdev->iftype = type;
2808
Johnny Kim8a143302015-06-10 17:06:46 +09002809 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002810
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002811 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2812
2813
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002814 nic->iftype = GO_MODE;
2815
2816 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002817 wilc_wait_msg_queue_idle();
Glen Lee53dc0cf2015-10-20 17:13:57 +09002818 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002819 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002820 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002821
2822
2823 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002824 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2825 wilc_set_mac_address(wl->vif[0].hif_drv,
2826 wl->vif[0].src_addr);
2827 wilc_set_operation_mode(priv->hWILCWFIDrv, AP_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002828
2829 /*Add saved WEP keys, if any*/
2830 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002831 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2832 g_key_wep_params.key_idx);
2833 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002834 g_key_wep_params.key,
2835 g_key_wep_params.key_len,
2836 g_key_wep_params.key_idx);
2837 }
2838
2839 /*No matter the driver handler passed here, it will be overwriiten*/
2840 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002841 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002842
2843 /*Add saved PTK and GTK keys, if any*/
2844 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2845 PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0],
2846 g_key_ptk_params.key[1],
2847 g_key_ptk_params.key[2],
2848 g_key_ptk_params.cipher);
2849 PRINT_D(CFG80211_DBG, "gtk %x %x %x cipher %x\n", g_key_gtk_params.key[0],
2850 g_key_gtk_params.key[1],
2851 g_key_gtk_params.key[2],
2852 g_key_gtk_params.cipher);
Glen Lee299382c2015-10-20 17:13:56 +09002853 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2854 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002855 g_add_ptk_key_params.key_idx,
2856 g_add_ptk_key_params.pairwise,
2857 g_add_ptk_key_params.mac_addr,
2858 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002859
Glen Lee299382c2015-10-20 17:13:56 +09002860 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2861 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002862 g_add_gtk_key_params.key_idx,
2863 g_add_gtk_key_params.pairwise,
2864 g_add_gtk_key_params.mac_addr,
2865 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002866 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002867
Glen Lee299382c2015-10-20 17:13:56 +09002868 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002869 for (i = 0; i < num_reg_frame; i++) {
2870 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2871 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002872 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002873 nic->g_struct_frame_reg[i].frame_type,
2874 nic->g_struct_frame_reg[i].reg);
2875 }
2876 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002877 break;
2878
2879 default:
2880 PRINT_ER("Unknown interface type= %d\n", type);
Leo Kimaaed3292015-10-12 16:55:38 +09002881 return -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002882 }
2883
Leo Kimaaed3292015-10-12 16:55:38 +09002884 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002885}
2886
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002887/* (austin.2013-07-23)
2888 *
2889 * To support revised cfg80211_ops
2890 *
2891 * add_beacon --> start_ap
2892 * set_beacon --> change_beacon
2893 * del_beacon --> stop_ap
2894 *
2895 * beacon_parameters --> cfg80211_ap_settings
2896 * cfg80211_beacon_data
2897 *
2898 * applicable for linux kernel 3.4+
2899 */
2900
2901/**
Chaehyun Lima13168d2015-09-14 12:24:12 +09002902 * @brief start_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002903 * @details Add a beacon with given parameters, @head, @interval
2904 * and @dtim_period will be valid, @tail is optional.
2905 * @param[in] wiphy
2906 * @param[in] dev The net device structure
2907 * @param[in] settings cfg80211_ap_settings parameters for the beacon to be added
2908 * @return int : Return 0 on Success.
2909 * @author austin
2910 * @date 23 JUL 2013
2911 * @version 1.0
2912 */
Chaehyun Lima13168d2015-09-14 12:24:12 +09002913static int start_ap(struct wiphy *wiphy, struct net_device *dev,
2914 struct cfg80211_ap_settings *settings)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002915{
2916 struct cfg80211_beacon_data *beacon = &(settings->beacon);
Chaehyun Lim27268872015-09-15 14:06:13 +09002917 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002918 s32 s32Error = 0;
Glen Lee684dc182015-10-20 17:14:02 +09002919 struct wilc *wl;
2920 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002921
2922 priv = wiphy_priv(wiphy);
Glen Lee684dc182015-10-20 17:14:02 +09002923 nic = netdev_priv(dev);
2924 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002925 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
2926
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302927 PRINT_D(HOSTAPD_DBG, "Interval = %d\n DTIM period = %d\n Head length = %zu Tail length = %zu\n",
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002928 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
2929
Chaehyun Lim80785a92015-09-14 12:24:01 +09002930 s32Error = set_channel(wiphy, &settings->chandef);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002931
Leo Kime6e12662015-09-16 18:36:03 +09002932 if (s32Error != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002933 PRINT_ER("Error in setting channel\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002934
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002935 wilc_wlan_set_bssid(dev, wl->vif[0].src_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002936
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002937 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002938 settings->beacon_interval,
2939 settings->dtim_period,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002940 beacon->head_len, (u8 *)beacon->head,
2941 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002942
2943 return s32Error;
2944}
2945
2946/**
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002947 * @brief change_beacon
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002948 * @details Add a beacon with given parameters, @head, @interval
2949 * and @dtim_period will be valid, @tail is optional.
2950 * @param[in] wiphy
2951 * @param[in] dev The net device structure
2952 * @param[in] beacon cfg80211_beacon_data for the beacon to be changed
2953 * @return int : Return 0 on Success.
2954 * @author austin
2955 * @date 23 JUL 2013
2956 * @version 1.0
2957 */
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002958static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
2959 struct cfg80211_beacon_data *beacon)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002960{
Chaehyun Lim27268872015-09-15 14:06:13 +09002961 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002962 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002963
2964 priv = wiphy_priv(wiphy);
2965 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
2966
2967
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002968 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002969 0,
2970 0,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002971 beacon->head_len, (u8 *)beacon->head,
2972 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002973
2974 return s32Error;
2975}
2976
2977/**
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002978 * @brief stop_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002979 * @details Remove beacon configuration and stop sending the beacon.
2980 * @param[in]
2981 * @return int : Return 0 on Success.
2982 * @author austin
2983 * @date 23 JUL 2013
2984 * @version 1.0
2985 */
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002986static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002987{
Leo Kime6e12662015-09-16 18:36:03 +09002988 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002989 struct wilc_priv *priv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002990 u8 NullBssid[ETH_ALEN] = {0};
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002991
Leo Kim7ae43362015-09-16 18:35:59 +09002992 if (!wiphy)
2993 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002994
2995 priv = wiphy_priv(wiphy);
2996
2997 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
2998
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002999 wilc_wlan_set_bssid(dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003000
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003001 s32Error = wilc_del_beacon(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003002
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003003 if (s32Error)
3004 PRINT_ER("Host delete beacon fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003005
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003006 return s32Error;
3007}
3008
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003009/**
Chaehyun Limed269552015-09-14 12:24:15 +09003010 * @brief add_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003011 * @details Add a new station.
3012 * @param[in]
3013 * @return int : Return 0 on Success.
3014 * @author mdaftedar
3015 * @date 01 MAR 2012
3016 * @version 1.0
3017 */
Chaehyun Limed269552015-09-14 12:24:15 +09003018static int add_station(struct wiphy *wiphy, struct net_device *dev,
3019 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003020{
Leo Kime6e12662015-09-16 18:36:03 +09003021 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003022 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09003023 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003024 perInterface_wlan_t *nic;
3025
Leo Kim7ae43362015-09-16 18:35:59 +09003026 if (!wiphy)
3027 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003028
3029 priv = wiphy_priv(wiphy);
3030 nic = netdev_priv(dev);
3031
3032 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003033 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09003034 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003035 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003036 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003037 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003038
3039 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
3040
3041 PRINT_D(CFG80211_DBG, "BSSID = %x%x%x%x%x%x\n", priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][0], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][1], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][2], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][3], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][4],
3042 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003043 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003044 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3045 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003046
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003047 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003048 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003049 } else {
Leo Kim22520122015-10-29 12:05:45 +09003050 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003051 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003052 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003053 memcpy(strStaParams.ht_supp_mcs_set,
3054 &params->ht_capa->mcs,
3055 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003056 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003057 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003058 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003059 }
3060
Leo Kimf676e172015-10-29 12:05:52 +09003061 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003062 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003063
Leo Kim22520122015-10-29 12:05:45 +09003064 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3065 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003066 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3067 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003068 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3069 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003070 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3071 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003072 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3073 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003074 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3075 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003076 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3077 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003078 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3079 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003080
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003081 s32Error = wilc_add_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003082 if (s32Error)
3083 PRINT_ER("Host add station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003084 }
3085
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003086 return s32Error;
3087}
3088
3089/**
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003090 * @brief del_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003091 * @details Remove a station; @mac may be NULL to remove all stations.
3092 * @param[in]
3093 * @return int : Return 0 on Success.
3094 * @author mdaftedar
3095 * @date 01 MAR 2012
3096 * @version 1.0
3097 */
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003098static int del_station(struct wiphy *wiphy, struct net_device *dev,
3099 struct station_del_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003100{
Arnd Bergmann057d1e92015-06-01 21:06:44 +02003101 const u8 *mac = params->mac;
Leo Kime6e12662015-09-16 18:36:03 +09003102 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003103 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003104 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003105
Leo Kim7ae43362015-09-16 18:35:59 +09003106 if (!wiphy)
3107 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003108
3109 priv = wiphy_priv(wiphy);
3110 nic = netdev_priv(dev);
3111
3112 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
3113 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
3114
3115
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003116 if (mac == NULL) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05303117 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003118 s32Error = wilc_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003119 } else {
3120 PRINT_D(HOSTAPD_DBG, "With mac address: %x%x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
3121 }
3122
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003123 s32Error = wilc_del_station(priv->hWILCWFIDrv, mac);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003124
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003125 if (s32Error)
3126 PRINT_ER("Host delete station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003127 }
3128 return s32Error;
3129}
3130
3131/**
Chaehyun Lim14b42082015-09-14 12:24:17 +09003132 * @brief change_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003133 * @details Modify a given station.
3134 * @param[in]
3135 * @return int : Return 0 on Success.
3136 * @author mdaftedar
3137 * @date 01 MAR 2012
3138 * @version 1.0
3139 */
Chaehyun Lim14b42082015-09-14 12:24:17 +09003140static int change_station(struct wiphy *wiphy, struct net_device *dev,
3141 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003142{
Leo Kime6e12662015-09-16 18:36:03 +09003143 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003144 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09003145 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003146 perInterface_wlan_t *nic;
3147
3148
3149 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
3150
Leo Kim7ae43362015-09-16 18:35:59 +09003151 if (!wiphy)
3152 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003153
3154 priv = wiphy_priv(wiphy);
3155 nic = netdev_priv(dev);
3156
3157 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003158 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003159 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003160 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003161 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003162
Leo Kim2353c382015-10-29 12:05:41 +09003163 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n",
3164 strStaParams.bssid[0], strStaParams.bssid[1],
3165 strStaParams.bssid[2], strStaParams.bssid[3],
3166 strStaParams.bssid[4], strStaParams.bssid[5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003167 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003168 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3169 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003170
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003171 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003172 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003173 } else {
Leo Kim22520122015-10-29 12:05:45 +09003174 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003175 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003176 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003177 memcpy(strStaParams.ht_supp_mcs_set,
3178 &params->ht_capa->mcs,
3179 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003180 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003181 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003182 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003183 }
3184
Leo Kimf676e172015-10-29 12:05:52 +09003185 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003186 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003187
Leo Kim22520122015-10-29 12:05:45 +09003188 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3189 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003190 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3191 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003192 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3193 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003194 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3195 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003196 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3197 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003198 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3199 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003200 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3201 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003202 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3203 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003204
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003205 s32Error = wilc_edit_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003206 if (s32Error)
3207 PRINT_ER("Host edit station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003208 }
3209 return s32Error;
3210}
3211
3212
3213/**
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003214 * @brief add_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003215 * @details
3216 * @param[in]
3217 * @return int : Return 0 on Success.
3218 * @author mdaftedar
3219 * @date 01 JUL 2012
3220 * @version 1.0
3221 */
Chaehyun Lim37316e82015-09-22 18:34:52 +09003222static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
3223 const char *name,
3224 unsigned char name_assign_type,
3225 enum nl80211_iftype type,
3226 u32 *flags,
3227 struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003228{
3229 perInterface_wlan_t *nic;
Chaehyun Lim27268872015-09-15 14:06:13 +09003230 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003231 struct net_device *new_ifc = NULL;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003232
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003233 priv = wiphy_priv(wiphy);
3234
3235
3236
3237 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
3238
3239 nic = netdev_priv(priv->wdev->netdev);
3240
3241
3242 if (type == NL80211_IFTYPE_MONITOR) {
3243 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
3244 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", nic->wilc_netdev);
3245 new_ifc = WILC_WFI_init_mon_interface(name, nic->wilc_netdev);
3246 if (new_ifc != NULL) {
3247 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003248 nic = netdev_priv(priv->wdev->netdev);
3249 nic->monitor_flag = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003250 } else
3251 PRINT_ER("Error in initializing monitor interface\n ");
3252 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003253 return priv->wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003254}
3255
3256/**
Chaehyun Limb4a73352015-09-14 12:24:10 +09003257 * @brief del_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003258 * @details
3259 * @param[in]
3260 * @return int : Return 0 on Success.
3261 * @author mdaftedar
3262 * @date 01 JUL 2012
3263 * @version 1.0
3264 */
Chaehyun Lim956d7212015-09-22 18:34:49 +09003265static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003266{
3267 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
Leo Kime6e12662015-09-16 18:36:03 +09003268 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003269}
3270
Chaehyun Lim08241922015-09-15 14:06:12 +09003271static struct cfg80211_ops wilc_cfg80211_ops = {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003272
Chaehyun Lim80785a92015-09-14 12:24:01 +09003273 .set_monitor_channel = set_channel,
Chaehyun Lim0e30d062015-09-14 12:24:02 +09003274 .scan = scan,
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +09003275 .connect = connect,
Chaehyun Limb027cde2015-09-14 12:24:04 +09003276 .disconnect = disconnect,
Chaehyun Lim953d4172015-09-14 12:24:05 +09003277 .add_key = add_key,
Chaehyun Lim3044ba72015-09-14 12:24:06 +09003278 .del_key = del_key,
Chaehyun Limf4893df2015-09-14 12:24:07 +09003279 .get_key = get_key,
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09003280 .set_default_key = set_default_key,
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003281 .add_virtual_intf = add_virtual_intf,
Chaehyun Limb4a73352015-09-14 12:24:10 +09003282 .del_virtual_intf = del_virtual_intf,
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09003283 .change_virtual_intf = change_virtual_intf,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003284
Chaehyun Lima13168d2015-09-14 12:24:12 +09003285 .start_ap = start_ap,
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09003286 .change_beacon = change_beacon,
Chaehyun Limc8cddd72015-09-14 12:24:14 +09003287 .stop_ap = stop_ap,
Chaehyun Limed269552015-09-14 12:24:15 +09003288 .add_station = add_station,
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003289 .del_station = del_station,
Chaehyun Lim14b42082015-09-14 12:24:17 +09003290 .change_station = change_station,
Chaehyun Limf06f5622015-09-14 12:24:18 +09003291 .get_station = get_station,
Chaehyun Limbdb63382015-09-14 12:24:19 +09003292 .dump_station = dump_station,
Chaehyun Lima5f7db62015-09-14 12:24:20 +09003293 .change_bss = change_bss,
Chaehyun Lima76b63e2015-09-14 12:24:21 +09003294 .set_wiphy_params = set_wiphy_params,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003295
Chaehyun Lim4d466572015-09-14 12:24:22 +09003296 .set_pmksa = set_pmksa,
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09003297 .del_pmksa = del_pmksa,
Chaehyun Limb33c39b2015-09-14 12:24:24 +09003298 .flush_pmksa = flush_pmksa,
Chaehyun Lim6d19d692015-09-14 12:24:25 +09003299 .remain_on_channel = remain_on_channel,
Chaehyun Lim1dd54402015-09-14 12:24:26 +09003300 .cancel_remain_on_channel = cancel_remain_on_channel,
Chaehyun Lim4a2f9b32015-09-14 12:24:27 +09003301 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
Chaehyun Lim12a26a32015-09-14 12:24:28 +09003302 .mgmt_tx = mgmt_tx,
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09003303 .mgmt_frame_register = wilc_mgmt_frame_register,
Chaehyun Lim46530672015-09-22 18:34:46 +09003304 .set_power_mgmt = set_power_mgmt,
Chaehyun Lima8047e22015-09-22 18:34:48 +09003305 .set_cqm_rssi_config = set_cqm_rssi_config,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003306
3307};
3308
3309
3310
3311
3312
3313/**
3314 * @brief WILC_WFI_update_stats
3315 * @details Modify parameters for a given BSS.
3316 * @param[in]
3317 * @return int : Return 0 on Success.
3318 * @author mdaftedar
3319 * @date 01 MAR 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09003320 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003321 */
3322int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
3323{
3324
Chaehyun Lim27268872015-09-15 14:06:13 +09003325 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003326
3327 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003328 switch (changed) {
3329
3330 case WILC_WFI_RX_PKT:
3331 {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003332 priv->netstats.rx_packets++;
3333 priv->netstats.rx_bytes += pktlen;
3334 priv->netstats.rx_time = get_jiffies_64();
3335 }
3336 break;
3337
3338 case WILC_WFI_TX_PKT:
3339 {
3340 priv->netstats.tx_packets++;
3341 priv->netstats.tx_bytes += pktlen;
3342 priv->netstats.tx_time = get_jiffies_64();
3343
3344 }
3345 break;
3346
3347 default:
3348 break;
3349 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003350 return 0;
3351}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003352
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003353/**
3354 * @brief WILC_WFI_CfgAlloc
3355 * @details Allocation of the wireless device structure and assigning it
3356 * to the cfg80211 operations structure.
3357 * @param[in] NONE
3358 * @return wireless_dev : Returns pointer to wireless_dev structure.
3359 * @author mdaftedar
3360 * @date 01 MAR 2012
3361 * @version 1.0
3362 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01003363static struct wireless_dev *WILC_WFI_CfgAlloc(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003364{
3365
3366 struct wireless_dev *wdev;
3367
3368
3369 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
3370 /*Allocating the wireless device structure*/
3371 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
3372 if (!wdev) {
3373 PRINT_ER("Cannot allocate wireless device\n");
3374 goto _fail_;
3375 }
3376
3377 /*Creating a new wiphy, linking wireless structure with the wiphy structure*/
Chaehyun Lim27268872015-09-15 14:06:13 +09003378 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003379 if (!wdev->wiphy) {
3380 PRINT_ER("Cannot allocate wiphy\n");
3381 goto _fail_mem_;
3382
3383 }
3384
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003385 /* enable 802.11n HT */
3386 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
3387 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
3388 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3389 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
3390 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003391
3392 /*wiphy bands*/
3393 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
3394
3395 return wdev;
3396
3397_fail_mem_:
3398 kfree(wdev);
3399_fail_:
3400 return NULL;
3401
3402}
3403/**
Chaehyun Lim8459fd52015-09-20 15:51:09 +09003404 * @brief wilc_create_wiphy
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003405 * @details Registering of the wiphy structure and interface modes
3406 * @param[in] NONE
3407 * @return NONE
3408 * @author mdaftedar
3409 * @date 01 MAR 2012
3410 * @version 1.0
3411 */
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01003412struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003413{
Chaehyun Lim27268872015-09-15 14:06:13 +09003414 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003415 struct wireless_dev *wdev;
Leo Kime6e12662015-09-16 18:36:03 +09003416 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003417
3418 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
3419
3420 wdev = WILC_WFI_CfgAlloc();
3421 if (wdev == NULL) {
3422 PRINT_ER("CfgAlloc Failed\n");
3423 return NULL;
3424 }
3425
3426
3427 /*Return hardware description structure (wiphy)'s priv*/
3428 priv = wdev_priv(wdev);
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003429 sema_init(&(priv->SemHandleUpdateStats), 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003430
3431 /*Link the wiphy with wireless structure*/
3432 priv->wdev = wdev;
3433
3434 /*Maximum number of probed ssid to be added by user for the scan request*/
3435 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003436 /*Maximum number of pmkids to be cashed*/
3437 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
3438 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003439
3440 wdev->wiphy->max_scan_ie_len = 1000;
3441
3442 /*signal strength in mBm (100*dBm) */
3443 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3444
3445 /*Set the availaible cipher suites*/
3446 wdev->wiphy->cipher_suites = cipher_suites;
3447 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003448 /*Setting default managment types: for register action frame: */
3449 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003450
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003451 wdev->wiphy->max_remain_on_channel_duration = 500;
3452 /*Setting the wiphy interfcae mode and type before registering the wiphy*/
3453 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
3454 BIT(NL80211_IFTYPE_P2P_CLIENT);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003455 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003456 wdev->iftype = NL80211_IFTYPE_STATION;
3457
3458
3459
3460 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
3461 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
3462 wdev->wiphy->interface_modes, wdev->iftype);
3463
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01003464 set_wiphy_dev(wdev->wiphy, dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003465
3466 /*Register wiphy structure*/
3467 s32Error = wiphy_register(wdev->wiphy);
3468 if (s32Error) {
3469 PRINT_ER("Cannot register wiphy device\n");
3470 /*should define what action to be taken in such failure*/
3471 } else {
3472 PRINT_D(CFG80211_DBG, "Successful Registering\n");
3473 }
3474
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003475 priv->dev = net;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003476 return wdev;
3477
3478
3479}
3480/**
3481 * @brief WILC_WFI_WiphyFree
3482 * @details Freeing allocation of the wireless device structure
3483 * @param[in] NONE
3484 * @return NONE
3485 * @author mdaftedar
3486 * @date 01 MAR 2012
3487 * @version 1.0
3488 */
Chaehyun Limdd4b6a82015-09-20 15:51:25 +09003489int wilc_init_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003490{
3491
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003492 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003493
Chaehyun Lim27268872015-09-15 14:06:13 +09003494 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003495
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003496 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
3497 priv = wdev_priv(net->ieee80211_ptr);
3498 if (op_ifcs == 0) {
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -07003499 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003500 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003501 }
3502 op_ifcs++;
3503 if (s32Error < 0) {
3504 PRINT_ER("Failed to creat refresh Timer\n");
3505 return s32Error;
3506 }
3507
Dean Lee72ed4dc2015-06-12 14:11:44 +09003508 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003509
Dean Lee72ed4dc2015-06-12 14:11:44 +09003510 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003511
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003512 sema_init(&(priv->hSemScanReq), 1);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003513 s32Error = wilc_init(net, &priv->hWILCWFIDrv);
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003514 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003515 PRINT_ER("Error while initializing hostinterface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003516
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003517 return s32Error;
3518}
3519
3520/**
3521 * @brief WILC_WFI_WiphyFree
3522 * @details Freeing allocation of the wireless device structure
3523 * @param[in] NONE
3524 * @return NONE
3525 * @author mdaftedar
3526 * @date 01 MAR 2012
3527 * @version 1.0
3528 */
Chaehyun Lima9a16822015-09-20 15:51:24 +09003529int wilc_deinit_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003530{
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003531 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003532
Chaehyun Lim27268872015-09-15 14:06:13 +09003533 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003534
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003535 priv = wdev_priv(net->ieee80211_ptr);
3536
Dean Lee72ed4dc2015-06-12 14:11:44 +09003537 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003538
Dean Lee72ed4dc2015-06-12 14:11:44 +09003539 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003540
3541 op_ifcs--;
3542
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003543 s32Error = wilc_deinit(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003544
3545 /* Clear the Shadow scan */
3546 clear_shadow_scan(priv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003547 if (op_ifcs == 0) {
3548 PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003549 del_timer_sync(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003550 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003551
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003552 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003553 PRINT_ER("Error while deintializing host interface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003554
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003555 return s32Error;
3556}
3557
3558
3559/**
3560 * @brief WILC_WFI_WiphyFree
3561 * @details Freeing allocation of the wireless device structure
3562 * @param[in] NONE
3563 * @return NONE
3564 * @author mdaftedar
3565 * @date 01 MAR 2012
3566 * @version 1.0
3567 */
Chaehyun Lim96da20a2015-09-20 15:51:08 +09003568void wilc_free_wiphy(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003569{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003570 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
3571
Chaehyun Lim619837a2015-09-20 15:51:10 +09003572 if (!net) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003573 PRINT_D(INIT_DBG, "net_device is NULL\n");
3574 return;
3575 }
3576
Chaehyun Lim619837a2015-09-20 15:51:10 +09003577 if (!net->ieee80211_ptr) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003578 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
3579 return;
3580 }
3581
Chaehyun Lim619837a2015-09-20 15:51:10 +09003582 if (!net->ieee80211_ptr->wiphy) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003583 PRINT_D(INIT_DBG, "wiphy is NULL\n");
3584 return;
3585 }
3586
3587 wiphy_unregister(net->ieee80211_ptr->wiphy);
3588
3589 PRINT_D(INIT_DBG, "Freeing wiphy\n");
3590 wiphy_free(net->ieee80211_ptr->wiphy);
3591 kfree(net->ieee80211_ptr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003592}