blob: 349b720fe57b645e30da6ee71704e530bc670cc9 [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
Leo Kimf1ab1172015-11-19 15:56:11 +0900109static tstrNetworkInfo last_scanned_shadow[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*/
Leo Kim2736f472015-11-19 15:56:12 +0900127static struct ieee80211_channel ieee80211_2ghz_channels[] = {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900128 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 = {
Leo Kim2736f472015-11-19 15:56:12 +0900184 .channels = ieee80211_2ghz_channels,
185 .n_channels = ARRAY_SIZE(ieee80211_2ghz_channels),
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900186 .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++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900217 if (last_scanned_shadow[last_scanned_cnt].pu8IEs) {
218 kfree(last_scanned_shadow[i].pu8IEs);
219 last_scanned_shadow[last_scanned_cnt].pu8IEs = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900220 }
221
Leo Kimf1ab1172015-11-19 15:56:11 +0900222 wilc_free_join_params(last_scanned_shadow[i].pJoinParams);
223 last_scanned_shadow[i].pJoinParams = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900224 }
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
Leo Kimf1ab1172015-11-19 15:56:11 +0900257 pstrNetworkInfo = &last_scanned_shadow[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900258
259 if ((!pstrNetworkInfo->u8Found) || all) {
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900260 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900261 struct ieee80211_channel *channel;
262
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900263 if (pstrNetworkInfo != NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900264
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900265 s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900266 channel = ieee80211_get_channel(wiphy, s32Freq);
267
268 rssi = get_rssi_avg(pstrNetworkInfo);
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900269 if (memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7) || bDirectScan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900270 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
271 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900272 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900273 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900274 }
275 }
276
277 }
278 }
279
280}
281
Arnd Bergmann1608c402015-11-16 15:04:53 +0100282static void reset_shadow_found(void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900283{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900284 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900285
Leo Kim771fbae2015-11-19 15:56:10 +0900286 for (i = 0; i < last_scanned_cnt; i++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900287 last_scanned_shadow[i].u8Found = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900288}
289
Arnd Bergmann1608c402015-11-16 15:04:53 +0100290static void update_scan_time(void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900291{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900292 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900293
Leo Kim771fbae2015-11-19 15:56:10 +0900294 for (i = 0; i < last_scanned_cnt; i++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900295 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900296}
297
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700298static void remove_network_from_shadow(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900299{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900300 unsigned long now = jiffies;
301 int i, j;
302
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900303
Leo Kim771fbae2015-11-19 15:56:10 +0900304 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900305 if (time_after(now, last_scanned_shadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) {
306 PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", last_scanned_shadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900307
Leo Kimf1ab1172015-11-19 15:56:11 +0900308 kfree(last_scanned_shadow[i].pu8IEs);
309 last_scanned_shadow[i].pu8IEs = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900310
Leo Kimf1ab1172015-11-19 15:56:11 +0900311 wilc_free_join_params(last_scanned_shadow[i].pJoinParams);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900312
Leo Kim771fbae2015-11-19 15:56:10 +0900313 for (j = i; (j < last_scanned_cnt - 1); j++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900314 last_scanned_shadow[j] = last_scanned_shadow[j + 1];
Leo Kim771fbae2015-11-19 15:56:10 +0900315
316 last_scanned_cnt--;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900317 }
318 }
319
Leo Kim771fbae2015-11-19 15:56:10 +0900320 PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n",
321 last_scanned_cnt);
322 if (last_scanned_cnt != 0) {
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700323 hAgingTimer.data = arg;
324 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
325 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900326 PRINT_D(CFG80211_DBG, "No need to restart Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700327 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900328}
329
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700330static void clear_duringIP(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900331{
332 PRINT_D(GENERIC_DBG, "GO:IP Obtained , enable scan\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100333 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900334}
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900335
Arnd Bergmann1608c402015-11-16 15:04:53 +0100336static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900337{
Chaehyun Lima74cc6b2015-10-02 16:41:17 +0900338 int state = -1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900339 int i;
340
Leo Kim771fbae2015-11-19 15:56:10 +0900341 if (last_scanned_cnt == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900342 PRINT_D(CFG80211_DBG, "Starting Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700343 hAgingTimer.data = (unsigned long)pUserVoid;
344 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900345 state = -1;
346 } else {
347 /* Linear search for now */
Leo Kim771fbae2015-11-19 15:56:10 +0900348 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900349 if (memcmp(last_scanned_shadow[i].au8bssid,
350 pstrNetworkInfo->au8bssid, 6) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900351 state = i;
352 break;
353 }
354 }
355 }
356 return state;
357}
358
Arnd Bergmann1608c402015-11-16 15:04:53 +0100359static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900360{
Chaehyun Lima74cc6b2015-10-02 16:41:17 +0900361 int ap_found = is_network_in_shadow(pstrNetworkInfo, pUserVoid);
Chaehyun Limfbc2fe12015-09-15 14:06:16 +0900362 u32 ap_index = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900363 u8 rssi_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900364
Leo Kim771fbae2015-11-19 15:56:10 +0900365 if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900366 PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
367 return;
368 }
369 if (ap_found == -1) {
Leo Kim771fbae2015-11-19 15:56:10 +0900370 ap_index = last_scanned_cnt;
371 last_scanned_cnt++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900372
373 } else {
374 ap_index = ap_found;
375 }
Leo Kimf1ab1172015-11-19 15:56:11 +0900376 rssi_index = last_scanned_shadow[ap_index].strRssi.u8Index;
377 last_scanned_shadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900378 if (rssi_index == NUM_RSSI) {
379 rssi_index = 0;
Leo Kimf1ab1172015-11-19 15:56:11 +0900380 last_scanned_shadow[ap_index].strRssi.u8Full = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900381 }
Leo Kimf1ab1172015-11-19 15:56:11 +0900382 last_scanned_shadow[ap_index].strRssi.u8Index = rssi_index;
383 last_scanned_shadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
384 last_scanned_shadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
385 last_scanned_shadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
386 memcpy(last_scanned_shadow[ap_index].au8ssid,
387 pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
388 memcpy(last_scanned_shadow[ap_index].au8bssid,
389 pstrNetworkInfo->au8bssid, ETH_ALEN);
390 last_scanned_shadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
391 last_scanned_shadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
392 last_scanned_shadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
393 last_scanned_shadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
394 last_scanned_shadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900395 if (ap_found != -1)
Leo Kimf1ab1172015-11-19 15:56:11 +0900396 kfree(last_scanned_shadow[ap_index].pu8IEs);
397 last_scanned_shadow[ap_index].pu8IEs =
Glen Leef3052582015-09-10 12:03:04 +0900398 kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL); /* will be deallocated by the WILC_WFI_CfgScan() function */
Leo Kimf1ab1172015-11-19 15:56:11 +0900399 memcpy(last_scanned_shadow[ap_index].pu8IEs,
400 pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
401 last_scanned_shadow[ap_index].u32TimeRcvdInScan = jiffies;
402 last_scanned_shadow[ap_index].u32TimeRcvdInScanCached = jiffies;
403 last_scanned_shadow[ap_index].u8Found = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900404 if (ap_found != -1)
Leo Kimf1ab1172015-11-19 15:56:11 +0900405 wilc_free_join_params(last_scanned_shadow[ap_index].pJoinParams);
406 last_scanned_shadow[ap_index].pJoinParams = pJoinParams;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900407}
408
409
410/**
411 * @brief CfgScanResult
412 * @details Callback function which returns the scan results found
413 *
414 * @param[in] tenuScanEvent enuScanEvent: enum, indicating the scan event triggered, whether that is
415 * SCAN_EVENT_NETWORK_FOUND or SCAN_EVENT_DONE
416 * tstrNetworkInfo* pstrNetworkInfo: structure holding the scan results information
417 * void* pUserVoid: Private structure associated with the wireless interface
418 * @return NONE
419 * @author mabubakr
420 * @date
421 * @version 1.0
422 */
Leo Kim1ec38152015-10-12 16:55:59 +0900423static void CfgScanResult(enum scan_event enuScanEvent, tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900424{
Chaehyun Lim27268872015-09-15 14:06:13 +0900425 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900426 struct wiphy *wiphy;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900427 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900428 struct ieee80211_channel *channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900429 struct cfg80211_bss *bss = NULL;
430
Chaehyun Lim27268872015-09-15 14:06:13 +0900431 priv = (struct wilc_priv *)pUserVoid;
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100432 if (priv->bCfgScanning) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900433 if (enuScanEvent == SCAN_EVENT_NETWORK_FOUND) {
434 wiphy = priv->dev->ieee80211_ptr->wiphy;
Leo Kim7ae43362015-09-16 18:35:59 +0900435
436 if (!wiphy)
437 return;
438
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900439 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC
440 &&
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900441 ((((s32)pstrNetworkInfo->s8rssi) * 100) < 0
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900442 ||
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900443 (((s32)pstrNetworkInfo->s8rssi) * 100) > 100)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900444 ) {
Leo Kim24db7132015-09-16 18:36:01 +0900445 PRINT_ER("wiphy signal type fial\n");
446 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900447 }
448
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900449 if (pstrNetworkInfo != NULL) {
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900450 s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900451 channel = ieee80211_get_channel(wiphy, s32Freq);
452
Leo Kim7ae43362015-09-16 18:35:59 +0900453 if (!channel)
454 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900455
456 PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530457 "BeaconPeriod: %d\n", channel->center_freq, (((s32)pstrNetworkInfo->s8rssi) * 100),
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900458 pstrNetworkInfo->u16CapInfo, pstrNetworkInfo->u16BeaconPeriod);
459
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100460 if (pstrNetworkInfo->bNewNetwork) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900461 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
462 /* max_scan_ssids */
463 PRINT_D(CFG80211_DBG, "Network %s found\n", pstrNetworkInfo->au8ssid);
464
465
466 priv->u32RcvdChCount++;
467
468
469
470 if (pJoinParams == NULL) {
471 PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n");
472 }
473 add_network_to_shadow(pstrNetworkInfo, priv, pJoinParams);
474
475 /*P2P peers are sent to WPA supplicant and added to shadow table*/
476
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900477 if (!(memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900478 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
479 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900480 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)pstrNetworkInfo->s8rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900481 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900482 }
483
484
485 } else {
486 PRINT_ER("Discovered networks exceeded the max limit\n");
487 }
488 } else {
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900489 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900490 /* So this network is discovered before, we'll just update its RSSI */
491 for (i = 0; i < priv->u32RcvdChCount; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900492 if (memcmp(last_scanned_shadow[i].au8bssid, pstrNetworkInfo->au8bssid, 6) == 0) {
493 PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", last_scanned_shadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900494
Leo Kimf1ab1172015-11-19 15:56:11 +0900495 last_scanned_shadow[i].s8rssi = pstrNetworkInfo->s8rssi;
496 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900497 break;
498 }
499 }
500 }
501 }
502 } else if (enuScanEvent == SCAN_EVENT_DONE) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530503 PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev);
504 PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n");
Dean Lee72ed4dc2015-06-12 14:11:44 +0900505 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900506
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530507 if (priv->u32RcvdChCount > 0)
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530508 PRINT_D(CFG80211_DBG, "%d Network(s) found\n", priv->u32RcvdChCount);
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530509 else
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530510 PRINT_D(CFG80211_DBG, "No networks found\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900511
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200512 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900513
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900514 if (priv->pstrScanReq != NULL) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900515 cfg80211_scan_done(priv->pstrScanReq, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900516 priv->u32RcvdChCount = 0;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900517 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900518 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900519 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200520 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900521
522 }
523 /*Aborting any scan operation during mac close*/
524 else if (enuScanEvent == SCAN_EVENT_ABORTED) {
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200525 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900526
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530527 PRINT_D(CFG80211_DBG, "Scan Aborted\n");
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900528 if (priv->pstrScanReq != NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900529
530 update_scan_time(priv);
Dean Lee72ed4dc2015-06-12 14:11:44 +0900531 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900532
Dean Lee72ed4dc2015-06-12 14:11:44 +0900533 cfg80211_scan_done(priv->pstrScanReq, false);
534 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900535 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900536 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200537 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900538 }
539 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900540}
541
542
543/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900544 * @brief CfgConnectResult
545 * @details
546 * @param[in] tenuConnDisconnEvent enuConnDisconnEvent: Type of connection response either
547 * connection response or disconnection notification.
548 * tstrConnectInfo* pstrConnectInfo: COnnection information.
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900549 * u8 u8MacStatus: Mac Status from firmware
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900550 * tstrDisconnectNotifInfo* pstrDisconnectNotifInfo: Disconnection Notification
551 * void* pUserVoid: Private data associated with wireless interface
552 * @return NONE
553 * @author mabubakr
554 * @date 01 MAR 2012
555 * @version 1.0
556 */
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100557int wilc_connecting;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900558
Leo Kimed3f0372015-10-12 16:56:01 +0900559static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900560 tstrConnectInfo *pstrConnectInfo,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900561 u8 u8MacStatus,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900562 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
563 void *pUserVoid)
564{
Chaehyun Lim27268872015-09-15 14:06:13 +0900565 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900566 struct net_device *dev;
Leo Kim441dc602015-10-12 16:55:35 +0900567 struct host_if_drv *pstrWFIDrv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900568 u8 NullBssid[ETH_ALEN] = {0};
Glen Leec1ec2c12015-10-20 17:13:58 +0900569 struct wilc *wl;
570 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900571
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100572 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900573
Chaehyun Lim27268872015-09-15 14:06:13 +0900574 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900575 dev = priv->dev;
Glen Leec1ec2c12015-10-20 17:13:58 +0900576 nic = netdev_priv(dev);
577 wl = nic->wilc;
Leo Kim441dc602015-10-12 16:55:35 +0900578 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900579
580 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
581 /*Initialization*/
Amitoj Kaur Chawlababa7c72015-10-15 13:48:29 +0530582 u16 u16ConnectStatus;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900583
584 u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
585
586 PRINT_D(CFG80211_DBG, " Connection response received = %d\n", u8MacStatus);
587
588 if ((u8MacStatus == MAC_DISCONNECTED) &&
589 (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
590 /* The case here is that our station was waiting for association response frame and has just received it containing status code
591 * = SUCCESSFUL_STATUSCODE, while mac status is MAC_DISCONNECTED (which means something wrong happened) */
592 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100593 wilc_wlan_set_bssid(priv->dev, NullBssid);
594 eth_zero_addr(wilc_connected_SSID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900595
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900596 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
Leo Kimab16ec02015-10-29 12:05:40 +0900597 if (!pstrWFIDrv->p2p_connect)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900598 u8WLANChannel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900599
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530600 PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d\n", u16ConnectStatus, u8MacStatus);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900601 }
602
603 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900604 bool bNeedScanRefresh = false;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900605 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900606
607 PRINT_INFO(CFG80211_DBG, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo->au8bssid[0],
608 pstrConnectInfo->au8bssid[1], pstrConnectInfo->au8bssid[2], pstrConnectInfo->au8bssid[3], pstrConnectInfo->au8bssid[4], pstrConnectInfo->au8bssid[5]);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900609 memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900610
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900611
Leo Kim771fbae2015-11-19 15:56:10 +0900612 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900613 if (memcmp(last_scanned_shadow[i].au8bssid,
614 pstrConnectInfo->au8bssid, ETH_ALEN) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900615 unsigned long now = jiffies;
616
617 if (time_after(now,
Leo Kimf1ab1172015-11-19 15:56:11 +0900618 last_scanned_shadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900619 bNeedScanRefresh = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900620 }
621
622 break;
623 }
624 }
625
Abdul Hussain5a66bf22015-06-16 09:44:06 +0000626 if (bNeedScanRefresh) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900627 /*Also, refrsh DIRECT- results if */
Dean Lee72ed4dc2015-06-12 14:11:44 +0900628 refresh_scan(priv, 1, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900629
630 }
631
632 }
633
634
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530635 PRINT_D(CFG80211_DBG, "Association request info elements length = %zu\n", pstrConnectInfo->ReqIEsLen);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900636
637 PRINT_D(CFG80211_DBG, "Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen);
638
639 cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
640 pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
641 pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
642 u16ConnectStatus, GFP_KERNEL); /* TODO: mostafa: u16ConnectStatus to */
643 /* be replaced by pstrConnectInfo->u16ConnectStatus */
644 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100645 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900646 PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n",
647 pstrDisconnectNotifInfo->u16reason, priv->dev);
648 u8P2Plocalrandom = 0x01;
649 u8P2Precvrandom = 0x00;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900650 bWilc_ie = false;
Shraddha Barkebcf02652015-10-05 17:00:32 +0530651 eth_zero_addr(priv->au8AssociatedBss);
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100652 wilc_wlan_set_bssid(priv->dev, NullBssid);
653 eth_zero_addr(wilc_connected_SSID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900654
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900655 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
Leo Kimab16ec02015-10-29 12:05:40 +0900656 if (!pstrWFIDrv->p2p_connect)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900657 u8WLANChannel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900658 /*Incase "P2P CLIENT Connected" send deauthentication reason by 3 to force the WPA_SUPPLICANT to directly change
659 * virtual interface to station*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900660 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900661 pstrDisconnectNotifInfo->u16reason = 3;
662 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900663 /*Incase "P2P CLIENT during connection(not connected)" send deauthentication reason by 1 to force the WPA_SUPPLICANT
664 * to scan again and retry the connection*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900665 else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900666 pstrDisconnectNotifInfo->u16reason = 1;
667 }
668 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
Sudip Mukherjeee26bb712015-06-30 13:51:51 +0530669 pstrDisconnectNotifInfo->ie_len, false,
670 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900671
672 }
673
674}
675
676
677/**
Chaehyun Lim80785a92015-09-14 12:24:01 +0900678 * @brief set_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900679 * @details Set channel for a given wireless interface. Some devices
680 * may support multi-channel operation (by channel hopping) so cfg80211
681 * doesn't verify much. Note, however, that the passed netdev may be
682 * %NULL as well if the user requested changing the channel for the
683 * device itself, or for a monitor interface.
684 * @param[in]
685 * @return int : Return 0 on Success
686 * @author mdaftedar
687 * @date 01 MAR 2012
688 * @version 1.0
689 */
Chaehyun Lim80785a92015-09-14 12:24:01 +0900690static int set_channel(struct wiphy *wiphy,
691 struct cfg80211_chan_def *chandef)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900692{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900693 u32 channelnum = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +0900694 struct wilc_priv *priv;
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900695 int result = 0;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900696
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900697 priv = wiphy_priv(wiphy);
698
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900699 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
700 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900701
Chaehyun Lim866a2c22015-10-02 16:41:21 +0900702 curr_channel = channelnum;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100703 result = wilc_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900704
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900705 if (result != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900706 PRINT_ER("Error in setting channel %d\n", channelnum);
707
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900708 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900709}
710
711/**
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900712 * @brief scan
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900713 * @details Request to do a scan. If returning zero, the scan request is given
714 * the driver, and will be valid until passed to cfg80211_scan_done().
715 * For scan results, call cfg80211_inform_bss(); you can call this outside
716 * the scan/scan_done bracket too.
717 * @param[in]
718 * @return int : Return 0 on Success
719 * @author mabubakr
720 * @date 01 MAR 2012
721 * @version 1.0
722 */
723
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900724static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900725{
Chaehyun Lim27268872015-09-15 14:06:13 +0900726 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900727 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +0900728 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900729 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
Leo Kim607db442015-10-05 15:25:37 +0900730 struct hidden_network strHiddenNetwork;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900731
732 priv = wiphy_priv(wiphy);
733
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900734 priv->pstrScanReq = request;
735
736 priv->u32RcvdChCount = 0;
737
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100738 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900739
740
741 reset_shadow_found(priv);
742
Dean Lee72ed4dc2015-06-12 14:11:44 +0900743 priv->bCfgScanning = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900744 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
745 /* max_scan_ssids */
746 for (i = 0; i < request->n_channels; i++) {
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900747 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900748 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
749 }
750
751 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530752 PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900753
754 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
755
756 if (request->n_ssids >= 1) {
757
758
Leo Kim607db442015-10-05 15:25:37 +0900759 strHiddenNetwork.pstrHiddenNetworkInfo = kmalloc(request->n_ssids * sizeof(struct hidden_network), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900760 strHiddenNetwork.u8ssidnum = request->n_ssids;
761
762
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900763 for (i = 0; i < request->n_ssids; i++) {
764
765 if (request->ssids[i].ssid != NULL && request->ssids[i].ssid_len != 0) {
Glen Leef3052582015-09-10 12:03:04 +0900766 strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900767 memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900768 strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len;
769 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530770 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900771 strHiddenNetwork.u8ssidnum -= 1;
772 }
773 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530774 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100775 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900776 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900777 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900778 CfgScanResult, (void *)priv, &strHiddenNetwork);
779 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530780 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100781 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900782 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900783 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900784 CfgScanResult, (void *)priv, NULL);
785 }
786
787 } else {
788 PRINT_ER("Requested num of scanned channels is greater than the max, supported"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530789 " channels\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900790 }
791
Leo Kime6e12662015-09-16 18:36:03 +0900792 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900793 s32Error = -EBUSY;
794 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
795 }
796
797 return s32Error;
798}
799
800/**
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900801 * @brief connect
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900802 * @details Connect to the ESS with the specified parameters. When connected,
803 * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
804 * If the connection fails for some reason, call cfg80211_connect_result()
805 * with the status from the AP.
806 * @param[in]
807 * @return int : Return 0 on Success
808 * @author mabubakr
809 * @date 01 MAR 2012
810 * @version 1.0
811 */
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900812static int connect(struct wiphy *wiphy, struct net_device *dev,
813 struct cfg80211_connect_params *sme)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900814{
Leo Kime6e12662015-09-16 18:36:03 +0900815 s32 s32Error = 0;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900816 u32 i;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900817 u8 u8security = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +0900818 enum AUTHTYPE tenuAuth_type = ANY;
Dean Lee576917a2015-06-15 11:58:57 +0900819 char *pcgroup_encrypt_val = NULL;
820 char *pccipher_group = NULL;
821 char *pcwpa_version = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900822
Chaehyun Lim27268872015-09-15 14:06:13 +0900823 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +0900824 struct host_if_drv *pstrWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900825 tstrNetworkInfo *pstrNetworkInfo = NULL;
826
827
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100828 wilc_connecting = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900829 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +0900830 pstrWFIDrv = (struct host_if_drv *)(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900831
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100832 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900833
Johnny Kim8a143302015-06-10 17:06:46 +0900834 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 +0900835 if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900836 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
Leo Kimab16ec02015-10-29 12:05:40 +0900837 pstrWFIDrv->p2p_connect = 1;
838 } else {
839 pstrWFIDrv->p2p_connect = 0;
840 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530841 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900842
Leo Kim771fbae2015-11-19 15:56:10 +0900843 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900844 if ((sme->ssid_len == last_scanned_shadow[i].u8SsidLen) &&
845 memcmp(last_scanned_shadow[i].au8ssid,
846 sme->ssid,
847 sme->ssid_len) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900848 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
849 if (sme->bssid == NULL) {
850 /* BSSID is not passed from the user, so decision of matching
851 * is done by SSID only */
852 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
853 break;
854 } else {
855 /* BSSID is also passed from the user, so decision of matching
856 * should consider also this passed BSSID */
Leo Kimf1ab1172015-11-19 15:56:11 +0900857 if (memcmp(last_scanned_shadow[i].au8bssid,
858 sme->bssid,
859 ETH_ALEN) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900860 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
861 break;
862 }
863 }
864 }
865 }
866
Leo Kim771fbae2015-11-19 15:56:10 +0900867 if (i < last_scanned_cnt) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900868 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
869
Leo Kimf1ab1172015-11-19 15:56:11 +0900870 pstrNetworkInfo = &last_scanned_shadow[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900871
872 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
873 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
874 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
875 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
876 } else {
877 s32Error = -ENOENT;
Leo Kim771fbae2015-11-19 15:56:10 +0900878 if (last_scanned_cnt == 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900879 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
880 else
881 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
882
883 goto done;
884 }
885
886 priv->WILC_WFI_wep_default = 0;
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900887 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
888 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900889
890 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
891 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
892
893 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
894
895 if (INFO) {
896 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
897 PRINT_D(CORECONFIG_DBG, "sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]);
898 }
899
900 if (sme->crypto.cipher_group != NO_ENCRYPT) {
901 /* To determine the u8security value, first we check the group cipher suite then {in case of WPA or WPA2}
902 * we will add to it the pairwise cipher suite(s) */
903 pcwpa_version = "Default";
904 PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900905 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900906 u8security = ENCRYPT_ENABLED | WEP;
907 pcgroup_encrypt_val = "WEP40";
908 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
909 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
910
911 if (INFO) {
912 for (i = 0; i < sme->key_len; i++)
913 PRINT_D(CORECONFIG_DBG, "WEP Key Value[%d] = %d\n", i, sme->key[i]);
914 }
915 priv->WILC_WFI_wep_default = sme->key_idx;
916 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900917 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900918
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900919 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900920 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900921 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
922 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900923 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900924
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100925 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
926 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900927 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900928 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
929 pcgroup_encrypt_val = "WEP104";
930 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
931
932 priv->WILC_WFI_wep_default = sme->key_idx;
933 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900934 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900935
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900936 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900937 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900938 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
939 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900940 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900941
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100942 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
943 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900944 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900945 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900946 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
947 pcgroup_encrypt_val = "WPA2_TKIP";
948 pccipher_group = "TKIP";
949 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
950 /* tenuSecurity_t = WPA2_AES; */
951 u8security = ENCRYPT_ENABLED | WPA2 | AES;
952 pcgroup_encrypt_val = "WPA2_AES";
953 pccipher_group = "AES";
954 }
955 pcwpa_version = "WPA_VERSION_2";
956 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
957 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900958 u8security = ENCRYPT_ENABLED | WPA | TKIP;
959 pcgroup_encrypt_val = "WPA_TKIP";
960 pccipher_group = "TKIP";
961 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
962 /* tenuSecurity_t = WPA_AES; */
963 u8security = ENCRYPT_ENABLED | WPA | AES;
964 pcgroup_encrypt_val = "WPA_AES";
965 pccipher_group = "AES";
966
967 }
968 pcwpa_version = "WPA_VERSION_1";
969
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900970 } else {
971 s32Error = -ENOTSUPP;
972 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
973
974 goto done;
975 }
976
977 }
978
979 /* After we set the u8security value from checking the group cipher suite, {in case of WPA or WPA2} we will
980 * add to it the pairwise cipher suite(s) */
981 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
982 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
983 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
984 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
985 u8security = u8security | TKIP;
986 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
987 u8security = u8security | AES;
988 }
989 }
990 }
991
992 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
993
994 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
995 switch (sme->auth_type) {
996 case NL80211_AUTHTYPE_OPEN_SYSTEM:
997 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
998 tenuAuth_type = OPEN_SYSTEM;
999 break;
1000
1001 case NL80211_AUTHTYPE_SHARED_KEY:
1002 tenuAuth_type = SHARED_KEY;
1003 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
1004 break;
1005
1006 default:
1007 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
1008 }
1009
1010
1011 /* ai: key_mgmt: enterprise case */
1012 if (sme->crypto.n_akm_suites) {
1013 switch (sme->crypto.akm_suites[0]) {
1014 case WLAN_AKM_SUITE_8021X:
1015 tenuAuth_type = IEEE8021;
1016 break;
1017
1018 default:
1019 break;
1020 }
1021 }
1022
1023
1024 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
1025
1026 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
1027 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
1028
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001029 curr_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001030
Leo Kimab16ec02015-10-29 12:05:40 +09001031 if (!pstrWFIDrv->p2p_connect)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001032 u8WLANChannel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001033
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001034 wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001035
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001036 s32Error = wilc_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001037 sme->ssid_len, sme->ie, sme->ie_len,
1038 CfgConnectResult, (void *)priv, u8security,
1039 tenuAuth_type, pstrNetworkInfo->u8channel,
1040 pstrNetworkInfo->pJoinParams);
Leo Kime6e12662015-09-16 18:36:03 +09001041 if (s32Error != 0) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001042 PRINT_ER("wilc_set_join_req(): Error(%d)\n", s32Error);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001043 s32Error = -ENOENT;
1044 goto done;
1045 }
1046
1047done:
1048
1049 return s32Error;
1050}
1051
1052
1053/**
Chaehyun Limb027cde2015-09-14 12:24:04 +09001054 * @brief disconnect
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001055 * @details Disconnect from the BSS/ESS.
1056 * @param[in]
1057 * @return int : Return 0 on Success
1058 * @author mdaftedar
1059 * @date 01 MAR 2012
1060 * @version 1.0
1061 */
Chaehyun Limb027cde2015-09-14 12:24:04 +09001062static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001063{
Leo Kime6e12662015-09-16 18:36:03 +09001064 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09001065 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09001066 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim51e825f2015-09-15 14:06:14 +09001067 u8 NullBssid[ETH_ALEN] = {0};
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001068
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001069 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001070 priv = wiphy_priv(wiphy);
1071
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001072 /*Invalidate u8WLANChannel value on wlan0 disconnect*/
Leo Kim441dc602015-10-12 16:55:35 +09001073 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Leo Kimab16ec02015-10-29 12:05:40 +09001074 if (!pstrWFIDrv->p2p_connect)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001075 u8WLANChannel = INVALID_CHANNEL;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001076 wilc_wlan_set_bssid(priv->dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001077
1078 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
1079
1080 u8P2Plocalrandom = 0x01;
1081 u8P2Precvrandom = 0x00;
Dean Lee72ed4dc2015-06-12 14:11:44 +09001082 bWilc_ie = false;
Leo Kim1229b1a2015-10-29 12:05:39 +09001083 pstrWFIDrv->p2p_timeout = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001084
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001085 s32Error = wilc_disconnect(priv->hWILCWFIDrv, reason_code);
Leo Kime6e12662015-09-16 18:36:03 +09001086 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001087 PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
1088 s32Error = -EINVAL;
1089 }
1090
1091 return s32Error;
1092}
1093
1094/**
Chaehyun Lim953d4172015-09-14 12:24:05 +09001095 * @brief add_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001096 * @details Add a key with the given parameters. @mac_addr will be %NULL
1097 * when adding a group key.
1098 * @param[in] key : key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, 8-byte Rx Mic Key
1099 * @return int : Return 0 on Success
1100 * @author mdaftedar
1101 * @date 01 MAR 2012
1102 * @version 1.0
1103 */
Chaehyun Lim953d4172015-09-14 12:24:05 +09001104static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1105 bool pairwise,
1106 const u8 *mac_addr, struct key_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001107
1108{
Leo Kime6e12662015-09-16 18:36:03 +09001109 s32 s32Error = 0, KeyLen = params->key_len;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001110 u32 i;
Chaehyun Lim27268872015-09-15 14:06:13 +09001111 struct wilc_priv *priv;
Arnd Bergmann057d1e92015-06-01 21:06:44 +02001112 const u8 *pu8RxMic = NULL;
1113 const u8 *pu8TxMic = NULL;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001114 u8 u8mode = NO_ENCRYPT;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001115 u8 u8gmode = NO_ENCRYPT;
1116 u8 u8pmode = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +09001117 enum AUTHTYPE tenuAuth_type = ANY;
Glen Lee76469202015-10-20 17:13:59 +09001118 struct wilc *wl;
1119 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001120
1121 priv = wiphy_priv(wiphy);
Glen Lee76469202015-10-20 17:13:59 +09001122 nic = netdev_priv(netdev);
1123 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001124
1125 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
1126
Johnny Kim8a143302015-06-10 17:06:46 +09001127 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001128
1129 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
1130 params->key[1],
1131 params->key[2]);
1132
1133
1134 switch (params->cipher) {
1135 case WLAN_CIPHER_SUITE_WEP40:
1136 case WLAN_CIPHER_SUITE_WEP104:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001137 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
1138
1139 priv->WILC_WFI_wep_default = key_index;
1140 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001141 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001142
1143 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
1144 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
1145
1146 for (i = 0; i < params->key_len; i++)
1147 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
1148
1149 tenuAuth_type = OPEN_SYSTEM;
1150
1151 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
1152 u8mode = ENCRYPT_ENABLED | WEP;
1153 else
1154 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
1155
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001156 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 +09001157 break;
1158 }
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001159 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001160 priv->WILC_WFI_wep_default = key_index;
1161 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001162 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001163
1164 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
1165 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
1166 if (INFO) {
1167 for (i = 0; i < params->key_len; i++)
1168 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
1169 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001170 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001171 }
1172
1173 break;
1174
1175 case WLAN_CIPHER_SUITE_TKIP:
1176 case WLAN_CIPHER_SUITE_CCMP:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001177 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
1178
1179 if (priv->wilc_gtk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001180 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001181 priv->wilc_gtk[key_index]->key = NULL;
1182 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001183
1184 }
1185 if (priv->wilc_ptk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001186 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001187 priv->wilc_ptk[key_index]->key = NULL;
1188 priv->wilc_ptk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001189 }
1190
1191
1192
Daniel Machon19132212015-08-05 08:18:31 +02001193 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001194 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1195 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1196 else
1197 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1198
1199 priv->wilc_groupkey = u8gmode;
1200
1201 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1202
1203 pu8TxMic = params->key + 24;
1204 pu8RxMic = params->key + 16;
1205 KeyLen = params->key_len - 16;
1206 }
1207 /* 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 +05301208 kfree(priv->wilc_gtk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001209
Glen Leef3052582015-09-10 12:03:04 +09001210 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001211 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001212
1213 /* 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 +05301214 kfree(priv->wilc_gtk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001215
1216 if ((params->seq_len) > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001217 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001218 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001219 }
1220
1221 priv->wilc_gtk[key_index]->cipher = params->cipher;
1222 priv->wilc_gtk[key_index]->key_len = params->key_len;
1223 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1224
1225 if (INFO) {
1226 for (i = 0; i < params->key_len; i++)
1227 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1228 for (i = 0; i < params->seq_len; i++)
1229 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1230 }
1231
1232
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001233 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001234 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode);
1235
1236 } else {
1237 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]);
1238
1239 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1240 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1241 else
1242 u8pmode = priv->wilc_groupkey | AES;
1243
1244
1245 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1246
1247 pu8TxMic = params->key + 24;
1248 pu8RxMic = params->key + 16;
1249 KeyLen = params->key_len - 16;
1250 }
1251
Shraddha Barkecccfc392015-10-12 20:49:19 +05301252 kfree(priv->wilc_ptk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001253
Glen Leef3052582015-09-10 12:03:04 +09001254 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001255
Shraddha Barkecccfc392015-10-12 20:49:19 +05301256 kfree(priv->wilc_ptk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001257
1258 if ((params->seq_len) > 0)
Glen Leef3052582015-09-10 12:03:04 +09001259 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001260
1261 if (INFO) {
1262 for (i = 0; i < params->key_len; i++)
1263 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1264
1265 for (i = 0; i < params->seq_len; i++)
1266 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1267 }
1268
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001269 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001270
1271 if ((params->seq_len) > 0)
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001272 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001273
1274 priv->wilc_ptk[key_index]->cipher = params->cipher;
1275 priv->wilc_ptk[key_index]->key_len = params->key_len;
1276 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1277
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001278 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001279 pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index);
1280 }
1281 break;
1282 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001283
1284 {
1285 u8mode = 0;
Daniel Machon19132212015-08-05 08:18:31 +02001286 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001287 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1288 /* swap the tx mic by rx mic */
1289 pu8RxMic = params->key + 24;
1290 pu8TxMic = params->key + 16;
1291 KeyLen = params->key_len - 16;
1292 }
1293
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001294 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001295 if (!g_gtk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001296 g_add_gtk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001297 g_add_gtk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001298 if (!mac_addr) {
1299 g_add_gtk_key_params.mac_addr = NULL;
1300 } else {
Glen Leef3052582015-09-10 12:03:04 +09001301 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001302 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1303 }
1304 g_key_gtk_params.key_len = params->key_len;
1305 g_key_gtk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001306 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001307 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1308 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001309 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001310 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1311 }
1312 g_key_gtk_params.cipher = params->cipher;
1313
1314 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1315 g_key_gtk_params.key[1],
1316 g_key_gtk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001317 g_gtk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001318 }
1319
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001320 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001321 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001322 } else {
1323 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1324 /* swap the tx mic by rx mic */
1325 pu8RxMic = params->key + 24;
1326 pu8TxMic = params->key + 16;
1327 KeyLen = params->key_len - 16;
1328 }
1329
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001330 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001331 if (!g_ptk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001332 g_add_ptk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001333 g_add_ptk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001334 if (!mac_addr) {
1335 g_add_ptk_key_params.mac_addr = NULL;
1336 } else {
Glen Leef3052582015-09-10 12:03:04 +09001337 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001338 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1339 }
1340 g_key_ptk_params.key_len = params->key_len;
1341 g_key_ptk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001342 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001343 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1344 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001345 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001346 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1347 }
1348 g_key_ptk_params.cipher = params->cipher;
1349
1350 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1351 g_key_ptk_params.key[1],
1352 g_key_ptk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001353 g_ptk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001354 }
1355
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001356 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001357 pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index);
1358 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1359 if (INFO) {
1360 for (i = 0; i < params->key_len; i++)
1361 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1362 }
1363 }
1364 }
1365 break;
1366
1367 default:
1368 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
1369 s32Error = -ENOTSUPP;
1370
1371 }
1372
1373 return s32Error;
1374}
1375
1376/**
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001377 * @brief del_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001378 * @details Remove a key given the @mac_addr (%NULL for a group key)
1379 * and @key_index, return -ENOENT if the key doesn't exist.
1380 * @param[in]
1381 * @return int : Return 0 on Success
1382 * @author mdaftedar
1383 * @date 01 MAR 2012
1384 * @version 1.0
1385 */
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001386static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1387 u8 key_index,
1388 bool pairwise,
1389 const u8 *mac_addr)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001390{
Chaehyun Lim27268872015-09-15 14:06:13 +09001391 struct wilc_priv *priv;
Glen Lee692e2ac2015-10-20 17:14:00 +09001392 struct wilc *wl;
1393 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001394
1395 priv = wiphy_priv(wiphy);
Glen Lee692e2ac2015-10-20 17:14:00 +09001396 nic = netdev_priv(netdev);
1397 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001398
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001399 /*delete saved keys, if any*/
Glen Lee692e2ac2015-10-20 17:14:00 +09001400 if (netdev == wl->vif[0].ndev) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09001401 g_ptk_keys_saved = false;
1402 g_gtk_keys_saved = false;
1403 g_wep_keys_saved = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001404
1405 /*Delete saved WEP keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301406 kfree(g_key_wep_params.key);
1407 g_key_wep_params.key = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001408
1409 /*freeing memory allocated by "wilc_gtk" and "wilc_ptk" in "WILC_WIFI_ADD_KEY"*/
1410
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001411 if ((priv->wilc_gtk[key_index]) != NULL) {
1412
Shraddha Barkecccfc392015-10-12 20:49:19 +05301413 kfree(priv->wilc_gtk[key_index]->key);
1414 priv->wilc_gtk[key_index]->key = NULL;
1415 kfree(priv->wilc_gtk[key_index]->seq);
1416 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001417
Chaehyun Lim49188af2015-08-11 10:32:41 +09001418 kfree(priv->wilc_gtk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001419 priv->wilc_gtk[key_index] = NULL;
1420
1421 }
1422
1423 if ((priv->wilc_ptk[key_index]) != NULL) {
1424
Shraddha Barkecccfc392015-10-12 20:49:19 +05301425 kfree(priv->wilc_ptk[key_index]->key);
1426 priv->wilc_ptk[key_index]->key = NULL;
1427 kfree(priv->wilc_ptk[key_index]->seq);
1428 priv->wilc_ptk[key_index]->seq = NULL;
Chaehyun Lim49188af2015-08-11 10:32:41 +09001429 kfree(priv->wilc_ptk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001430 priv->wilc_ptk[key_index] = NULL;
1431 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001432
1433 /*Delete saved PTK and GTK keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301434 kfree(g_key_ptk_params.key);
1435 g_key_ptk_params.key = NULL;
1436 kfree(g_key_ptk_params.seq);
1437 g_key_ptk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001438
Shraddha Barkecccfc392015-10-12 20:49:19 +05301439 kfree(g_key_gtk_params.key);
1440 g_key_gtk_params.key = NULL;
1441 kfree(g_key_gtk_params.seq);
1442 g_key_gtk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001443
1444 /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001445 wilc_set_machw_change_vir_if(netdev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001446 }
1447
1448 if (key_index >= 0 && key_index <= 3) {
Chaehyun Lim2cc46832015-08-07 09:02:01 +09001449 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001450 priv->WILC_WFI_wep_key_len[key_index] = 0;
1451
1452 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001453 wilc_remove_wep_key(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001454 } else {
1455 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001456 wilc_remove_key(priv->hWILCWFIDrv, mac_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001457 }
1458
Leo Kimaaed3292015-10-12 16:55:38 +09001459 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001460}
1461
1462/**
Chaehyun Limf4893df2015-09-14 12:24:07 +09001463 * @brief get_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001464 * @details Get information about the key with the given parameters.
1465 * @mac_addr will be %NULL when requesting information for a group
1466 * key. All pointers given to the @callback function need not be valid
1467 * after it returns. This function should return an error if it is
1468 * not possible to retrieve the key, -ENOENT if it doesn't exist.
1469 * @param[in]
1470 * @return int : Return 0 on Success
1471 * @author mdaftedar
1472 * @date 01 MAR 2012
1473 * @version 1.0
1474 */
Chaehyun Limf4893df2015-09-14 12:24:07 +09001475static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1476 bool pairwise,
1477 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001478{
Chaehyun Lim27268872015-09-15 14:06:13 +09001479 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001480 struct key_params key_params;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001481 u32 i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001482
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001483 priv = wiphy_priv(wiphy);
1484
1485
Alison Schofield3604af52015-10-12 13:22:44 -07001486 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001487 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1488
1489 key_params.key = priv->wilc_gtk[key_index]->key;
1490 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1491 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1492 key_params.seq = priv->wilc_gtk[key_index]->seq;
1493 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1494 if (INFO) {
1495 for (i = 0; i < key_params.key_len; i++)
1496 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1497 }
1498 } else {
1499 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1500
1501 key_params.key = priv->wilc_ptk[key_index]->key;
1502 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1503 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1504 key_params.seq = priv->wilc_ptk[key_index]->seq;
1505 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1506 }
1507
1508 callback(cookie, &key_params);
1509
Leo Kimaaed3292015-10-12 16:55:38 +09001510 return 0; /* priv->wilc_gtk->key_len ?0 : -ENOENT; */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001511}
1512
1513/**
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001514 * @brief set_default_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001515 * @details Set the default management frame key on an interface
1516 * @param[in]
1517 * @return int : Return 0 on Success.
1518 * @author mdaftedar
1519 * @date 01 MAR 2012
1520 * @version 1.0
1521 */
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001522static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1523 bool unicast, bool multicast)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001524{
Chaehyun Lim27268872015-09-15 14:06:13 +09001525 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001526
1527
1528 priv = wiphy_priv(wiphy);
1529
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301530 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001531
1532 if (key_index != priv->WILC_WFI_wep_default) {
1533
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001534 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001535 }
1536
Leo Kimaaed3292015-10-12 16:55:38 +09001537 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001538}
1539
1540/**
Chaehyun Limf06f5622015-09-14 12:24:18 +09001541 * @brief get_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001542 * @details Get station information for the station identified by @mac
1543 * @param[in] NONE
1544 * @return int : Return 0 on Success.
1545 * @author mdaftedar
1546 * @date 01 MAR 2012
1547 * @version 1.0
1548 */
1549
Chaehyun Limf06f5622015-09-14 12:24:18 +09001550static int get_station(struct wiphy *wiphy, struct net_device *dev,
1551 const u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001552{
Chaehyun Lim27268872015-09-15 14:06:13 +09001553 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001554 perInterface_wlan_t *nic;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001555 u32 i = 0;
1556 u32 associatedsta = 0;
1557 u32 inactive_time = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001558 priv = wiphy_priv(wiphy);
1559 nic = netdev_priv(dev);
1560
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001561 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
1562 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1563
1564 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1565
1566 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1567
1568 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1569 associatedsta = i;
1570 break;
1571 }
1572
1573 }
1574
1575 if (associatedsta == -1) {
Leo Kimaaed3292015-10-12 16:55:38 +09001576 PRINT_ER("Station required is not associated\n");
1577 return -ENOENT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001578 }
1579
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001580 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001581
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001582 wilc_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001583 sinfo->inactive_time = 1000 * inactive_time;
1584 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
1585
1586 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001587
1588 if (nic->iftype == STATION_MODE) {
Leo Kim03e7b9c2015-10-12 16:55:58 +09001589 struct rf_info strStatistics;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001590
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001591 wilc_get_statistics(priv->hWILCWFIDrv, &strStatistics);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001592
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001593 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
Chandra S Gorentla62129902015-08-05 22:11:57 +05301594 BIT(NL80211_STA_INFO_RX_PACKETS) |
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001595 BIT(NL80211_STA_INFO_TX_PACKETS) |
1596 BIT(NL80211_STA_INFO_TX_FAILED) |
1597 BIT(NL80211_STA_INFO_TX_BITRATE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001598
Leo Kim00c8dfc2015-10-29 12:05:30 +09001599 sinfo->signal = strStatistics.rssi;
Leo Kim9b992742015-10-29 12:05:32 +09001600 sinfo->rx_packets = strStatistics.rx_cnt;
Leo Kim54160372015-10-29 12:05:33 +09001601 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1602 sinfo->tx_failed = strStatistics.tx_fail_cnt;
Leo Kim5babeec2015-10-29 12:05:29 +09001603 sinfo->txrate.legacy = strStatistics.link_speed * 10;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001604
Leo Kim5babeec2015-10-29 12:05:29 +09001605 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1606 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001607 wilc_enable_tcp_ack_filter(true);
Leo Kim5babeec2015-10-29 12:05:29 +09001608 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001609 wilc_enable_tcp_ack_filter(false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001610
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001611 PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
1612 sinfo->tx_failed, sinfo->txrate.legacy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001613 }
Leo Kimaaed3292015-10-12 16:55:38 +09001614 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001615}
1616
1617
1618/**
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001619 * @brief change_bss
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001620 * @details Modify parameters for a given BSS.
1621 * @param[in]
1622 * -use_cts_prot: Whether to use CTS protection
1623 * (0 = no, 1 = yes, -1 = do not change)
1624 * -use_short_preamble: Whether the use of short preambles is allowed
1625 * (0 = no, 1 = yes, -1 = do not change)
1626 * -use_short_slot_time: Whether the use of short slot time is allowed
1627 * (0 = no, 1 = yes, -1 = do not change)
1628 * -basic_rates: basic rates in IEEE 802.11 format
1629 * (or NULL for no change)
1630 * -basic_rates_len: number of basic rates
1631 * -ap_isolate: do not forward packets between connected stations
1632 * -ht_opmode: HT Operation mode
1633 * (u16 = opmode, -1 = do not change)
1634 * @return int : Return 0 on Success.
1635 * @author mdaftedar
1636 * @date 01 MAR 2012
1637 * @version 1.0
1638 */
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001639static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1640 struct bss_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001641{
1642 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1643 return 0;
1644}
1645
1646/**
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001647 * @brief set_wiphy_params
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001648 * @details Notify that wiphy parameters have changed;
1649 * @param[in] Changed bitfield (see &enum wiphy_params_flags) describes which values
1650 * have changed.
1651 * @return int : Return 0 on Success
1652 * @author mdaftedar
1653 * @date 01 MAR 2012
1654 * @version 1.0
1655 */
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001656static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001657{
Leo Kime6e12662015-09-16 18:36:03 +09001658 s32 s32Error = 0;
Leo Kim95296502015-10-05 15:25:46 +09001659 struct cfg_param_val pstrCfgParamVal;
Chaehyun Lim27268872015-09-15 14:06:13 +09001660 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001661
1662 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001663
Tony Cho87c05b22015-10-12 16:56:07 +09001664 pstrCfgParamVal.flag = 0;
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301665 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001666
1667 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1668 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1669 priv->dev->ieee80211_ptr->wiphy->retry_short);
Tony Cho87c05b22015-10-12 16:56:07 +09001670 pstrCfgParamVal.flag |= RETRY_SHORT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001671 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1672 }
1673 if (changed & WIPHY_PARAM_RETRY_LONG) {
1674
1675 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 +09001676 pstrCfgParamVal.flag |= RETRY_LONG;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001677 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1678
1679 }
1680 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1681 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 +09001682 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001683 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1684
1685 }
1686
1687 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1688 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1689
Tony Cho87c05b22015-10-12 16:56:07 +09001690 pstrCfgParamVal.flag |= RTS_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001691 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1692
1693 }
1694
1695 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001696 s32Error = wilc_hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001697 if (s32Error)
1698 PRINT_ER("Error in setting WIPHY PARAMS\n");
1699
1700
1701 return s32Error;
1702}
Arnd Bergmanne5af0562015-05-29 22:52:12 +02001703
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001704/**
Chaehyun Lim4d466572015-09-14 12:24:22 +09001705 * @brief set_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001706 * @details Cache a PMKID for a BSSID. This is mostly useful for fullmac
1707 * devices running firmwares capable of generating the (re) association
1708 * RSN IE. It allows for faster roaming between WPA2 BSSIDs.
1709 * @param[in]
1710 * @return int : Return 0 on Success
1711 * @author mdaftedar
1712 * @date 01 MAR 2012
1713 * @version 1.0
1714 */
Chaehyun Lim4d466572015-09-14 12:24:22 +09001715static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1716 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001717{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001718 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001719 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001720 u8 flag = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001721
Chaehyun Lim27268872015-09-15 14:06:13 +09001722 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001723
1724 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1725
1726
1727 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001728 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001729 ETH_ALEN)) {
1730 /*If bssid already exists and pmkid value needs to reset*/
1731 flag = PMKID_FOUND;
1732 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1733 break;
1734 }
1735 }
1736 if (i < WILC_MAX_NUM_PMKIDS) {
1737 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001738 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001739 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001740 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001741 PMKID_LEN);
1742 if (!(flag == PMKID_FOUND))
1743 priv->pmkid_list.numpmkid++;
1744 } else {
1745 PRINT_ER("Invalid PMKID index\n");
1746 s32Error = -EINVAL;
1747 }
1748
1749 if (!s32Error) {
1750 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001751 s32Error = wilc_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001752 }
1753 return s32Error;
1754}
1755
1756/**
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001757 * @brief del_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001758 * @details Delete a cached PMKID.
1759 * @param[in]
1760 * @return int : Return 0 on Success
1761 * @author mdaftedar
1762 * @date 01 MAR 2012
1763 * @version 1.0
1764 */
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001765static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1766 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001767{
1768
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001769 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001770 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001771
Chaehyun Lim27268872015-09-15 14:06:13 +09001772 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001773
1774 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1775
1776 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001777 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001778 ETH_ALEN)) {
1779 /*If bssid is found, reset the values*/
1780 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
Leo Kimcd1e6cb2015-10-05 15:25:45 +09001781 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001782 break;
1783 }
1784 }
1785
1786 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1787 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001788 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001789 priv->pmkid_list.pmkidlist[i + 1].bssid,
1790 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001791 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001792 priv->pmkid_list.pmkidlist[i].pmkid,
1793 PMKID_LEN);
1794 }
1795 priv->pmkid_list.numpmkid--;
1796 } else {
1797 s32Error = -EINVAL;
1798 }
1799
1800 return s32Error;
1801}
1802
1803/**
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001804 * @brief flush_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001805 * @details Flush all cached PMKIDs.
1806 * @param[in]
1807 * @return int : Return 0 on Success
1808 * @author mdaftedar
1809 * @date 01 MAR 2012
1810 * @version 1.0
1811 */
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001812static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001813{
Chaehyun Lim27268872015-09-15 14:06:13 +09001814 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001815
1816 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
1817
1818 /*Get cashed Pmkids and set all with zeros*/
Leo Kima949f902015-10-05 15:25:44 +09001819 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001820
1821 return 0;
1822}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001823
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001824
1825/**
1826 * @brief WILC_WFI_CfgParseRxAction
1827 * @details Function parses the received frames and modifies the following attributes:
1828 * -GO Intent
1829 * -Channel list
1830 * -Operating Channel
1831 *
1832 * @param[in] u8* Buffer, u32 length
1833 * @return NONE.
1834 * @author mdaftedar
1835 * @date 12 DEC 2012
1836 * @version
1837 */
1838
Arnd Bergmann1608c402015-11-16 15:04:53 +01001839static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001840{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001841 u32 index = 0;
1842 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001843
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001844 u8 op_channel_attr_index = 0;
1845 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001846
1847 while (index < len) {
1848 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001849 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001850 }
1851
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301852 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001853 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301854 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001855 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001856 index += buf[index + 1] + 3; /* ID,Length byte */
1857 }
Alison Schofield3604af52015-10-12 13:22:44 -07001858 if (u8WLANChannel != INVALID_CHANNEL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001859
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001860 /*Modify channel list attribute*/
1861 if (channel_list_attr_index) {
1862 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1863 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1864 if (buf[i] == 0x51) {
1865 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
1866 buf[j] = u8WLANChannel;
1867 }
1868 break;
1869 }
1870 }
1871 }
1872 /*Modify operating channel attribute*/
1873 if (op_channel_attr_index) {
1874 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1875 buf[op_channel_attr_index + 6] = 0x51;
1876 buf[op_channel_attr_index + 7] = u8WLANChannel;
1877 }
1878 }
1879}
1880
1881/**
1882 * @brief WILC_WFI_CfgParseTxAction
1883 * @details Function parses the transmitted action frames and modifies the
1884 * GO Intent attribute
1885 * @param[in] u8* Buffer, u32 length, bool bOperChan, u8 iftype
1886 * @return NONE.
1887 * @author mdaftedar
1888 * @date 12 DEC 2012
1889 * @version
1890 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01001891static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001892{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001893 u32 index = 0;
1894 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001895
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001896 u8 op_channel_attr_index = 0;
1897 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001898
1899 while (index < len) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001900 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001901 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001902
1903 break;
1904 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001905
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301906 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001907 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301908 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001909 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001910 index += buf[index + 1] + 3; /* ID,Length byte */
1911 }
Alison Schofield3604af52015-10-12 13:22:44 -07001912 if (u8WLANChannel != INVALID_CHANNEL && bOperChan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001913
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001914 /*Modify channel list attribute*/
1915 if (channel_list_attr_index) {
1916 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1917 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1918 if (buf[i] == 0x51) {
1919 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
1920 buf[j] = u8WLANChannel;
1921 }
1922 break;
1923 }
1924 }
1925 }
1926 /*Modify operating channel attribute*/
1927 if (op_channel_attr_index) {
1928 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1929 buf[op_channel_attr_index + 6] = 0x51;
1930 buf[op_channel_attr_index + 7] = u8WLANChannel;
1931 }
1932 }
1933}
1934
1935/* @brief WILC_WFI_p2p_rx
1936 * @details
1937 * @param[in]
1938 *
1939 * @return None
1940 * @author Mai Daftedar
1941 * @date 2 JUN 2013
1942 * @version 1.0
1943 */
1944
Chaehyun Limfbc2fe12015-09-15 14:06:16 +09001945void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001946{
1947
Chaehyun Lim27268872015-09-15 14:06:13 +09001948 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001949 u32 header, pkt_offset;
Leo Kim441dc602015-10-12 16:55:35 +09001950 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001951 u32 i = 0;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001952 s32 s32Freq;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001953
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001954 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001955 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001956
1957 /* Get WILC header */
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001958 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001959
1960 /* The packet offset field conain info about what type of managment frame */
1961 /* we are dealing with and ack status */
1962 pkt_offset = GET_PKT_OFFSET(header);
1963
1964 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1965 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1966 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001967 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001968 return;
1969 } else {
1970 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
1971 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],
1972 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001973 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001974 } else {
1975 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],
1976 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001977 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001978 }
1979 return;
1980 }
1981 } else {
1982
1983 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
1984
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001985 /*Upper layer is informed that the frame is received on this freq*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001986 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001987
1988 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1989 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
1990
Leo Kim1229b1a2015-10-29 12:05:39 +09001991 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001992 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
1993 return;
1994 }
1995 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1996
1997 switch (buff[ACTION_SUBTYPE_ID]) {
1998 case GAS_INTIAL_REQ:
1999 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
2000 break;
2001
2002 case GAS_INTIAL_RSP:
2003 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
2004 break;
2005
2006 case PUBLIC_ACT_VENDORSPEC:
2007 /*Now we have a public action vendor specific action frame, check if its a p2p public action frame
2008 * 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 +09002009 if (!memcmp(u8P2P_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002010 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
2011 if (!bWilc_ie) {
2012 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002013 if (!memcmp(u8P2P_vendorspec, &buff[i], 6)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002014 u8P2Precvrandom = buff[i + 6];
Dean Lee72ed4dc2015-06-12 14:11:44 +09002015 bWilc_ie = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002016 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", u8P2Precvrandom);
2017 break;
2018 }
2019 }
2020 }
2021 }
2022 if (u8P2Plocalrandom > u8P2Precvrandom) {
2023 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2024 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2025 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002026 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(u8P2P_oui, &buff[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002027 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
2028 break;
2029 }
2030 }
2031 }
2032 } else
2033 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2034 }
2035
2036
2037 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (bWilc_ie)) {
2038 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
2039 /* extra attribute for sig_dbm: signal strength in mBm, or 0 if unknown */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002040 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002041 return;
2042 }
2043 break;
2044
2045 default:
2046 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
2047 break;
2048 }
2049 }
2050 }
2051
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002052 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002053 }
2054}
2055
2056/**
2057 * @brief WILC_WFI_mgmt_tx_complete
2058 * @details Returns result of writing mgmt frame to VMM (Tx buffers are freed here)
2059 * @param[in] priv
2060 * transmitting status
2061 * @return None
2062 * @author Amr Abdelmoghny
2063 * @date 20 MAY 2013
2064 * @version 1.0
2065 */
2066static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
2067{
2068 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
2069
2070
2071 kfree(pv_data->buff);
2072 kfree(pv_data);
2073}
2074
2075/**
2076 * @brief WILC_WFI_RemainOnChannelReady
2077 * @details Callback function, called from handle_remain_on_channel on being ready on channel
2078 * @param
2079 * @return none
2080 * @author Amr abdelmoghny
2081 * @date 9 JUNE 2013
2082 * @version
2083 */
2084
2085static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
2086{
Chaehyun Lim27268872015-09-15 14:06:13 +09002087 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002088
Chaehyun Lim27268872015-09-15 14:06:13 +09002089 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002090
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302091 PRINT_D(HOSTINF_DBG, "Remain on channel ready\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002092
Dean Lee72ed4dc2015-06-12 14:11:44 +09002093 priv->bInP2PlistenState = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002094
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002095 cfg80211_ready_on_channel(priv->wdev,
2096 priv->strRemainOnChanParams.u64ListenCookie,
2097 priv->strRemainOnChanParams.pstrListenChan,
2098 priv->strRemainOnChanParams.u32ListenDuration,
2099 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002100}
2101
2102/**
2103 * @brief WILC_WFI_RemainOnChannelExpired
2104 * @details Callback function, called on expiration of remain-on-channel duration
2105 * @param
2106 * @return none
2107 * @author Amr abdelmoghny
2108 * @date 15 MAY 2013
2109 * @version
2110 */
2111
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002112static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002113{
Chaehyun Lim27268872015-09-15 14:06:13 +09002114 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002115
Chaehyun Lim27268872015-09-15 14:06:13 +09002116 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002117
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002118 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302119 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002120
Dean Lee72ed4dc2015-06-12 14:11:44 +09002121 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002122
2123 /*Inform wpas of remain-on-channel expiration*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002124 cfg80211_remain_on_channel_expired(priv->wdev,
2125 priv->strRemainOnChanParams.u64ListenCookie,
2126 priv->strRemainOnChanParams.pstrListenChan,
2127 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002128 } else {
2129 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
2130 , priv->strRemainOnChanParams.u32ListenSessionID);
2131 }
2132}
2133
2134
2135/**
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002136 * @brief remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002137 * @details Request the driver to remain awake on the specified
2138 * channel for the specified duration to complete an off-channel
2139 * operation (e.g., public action frame exchange). When the driver is
2140 * ready on the requested channel, it must indicate this with an event
2141 * notification by calling cfg80211_ready_on_channel().
2142 * @param[in]
2143 * @return int : Return 0 on Success
2144 * @author mdaftedar
2145 * @date 01 MAR 2012
2146 * @version 1.0
2147 */
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002148static int remain_on_channel(struct wiphy *wiphy,
2149 struct wireless_dev *wdev,
2150 struct ieee80211_channel *chan,
2151 unsigned int duration, u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002152{
Leo Kime6e12662015-09-16 18:36:03 +09002153 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002154 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002155
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002156 priv = wiphy_priv(wiphy);
2157
2158 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
2159
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002160
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002161 if (wdev->iftype == NL80211_IFTYPE_AP) {
2162 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
2163 return s32Error;
2164 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002165
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002166 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002167
2168 /*Setting params needed by WILC_WFI_RemainOnChannelExpired()*/
2169 priv->strRemainOnChanParams.pstrListenChan = chan;
2170 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002171 priv->strRemainOnChanParams.u32ListenDuration = duration;
2172 priv->strRemainOnChanParams.u32ListenSessionID++;
2173
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002174 s32Error = wilc_remain_on_channel(priv->hWILCWFIDrv
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002175 , priv->strRemainOnChanParams.u32ListenSessionID
2176 , duration
2177 , chan->hw_value
2178 , WILC_WFI_RemainOnChannelExpired
2179 , WILC_WFI_RemainOnChannelReady
2180 , (void *)priv);
2181
2182 return s32Error;
2183}
2184
2185/**
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002186 * @brief cancel_remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002187 * @details Cancel an on-going remain-on-channel operation.
2188 * This allows the operation to be terminated prior to timeout based on
2189 * the duration value.
2190 * @param[in] struct wiphy *wiphy,
2191 * @param[in] struct net_device *dev
2192 * @param[in] u64 cookie,
2193 * @return int : Return 0 on Success
2194 * @author mdaftedar
2195 * @date 01 MAR 2012
2196 * @version 1.0
2197 */
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002198static int cancel_remain_on_channel(struct wiphy *wiphy,
2199 struct wireless_dev *wdev,
2200 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002201{
Leo Kime6e12662015-09-16 18:36:03 +09002202 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002203 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002204
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002205 priv = wiphy_priv(wiphy);
2206
2207 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
2208
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002209 s32Error = wilc_listen_state_expired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002210 return s32Error;
2211}
2212/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002213 * @brief WILC_WFI_mgmt_tx_frame
2214 * @details
2215 *
2216 * @param[in]
2217 * @return NONE.
2218 * @author mdaftedar
2219 * @date 01 JUL 2012
2220 * @version
2221 */
Chaehyun Limc1560322015-09-22 18:34:51 +09002222static int mgmt_tx(struct wiphy *wiphy,
2223 struct wireless_dev *wdev,
2224 struct cfg80211_mgmt_tx_params *params,
2225 u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002226{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002227 struct ieee80211_channel *chan = params->chan;
2228 unsigned int wait = params->wait;
2229 const u8 *buf = params->buf;
2230 size_t len = params->len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002231 const struct ieee80211_mgmt *mgmt;
2232 struct p2p_mgmt_data *mgmt_tx;
Chaehyun Lim27268872015-09-15 14:06:13 +09002233 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002234 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002235 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002236 perInterface_wlan_t *nic;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002237 u32 buf_len = len + sizeof(u8P2P_vendorspec) + sizeof(u8P2Plocalrandom);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002238
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002239 nic = netdev_priv(wdev->netdev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002240 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002241 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002242
2243 *cookie = (unsigned long)buf;
2244 priv->u64tx_cookie = *cookie;
2245 mgmt = (const struct ieee80211_mgmt *) buf;
2246
2247 if (ieee80211_is_mgmt(mgmt->frame_control)) {
2248
2249 /*mgmt frame allocation*/
Glen Leef3052582015-09-10 12:03:04 +09002250 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002251 if (mgmt_tx == NULL) {
2252 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
Leo Kime6e12662015-09-16 18:36:03 +09002253 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002254 }
Glen Leef3052582015-09-10 12:03:04 +09002255 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002256 if (mgmt_tx->buff == NULL) {
2257 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
Tony Chof638dd32015-09-07 19:09:31 +09002258 kfree(mgmt_tx);
Leo Kime6e12662015-09-16 18:36:03 +09002259 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002260 }
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09002261 memcpy(mgmt_tx->buff, buf, len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002262 mgmt_tx->size = len;
2263
2264
2265 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
2266 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
2267 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002268 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002269 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002270 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002271 } else if (ieee80211_is_action(mgmt->frame_control)) {
Chaehyun Limd85f5322015-06-11 14:35:54 +09002272 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002273
2274
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002275 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002276 /*Only set the channel, if not a negotiation confirmation frame
2277 * (If Negotiation confirmation frame, force it
2278 * to be transmitted on the same negotiation channel)*/
2279
2280 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
2281 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
2282 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002283 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002284 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002285 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002286 }
2287 switch (buf[ACTION_SUBTYPE_ID]) {
2288 case GAS_INTIAL_REQ:
2289 {
2290 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
2291 break;
2292 }
2293
2294 case GAS_INTIAL_RSP:
2295 {
2296 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
2297 break;
2298 }
2299
2300 case PUBLIC_ACT_VENDORSPEC:
2301 {
2302 /*Now we have a public action vendor specific action frame, check if its a p2p public action frame
2303 * 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 +09002304 if (!memcmp(u8P2P_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002305 /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/
2306 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
2307 if (u8P2Plocalrandom == 1 && u8P2Precvrandom < u8P2Plocalrandom) {
2308 get_random_bytes(&u8P2Plocalrandom, 1);
2309 /*Increment the number to prevent if its 0*/
2310 u8P2Plocalrandom++;
2311 }
2312 }
2313
2314 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2315 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2316 if (u8P2Plocalrandom > u8P2Precvrandom) {
2317 PRINT_D(GENERIC_DBG, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2318
2319 /*Search for the p2p information information element , after the Public action subtype theres a byte for teh dialog token, skip that*/
2320 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002321 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(u8P2P_oui, &buf[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002322 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
Dean Lee72ed4dc2015-06-12 14:11:44 +09002323 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002324
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002325 /*If using supplicant go intent, no need at all*/
2326 /*to parse transmitted negotiation frames*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002327 else
Dean Lee72ed4dc2015-06-12 14:11:44 +09002328 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002329 break;
2330 }
2331 }
2332
2333 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
Shivani Bhardwajd8060fc2015-10-29 00:30:01 +05302334 /*
2335 * Adding WILC information element to allow two WILC devices to
2336 * identify each other and connect
2337 */
2338 memcpy(&mgmt_tx->buff[len], u8P2P_vendorspec, sizeof(u8P2P_vendorspec));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002339 mgmt_tx->buff[len + sizeof(u8P2P_vendorspec)] = u8P2Plocalrandom;
2340 mgmt_tx->size = buf_len;
2341 }
2342 } else
2343 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2344 }
2345
2346 } else {
2347 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
2348 }
2349
2350 break;
2351 }
2352
2353 default:
2354 {
2355 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
2356 break;
2357 }
2358 }
2359
2360 }
2361
2362 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 +09002363 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002364
Leo Kim1229b1a2015-10-29 12:05:39 +09002365 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n",
2366 jiffies, pstrWFIDrv->p2p_timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002367 }
2368
Glen Lee829c4772015-10-29 12:18:44 +09002369 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
2370 mgmt_tx->buff, mgmt_tx->size,
Glen Leec9d48342015-10-01 16:03:43 +09002371 WILC_WFI_mgmt_tx_complete);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002372 } else {
2373 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
2374 }
Leo Kimaaed3292015-10-12 16:55:38 +09002375 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002376}
2377
Chaehyun Lim85c587a2015-09-22 18:34:50 +09002378static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
2379 struct wireless_dev *wdev,
2380 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002381{
Chaehyun Lim27268872015-09-15 14:06:13 +09002382 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002383 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002384
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002385 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002386 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002387
2388
2389 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
Leo Kim1229b1a2015-10-29 12:05:39 +09002390 pstrWFIDrv->p2p_timeout = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002391
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +01002392 if (!priv->bInP2PlistenState) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002393 cfg80211_remain_on_channel_expired(priv->wdev,
2394 priv->strRemainOnChanParams.u64ListenCookie,
2395 priv->strRemainOnChanParams.pstrListenChan,
2396 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002397 }
2398
2399 return 0;
2400}
2401
2402/**
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002403 * @brief wilc_mgmt_frame_register
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002404 * @details Notify driver that a management frame type was
2405 * registered. Note that this callback may not sleep, and cannot run
2406 * concurrently with itself.
2407 * @param[in]
2408 * @return NONE.
2409 * @author mdaftedar
2410 * @date 01 JUL 2012
2411 * @version
2412 */
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002413void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
2414 u16 frame_type, bool reg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002415{
2416
Chaehyun Lim27268872015-09-15 14:06:13 +09002417 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002418 perInterface_wlan_t *nic;
Glen Lee1b869352015-10-20 17:14:01 +09002419 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002420
2421 priv = wiphy_priv(wiphy);
2422 nic = netdev_priv(priv->wdev->netdev);
Glen Lee1b869352015-10-20 17:14:01 +09002423 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002424
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002425 if (!frame_type)
2426 return;
2427
2428 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
2429 switch (frame_type) {
2430 case PROBE_REQ:
2431 {
2432 nic->g_struct_frame_reg[0].frame_type = frame_type;
2433 nic->g_struct_frame_reg[0].reg = reg;
2434 }
2435 break;
2436
2437 case ACTION:
2438 {
2439 nic->g_struct_frame_reg[1].frame_type = frame_type;
2440 nic->g_struct_frame_reg[1].reg = reg;
2441 }
2442 break;
2443
2444 default:
2445 {
2446 break;
2447 }
2448
2449 }
2450 /*If mac is closed, then return*/
Glen Lee1b869352015-10-20 17:14:01 +09002451 if (!wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002452 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
2453 return;
2454 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002455 wilc_frame_register(priv->hWILCWFIDrv, frame_type, reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002456
2457
2458}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002459
2460/**
Chaehyun Lima8047e22015-09-22 18:34:48 +09002461 * @brief set_cqm_rssi_config
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002462 * @details Configure connection quality monitor RSSI threshold.
2463 * @param[in] struct wiphy *wiphy:
2464 * @param[in] struct net_device *dev:
2465 * @param[in] s32 rssi_thold:
2466 * @param[in] u32 rssi_hyst:
2467 * @return int : Return 0 on Success
2468 * @author mdaftedar
2469 * @date 01 MAR 2012
2470 * @version 1.0
2471 */
Chaehyun Lima8047e22015-09-22 18:34:48 +09002472static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
2473 s32 rssi_thold, u32 rssi_hyst)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002474{
2475 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2476 return 0;
2477
2478}
2479/**
Chaehyun Limbdb63382015-09-14 12:24:19 +09002480 * @brief dump_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002481 * @details Configure connection quality monitor RSSI threshold.
2482 * @param[in] struct wiphy *wiphy:
2483 * @param[in] struct net_device *dev
2484 * @param[in] int idx
2485 * @param[in] u8 *mac
2486 * @param[in] struct station_info *sinfo
2487 * @return int : Return 0 on Success
2488 * @author mdaftedar
2489 * @date 01 MAR 2012
2490 * @version 1.0
2491 */
Chaehyun Limbdb63382015-09-14 12:24:19 +09002492static int dump_station(struct wiphy *wiphy, struct net_device *dev,
2493 int idx, u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002494{
Chaehyun Lim27268872015-09-15 14:06:13 +09002495 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002496
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002497 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2498
2499 if (idx != 0)
2500 return -ENOENT;
2501
2502 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002503
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002504 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002505
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002506 wilc_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002507
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002508 return 0;
2509
2510}
2511
2512
2513/**
Chaehyun Lim46530672015-09-22 18:34:46 +09002514 * @brief set_power_mgmt
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002515 * @details
2516 * @param[in]
2517 * @return int : Return 0 on Success.
2518 * @author mdaftedar
2519 * @date 01 JUL 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09002520 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002521 */
Chaehyun Lim46530672015-09-22 18:34:46 +09002522static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2523 bool enabled, int timeout)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002524{
Chaehyun Lim27268872015-09-15 14:06:13 +09002525 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002526
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002527 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2528
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002529 if (wiphy == NULL)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002530 return -ENOENT;
2531
2532 priv = wiphy_priv(wiphy);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002533 if (priv->hWILCWFIDrv == NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002534 PRINT_ER("Driver is NULL\n");
2535 return -EIO;
2536 }
2537
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002538 if (wilc_enable_ps)
2539 wilc_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002540
2541
Leo Kime6e12662015-09-16 18:36:03 +09002542 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002543
2544}
Glen Lee108b3432015-09-16 18:53:20 +09002545
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002546/**
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002547 * @brief change_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002548 * @details Change type/configuration of virtual interface,
2549 * keep the struct wireless_dev's iftype updated.
2550 * @param[in] NONE
2551 * @return int : Return 0 on Success.
2552 * @author mdaftedar
2553 * @date 01 MAR 2012
2554 * @version 1.0
2555 */
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002556static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2557 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002558{
Chaehyun Lim27268872015-09-15 14:06:13 +09002559 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002560 perInterface_wlan_t *nic;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002561 u8 interface_type;
Chaehyun Limd85f5322015-06-11 14:35:54 +09002562 u16 TID = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002563 u8 i;
Glen Lee299382c2015-10-20 17:13:56 +09002564 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002565
2566 nic = netdev_priv(dev);
2567 priv = wiphy_priv(wiphy);
Glen Lee299382c2015-10-20 17:13:56 +09002568 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002569
2570 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2571 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
2572 u8P2Plocalrandom = 0x01;
2573 u8P2Precvrandom = 0x00;
2574
Dean Lee72ed4dc2015-06-12 14:11:44 +09002575 bWilc_ie = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002576
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002577 wilc_optaining_ip = false;
2578 del_timer(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002579 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002580 /*Set WILC_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/
2581 if (g_ptk_keys_saved && g_gtk_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002582 wilc_set_machw_change_vir_if(dev, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002583 }
2584
2585 switch (type) {
2586 case NL80211_IFTYPE_STATION:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002587 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002588 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002589
2590 /* send delba over wlan interface */
2591
2592
2593 dev->ieee80211_ptr->iftype = type;
2594 priv->wdev->iftype = type;
2595 nic->monitor_flag = 0;
2596 nic->iftype = STATION_MODE;
2597
2598 /*Remove the enteries of the previously connected clients*/
2599 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002600 interface_type = nic->iftype;
2601 nic->iftype = STATION_MODE;
2602
Glen Lee299382c2015-10-20 17:13:56 +09002603 if (wl->initialized) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002604 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2605 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002606 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002607 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002608
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002609 /*Eliminate host interface blocking state*/
Glen Lee299382c2015-10-20 17:13:56 +09002610 up(&wl->cfg_event);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002611
Glen Lee53dc0cf2015-10-20 17:13:57 +09002612 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002613 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002614 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002615 nic->iftype = interface_type;
2616
2617 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002618 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2619 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002620 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002621 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002622
2623 /*Add saved WEP keys, if any*/
2624 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002625 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002626 g_key_wep_params.key_idx);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002627 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002628 g_key_wep_params.key,
2629 g_key_wep_params.key_len,
2630 g_key_wep_params.key_idx);
2631 }
2632
2633 /*No matter the driver handler passed here, it will be overwriiten*/
2634 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002635 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002636
2637 /*Add saved PTK and GTK keys, if any*/
2638 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2639 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2640 g_key_ptk_params.key[1],
2641 g_key_ptk_params.key[2]);
2642 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2643 g_key_gtk_params.key[1],
2644 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002645 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2646 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002647 g_add_ptk_key_params.key_idx,
2648 g_add_ptk_key_params.pairwise,
2649 g_add_ptk_key_params.mac_addr,
2650 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002651
Glen Lee299382c2015-10-20 17:13:56 +09002652 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2653 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002654 g_add_gtk_key_params.key_idx,
2655 g_add_gtk_key_params.pairwise,
2656 g_add_gtk_key_params.mac_addr,
2657 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002658 }
2659
Glen Lee299382c2015-10-20 17:13:56 +09002660 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002661 for (i = 0; i < num_reg_frame; i++) {
2662 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2663 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002664 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002665 nic->g_struct_frame_reg[i].frame_type,
2666 nic->g_struct_frame_reg[i].reg);
2667 }
2668 }
2669
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002670 wilc_enable_ps = true;
2671 wilc_set_power_mgmt(priv->hWILCWFIDrv, 1, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002672 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002673 break;
2674
2675 case NL80211_IFTYPE_P2P_CLIENT:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002676 wilc_enable_ps = false;
2677 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
2678 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002679 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002680
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002681 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2682 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002683
2684 dev->ieee80211_ptr->iftype = type;
2685 priv->wdev->iftype = type;
2686 nic->monitor_flag = 0;
2687
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002688 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2689 nic->iftype = CLIENT_MODE;
2690
2691
Glen Lee299382c2015-10-20 17:13:56 +09002692 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002693 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002694 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002695
Glen Lee53dc0cf2015-10-20 17:13:57 +09002696 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002697 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002698 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002699
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002700 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2701 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002702 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002703 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002704
2705 /*Add saved WEP keys, if any*/
2706 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002707 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2708 g_key_wep_params.key_idx);
2709 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
2710 g_key_wep_params.key,
2711 g_key_wep_params.key_len,
2712 g_key_wep_params.key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002713 }
2714
2715 /*No matter the driver handler passed here, it will be overwriiten*/
2716 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002717 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002718
2719 /*Add saved PTK and GTK keys, if any*/
2720 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2721 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2722 g_key_ptk_params.key[1],
2723 g_key_ptk_params.key[2]);
2724 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2725 g_key_gtk_params.key[1],
2726 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002727 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2728 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002729 g_add_ptk_key_params.key_idx,
2730 g_add_ptk_key_params.pairwise,
2731 g_add_ptk_key_params.mac_addr,
2732 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002733
Glen Lee299382c2015-10-20 17:13:56 +09002734 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2735 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002736 g_add_gtk_key_params.key_idx,
2737 g_add_gtk_key_params.pairwise,
2738 g_add_gtk_key_params.mac_addr,
2739 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002740 }
2741
2742 /*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 +09002743 refresh_scan(priv, 1, true);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002744 wilc_set_machw_change_vir_if(dev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002745
Glen Lee299382c2015-10-20 17:13:56 +09002746 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002747 for (i = 0; i < num_reg_frame; i++) {
2748 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2749 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002750 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002751 nic->g_struct_frame_reg[i].frame_type,
2752 nic->g_struct_frame_reg[i].reg);
2753 }
2754 }
2755 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002756 break;
2757
2758 case NL80211_IFTYPE_AP:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002759 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002760 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002761 dev->ieee80211_ptr->iftype = type;
2762 priv->wdev->iftype = type;
2763 nic->iftype = AP_MODE;
Johnny Kim8a143302015-06-10 17:06:46 +09002764 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002765
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002766 PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002767 wilc_wlan_get_firmware(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002768 /*If wilc is running, then close-open to actually get new firmware running (serves P2P)*/
Glen Lee299382c2015-10-20 17:13:56 +09002769 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002770 nic->iftype = AP_MODE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002771 wilc_mac_close(dev);
2772 wilc_mac_open(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002773
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002774 for (i = 0; i < num_reg_frame; i++) {
2775 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2776 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002777 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002778 nic->g_struct_frame_reg[i].frame_type,
2779 nic->g_struct_frame_reg[i].reg);
2780 }
2781 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002782 break;
2783
2784 case NL80211_IFTYPE_P2P_GO:
2785 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
2786
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002787 wilc_optaining_ip = true;
2788 mod_timer(&wilc_during_ip_timer, jiffies + msecs_to_jiffies(duringIP_TIME));
2789 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002790 /*Delete block ack has to be the latest config packet*/
2791 /*sent before downloading new FW. This is because it blocks on*/
2792 /*hWaitResponse semaphore, which allows previous config*/
2793 /*packets to actually take action on old FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002794 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2795 wl->vif[0].bssid, TID);
2796 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002797 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002798 dev->ieee80211_ptr->iftype = type;
2799 priv->wdev->iftype = type;
2800
Johnny Kim8a143302015-06-10 17:06:46 +09002801 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002802
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002803 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2804
2805
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002806 nic->iftype = GO_MODE;
2807
2808 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002809 wilc_wait_msg_queue_idle();
Glen Lee53dc0cf2015-10-20 17:13:57 +09002810 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002811 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002812 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002813
2814
2815 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002816 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2817 wilc_set_mac_address(wl->vif[0].hif_drv,
2818 wl->vif[0].src_addr);
2819 wilc_set_operation_mode(priv->hWILCWFIDrv, AP_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002820
2821 /*Add saved WEP keys, if any*/
2822 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002823 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2824 g_key_wep_params.key_idx);
2825 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002826 g_key_wep_params.key,
2827 g_key_wep_params.key_len,
2828 g_key_wep_params.key_idx);
2829 }
2830
2831 /*No matter the driver handler passed here, it will be overwriiten*/
2832 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002833 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002834
2835 /*Add saved PTK and GTK keys, if any*/
2836 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2837 PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0],
2838 g_key_ptk_params.key[1],
2839 g_key_ptk_params.key[2],
2840 g_key_ptk_params.cipher);
2841 PRINT_D(CFG80211_DBG, "gtk %x %x %x cipher %x\n", g_key_gtk_params.key[0],
2842 g_key_gtk_params.key[1],
2843 g_key_gtk_params.key[2],
2844 g_key_gtk_params.cipher);
Glen Lee299382c2015-10-20 17:13:56 +09002845 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2846 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002847 g_add_ptk_key_params.key_idx,
2848 g_add_ptk_key_params.pairwise,
2849 g_add_ptk_key_params.mac_addr,
2850 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002851
Glen Lee299382c2015-10-20 17:13:56 +09002852 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2853 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002854 g_add_gtk_key_params.key_idx,
2855 g_add_gtk_key_params.pairwise,
2856 g_add_gtk_key_params.mac_addr,
2857 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002858 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002859
Glen Lee299382c2015-10-20 17:13:56 +09002860 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002861 for (i = 0; i < num_reg_frame; i++) {
2862 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2863 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002864 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002865 nic->g_struct_frame_reg[i].frame_type,
2866 nic->g_struct_frame_reg[i].reg);
2867 }
2868 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002869 break;
2870
2871 default:
2872 PRINT_ER("Unknown interface type= %d\n", type);
Leo Kimaaed3292015-10-12 16:55:38 +09002873 return -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002874 }
2875
Leo Kimaaed3292015-10-12 16:55:38 +09002876 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002877}
2878
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002879/* (austin.2013-07-23)
2880 *
2881 * To support revised cfg80211_ops
2882 *
2883 * add_beacon --> start_ap
2884 * set_beacon --> change_beacon
2885 * del_beacon --> stop_ap
2886 *
2887 * beacon_parameters --> cfg80211_ap_settings
2888 * cfg80211_beacon_data
2889 *
2890 * applicable for linux kernel 3.4+
2891 */
2892
2893/**
Chaehyun Lima13168d2015-09-14 12:24:12 +09002894 * @brief start_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002895 * @details Add a beacon with given parameters, @head, @interval
2896 * and @dtim_period will be valid, @tail is optional.
2897 * @param[in] wiphy
2898 * @param[in] dev The net device structure
2899 * @param[in] settings cfg80211_ap_settings parameters for the beacon to be added
2900 * @return int : Return 0 on Success.
2901 * @author austin
2902 * @date 23 JUL 2013
2903 * @version 1.0
2904 */
Chaehyun Lima13168d2015-09-14 12:24:12 +09002905static int start_ap(struct wiphy *wiphy, struct net_device *dev,
2906 struct cfg80211_ap_settings *settings)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002907{
2908 struct cfg80211_beacon_data *beacon = &(settings->beacon);
Chaehyun Lim27268872015-09-15 14:06:13 +09002909 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002910 s32 s32Error = 0;
Glen Lee684dc182015-10-20 17:14:02 +09002911 struct wilc *wl;
2912 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002913
2914 priv = wiphy_priv(wiphy);
Glen Lee684dc182015-10-20 17:14:02 +09002915 nic = netdev_priv(dev);
2916 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002917 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
2918
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302919 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 +09002920 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
2921
Chaehyun Lim80785a92015-09-14 12:24:01 +09002922 s32Error = set_channel(wiphy, &settings->chandef);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002923
Leo Kime6e12662015-09-16 18:36:03 +09002924 if (s32Error != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002925 PRINT_ER("Error in setting channel\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002926
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002927 wilc_wlan_set_bssid(dev, wl->vif[0].src_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002928
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002929 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002930 settings->beacon_interval,
2931 settings->dtim_period,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002932 beacon->head_len, (u8 *)beacon->head,
2933 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002934
2935 return s32Error;
2936}
2937
2938/**
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002939 * @brief change_beacon
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002940 * @details Add a beacon with given parameters, @head, @interval
2941 * and @dtim_period will be valid, @tail is optional.
2942 * @param[in] wiphy
2943 * @param[in] dev The net device structure
2944 * @param[in] beacon cfg80211_beacon_data for the beacon to be changed
2945 * @return int : Return 0 on Success.
2946 * @author austin
2947 * @date 23 JUL 2013
2948 * @version 1.0
2949 */
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002950static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
2951 struct cfg80211_beacon_data *beacon)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002952{
Chaehyun Lim27268872015-09-15 14:06:13 +09002953 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002954 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002955
2956 priv = wiphy_priv(wiphy);
2957 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
2958
2959
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002960 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002961 0,
2962 0,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002963 beacon->head_len, (u8 *)beacon->head,
2964 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002965
2966 return s32Error;
2967}
2968
2969/**
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002970 * @brief stop_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002971 * @details Remove beacon configuration and stop sending the beacon.
2972 * @param[in]
2973 * @return int : Return 0 on Success.
2974 * @author austin
2975 * @date 23 JUL 2013
2976 * @version 1.0
2977 */
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002978static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002979{
Leo Kime6e12662015-09-16 18:36:03 +09002980 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002981 struct wilc_priv *priv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002982 u8 NullBssid[ETH_ALEN] = {0};
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002983
Leo Kim7ae43362015-09-16 18:35:59 +09002984 if (!wiphy)
2985 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002986
2987 priv = wiphy_priv(wiphy);
2988
2989 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
2990
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002991 wilc_wlan_set_bssid(dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002992
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002993 s32Error = wilc_del_beacon(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002994
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002995 if (s32Error)
2996 PRINT_ER("Host delete beacon fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002997
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002998 return s32Error;
2999}
3000
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003001/**
Chaehyun Limed269552015-09-14 12:24:15 +09003002 * @brief add_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003003 * @details Add a new station.
3004 * @param[in]
3005 * @return int : Return 0 on Success.
3006 * @author mdaftedar
3007 * @date 01 MAR 2012
3008 * @version 1.0
3009 */
Chaehyun Limed269552015-09-14 12:24:15 +09003010static int add_station(struct wiphy *wiphy, struct net_device *dev,
3011 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003012{
Leo Kime6e12662015-09-16 18:36:03 +09003013 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003014 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09003015 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003016 perInterface_wlan_t *nic;
3017
Leo Kim7ae43362015-09-16 18:35:59 +09003018 if (!wiphy)
3019 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003020
3021 priv = wiphy_priv(wiphy);
3022 nic = netdev_priv(dev);
3023
3024 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003025 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09003026 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003027 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003028 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003029 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003030
3031 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
3032
3033 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],
3034 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003035 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003036 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3037 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003038
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003039 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003040 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003041 } else {
Leo Kim22520122015-10-29 12:05:45 +09003042 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003043 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003044 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003045 memcpy(strStaParams.ht_supp_mcs_set,
3046 &params->ht_capa->mcs,
3047 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003048 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003049 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003050 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003051 }
3052
Leo Kimf676e172015-10-29 12:05:52 +09003053 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003054 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003055
Leo Kim22520122015-10-29 12:05:45 +09003056 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3057 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003058 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3059 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003060 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3061 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003062 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3063 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003064 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3065 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003066 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3067 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003068 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3069 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003070 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3071 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003072
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003073 s32Error = wilc_add_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003074 if (s32Error)
3075 PRINT_ER("Host add station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003076 }
3077
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003078 return s32Error;
3079}
3080
3081/**
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003082 * @brief del_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003083 * @details Remove a station; @mac may be NULL to remove all stations.
3084 * @param[in]
3085 * @return int : Return 0 on Success.
3086 * @author mdaftedar
3087 * @date 01 MAR 2012
3088 * @version 1.0
3089 */
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003090static int del_station(struct wiphy *wiphy, struct net_device *dev,
3091 struct station_del_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003092{
Arnd Bergmann057d1e92015-06-01 21:06:44 +02003093 const u8 *mac = params->mac;
Leo Kime6e12662015-09-16 18:36:03 +09003094 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003095 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003096 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003097
Leo Kim7ae43362015-09-16 18:35:59 +09003098 if (!wiphy)
3099 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003100
3101 priv = wiphy_priv(wiphy);
3102 nic = netdev_priv(dev);
3103
3104 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
3105 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
3106
3107
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003108 if (mac == NULL) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05303109 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003110 s32Error = wilc_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003111 } else {
3112 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]);
3113 }
3114
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003115 s32Error = wilc_del_station(priv->hWILCWFIDrv, mac);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003116
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003117 if (s32Error)
3118 PRINT_ER("Host delete station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003119 }
3120 return s32Error;
3121}
3122
3123/**
Chaehyun Lim14b42082015-09-14 12:24:17 +09003124 * @brief change_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003125 * @details Modify a given station.
3126 * @param[in]
3127 * @return int : Return 0 on Success.
3128 * @author mdaftedar
3129 * @date 01 MAR 2012
3130 * @version 1.0
3131 */
Chaehyun Lim14b42082015-09-14 12:24:17 +09003132static int change_station(struct wiphy *wiphy, struct net_device *dev,
3133 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003134{
Leo Kime6e12662015-09-16 18:36:03 +09003135 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003136 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09003137 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003138 perInterface_wlan_t *nic;
3139
3140
3141 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
3142
Leo Kim7ae43362015-09-16 18:35:59 +09003143 if (!wiphy)
3144 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003145
3146 priv = wiphy_priv(wiphy);
3147 nic = netdev_priv(dev);
3148
3149 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003150 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003151 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003152 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003153 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003154
Leo Kim2353c382015-10-29 12:05:41 +09003155 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n",
3156 strStaParams.bssid[0], strStaParams.bssid[1],
3157 strStaParams.bssid[2], strStaParams.bssid[3],
3158 strStaParams.bssid[4], strStaParams.bssid[5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003159 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003160 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3161 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003162
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003163 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003164 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003165 } else {
Leo Kim22520122015-10-29 12:05:45 +09003166 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003167 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003168 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003169 memcpy(strStaParams.ht_supp_mcs_set,
3170 &params->ht_capa->mcs,
3171 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003172 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003173 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003174 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003175 }
3176
Leo Kimf676e172015-10-29 12:05:52 +09003177 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003178 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003179
Leo Kim22520122015-10-29 12:05:45 +09003180 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3181 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003182 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3183 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003184 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3185 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003186 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3187 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003188 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3189 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003190 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3191 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003192 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3193 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003194 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3195 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003196
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003197 s32Error = wilc_edit_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003198 if (s32Error)
3199 PRINT_ER("Host edit station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003200 }
3201 return s32Error;
3202}
3203
3204
3205/**
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003206 * @brief add_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003207 * @details
3208 * @param[in]
3209 * @return int : Return 0 on Success.
3210 * @author mdaftedar
3211 * @date 01 JUL 2012
3212 * @version 1.0
3213 */
Chaehyun Lim37316e82015-09-22 18:34:52 +09003214static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
3215 const char *name,
3216 unsigned char name_assign_type,
3217 enum nl80211_iftype type,
3218 u32 *flags,
3219 struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003220{
3221 perInterface_wlan_t *nic;
Chaehyun Lim27268872015-09-15 14:06:13 +09003222 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003223 struct net_device *new_ifc = NULL;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003224
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003225 priv = wiphy_priv(wiphy);
3226
3227
3228
3229 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
3230
3231 nic = netdev_priv(priv->wdev->netdev);
3232
3233
3234 if (type == NL80211_IFTYPE_MONITOR) {
3235 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
3236 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", nic->wilc_netdev);
3237 new_ifc = WILC_WFI_init_mon_interface(name, nic->wilc_netdev);
3238 if (new_ifc != NULL) {
3239 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003240 nic = netdev_priv(priv->wdev->netdev);
3241 nic->monitor_flag = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003242 } else
3243 PRINT_ER("Error in initializing monitor interface\n ");
3244 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003245 return priv->wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003246}
3247
3248/**
Chaehyun Limb4a73352015-09-14 12:24:10 +09003249 * @brief del_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003250 * @details
3251 * @param[in]
3252 * @return int : Return 0 on Success.
3253 * @author mdaftedar
3254 * @date 01 JUL 2012
3255 * @version 1.0
3256 */
Chaehyun Lim956d7212015-09-22 18:34:49 +09003257static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003258{
3259 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
Leo Kime6e12662015-09-16 18:36:03 +09003260 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003261}
3262
Chaehyun Lim08241922015-09-15 14:06:12 +09003263static struct cfg80211_ops wilc_cfg80211_ops = {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003264
Chaehyun Lim80785a92015-09-14 12:24:01 +09003265 .set_monitor_channel = set_channel,
Chaehyun Lim0e30d062015-09-14 12:24:02 +09003266 .scan = scan,
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +09003267 .connect = connect,
Chaehyun Limb027cde2015-09-14 12:24:04 +09003268 .disconnect = disconnect,
Chaehyun Lim953d4172015-09-14 12:24:05 +09003269 .add_key = add_key,
Chaehyun Lim3044ba72015-09-14 12:24:06 +09003270 .del_key = del_key,
Chaehyun Limf4893df2015-09-14 12:24:07 +09003271 .get_key = get_key,
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09003272 .set_default_key = set_default_key,
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003273 .add_virtual_intf = add_virtual_intf,
Chaehyun Limb4a73352015-09-14 12:24:10 +09003274 .del_virtual_intf = del_virtual_intf,
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09003275 .change_virtual_intf = change_virtual_intf,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003276
Chaehyun Lima13168d2015-09-14 12:24:12 +09003277 .start_ap = start_ap,
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09003278 .change_beacon = change_beacon,
Chaehyun Limc8cddd72015-09-14 12:24:14 +09003279 .stop_ap = stop_ap,
Chaehyun Limed269552015-09-14 12:24:15 +09003280 .add_station = add_station,
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003281 .del_station = del_station,
Chaehyun Lim14b42082015-09-14 12:24:17 +09003282 .change_station = change_station,
Chaehyun Limf06f5622015-09-14 12:24:18 +09003283 .get_station = get_station,
Chaehyun Limbdb63382015-09-14 12:24:19 +09003284 .dump_station = dump_station,
Chaehyun Lima5f7db62015-09-14 12:24:20 +09003285 .change_bss = change_bss,
Chaehyun Lima76b63e2015-09-14 12:24:21 +09003286 .set_wiphy_params = set_wiphy_params,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003287
Chaehyun Lim4d466572015-09-14 12:24:22 +09003288 .set_pmksa = set_pmksa,
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09003289 .del_pmksa = del_pmksa,
Chaehyun Limb33c39b2015-09-14 12:24:24 +09003290 .flush_pmksa = flush_pmksa,
Chaehyun Lim6d19d692015-09-14 12:24:25 +09003291 .remain_on_channel = remain_on_channel,
Chaehyun Lim1dd54402015-09-14 12:24:26 +09003292 .cancel_remain_on_channel = cancel_remain_on_channel,
Chaehyun Lim4a2f9b32015-09-14 12:24:27 +09003293 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
Chaehyun Lim12a26a32015-09-14 12:24:28 +09003294 .mgmt_tx = mgmt_tx,
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09003295 .mgmt_frame_register = wilc_mgmt_frame_register,
Chaehyun Lim46530672015-09-22 18:34:46 +09003296 .set_power_mgmt = set_power_mgmt,
Chaehyun Lima8047e22015-09-22 18:34:48 +09003297 .set_cqm_rssi_config = set_cqm_rssi_config,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003298
3299};
3300
3301
3302
3303
3304
3305/**
3306 * @brief WILC_WFI_update_stats
3307 * @details Modify parameters for a given BSS.
3308 * @param[in]
3309 * @return int : Return 0 on Success.
3310 * @author mdaftedar
3311 * @date 01 MAR 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09003312 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003313 */
3314int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
3315{
3316
Chaehyun Lim27268872015-09-15 14:06:13 +09003317 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003318
3319 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003320 switch (changed) {
3321
3322 case WILC_WFI_RX_PKT:
3323 {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003324 priv->netstats.rx_packets++;
3325 priv->netstats.rx_bytes += pktlen;
3326 priv->netstats.rx_time = get_jiffies_64();
3327 }
3328 break;
3329
3330 case WILC_WFI_TX_PKT:
3331 {
3332 priv->netstats.tx_packets++;
3333 priv->netstats.tx_bytes += pktlen;
3334 priv->netstats.tx_time = get_jiffies_64();
3335
3336 }
3337 break;
3338
3339 default:
3340 break;
3341 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003342 return 0;
3343}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003344
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003345/**
3346 * @brief WILC_WFI_CfgAlloc
3347 * @details Allocation of the wireless device structure and assigning it
3348 * to the cfg80211 operations structure.
3349 * @param[in] NONE
3350 * @return wireless_dev : Returns pointer to wireless_dev structure.
3351 * @author mdaftedar
3352 * @date 01 MAR 2012
3353 * @version 1.0
3354 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01003355static struct wireless_dev *WILC_WFI_CfgAlloc(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003356{
3357
3358 struct wireless_dev *wdev;
3359
3360
3361 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
3362 /*Allocating the wireless device structure*/
3363 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
3364 if (!wdev) {
3365 PRINT_ER("Cannot allocate wireless device\n");
3366 goto _fail_;
3367 }
3368
3369 /*Creating a new wiphy, linking wireless structure with the wiphy structure*/
Chaehyun Lim27268872015-09-15 14:06:13 +09003370 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003371 if (!wdev->wiphy) {
3372 PRINT_ER("Cannot allocate wiphy\n");
3373 goto _fail_mem_;
3374
3375 }
3376
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003377 /* enable 802.11n HT */
3378 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
3379 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
3380 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3381 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
3382 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003383
3384 /*wiphy bands*/
3385 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
3386
3387 return wdev;
3388
3389_fail_mem_:
3390 kfree(wdev);
3391_fail_:
3392 return NULL;
3393
3394}
3395/**
Chaehyun Lim8459fd52015-09-20 15:51:09 +09003396 * @brief wilc_create_wiphy
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003397 * @details Registering of the wiphy structure and interface modes
3398 * @param[in] NONE
3399 * @return NONE
3400 * @author mdaftedar
3401 * @date 01 MAR 2012
3402 * @version 1.0
3403 */
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01003404struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003405{
Chaehyun Lim27268872015-09-15 14:06:13 +09003406 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003407 struct wireless_dev *wdev;
Leo Kime6e12662015-09-16 18:36:03 +09003408 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003409
3410 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
3411
3412 wdev = WILC_WFI_CfgAlloc();
3413 if (wdev == NULL) {
3414 PRINT_ER("CfgAlloc Failed\n");
3415 return NULL;
3416 }
3417
3418
3419 /*Return hardware description structure (wiphy)'s priv*/
3420 priv = wdev_priv(wdev);
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003421 sema_init(&(priv->SemHandleUpdateStats), 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003422
3423 /*Link the wiphy with wireless structure*/
3424 priv->wdev = wdev;
3425
3426 /*Maximum number of probed ssid to be added by user for the scan request*/
3427 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003428 /*Maximum number of pmkids to be cashed*/
3429 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
3430 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003431
3432 wdev->wiphy->max_scan_ie_len = 1000;
3433
3434 /*signal strength in mBm (100*dBm) */
3435 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3436
3437 /*Set the availaible cipher suites*/
3438 wdev->wiphy->cipher_suites = cipher_suites;
3439 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003440 /*Setting default managment types: for register action frame: */
3441 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003442
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003443 wdev->wiphy->max_remain_on_channel_duration = 500;
3444 /*Setting the wiphy interfcae mode and type before registering the wiphy*/
3445 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
3446 BIT(NL80211_IFTYPE_P2P_CLIENT);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003447 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003448 wdev->iftype = NL80211_IFTYPE_STATION;
3449
3450
3451
3452 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
3453 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
3454 wdev->wiphy->interface_modes, wdev->iftype);
3455
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01003456 set_wiphy_dev(wdev->wiphy, dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003457
3458 /*Register wiphy structure*/
3459 s32Error = wiphy_register(wdev->wiphy);
3460 if (s32Error) {
3461 PRINT_ER("Cannot register wiphy device\n");
3462 /*should define what action to be taken in such failure*/
3463 } else {
3464 PRINT_D(CFG80211_DBG, "Successful Registering\n");
3465 }
3466
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003467 priv->dev = net;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003468 return wdev;
3469
3470
3471}
3472/**
3473 * @brief WILC_WFI_WiphyFree
3474 * @details Freeing allocation of the wireless device structure
3475 * @param[in] NONE
3476 * @return NONE
3477 * @author mdaftedar
3478 * @date 01 MAR 2012
3479 * @version 1.0
3480 */
Chaehyun Limdd4b6a82015-09-20 15:51:25 +09003481int wilc_init_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003482{
3483
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003484 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003485
Chaehyun Lim27268872015-09-15 14:06:13 +09003486 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003487
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003488 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
3489 priv = wdev_priv(net->ieee80211_ptr);
3490 if (op_ifcs == 0) {
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -07003491 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003492 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003493 }
3494 op_ifcs++;
3495 if (s32Error < 0) {
3496 PRINT_ER("Failed to creat refresh Timer\n");
3497 return s32Error;
3498 }
3499
Dean Lee72ed4dc2015-06-12 14:11:44 +09003500 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003501
Dean Lee72ed4dc2015-06-12 14:11:44 +09003502 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003503
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003504 sema_init(&(priv->hSemScanReq), 1);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003505 s32Error = wilc_init(net, &priv->hWILCWFIDrv);
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003506 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003507 PRINT_ER("Error while initializing hostinterface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003508
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003509 return s32Error;
3510}
3511
3512/**
3513 * @brief WILC_WFI_WiphyFree
3514 * @details Freeing allocation of the wireless device structure
3515 * @param[in] NONE
3516 * @return NONE
3517 * @author mdaftedar
3518 * @date 01 MAR 2012
3519 * @version 1.0
3520 */
Chaehyun Lima9a16822015-09-20 15:51:24 +09003521int wilc_deinit_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003522{
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003523 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003524
Chaehyun Lim27268872015-09-15 14:06:13 +09003525 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003526
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003527 priv = wdev_priv(net->ieee80211_ptr);
3528
Dean Lee72ed4dc2015-06-12 14:11:44 +09003529 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003530
Dean Lee72ed4dc2015-06-12 14:11:44 +09003531 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003532
3533 op_ifcs--;
3534
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003535 s32Error = wilc_deinit(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003536
3537 /* Clear the Shadow scan */
3538 clear_shadow_scan(priv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003539 if (op_ifcs == 0) {
3540 PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003541 del_timer_sync(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003542 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003543
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003544 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003545 PRINT_ER("Error while deintializing host interface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003546
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003547 return s32Error;
3548}
3549
3550
3551/**
3552 * @brief WILC_WFI_WiphyFree
3553 * @details Freeing allocation of the wireless device structure
3554 * @param[in] NONE
3555 * @return NONE
3556 * @author mdaftedar
3557 * @date 01 MAR 2012
3558 * @version 1.0
3559 */
Chaehyun Lim96da20a2015-09-20 15:51:08 +09003560void wilc_free_wiphy(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003561{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003562 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
3563
Chaehyun Lim619837a2015-09-20 15:51:10 +09003564 if (!net) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003565 PRINT_D(INIT_DBG, "net_device is NULL\n");
3566 return;
3567 }
3568
Chaehyun Lim619837a2015-09-20 15:51:10 +09003569 if (!net->ieee80211_ptr) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003570 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
3571 return;
3572 }
3573
Chaehyun Lim619837a2015-09-20 15:51:10 +09003574 if (!net->ieee80211_ptr->wiphy) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003575 PRINT_D(INIT_DBG, "wiphy is NULL\n");
3576 return;
3577 }
3578
3579 wiphy_unregister(net->ieee80211_ptr->wiphy);
3580
3581 PRINT_D(INIT_DBG, "Freeing wiphy\n");
3582 wiphy_free(net->ieee80211_ptr->wiphy);
3583 kfree(net->ieee80211_ptr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003584}