blob: 6ab4a79e70e0928fb3727db8da0852bea40917e2 [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 */
Leo Kim8d48b5b2015-11-19 15:56:13 +0900152static struct ieee80211_rate ieee80211_bitrates[] = {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900153 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
Leo Kim0bd82742015-11-19 15:56:14 +0900172static u8 wlan_channel = INVALID_CHANNEL;
Arnd Bergmann1608c402015-11-16 15:04:53 +0100173static u8 curr_channel;
Leo Kim881eb5d2015-11-19 15:56:15 +0900174static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09};
Arnd Bergmann1608c402015-11-16 15:04:53 +0100175static u8 u8P2Plocalrandom = 0x01;
176static u8 u8P2Precvrandom = 0x00;
177static u8 u8P2P_vendorspec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
178static bool bWilc_ie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900179
180static struct ieee80211_supported_band WILC_WFI_band_2ghz = {
Leo Kim2736f472015-11-19 15:56:12 +0900181 .channels = ieee80211_2ghz_channels,
182 .n_channels = ARRAY_SIZE(ieee80211_2ghz_channels),
Leo Kim8d48b5b2015-11-19 15:56:13 +0900183 .bitrates = ieee80211_bitrates,
184 .n_bitrates = ARRAY_SIZE(ieee80211_bitrates),
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900185};
186
187
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900188struct add_key_params {
189 u8 key_idx;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900190 bool pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900191 u8 *mac_addr;
192};
Arnd Bergmann1608c402015-11-16 15:04:53 +0100193static struct add_key_params g_add_gtk_key_params;
194static struct wilc_wfi_key g_key_gtk_params;
195static struct add_key_params g_add_ptk_key_params;
196static struct wilc_wfi_key g_key_ptk_params;
197static struct wilc_wfi_wep_key g_key_wep_params;
198static bool g_ptk_keys_saved;
199static bool g_gtk_keys_saved;
200static bool g_wep_keys_saved;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900201
202#define AGING_TIME (9 * 1000)
203#define duringIP_TIME 15000
204
Arnd Bergmann1608c402015-11-16 15:04:53 +0100205static void clear_shadow_scan(void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900206{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900207 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900208
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900209 if (op_ifcs == 0) {
Greg Kroah-Hartman4183e972015-08-14 20:11:16 -0700210 del_timer_sync(&hAgingTimer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900211 PRINT_INFO(CORECONFIG_DBG, "destroy aging timer\n");
212
Leo Kim771fbae2015-11-19 15:56:10 +0900213 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900214 if (last_scanned_shadow[last_scanned_cnt].pu8IEs) {
215 kfree(last_scanned_shadow[i].pu8IEs);
216 last_scanned_shadow[last_scanned_cnt].pu8IEs = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900217 }
218
Leo Kimf1ab1172015-11-19 15:56:11 +0900219 wilc_free_join_params(last_scanned_shadow[i].pJoinParams);
220 last_scanned_shadow[i].pJoinParams = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900221 }
Leo Kim771fbae2015-11-19 15:56:10 +0900222 last_scanned_cnt = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900223 }
224
225}
226
Arnd Bergmann1608c402015-11-16 15:04:53 +0100227static u32 get_rssi_avg(tstrNetworkInfo *pstrNetworkInfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900228{
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900229 u8 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900230 int rssi_v = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900231 u8 num_rssi = (pstrNetworkInfo->strRssi.u8Full) ? NUM_RSSI : (pstrNetworkInfo->strRssi.u8Index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900232
233 for (i = 0; i < num_rssi; i++)
234 rssi_v += pstrNetworkInfo->strRssi.as8RSSI[i];
235
236 rssi_v /= num_rssi;
237 return rssi_v;
238}
239
Arnd Bergmann1608c402015-11-16 15:04:53 +0100240static void refresh_scan(void *pUserVoid, u8 all, bool bDirectScan)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900241{
Chaehyun Lim27268872015-09-15 14:06:13 +0900242 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900243 struct wiphy *wiphy;
244 struct cfg80211_bss *bss = NULL;
245 int i;
246 int rssi = 0;
247
Chaehyun Lim27268872015-09-15 14:06:13 +0900248 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900249 wiphy = priv->dev->ieee80211_ptr->wiphy;
250
Leo Kim771fbae2015-11-19 15:56:10 +0900251 for (i = 0; i < last_scanned_cnt; i++) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900252 tstrNetworkInfo *pstrNetworkInfo;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900253
Leo Kimf1ab1172015-11-19 15:56:11 +0900254 pstrNetworkInfo = &last_scanned_shadow[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900255
256 if ((!pstrNetworkInfo->u8Found) || all) {
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900257 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900258 struct ieee80211_channel *channel;
259
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900260 if (pstrNetworkInfo != NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900261
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900262 s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900263 channel = ieee80211_get_channel(wiphy, s32Freq);
264
265 rssi = get_rssi_avg(pstrNetworkInfo);
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900266 if (memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7) || bDirectScan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900267 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
268 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900269 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900270 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900271 }
272 }
273
274 }
275 }
276
277}
278
Arnd Bergmann1608c402015-11-16 15:04:53 +0100279static void reset_shadow_found(void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900280{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900281 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900282
Leo Kim771fbae2015-11-19 15:56:10 +0900283 for (i = 0; i < last_scanned_cnt; i++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900284 last_scanned_shadow[i].u8Found = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900285}
286
Arnd Bergmann1608c402015-11-16 15:04:53 +0100287static void update_scan_time(void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900288{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900289 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900290
Leo Kim771fbae2015-11-19 15:56:10 +0900291 for (i = 0; i < last_scanned_cnt; i++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900292 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900293}
294
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700295static void remove_network_from_shadow(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900296{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900297 unsigned long now = jiffies;
298 int i, j;
299
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900300
Leo Kim771fbae2015-11-19 15:56:10 +0900301 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900302 if (time_after(now, last_scanned_shadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) {
303 PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", last_scanned_shadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900304
Leo Kimf1ab1172015-11-19 15:56:11 +0900305 kfree(last_scanned_shadow[i].pu8IEs);
306 last_scanned_shadow[i].pu8IEs = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900307
Leo Kimf1ab1172015-11-19 15:56:11 +0900308 wilc_free_join_params(last_scanned_shadow[i].pJoinParams);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900309
Leo Kim771fbae2015-11-19 15:56:10 +0900310 for (j = i; (j < last_scanned_cnt - 1); j++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900311 last_scanned_shadow[j] = last_scanned_shadow[j + 1];
Leo Kim771fbae2015-11-19 15:56:10 +0900312
313 last_scanned_cnt--;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900314 }
315 }
316
Leo Kim771fbae2015-11-19 15:56:10 +0900317 PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n",
318 last_scanned_cnt);
319 if (last_scanned_cnt != 0) {
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700320 hAgingTimer.data = arg;
321 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
322 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900323 PRINT_D(CFG80211_DBG, "No need to restart Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700324 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900325}
326
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700327static void clear_duringIP(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900328{
329 PRINT_D(GENERIC_DBG, "GO:IP Obtained , enable scan\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100330 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900331}
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900332
Arnd Bergmann1608c402015-11-16 15:04:53 +0100333static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900334{
Chaehyun Lima74cc6b2015-10-02 16:41:17 +0900335 int state = -1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900336 int i;
337
Leo Kim771fbae2015-11-19 15:56:10 +0900338 if (last_scanned_cnt == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900339 PRINT_D(CFG80211_DBG, "Starting Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700340 hAgingTimer.data = (unsigned long)pUserVoid;
341 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900342 state = -1;
343 } else {
344 /* Linear search for now */
Leo Kim771fbae2015-11-19 15:56:10 +0900345 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900346 if (memcmp(last_scanned_shadow[i].au8bssid,
347 pstrNetworkInfo->au8bssid, 6) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900348 state = i;
349 break;
350 }
351 }
352 }
353 return state;
354}
355
Arnd Bergmann1608c402015-11-16 15:04:53 +0100356static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900357{
Chaehyun Lima74cc6b2015-10-02 16:41:17 +0900358 int ap_found = is_network_in_shadow(pstrNetworkInfo, pUserVoid);
Chaehyun Limfbc2fe12015-09-15 14:06:16 +0900359 u32 ap_index = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900360 u8 rssi_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900361
Leo Kim771fbae2015-11-19 15:56:10 +0900362 if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900363 PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
364 return;
365 }
366 if (ap_found == -1) {
Leo Kim771fbae2015-11-19 15:56:10 +0900367 ap_index = last_scanned_cnt;
368 last_scanned_cnt++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900369
370 } else {
371 ap_index = ap_found;
372 }
Leo Kimf1ab1172015-11-19 15:56:11 +0900373 rssi_index = last_scanned_shadow[ap_index].strRssi.u8Index;
374 last_scanned_shadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900375 if (rssi_index == NUM_RSSI) {
376 rssi_index = 0;
Leo Kimf1ab1172015-11-19 15:56:11 +0900377 last_scanned_shadow[ap_index].strRssi.u8Full = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900378 }
Leo Kimf1ab1172015-11-19 15:56:11 +0900379 last_scanned_shadow[ap_index].strRssi.u8Index = rssi_index;
380 last_scanned_shadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
381 last_scanned_shadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
382 last_scanned_shadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
383 memcpy(last_scanned_shadow[ap_index].au8ssid,
384 pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
385 memcpy(last_scanned_shadow[ap_index].au8bssid,
386 pstrNetworkInfo->au8bssid, ETH_ALEN);
387 last_scanned_shadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
388 last_scanned_shadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
389 last_scanned_shadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
390 last_scanned_shadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
391 last_scanned_shadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900392 if (ap_found != -1)
Leo Kimf1ab1172015-11-19 15:56:11 +0900393 kfree(last_scanned_shadow[ap_index].pu8IEs);
394 last_scanned_shadow[ap_index].pu8IEs =
Glen Leef3052582015-09-10 12:03:04 +0900395 kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL); /* will be deallocated by the WILC_WFI_CfgScan() function */
Leo Kimf1ab1172015-11-19 15:56:11 +0900396 memcpy(last_scanned_shadow[ap_index].pu8IEs,
397 pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
398 last_scanned_shadow[ap_index].u32TimeRcvdInScan = jiffies;
399 last_scanned_shadow[ap_index].u32TimeRcvdInScanCached = jiffies;
400 last_scanned_shadow[ap_index].u8Found = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900401 if (ap_found != -1)
Leo Kimf1ab1172015-11-19 15:56:11 +0900402 wilc_free_join_params(last_scanned_shadow[ap_index].pJoinParams);
403 last_scanned_shadow[ap_index].pJoinParams = pJoinParams;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900404}
405
406
407/**
408 * @brief CfgScanResult
409 * @details Callback function which returns the scan results found
410 *
411 * @param[in] tenuScanEvent enuScanEvent: enum, indicating the scan event triggered, whether that is
412 * SCAN_EVENT_NETWORK_FOUND or SCAN_EVENT_DONE
413 * tstrNetworkInfo* pstrNetworkInfo: structure holding the scan results information
414 * void* pUserVoid: Private structure associated with the wireless interface
415 * @return NONE
416 * @author mabubakr
417 * @date
418 * @version 1.0
419 */
Leo Kim1ec38152015-10-12 16:55:59 +0900420static void CfgScanResult(enum scan_event enuScanEvent, tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900421{
Chaehyun Lim27268872015-09-15 14:06:13 +0900422 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900423 struct wiphy *wiphy;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900424 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900425 struct ieee80211_channel *channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900426 struct cfg80211_bss *bss = NULL;
427
Chaehyun Lim27268872015-09-15 14:06:13 +0900428 priv = (struct wilc_priv *)pUserVoid;
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100429 if (priv->bCfgScanning) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900430 if (enuScanEvent == SCAN_EVENT_NETWORK_FOUND) {
431 wiphy = priv->dev->ieee80211_ptr->wiphy;
Leo Kim7ae43362015-09-16 18:35:59 +0900432
433 if (!wiphy)
434 return;
435
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900436 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC
437 &&
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900438 ((((s32)pstrNetworkInfo->s8rssi) * 100) < 0
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900439 ||
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900440 (((s32)pstrNetworkInfo->s8rssi) * 100) > 100)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900441 ) {
Leo Kim24db7132015-09-16 18:36:01 +0900442 PRINT_ER("wiphy signal type fial\n");
443 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900444 }
445
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900446 if (pstrNetworkInfo != NULL) {
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900447 s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900448 channel = ieee80211_get_channel(wiphy, s32Freq);
449
Leo Kim7ae43362015-09-16 18:35:59 +0900450 if (!channel)
451 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900452
453 PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530454 "BeaconPeriod: %d\n", channel->center_freq, (((s32)pstrNetworkInfo->s8rssi) * 100),
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900455 pstrNetworkInfo->u16CapInfo, pstrNetworkInfo->u16BeaconPeriod);
456
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100457 if (pstrNetworkInfo->bNewNetwork) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900458 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
459 /* max_scan_ssids */
460 PRINT_D(CFG80211_DBG, "Network %s found\n", pstrNetworkInfo->au8ssid);
461
462
463 priv->u32RcvdChCount++;
464
465
466
467 if (pJoinParams == NULL) {
468 PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n");
469 }
470 add_network_to_shadow(pstrNetworkInfo, priv, pJoinParams);
471
472 /*P2P peers are sent to WPA supplicant and added to shadow table*/
473
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900474 if (!(memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900475 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
476 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900477 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)pstrNetworkInfo->s8rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900478 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900479 }
480
481
482 } else {
483 PRINT_ER("Discovered networks exceeded the max limit\n");
484 }
485 } else {
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900486 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900487 /* So this network is discovered before, we'll just update its RSSI */
488 for (i = 0; i < priv->u32RcvdChCount; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900489 if (memcmp(last_scanned_shadow[i].au8bssid, pstrNetworkInfo->au8bssid, 6) == 0) {
490 PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", last_scanned_shadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900491
Leo Kimf1ab1172015-11-19 15:56:11 +0900492 last_scanned_shadow[i].s8rssi = pstrNetworkInfo->s8rssi;
493 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900494 break;
495 }
496 }
497 }
498 }
499 } else if (enuScanEvent == SCAN_EVENT_DONE) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530500 PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev);
501 PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n");
Dean Lee72ed4dc2015-06-12 14:11:44 +0900502 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900503
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530504 if (priv->u32RcvdChCount > 0)
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530505 PRINT_D(CFG80211_DBG, "%d Network(s) found\n", priv->u32RcvdChCount);
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530506 else
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530507 PRINT_D(CFG80211_DBG, "No networks found\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900508
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200509 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900510
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900511 if (priv->pstrScanReq != NULL) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900512 cfg80211_scan_done(priv->pstrScanReq, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900513 priv->u32RcvdChCount = 0;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900514 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900515 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900516 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200517 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900518
519 }
520 /*Aborting any scan operation during mac close*/
521 else if (enuScanEvent == SCAN_EVENT_ABORTED) {
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200522 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900523
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530524 PRINT_D(CFG80211_DBG, "Scan Aborted\n");
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900525 if (priv->pstrScanReq != NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900526
527 update_scan_time(priv);
Dean Lee72ed4dc2015-06-12 14:11:44 +0900528 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900529
Dean Lee72ed4dc2015-06-12 14:11:44 +0900530 cfg80211_scan_done(priv->pstrScanReq, false);
531 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900532 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900533 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200534 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900535 }
536 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900537}
538
539
540/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900541 * @brief CfgConnectResult
542 * @details
543 * @param[in] tenuConnDisconnEvent enuConnDisconnEvent: Type of connection response either
544 * connection response or disconnection notification.
545 * tstrConnectInfo* pstrConnectInfo: COnnection information.
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900546 * u8 u8MacStatus: Mac Status from firmware
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900547 * tstrDisconnectNotifInfo* pstrDisconnectNotifInfo: Disconnection Notification
548 * void* pUserVoid: Private data associated with wireless interface
549 * @return NONE
550 * @author mabubakr
551 * @date 01 MAR 2012
552 * @version 1.0
553 */
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100554int wilc_connecting;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900555
Leo Kimed3f0372015-10-12 16:56:01 +0900556static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900557 tstrConnectInfo *pstrConnectInfo,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900558 u8 u8MacStatus,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900559 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
560 void *pUserVoid)
561{
Chaehyun Lim27268872015-09-15 14:06:13 +0900562 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900563 struct net_device *dev;
Leo Kim441dc602015-10-12 16:55:35 +0900564 struct host_if_drv *pstrWFIDrv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900565 u8 NullBssid[ETH_ALEN] = {0};
Glen Leec1ec2c12015-10-20 17:13:58 +0900566 struct wilc *wl;
567 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900568
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100569 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900570
Chaehyun Lim27268872015-09-15 14:06:13 +0900571 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900572 dev = priv->dev;
Glen Leec1ec2c12015-10-20 17:13:58 +0900573 nic = netdev_priv(dev);
574 wl = nic->wilc;
Leo Kim441dc602015-10-12 16:55:35 +0900575 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900576
577 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
578 /*Initialization*/
Amitoj Kaur Chawlababa7c72015-10-15 13:48:29 +0530579 u16 u16ConnectStatus;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900580
581 u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
582
583 PRINT_D(CFG80211_DBG, " Connection response received = %d\n", u8MacStatus);
584
585 if ((u8MacStatus == MAC_DISCONNECTED) &&
586 (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
587 /* The case here is that our station was waiting for association response frame and has just received it containing status code
588 * = SUCCESSFUL_STATUSCODE, while mac status is MAC_DISCONNECTED (which means something wrong happened) */
589 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100590 wilc_wlan_set_bssid(priv->dev, NullBssid);
591 eth_zero_addr(wilc_connected_SSID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900592
Leo Kimab16ec02015-10-29 12:05:40 +0900593 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900594 wlan_channel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900595
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530596 PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d\n", u16ConnectStatus, u8MacStatus);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900597 }
598
599 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900600 bool bNeedScanRefresh = false;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900601 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900602
603 PRINT_INFO(CFG80211_DBG, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo->au8bssid[0],
604 pstrConnectInfo->au8bssid[1], pstrConnectInfo->au8bssid[2], pstrConnectInfo->au8bssid[3], pstrConnectInfo->au8bssid[4], pstrConnectInfo->au8bssid[5]);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900605 memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900606
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900607
Leo Kim771fbae2015-11-19 15:56:10 +0900608 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900609 if (memcmp(last_scanned_shadow[i].au8bssid,
610 pstrConnectInfo->au8bssid, ETH_ALEN) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900611 unsigned long now = jiffies;
612
613 if (time_after(now,
Leo Kimf1ab1172015-11-19 15:56:11 +0900614 last_scanned_shadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900615 bNeedScanRefresh = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900616 }
617
618 break;
619 }
620 }
621
Abdul Hussain5a66bf22015-06-16 09:44:06 +0000622 if (bNeedScanRefresh) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900623 /*Also, refrsh DIRECT- results if */
Dean Lee72ed4dc2015-06-12 14:11:44 +0900624 refresh_scan(priv, 1, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900625
626 }
627
628 }
629
630
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530631 PRINT_D(CFG80211_DBG, "Association request info elements length = %zu\n", pstrConnectInfo->ReqIEsLen);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900632
633 PRINT_D(CFG80211_DBG, "Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen);
634
635 cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
636 pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
637 pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
638 u16ConnectStatus, GFP_KERNEL); /* TODO: mostafa: u16ConnectStatus to */
639 /* be replaced by pstrConnectInfo->u16ConnectStatus */
640 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100641 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900642 PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n",
643 pstrDisconnectNotifInfo->u16reason, priv->dev);
644 u8P2Plocalrandom = 0x01;
645 u8P2Precvrandom = 0x00;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900646 bWilc_ie = false;
Shraddha Barkebcf02652015-10-05 17:00:32 +0530647 eth_zero_addr(priv->au8AssociatedBss);
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100648 wilc_wlan_set_bssid(priv->dev, NullBssid);
649 eth_zero_addr(wilc_connected_SSID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900650
Leo Kimab16ec02015-10-29 12:05:40 +0900651 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900652 wlan_channel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900653 /*Incase "P2P CLIENT Connected" send deauthentication reason by 3 to force the WPA_SUPPLICANT to directly change
654 * virtual interface to station*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900655 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900656 pstrDisconnectNotifInfo->u16reason = 3;
657 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900658 /*Incase "P2P CLIENT during connection(not connected)" send deauthentication reason by 1 to force the WPA_SUPPLICANT
659 * to scan again and retry the connection*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900660 else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900661 pstrDisconnectNotifInfo->u16reason = 1;
662 }
663 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
Sudip Mukherjeee26bb712015-06-30 13:51:51 +0530664 pstrDisconnectNotifInfo->ie_len, false,
665 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900666
667 }
668
669}
670
671
672/**
Chaehyun Lim80785a92015-09-14 12:24:01 +0900673 * @brief set_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900674 * @details Set channel for a given wireless interface. Some devices
675 * may support multi-channel operation (by channel hopping) so cfg80211
676 * doesn't verify much. Note, however, that the passed netdev may be
677 * %NULL as well if the user requested changing the channel for the
678 * device itself, or for a monitor interface.
679 * @param[in]
680 * @return int : Return 0 on Success
681 * @author mdaftedar
682 * @date 01 MAR 2012
683 * @version 1.0
684 */
Chaehyun Lim80785a92015-09-14 12:24:01 +0900685static int set_channel(struct wiphy *wiphy,
686 struct cfg80211_chan_def *chandef)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900687{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900688 u32 channelnum = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +0900689 struct wilc_priv *priv;
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900690 int result = 0;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900691
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900692 priv = wiphy_priv(wiphy);
693
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900694 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
695 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900696
Chaehyun Lim866a2c22015-10-02 16:41:21 +0900697 curr_channel = channelnum;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100698 result = wilc_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900699
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900700 if (result != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900701 PRINT_ER("Error in setting channel %d\n", channelnum);
702
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900703 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900704}
705
706/**
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900707 * @brief scan
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900708 * @details Request to do a scan. If returning zero, the scan request is given
709 * the driver, and will be valid until passed to cfg80211_scan_done().
710 * For scan results, call cfg80211_inform_bss(); you can call this outside
711 * the scan/scan_done bracket too.
712 * @param[in]
713 * @return int : Return 0 on Success
714 * @author mabubakr
715 * @date 01 MAR 2012
716 * @version 1.0
717 */
718
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900719static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900720{
Chaehyun Lim27268872015-09-15 14:06:13 +0900721 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900722 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +0900723 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900724 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
Leo Kim607db442015-10-05 15:25:37 +0900725 struct hidden_network strHiddenNetwork;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900726
727 priv = wiphy_priv(wiphy);
728
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900729 priv->pstrScanReq = request;
730
731 priv->u32RcvdChCount = 0;
732
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100733 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900734
735
736 reset_shadow_found(priv);
737
Dean Lee72ed4dc2015-06-12 14:11:44 +0900738 priv->bCfgScanning = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900739 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
740 /* max_scan_ssids */
741 for (i = 0; i < request->n_channels; i++) {
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900742 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900743 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
744 }
745
746 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530747 PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900748
749 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
750
751 if (request->n_ssids >= 1) {
752
753
Leo Kim607db442015-10-05 15:25:37 +0900754 strHiddenNetwork.pstrHiddenNetworkInfo = kmalloc(request->n_ssids * sizeof(struct hidden_network), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900755 strHiddenNetwork.u8ssidnum = request->n_ssids;
756
757
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900758 for (i = 0; i < request->n_ssids; i++) {
759
760 if (request->ssids[i].ssid != NULL && request->ssids[i].ssid_len != 0) {
Glen Leef3052582015-09-10 12:03:04 +0900761 strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900762 memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900763 strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len;
764 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530765 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900766 strHiddenNetwork.u8ssidnum -= 1;
767 }
768 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530769 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100770 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900771 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900772 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900773 CfgScanResult, (void *)priv, &strHiddenNetwork);
774 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530775 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100776 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900777 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900778 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900779 CfgScanResult, (void *)priv, NULL);
780 }
781
782 } else {
783 PRINT_ER("Requested num of scanned channels is greater than the max, supported"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530784 " channels\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900785 }
786
Leo Kime6e12662015-09-16 18:36:03 +0900787 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900788 s32Error = -EBUSY;
789 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
790 }
791
792 return s32Error;
793}
794
795/**
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900796 * @brief connect
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900797 * @details Connect to the ESS with the specified parameters. When connected,
798 * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
799 * If the connection fails for some reason, call cfg80211_connect_result()
800 * with the status from the AP.
801 * @param[in]
802 * @return int : Return 0 on Success
803 * @author mabubakr
804 * @date 01 MAR 2012
805 * @version 1.0
806 */
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900807static int connect(struct wiphy *wiphy, struct net_device *dev,
808 struct cfg80211_connect_params *sme)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900809{
Leo Kime6e12662015-09-16 18:36:03 +0900810 s32 s32Error = 0;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900811 u32 i;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900812 u8 u8security = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +0900813 enum AUTHTYPE tenuAuth_type = ANY;
Dean Lee576917a2015-06-15 11:58:57 +0900814 char *pcgroup_encrypt_val = NULL;
815 char *pccipher_group = NULL;
816 char *pcwpa_version = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900817
Chaehyun Lim27268872015-09-15 14:06:13 +0900818 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +0900819 struct host_if_drv *pstrWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900820 tstrNetworkInfo *pstrNetworkInfo = NULL;
821
822
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100823 wilc_connecting = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900824 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +0900825 pstrWFIDrv = (struct host_if_drv *)(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900826
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100827 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900828
Johnny Kim8a143302015-06-10 17:06:46 +0900829 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 +0900830 if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900831 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
Leo Kimab16ec02015-10-29 12:05:40 +0900832 pstrWFIDrv->p2p_connect = 1;
833 } else {
834 pstrWFIDrv->p2p_connect = 0;
835 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530836 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900837
Leo Kim771fbae2015-11-19 15:56:10 +0900838 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900839 if ((sme->ssid_len == last_scanned_shadow[i].u8SsidLen) &&
840 memcmp(last_scanned_shadow[i].au8ssid,
841 sme->ssid,
842 sme->ssid_len) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900843 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
844 if (sme->bssid == NULL) {
845 /* BSSID is not passed from the user, so decision of matching
846 * is done by SSID only */
847 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
848 break;
849 } else {
850 /* BSSID is also passed from the user, so decision of matching
851 * should consider also this passed BSSID */
Leo Kimf1ab1172015-11-19 15:56:11 +0900852 if (memcmp(last_scanned_shadow[i].au8bssid,
853 sme->bssid,
854 ETH_ALEN) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900855 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
856 break;
857 }
858 }
859 }
860 }
861
Leo Kim771fbae2015-11-19 15:56:10 +0900862 if (i < last_scanned_cnt) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900863 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
864
Leo Kimf1ab1172015-11-19 15:56:11 +0900865 pstrNetworkInfo = &last_scanned_shadow[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900866
867 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
868 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
869 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
870 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
871 } else {
872 s32Error = -ENOENT;
Leo Kim771fbae2015-11-19 15:56:10 +0900873 if (last_scanned_cnt == 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900874 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
875 else
876 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
877
878 goto done;
879 }
880
881 priv->WILC_WFI_wep_default = 0;
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900882 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
883 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900884
885 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
886 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
887
888 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
889
890 if (INFO) {
891 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
892 PRINT_D(CORECONFIG_DBG, "sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]);
893 }
894
895 if (sme->crypto.cipher_group != NO_ENCRYPT) {
896 /* To determine the u8security value, first we check the group cipher suite then {in case of WPA or WPA2}
897 * we will add to it the pairwise cipher suite(s) */
898 pcwpa_version = "Default";
899 PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900900 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900901 u8security = ENCRYPT_ENABLED | WEP;
902 pcgroup_encrypt_val = "WEP40";
903 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
904 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
905
906 if (INFO) {
907 for (i = 0; i < sme->key_len; i++)
908 PRINT_D(CORECONFIG_DBG, "WEP Key Value[%d] = %d\n", i, sme->key[i]);
909 }
910 priv->WILC_WFI_wep_default = sme->key_idx;
911 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900912 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900913
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900914 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900915 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900916 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
917 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900918 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900919
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100920 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
921 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900922 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900923 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
924 pcgroup_encrypt_val = "WEP104";
925 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
926
927 priv->WILC_WFI_wep_default = sme->key_idx;
928 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900929 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900930
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900931 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900932 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900933 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
934 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900935 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900936
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100937 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
938 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900939 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900940 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900941 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
942 pcgroup_encrypt_val = "WPA2_TKIP";
943 pccipher_group = "TKIP";
944 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
945 /* tenuSecurity_t = WPA2_AES; */
946 u8security = ENCRYPT_ENABLED | WPA2 | AES;
947 pcgroup_encrypt_val = "WPA2_AES";
948 pccipher_group = "AES";
949 }
950 pcwpa_version = "WPA_VERSION_2";
951 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
952 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900953 u8security = ENCRYPT_ENABLED | WPA | TKIP;
954 pcgroup_encrypt_val = "WPA_TKIP";
955 pccipher_group = "TKIP";
956 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
957 /* tenuSecurity_t = WPA_AES; */
958 u8security = ENCRYPT_ENABLED | WPA | AES;
959 pcgroup_encrypt_val = "WPA_AES";
960 pccipher_group = "AES";
961
962 }
963 pcwpa_version = "WPA_VERSION_1";
964
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900965 } else {
966 s32Error = -ENOTSUPP;
967 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
968
969 goto done;
970 }
971
972 }
973
974 /* After we set the u8security value from checking the group cipher suite, {in case of WPA or WPA2} we will
975 * add to it the pairwise cipher suite(s) */
976 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
977 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
978 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
979 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
980 u8security = u8security | TKIP;
981 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
982 u8security = u8security | AES;
983 }
984 }
985 }
986
987 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
988
989 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
990 switch (sme->auth_type) {
991 case NL80211_AUTHTYPE_OPEN_SYSTEM:
992 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
993 tenuAuth_type = OPEN_SYSTEM;
994 break;
995
996 case NL80211_AUTHTYPE_SHARED_KEY:
997 tenuAuth_type = SHARED_KEY;
998 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
999 break;
1000
1001 default:
1002 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
1003 }
1004
1005
1006 /* ai: key_mgmt: enterprise case */
1007 if (sme->crypto.n_akm_suites) {
1008 switch (sme->crypto.akm_suites[0]) {
1009 case WLAN_AKM_SUITE_8021X:
1010 tenuAuth_type = IEEE8021;
1011 break;
1012
1013 default:
1014 break;
1015 }
1016 }
1017
1018
1019 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
1020
1021 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
1022 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
1023
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001024 curr_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001025
Leo Kimab16ec02015-10-29 12:05:40 +09001026 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +09001027 wlan_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001028
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001029 wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001030
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001031 s32Error = wilc_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001032 sme->ssid_len, sme->ie, sme->ie_len,
1033 CfgConnectResult, (void *)priv, u8security,
1034 tenuAuth_type, pstrNetworkInfo->u8channel,
1035 pstrNetworkInfo->pJoinParams);
Leo Kime6e12662015-09-16 18:36:03 +09001036 if (s32Error != 0) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001037 PRINT_ER("wilc_set_join_req(): Error(%d)\n", s32Error);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001038 s32Error = -ENOENT;
1039 goto done;
1040 }
1041
1042done:
1043
1044 return s32Error;
1045}
1046
1047
1048/**
Chaehyun Limb027cde2015-09-14 12:24:04 +09001049 * @brief disconnect
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001050 * @details Disconnect from the BSS/ESS.
1051 * @param[in]
1052 * @return int : Return 0 on Success
1053 * @author mdaftedar
1054 * @date 01 MAR 2012
1055 * @version 1.0
1056 */
Chaehyun Limb027cde2015-09-14 12:24:04 +09001057static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001058{
Leo Kime6e12662015-09-16 18:36:03 +09001059 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09001060 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09001061 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim51e825f2015-09-15 14:06:14 +09001062 u8 NullBssid[ETH_ALEN] = {0};
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001063
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001064 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001065 priv = wiphy_priv(wiphy);
1066
Leo Kim441dc602015-10-12 16:55:35 +09001067 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Leo Kimab16ec02015-10-29 12:05:40 +09001068 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +09001069 wlan_channel = INVALID_CHANNEL;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001070 wilc_wlan_set_bssid(priv->dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001071
1072 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
1073
1074 u8P2Plocalrandom = 0x01;
1075 u8P2Precvrandom = 0x00;
Dean Lee72ed4dc2015-06-12 14:11:44 +09001076 bWilc_ie = false;
Leo Kim1229b1a2015-10-29 12:05:39 +09001077 pstrWFIDrv->p2p_timeout = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001078
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001079 s32Error = wilc_disconnect(priv->hWILCWFIDrv, reason_code);
Leo Kime6e12662015-09-16 18:36:03 +09001080 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001081 PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
1082 s32Error = -EINVAL;
1083 }
1084
1085 return s32Error;
1086}
1087
1088/**
Chaehyun Lim953d4172015-09-14 12:24:05 +09001089 * @brief add_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001090 * @details Add a key with the given parameters. @mac_addr will be %NULL
1091 * when adding a group key.
1092 * @param[in] key : key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, 8-byte Rx Mic Key
1093 * @return int : Return 0 on Success
1094 * @author mdaftedar
1095 * @date 01 MAR 2012
1096 * @version 1.0
1097 */
Chaehyun Lim953d4172015-09-14 12:24:05 +09001098static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1099 bool pairwise,
1100 const u8 *mac_addr, struct key_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001101
1102{
Leo Kime6e12662015-09-16 18:36:03 +09001103 s32 s32Error = 0, KeyLen = params->key_len;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001104 u32 i;
Chaehyun Lim27268872015-09-15 14:06:13 +09001105 struct wilc_priv *priv;
Arnd Bergmann057d1e92015-06-01 21:06:44 +02001106 const u8 *pu8RxMic = NULL;
1107 const u8 *pu8TxMic = NULL;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001108 u8 u8mode = NO_ENCRYPT;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001109 u8 u8gmode = NO_ENCRYPT;
1110 u8 u8pmode = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +09001111 enum AUTHTYPE tenuAuth_type = ANY;
Glen Lee76469202015-10-20 17:13:59 +09001112 struct wilc *wl;
1113 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001114
1115 priv = wiphy_priv(wiphy);
Glen Lee76469202015-10-20 17:13:59 +09001116 nic = netdev_priv(netdev);
1117 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001118
1119 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
1120
Johnny Kim8a143302015-06-10 17:06:46 +09001121 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001122
1123 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
1124 params->key[1],
1125 params->key[2]);
1126
1127
1128 switch (params->cipher) {
1129 case WLAN_CIPHER_SUITE_WEP40:
1130 case WLAN_CIPHER_SUITE_WEP104:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001131 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
1132
1133 priv->WILC_WFI_wep_default = key_index;
1134 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001135 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001136
1137 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
1138 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
1139
1140 for (i = 0; i < params->key_len; i++)
1141 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
1142
1143 tenuAuth_type = OPEN_SYSTEM;
1144
1145 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
1146 u8mode = ENCRYPT_ENABLED | WEP;
1147 else
1148 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
1149
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001150 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 +09001151 break;
1152 }
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001153 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001154 priv->WILC_WFI_wep_default = key_index;
1155 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001156 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001157
1158 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
1159 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
1160 if (INFO) {
1161 for (i = 0; i < params->key_len; i++)
1162 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
1163 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001164 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001165 }
1166
1167 break;
1168
1169 case WLAN_CIPHER_SUITE_TKIP:
1170 case WLAN_CIPHER_SUITE_CCMP:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001171 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
1172
1173 if (priv->wilc_gtk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001174 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001175 priv->wilc_gtk[key_index]->key = NULL;
1176 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001177
1178 }
1179 if (priv->wilc_ptk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001180 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001181 priv->wilc_ptk[key_index]->key = NULL;
1182 priv->wilc_ptk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001183 }
1184
1185
1186
Daniel Machon19132212015-08-05 08:18:31 +02001187 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001188 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1189 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1190 else
1191 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1192
1193 priv->wilc_groupkey = u8gmode;
1194
1195 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1196
1197 pu8TxMic = params->key + 24;
1198 pu8RxMic = params->key + 16;
1199 KeyLen = params->key_len - 16;
1200 }
1201 /* 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 +05301202 kfree(priv->wilc_gtk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001203
Glen Leef3052582015-09-10 12:03:04 +09001204 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001205 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001206
1207 /* 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 +05301208 kfree(priv->wilc_gtk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001209
1210 if ((params->seq_len) > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001211 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001212 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001213 }
1214
1215 priv->wilc_gtk[key_index]->cipher = params->cipher;
1216 priv->wilc_gtk[key_index]->key_len = params->key_len;
1217 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1218
1219 if (INFO) {
1220 for (i = 0; i < params->key_len; i++)
1221 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1222 for (i = 0; i < params->seq_len; i++)
1223 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1224 }
1225
1226
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001227 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001228 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode);
1229
1230 } else {
1231 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]);
1232
1233 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1234 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1235 else
1236 u8pmode = priv->wilc_groupkey | AES;
1237
1238
1239 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1240
1241 pu8TxMic = params->key + 24;
1242 pu8RxMic = params->key + 16;
1243 KeyLen = params->key_len - 16;
1244 }
1245
Shraddha Barkecccfc392015-10-12 20:49:19 +05301246 kfree(priv->wilc_ptk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001247
Glen Leef3052582015-09-10 12:03:04 +09001248 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001249
Shraddha Barkecccfc392015-10-12 20:49:19 +05301250 kfree(priv->wilc_ptk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001251
1252 if ((params->seq_len) > 0)
Glen Leef3052582015-09-10 12:03:04 +09001253 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001254
1255 if (INFO) {
1256 for (i = 0; i < params->key_len; i++)
1257 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1258
1259 for (i = 0; i < params->seq_len; i++)
1260 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1261 }
1262
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001263 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001264
1265 if ((params->seq_len) > 0)
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001266 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001267
1268 priv->wilc_ptk[key_index]->cipher = params->cipher;
1269 priv->wilc_ptk[key_index]->key_len = params->key_len;
1270 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1271
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001272 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001273 pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index);
1274 }
1275 break;
1276 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001277
1278 {
1279 u8mode = 0;
Daniel Machon19132212015-08-05 08:18:31 +02001280 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001281 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1282 /* swap the tx mic by rx mic */
1283 pu8RxMic = params->key + 24;
1284 pu8TxMic = params->key + 16;
1285 KeyLen = params->key_len - 16;
1286 }
1287
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001288 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001289 if (!g_gtk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001290 g_add_gtk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001291 g_add_gtk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001292 if (!mac_addr) {
1293 g_add_gtk_key_params.mac_addr = NULL;
1294 } else {
Glen Leef3052582015-09-10 12:03:04 +09001295 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001296 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1297 }
1298 g_key_gtk_params.key_len = params->key_len;
1299 g_key_gtk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001300 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001301 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1302 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001303 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001304 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1305 }
1306 g_key_gtk_params.cipher = params->cipher;
1307
1308 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1309 g_key_gtk_params.key[1],
1310 g_key_gtk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001311 g_gtk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001312 }
1313
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001314 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001315 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001316 } else {
1317 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1318 /* swap the tx mic by rx mic */
1319 pu8RxMic = params->key + 24;
1320 pu8TxMic = params->key + 16;
1321 KeyLen = params->key_len - 16;
1322 }
1323
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001324 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001325 if (!g_ptk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001326 g_add_ptk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001327 g_add_ptk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001328 if (!mac_addr) {
1329 g_add_ptk_key_params.mac_addr = NULL;
1330 } else {
Glen Leef3052582015-09-10 12:03:04 +09001331 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001332 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1333 }
1334 g_key_ptk_params.key_len = params->key_len;
1335 g_key_ptk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001336 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001337 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1338 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001339 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001340 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1341 }
1342 g_key_ptk_params.cipher = params->cipher;
1343
1344 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1345 g_key_ptk_params.key[1],
1346 g_key_ptk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001347 g_ptk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001348 }
1349
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001350 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001351 pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index);
1352 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1353 if (INFO) {
1354 for (i = 0; i < params->key_len; i++)
1355 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1356 }
1357 }
1358 }
1359 break;
1360
1361 default:
1362 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
1363 s32Error = -ENOTSUPP;
1364
1365 }
1366
1367 return s32Error;
1368}
1369
1370/**
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001371 * @brief del_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001372 * @details Remove a key given the @mac_addr (%NULL for a group key)
1373 * and @key_index, return -ENOENT if the key doesn't exist.
1374 * @param[in]
1375 * @return int : Return 0 on Success
1376 * @author mdaftedar
1377 * @date 01 MAR 2012
1378 * @version 1.0
1379 */
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001380static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1381 u8 key_index,
1382 bool pairwise,
1383 const u8 *mac_addr)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001384{
Chaehyun Lim27268872015-09-15 14:06:13 +09001385 struct wilc_priv *priv;
Glen Lee692e2ac2015-10-20 17:14:00 +09001386 struct wilc *wl;
1387 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001388
1389 priv = wiphy_priv(wiphy);
Glen Lee692e2ac2015-10-20 17:14:00 +09001390 nic = netdev_priv(netdev);
1391 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001392
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001393 /*delete saved keys, if any*/
Glen Lee692e2ac2015-10-20 17:14:00 +09001394 if (netdev == wl->vif[0].ndev) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09001395 g_ptk_keys_saved = false;
1396 g_gtk_keys_saved = false;
1397 g_wep_keys_saved = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001398
1399 /*Delete saved WEP keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301400 kfree(g_key_wep_params.key);
1401 g_key_wep_params.key = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001402
1403 /*freeing memory allocated by "wilc_gtk" and "wilc_ptk" in "WILC_WIFI_ADD_KEY"*/
1404
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001405 if ((priv->wilc_gtk[key_index]) != NULL) {
1406
Shraddha Barkecccfc392015-10-12 20:49:19 +05301407 kfree(priv->wilc_gtk[key_index]->key);
1408 priv->wilc_gtk[key_index]->key = NULL;
1409 kfree(priv->wilc_gtk[key_index]->seq);
1410 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001411
Chaehyun Lim49188af2015-08-11 10:32:41 +09001412 kfree(priv->wilc_gtk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001413 priv->wilc_gtk[key_index] = NULL;
1414
1415 }
1416
1417 if ((priv->wilc_ptk[key_index]) != NULL) {
1418
Shraddha Barkecccfc392015-10-12 20:49:19 +05301419 kfree(priv->wilc_ptk[key_index]->key);
1420 priv->wilc_ptk[key_index]->key = NULL;
1421 kfree(priv->wilc_ptk[key_index]->seq);
1422 priv->wilc_ptk[key_index]->seq = NULL;
Chaehyun Lim49188af2015-08-11 10:32:41 +09001423 kfree(priv->wilc_ptk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001424 priv->wilc_ptk[key_index] = NULL;
1425 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001426
1427 /*Delete saved PTK and GTK keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301428 kfree(g_key_ptk_params.key);
1429 g_key_ptk_params.key = NULL;
1430 kfree(g_key_ptk_params.seq);
1431 g_key_ptk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001432
Shraddha Barkecccfc392015-10-12 20:49:19 +05301433 kfree(g_key_gtk_params.key);
1434 g_key_gtk_params.key = NULL;
1435 kfree(g_key_gtk_params.seq);
1436 g_key_gtk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001437
1438 /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001439 wilc_set_machw_change_vir_if(netdev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001440 }
1441
1442 if (key_index >= 0 && key_index <= 3) {
Chaehyun Lim2cc46832015-08-07 09:02:01 +09001443 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001444 priv->WILC_WFI_wep_key_len[key_index] = 0;
1445
1446 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001447 wilc_remove_wep_key(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001448 } else {
1449 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001450 wilc_remove_key(priv->hWILCWFIDrv, mac_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001451 }
1452
Leo Kimaaed3292015-10-12 16:55:38 +09001453 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001454}
1455
1456/**
Chaehyun Limf4893df2015-09-14 12:24:07 +09001457 * @brief get_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001458 * @details Get information about the key with the given parameters.
1459 * @mac_addr will be %NULL when requesting information for a group
1460 * key. All pointers given to the @callback function need not be valid
1461 * after it returns. This function should return an error if it is
1462 * not possible to retrieve the key, -ENOENT if it doesn't exist.
1463 * @param[in]
1464 * @return int : Return 0 on Success
1465 * @author mdaftedar
1466 * @date 01 MAR 2012
1467 * @version 1.0
1468 */
Chaehyun Limf4893df2015-09-14 12:24:07 +09001469static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1470 bool pairwise,
1471 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001472{
Chaehyun Lim27268872015-09-15 14:06:13 +09001473 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001474 struct key_params key_params;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001475 u32 i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001476
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001477 priv = wiphy_priv(wiphy);
1478
1479
Alison Schofield3604af52015-10-12 13:22:44 -07001480 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001481 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1482
1483 key_params.key = priv->wilc_gtk[key_index]->key;
1484 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1485 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1486 key_params.seq = priv->wilc_gtk[key_index]->seq;
1487 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1488 if (INFO) {
1489 for (i = 0; i < key_params.key_len; i++)
1490 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1491 }
1492 } else {
1493 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1494
1495 key_params.key = priv->wilc_ptk[key_index]->key;
1496 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1497 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1498 key_params.seq = priv->wilc_ptk[key_index]->seq;
1499 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1500 }
1501
1502 callback(cookie, &key_params);
1503
Leo Kimaaed3292015-10-12 16:55:38 +09001504 return 0; /* priv->wilc_gtk->key_len ?0 : -ENOENT; */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001505}
1506
1507/**
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001508 * @brief set_default_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001509 * @details Set the default management frame key on an interface
1510 * @param[in]
1511 * @return int : Return 0 on Success.
1512 * @author mdaftedar
1513 * @date 01 MAR 2012
1514 * @version 1.0
1515 */
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001516static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1517 bool unicast, bool multicast)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001518{
Chaehyun Lim27268872015-09-15 14:06:13 +09001519 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001520
1521
1522 priv = wiphy_priv(wiphy);
1523
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301524 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001525
1526 if (key_index != priv->WILC_WFI_wep_default) {
1527
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001528 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001529 }
1530
Leo Kimaaed3292015-10-12 16:55:38 +09001531 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001532}
1533
1534/**
Chaehyun Limf06f5622015-09-14 12:24:18 +09001535 * @brief get_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001536 * @details Get station information for the station identified by @mac
1537 * @param[in] NONE
1538 * @return int : Return 0 on Success.
1539 * @author mdaftedar
1540 * @date 01 MAR 2012
1541 * @version 1.0
1542 */
1543
Chaehyun Limf06f5622015-09-14 12:24:18 +09001544static int get_station(struct wiphy *wiphy, struct net_device *dev,
1545 const u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001546{
Chaehyun Lim27268872015-09-15 14:06:13 +09001547 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001548 perInterface_wlan_t *nic;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001549 u32 i = 0;
1550 u32 associatedsta = 0;
1551 u32 inactive_time = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001552 priv = wiphy_priv(wiphy);
1553 nic = netdev_priv(dev);
1554
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001555 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
1556 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1557
1558 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1559
1560 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1561
1562 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1563 associatedsta = i;
1564 break;
1565 }
1566
1567 }
1568
1569 if (associatedsta == -1) {
Leo Kimaaed3292015-10-12 16:55:38 +09001570 PRINT_ER("Station required is not associated\n");
1571 return -ENOENT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001572 }
1573
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001574 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001575
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001576 wilc_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001577 sinfo->inactive_time = 1000 * inactive_time;
1578 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
1579
1580 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001581
1582 if (nic->iftype == STATION_MODE) {
Leo Kim03e7b9c2015-10-12 16:55:58 +09001583 struct rf_info strStatistics;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001584
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001585 wilc_get_statistics(priv->hWILCWFIDrv, &strStatistics);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001586
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001587 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
Chandra S Gorentla62129902015-08-05 22:11:57 +05301588 BIT(NL80211_STA_INFO_RX_PACKETS) |
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001589 BIT(NL80211_STA_INFO_TX_PACKETS) |
1590 BIT(NL80211_STA_INFO_TX_FAILED) |
1591 BIT(NL80211_STA_INFO_TX_BITRATE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001592
Leo Kim00c8dfc2015-10-29 12:05:30 +09001593 sinfo->signal = strStatistics.rssi;
Leo Kim9b992742015-10-29 12:05:32 +09001594 sinfo->rx_packets = strStatistics.rx_cnt;
Leo Kim54160372015-10-29 12:05:33 +09001595 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1596 sinfo->tx_failed = strStatistics.tx_fail_cnt;
Leo Kim5babeec2015-10-29 12:05:29 +09001597 sinfo->txrate.legacy = strStatistics.link_speed * 10;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001598
Leo Kim5babeec2015-10-29 12:05:29 +09001599 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1600 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001601 wilc_enable_tcp_ack_filter(true);
Leo Kim5babeec2015-10-29 12:05:29 +09001602 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001603 wilc_enable_tcp_ack_filter(false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001604
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001605 PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
1606 sinfo->tx_failed, sinfo->txrate.legacy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001607 }
Leo Kimaaed3292015-10-12 16:55:38 +09001608 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001609}
1610
1611
1612/**
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001613 * @brief change_bss
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001614 * @details Modify parameters for a given BSS.
1615 * @param[in]
1616 * -use_cts_prot: Whether to use CTS protection
1617 * (0 = no, 1 = yes, -1 = do not change)
1618 * -use_short_preamble: Whether the use of short preambles is allowed
1619 * (0 = no, 1 = yes, -1 = do not change)
1620 * -use_short_slot_time: Whether the use of short slot time is allowed
1621 * (0 = no, 1 = yes, -1 = do not change)
1622 * -basic_rates: basic rates in IEEE 802.11 format
1623 * (or NULL for no change)
1624 * -basic_rates_len: number of basic rates
1625 * -ap_isolate: do not forward packets between connected stations
1626 * -ht_opmode: HT Operation mode
1627 * (u16 = opmode, -1 = do not change)
1628 * @return int : Return 0 on Success.
1629 * @author mdaftedar
1630 * @date 01 MAR 2012
1631 * @version 1.0
1632 */
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001633static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1634 struct bss_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001635{
1636 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1637 return 0;
1638}
1639
1640/**
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001641 * @brief set_wiphy_params
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001642 * @details Notify that wiphy parameters have changed;
1643 * @param[in] Changed bitfield (see &enum wiphy_params_flags) describes which values
1644 * have changed.
1645 * @return int : Return 0 on Success
1646 * @author mdaftedar
1647 * @date 01 MAR 2012
1648 * @version 1.0
1649 */
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001650static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001651{
Leo Kime6e12662015-09-16 18:36:03 +09001652 s32 s32Error = 0;
Leo Kim95296502015-10-05 15:25:46 +09001653 struct cfg_param_val pstrCfgParamVal;
Chaehyun Lim27268872015-09-15 14:06:13 +09001654 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001655
1656 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001657
Tony Cho87c05b22015-10-12 16:56:07 +09001658 pstrCfgParamVal.flag = 0;
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301659 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001660
1661 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1662 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1663 priv->dev->ieee80211_ptr->wiphy->retry_short);
Tony Cho87c05b22015-10-12 16:56:07 +09001664 pstrCfgParamVal.flag |= RETRY_SHORT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001665 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1666 }
1667 if (changed & WIPHY_PARAM_RETRY_LONG) {
1668
1669 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 +09001670 pstrCfgParamVal.flag |= RETRY_LONG;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001671 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1672
1673 }
1674 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1675 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 +09001676 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001677 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1678
1679 }
1680
1681 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1682 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1683
Tony Cho87c05b22015-10-12 16:56:07 +09001684 pstrCfgParamVal.flag |= RTS_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001685 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1686
1687 }
1688
1689 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001690 s32Error = wilc_hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001691 if (s32Error)
1692 PRINT_ER("Error in setting WIPHY PARAMS\n");
1693
1694
1695 return s32Error;
1696}
Arnd Bergmanne5af0562015-05-29 22:52:12 +02001697
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001698/**
Chaehyun Lim4d466572015-09-14 12:24:22 +09001699 * @brief set_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001700 * @details Cache a PMKID for a BSSID. This is mostly useful for fullmac
1701 * devices running firmwares capable of generating the (re) association
1702 * RSN IE. It allows for faster roaming between WPA2 BSSIDs.
1703 * @param[in]
1704 * @return int : Return 0 on Success
1705 * @author mdaftedar
1706 * @date 01 MAR 2012
1707 * @version 1.0
1708 */
Chaehyun Lim4d466572015-09-14 12:24:22 +09001709static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1710 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001711{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001712 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001713 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001714 u8 flag = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001715
Chaehyun Lim27268872015-09-15 14:06:13 +09001716 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001717
1718 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1719
1720
1721 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001722 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001723 ETH_ALEN)) {
1724 /*If bssid already exists and pmkid value needs to reset*/
1725 flag = PMKID_FOUND;
1726 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1727 break;
1728 }
1729 }
1730 if (i < WILC_MAX_NUM_PMKIDS) {
1731 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001732 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001733 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001734 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001735 PMKID_LEN);
1736 if (!(flag == PMKID_FOUND))
1737 priv->pmkid_list.numpmkid++;
1738 } else {
1739 PRINT_ER("Invalid PMKID index\n");
1740 s32Error = -EINVAL;
1741 }
1742
1743 if (!s32Error) {
1744 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001745 s32Error = wilc_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001746 }
1747 return s32Error;
1748}
1749
1750/**
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001751 * @brief del_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001752 * @details Delete a cached PMKID.
1753 * @param[in]
1754 * @return int : Return 0 on Success
1755 * @author mdaftedar
1756 * @date 01 MAR 2012
1757 * @version 1.0
1758 */
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001759static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1760 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001761{
1762
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001763 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001764 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001765
Chaehyun Lim27268872015-09-15 14:06:13 +09001766 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001767
1768 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1769
1770 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001771 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001772 ETH_ALEN)) {
1773 /*If bssid is found, reset the values*/
1774 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
Leo Kimcd1e6cb2015-10-05 15:25:45 +09001775 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001776 break;
1777 }
1778 }
1779
1780 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1781 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001782 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001783 priv->pmkid_list.pmkidlist[i + 1].bssid,
1784 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001785 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001786 priv->pmkid_list.pmkidlist[i].pmkid,
1787 PMKID_LEN);
1788 }
1789 priv->pmkid_list.numpmkid--;
1790 } else {
1791 s32Error = -EINVAL;
1792 }
1793
1794 return s32Error;
1795}
1796
1797/**
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001798 * @brief flush_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001799 * @details Flush all cached PMKIDs.
1800 * @param[in]
1801 * @return int : Return 0 on Success
1802 * @author mdaftedar
1803 * @date 01 MAR 2012
1804 * @version 1.0
1805 */
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001806static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001807{
Chaehyun Lim27268872015-09-15 14:06:13 +09001808 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001809
1810 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
1811
1812 /*Get cashed Pmkids and set all with zeros*/
Leo Kima949f902015-10-05 15:25:44 +09001813 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001814
1815 return 0;
1816}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001817
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001818
1819/**
1820 * @brief WILC_WFI_CfgParseRxAction
1821 * @details Function parses the received frames and modifies the following attributes:
1822 * -GO Intent
1823 * -Channel list
1824 * -Operating Channel
1825 *
1826 * @param[in] u8* Buffer, u32 length
1827 * @return NONE.
1828 * @author mdaftedar
1829 * @date 12 DEC 2012
1830 * @version
1831 */
1832
Arnd Bergmann1608c402015-11-16 15:04:53 +01001833static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001834{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001835 u32 index = 0;
1836 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001837
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001838 u8 op_channel_attr_index = 0;
1839 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001840
1841 while (index < len) {
1842 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001843 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001844 }
1845
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301846 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001847 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301848 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001849 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001850 index += buf[index + 1] + 3; /* ID,Length byte */
1851 }
Leo Kim0bd82742015-11-19 15:56:14 +09001852 if (wlan_channel != INVALID_CHANNEL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001853 /*Modify channel list attribute*/
1854 if (channel_list_attr_index) {
1855 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1856 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1857 if (buf[i] == 0x51) {
1858 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
Leo Kim0bd82742015-11-19 15:56:14 +09001859 buf[j] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001860 }
1861 break;
1862 }
1863 }
1864 }
1865 /*Modify operating channel attribute*/
1866 if (op_channel_attr_index) {
1867 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1868 buf[op_channel_attr_index + 6] = 0x51;
Leo Kim0bd82742015-11-19 15:56:14 +09001869 buf[op_channel_attr_index + 7] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001870 }
1871 }
1872}
1873
1874/**
1875 * @brief WILC_WFI_CfgParseTxAction
1876 * @details Function parses the transmitted action frames and modifies the
1877 * GO Intent attribute
1878 * @param[in] u8* Buffer, u32 length, bool bOperChan, u8 iftype
1879 * @return NONE.
1880 * @author mdaftedar
1881 * @date 12 DEC 2012
1882 * @version
1883 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01001884static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001885{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001886 u32 index = 0;
1887 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001888
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001889 u8 op_channel_attr_index = 0;
1890 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001891
1892 while (index < len) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001893 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001894 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001895
1896 break;
1897 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001898
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301899 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001900 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301901 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001902 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001903 index += buf[index + 1] + 3; /* ID,Length byte */
1904 }
Leo Kim0bd82742015-11-19 15:56:14 +09001905 if (wlan_channel != INVALID_CHANNEL && bOperChan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001906 /*Modify channel list attribute*/
1907 if (channel_list_attr_index) {
1908 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1909 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1910 if (buf[i] == 0x51) {
1911 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
Leo Kim0bd82742015-11-19 15:56:14 +09001912 buf[j] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001913 }
1914 break;
1915 }
1916 }
1917 }
1918 /*Modify operating channel attribute*/
1919 if (op_channel_attr_index) {
1920 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1921 buf[op_channel_attr_index + 6] = 0x51;
Leo Kim0bd82742015-11-19 15:56:14 +09001922 buf[op_channel_attr_index + 7] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001923 }
1924 }
1925}
1926
1927/* @brief WILC_WFI_p2p_rx
1928 * @details
1929 * @param[in]
1930 *
1931 * @return None
1932 * @author Mai Daftedar
1933 * @date 2 JUN 2013
1934 * @version 1.0
1935 */
1936
Chaehyun Limfbc2fe12015-09-15 14:06:16 +09001937void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001938{
1939
Chaehyun Lim27268872015-09-15 14:06:13 +09001940 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001941 u32 header, pkt_offset;
Leo Kim441dc602015-10-12 16:55:35 +09001942 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001943 u32 i = 0;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001944 s32 s32Freq;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001945
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001946 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001947 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001948
1949 /* Get WILC header */
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001950 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001951
1952 /* The packet offset field conain info about what type of managment frame */
1953 /* we are dealing with and ack status */
1954 pkt_offset = GET_PKT_OFFSET(header);
1955
1956 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1957 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1958 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001959 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001960 return;
1961 } else {
1962 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
1963 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],
1964 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001965 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001966 } else {
1967 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],
1968 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001969 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001970 }
1971 return;
1972 }
1973 } else {
1974
1975 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
1976
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001977 /*Upper layer is informed that the frame is received on this freq*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001978 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001979
1980 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1981 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
1982
Leo Kim1229b1a2015-10-29 12:05:39 +09001983 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001984 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
1985 return;
1986 }
1987 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1988
1989 switch (buff[ACTION_SUBTYPE_ID]) {
1990 case GAS_INTIAL_REQ:
1991 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
1992 break;
1993
1994 case GAS_INTIAL_RSP:
1995 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
1996 break;
1997
1998 case PUBLIC_ACT_VENDORSPEC:
Leo Kim881eb5d2015-11-19 15:56:15 +09001999 if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002000 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
2001 if (!bWilc_ie) {
2002 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002003 if (!memcmp(u8P2P_vendorspec, &buff[i], 6)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002004 u8P2Precvrandom = buff[i + 6];
Dean Lee72ed4dc2015-06-12 14:11:44 +09002005 bWilc_ie = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002006 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", u8P2Precvrandom);
2007 break;
2008 }
2009 }
2010 }
2011 }
2012 if (u8P2Plocalrandom > u8P2Precvrandom) {
2013 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2014 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2015 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
Leo Kim881eb5d2015-11-19 15:56:15 +09002016 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002017 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
2018 break;
2019 }
2020 }
2021 }
2022 } else
2023 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2024 }
2025
2026
2027 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (bWilc_ie)) {
2028 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
2029 /* extra attribute for sig_dbm: signal strength in mBm, or 0 if unknown */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002030 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002031 return;
2032 }
2033 break;
2034
2035 default:
2036 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
2037 break;
2038 }
2039 }
2040 }
2041
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002042 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002043 }
2044}
2045
2046/**
2047 * @brief WILC_WFI_mgmt_tx_complete
2048 * @details Returns result of writing mgmt frame to VMM (Tx buffers are freed here)
2049 * @param[in] priv
2050 * transmitting status
2051 * @return None
2052 * @author Amr Abdelmoghny
2053 * @date 20 MAY 2013
2054 * @version 1.0
2055 */
2056static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
2057{
2058 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
2059
2060
2061 kfree(pv_data->buff);
2062 kfree(pv_data);
2063}
2064
2065/**
2066 * @brief WILC_WFI_RemainOnChannelReady
2067 * @details Callback function, called from handle_remain_on_channel on being ready on channel
2068 * @param
2069 * @return none
2070 * @author Amr abdelmoghny
2071 * @date 9 JUNE 2013
2072 * @version
2073 */
2074
2075static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
2076{
Chaehyun Lim27268872015-09-15 14:06:13 +09002077 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002078
Chaehyun Lim27268872015-09-15 14:06:13 +09002079 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002080
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302081 PRINT_D(HOSTINF_DBG, "Remain on channel ready\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002082
Dean Lee72ed4dc2015-06-12 14:11:44 +09002083 priv->bInP2PlistenState = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002084
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002085 cfg80211_ready_on_channel(priv->wdev,
2086 priv->strRemainOnChanParams.u64ListenCookie,
2087 priv->strRemainOnChanParams.pstrListenChan,
2088 priv->strRemainOnChanParams.u32ListenDuration,
2089 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002090}
2091
2092/**
2093 * @brief WILC_WFI_RemainOnChannelExpired
2094 * @details Callback function, called on expiration of remain-on-channel duration
2095 * @param
2096 * @return none
2097 * @author Amr abdelmoghny
2098 * @date 15 MAY 2013
2099 * @version
2100 */
2101
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002102static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002103{
Chaehyun Lim27268872015-09-15 14:06:13 +09002104 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002105
Chaehyun Lim27268872015-09-15 14:06:13 +09002106 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002107
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002108 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302109 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002110
Dean Lee72ed4dc2015-06-12 14:11:44 +09002111 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002112
2113 /*Inform wpas of remain-on-channel expiration*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002114 cfg80211_remain_on_channel_expired(priv->wdev,
2115 priv->strRemainOnChanParams.u64ListenCookie,
2116 priv->strRemainOnChanParams.pstrListenChan,
2117 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002118 } else {
2119 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
2120 , priv->strRemainOnChanParams.u32ListenSessionID);
2121 }
2122}
2123
2124
2125/**
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002126 * @brief remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002127 * @details Request the driver to remain awake on the specified
2128 * channel for the specified duration to complete an off-channel
2129 * operation (e.g., public action frame exchange). When the driver is
2130 * ready on the requested channel, it must indicate this with an event
2131 * notification by calling cfg80211_ready_on_channel().
2132 * @param[in]
2133 * @return int : Return 0 on Success
2134 * @author mdaftedar
2135 * @date 01 MAR 2012
2136 * @version 1.0
2137 */
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002138static int remain_on_channel(struct wiphy *wiphy,
2139 struct wireless_dev *wdev,
2140 struct ieee80211_channel *chan,
2141 unsigned int duration, u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002142{
Leo Kime6e12662015-09-16 18:36:03 +09002143 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002144 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002145
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002146 priv = wiphy_priv(wiphy);
2147
2148 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
2149
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002150
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002151 if (wdev->iftype == NL80211_IFTYPE_AP) {
2152 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
2153 return s32Error;
2154 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002155
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002156 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002157
2158 /*Setting params needed by WILC_WFI_RemainOnChannelExpired()*/
2159 priv->strRemainOnChanParams.pstrListenChan = chan;
2160 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002161 priv->strRemainOnChanParams.u32ListenDuration = duration;
2162 priv->strRemainOnChanParams.u32ListenSessionID++;
2163
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002164 s32Error = wilc_remain_on_channel(priv->hWILCWFIDrv
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002165 , priv->strRemainOnChanParams.u32ListenSessionID
2166 , duration
2167 , chan->hw_value
2168 , WILC_WFI_RemainOnChannelExpired
2169 , WILC_WFI_RemainOnChannelReady
2170 , (void *)priv);
2171
2172 return s32Error;
2173}
2174
2175/**
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002176 * @brief cancel_remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002177 * @details Cancel an on-going remain-on-channel operation.
2178 * This allows the operation to be terminated prior to timeout based on
2179 * the duration value.
2180 * @param[in] struct wiphy *wiphy,
2181 * @param[in] struct net_device *dev
2182 * @param[in] u64 cookie,
2183 * @return int : Return 0 on Success
2184 * @author mdaftedar
2185 * @date 01 MAR 2012
2186 * @version 1.0
2187 */
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002188static int cancel_remain_on_channel(struct wiphy *wiphy,
2189 struct wireless_dev *wdev,
2190 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002191{
Leo Kime6e12662015-09-16 18:36:03 +09002192 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002193 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002194
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002195 priv = wiphy_priv(wiphy);
2196
2197 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
2198
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002199 s32Error = wilc_listen_state_expired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002200 return s32Error;
2201}
2202/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002203 * @brief WILC_WFI_mgmt_tx_frame
2204 * @details
2205 *
2206 * @param[in]
2207 * @return NONE.
2208 * @author mdaftedar
2209 * @date 01 JUL 2012
2210 * @version
2211 */
Chaehyun Limc1560322015-09-22 18:34:51 +09002212static int mgmt_tx(struct wiphy *wiphy,
2213 struct wireless_dev *wdev,
2214 struct cfg80211_mgmt_tx_params *params,
2215 u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002216{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002217 struct ieee80211_channel *chan = params->chan;
2218 unsigned int wait = params->wait;
2219 const u8 *buf = params->buf;
2220 size_t len = params->len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002221 const struct ieee80211_mgmt *mgmt;
2222 struct p2p_mgmt_data *mgmt_tx;
Chaehyun Lim27268872015-09-15 14:06:13 +09002223 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002224 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002225 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002226 perInterface_wlan_t *nic;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002227 u32 buf_len = len + sizeof(u8P2P_vendorspec) + sizeof(u8P2Plocalrandom);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002228
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002229 nic = netdev_priv(wdev->netdev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002230 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002231 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002232
2233 *cookie = (unsigned long)buf;
2234 priv->u64tx_cookie = *cookie;
2235 mgmt = (const struct ieee80211_mgmt *) buf;
2236
2237 if (ieee80211_is_mgmt(mgmt->frame_control)) {
2238
2239 /*mgmt frame allocation*/
Glen Leef3052582015-09-10 12:03:04 +09002240 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002241 if (mgmt_tx == NULL) {
2242 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
Leo Kime6e12662015-09-16 18:36:03 +09002243 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002244 }
Glen Leef3052582015-09-10 12:03:04 +09002245 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002246 if (mgmt_tx->buff == NULL) {
2247 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
Tony Chof638dd32015-09-07 19:09:31 +09002248 kfree(mgmt_tx);
Leo Kime6e12662015-09-16 18:36:03 +09002249 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002250 }
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09002251 memcpy(mgmt_tx->buff, buf, len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002252 mgmt_tx->size = len;
2253
2254
2255 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
2256 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
2257 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002258 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002259 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002260 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002261 } else if (ieee80211_is_action(mgmt->frame_control)) {
Chaehyun Limd85f5322015-06-11 14:35:54 +09002262 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002263
2264
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002265 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002266 /*Only set the channel, if not a negotiation confirmation frame
2267 * (If Negotiation confirmation frame, force it
2268 * to be transmitted on the same negotiation channel)*/
2269
2270 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
2271 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
2272 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002273 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002274 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002275 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002276 }
2277 switch (buf[ACTION_SUBTYPE_ID]) {
2278 case GAS_INTIAL_REQ:
2279 {
2280 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
2281 break;
2282 }
2283
2284 case GAS_INTIAL_RSP:
2285 {
2286 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
2287 break;
2288 }
2289
2290 case PUBLIC_ACT_VENDORSPEC:
2291 {
Leo Kim881eb5d2015-11-19 15:56:15 +09002292 if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002293 /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/
2294 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
2295 if (u8P2Plocalrandom == 1 && u8P2Precvrandom < u8P2Plocalrandom) {
2296 get_random_bytes(&u8P2Plocalrandom, 1);
2297 /*Increment the number to prevent if its 0*/
2298 u8P2Plocalrandom++;
2299 }
2300 }
2301
2302 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2303 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2304 if (u8P2Plocalrandom > u8P2Precvrandom) {
2305 PRINT_D(GENERIC_DBG, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2306
2307 /*Search for the p2p information information element , after the Public action subtype theres a byte for teh dialog token, skip that*/
2308 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
Leo Kim881eb5d2015-11-19 15:56:15 +09002309 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002310 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
Dean Lee72ed4dc2015-06-12 14:11:44 +09002311 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002312
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002313 /*If using supplicant go intent, no need at all*/
2314 /*to parse transmitted negotiation frames*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002315 else
Dean Lee72ed4dc2015-06-12 14:11:44 +09002316 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002317 break;
2318 }
2319 }
2320
2321 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
Shivani Bhardwajd8060fc2015-10-29 00:30:01 +05302322 /*
2323 * Adding WILC information element to allow two WILC devices to
2324 * identify each other and connect
2325 */
2326 memcpy(&mgmt_tx->buff[len], u8P2P_vendorspec, sizeof(u8P2P_vendorspec));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002327 mgmt_tx->buff[len + sizeof(u8P2P_vendorspec)] = u8P2Plocalrandom;
2328 mgmt_tx->size = buf_len;
2329 }
2330 } else
2331 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2332 }
2333
2334 } else {
2335 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
2336 }
2337
2338 break;
2339 }
2340
2341 default:
2342 {
2343 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
2344 break;
2345 }
2346 }
2347
2348 }
2349
2350 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 +09002351 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002352
Leo Kim1229b1a2015-10-29 12:05:39 +09002353 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n",
2354 jiffies, pstrWFIDrv->p2p_timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002355 }
2356
Glen Lee829c4772015-10-29 12:18:44 +09002357 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
2358 mgmt_tx->buff, mgmt_tx->size,
Glen Leec9d48342015-10-01 16:03:43 +09002359 WILC_WFI_mgmt_tx_complete);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002360 } else {
2361 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
2362 }
Leo Kimaaed3292015-10-12 16:55:38 +09002363 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002364}
2365
Chaehyun Lim85c587a2015-09-22 18:34:50 +09002366static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
2367 struct wireless_dev *wdev,
2368 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002369{
Chaehyun Lim27268872015-09-15 14:06:13 +09002370 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002371 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002372
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002373 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002374 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002375
2376
2377 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
Leo Kim1229b1a2015-10-29 12:05:39 +09002378 pstrWFIDrv->p2p_timeout = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002379
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +01002380 if (!priv->bInP2PlistenState) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002381 cfg80211_remain_on_channel_expired(priv->wdev,
2382 priv->strRemainOnChanParams.u64ListenCookie,
2383 priv->strRemainOnChanParams.pstrListenChan,
2384 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002385 }
2386
2387 return 0;
2388}
2389
2390/**
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002391 * @brief wilc_mgmt_frame_register
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002392 * @details Notify driver that a management frame type was
2393 * registered. Note that this callback may not sleep, and cannot run
2394 * concurrently with itself.
2395 * @param[in]
2396 * @return NONE.
2397 * @author mdaftedar
2398 * @date 01 JUL 2012
2399 * @version
2400 */
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002401void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
2402 u16 frame_type, bool reg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002403{
2404
Chaehyun Lim27268872015-09-15 14:06:13 +09002405 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002406 perInterface_wlan_t *nic;
Glen Lee1b869352015-10-20 17:14:01 +09002407 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002408
2409 priv = wiphy_priv(wiphy);
2410 nic = netdev_priv(priv->wdev->netdev);
Glen Lee1b869352015-10-20 17:14:01 +09002411 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002412
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002413 if (!frame_type)
2414 return;
2415
2416 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
2417 switch (frame_type) {
2418 case PROBE_REQ:
2419 {
2420 nic->g_struct_frame_reg[0].frame_type = frame_type;
2421 nic->g_struct_frame_reg[0].reg = reg;
2422 }
2423 break;
2424
2425 case ACTION:
2426 {
2427 nic->g_struct_frame_reg[1].frame_type = frame_type;
2428 nic->g_struct_frame_reg[1].reg = reg;
2429 }
2430 break;
2431
2432 default:
2433 {
2434 break;
2435 }
2436
2437 }
2438 /*If mac is closed, then return*/
Glen Lee1b869352015-10-20 17:14:01 +09002439 if (!wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002440 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
2441 return;
2442 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002443 wilc_frame_register(priv->hWILCWFIDrv, frame_type, reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002444
2445
2446}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002447
2448/**
Chaehyun Lima8047e22015-09-22 18:34:48 +09002449 * @brief set_cqm_rssi_config
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002450 * @details Configure connection quality monitor RSSI threshold.
2451 * @param[in] struct wiphy *wiphy:
2452 * @param[in] struct net_device *dev:
2453 * @param[in] s32 rssi_thold:
2454 * @param[in] u32 rssi_hyst:
2455 * @return int : Return 0 on Success
2456 * @author mdaftedar
2457 * @date 01 MAR 2012
2458 * @version 1.0
2459 */
Chaehyun Lima8047e22015-09-22 18:34:48 +09002460static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
2461 s32 rssi_thold, u32 rssi_hyst)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002462{
2463 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2464 return 0;
2465
2466}
2467/**
Chaehyun Limbdb63382015-09-14 12:24:19 +09002468 * @brief dump_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002469 * @details Configure connection quality monitor RSSI threshold.
2470 * @param[in] struct wiphy *wiphy:
2471 * @param[in] struct net_device *dev
2472 * @param[in] int idx
2473 * @param[in] u8 *mac
2474 * @param[in] struct station_info *sinfo
2475 * @return int : Return 0 on Success
2476 * @author mdaftedar
2477 * @date 01 MAR 2012
2478 * @version 1.0
2479 */
Chaehyun Limbdb63382015-09-14 12:24:19 +09002480static int dump_station(struct wiphy *wiphy, struct net_device *dev,
2481 int idx, u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002482{
Chaehyun Lim27268872015-09-15 14:06:13 +09002483 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002484
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002485 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2486
2487 if (idx != 0)
2488 return -ENOENT;
2489
2490 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002491
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002492 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002493
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002494 wilc_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002495
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002496 return 0;
2497
2498}
2499
2500
2501/**
Chaehyun Lim46530672015-09-22 18:34:46 +09002502 * @brief set_power_mgmt
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002503 * @details
2504 * @param[in]
2505 * @return int : Return 0 on Success.
2506 * @author mdaftedar
2507 * @date 01 JUL 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09002508 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002509 */
Chaehyun Lim46530672015-09-22 18:34:46 +09002510static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2511 bool enabled, int timeout)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002512{
Chaehyun Lim27268872015-09-15 14:06:13 +09002513 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002514
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002515 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2516
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002517 if (wiphy == NULL)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002518 return -ENOENT;
2519
2520 priv = wiphy_priv(wiphy);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002521 if (priv->hWILCWFIDrv == NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002522 PRINT_ER("Driver is NULL\n");
2523 return -EIO;
2524 }
2525
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002526 if (wilc_enable_ps)
2527 wilc_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002528
2529
Leo Kime6e12662015-09-16 18:36:03 +09002530 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002531
2532}
Glen Lee108b3432015-09-16 18:53:20 +09002533
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002534/**
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002535 * @brief change_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002536 * @details Change type/configuration of virtual interface,
2537 * keep the struct wireless_dev's iftype updated.
2538 * @param[in] NONE
2539 * @return int : Return 0 on Success.
2540 * @author mdaftedar
2541 * @date 01 MAR 2012
2542 * @version 1.0
2543 */
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002544static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2545 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002546{
Chaehyun Lim27268872015-09-15 14:06:13 +09002547 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002548 perInterface_wlan_t *nic;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002549 u8 interface_type;
Chaehyun Limd85f5322015-06-11 14:35:54 +09002550 u16 TID = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002551 u8 i;
Glen Lee299382c2015-10-20 17:13:56 +09002552 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002553
2554 nic = netdev_priv(dev);
2555 priv = wiphy_priv(wiphy);
Glen Lee299382c2015-10-20 17:13:56 +09002556 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002557
2558 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2559 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
2560 u8P2Plocalrandom = 0x01;
2561 u8P2Precvrandom = 0x00;
2562
Dean Lee72ed4dc2015-06-12 14:11:44 +09002563 bWilc_ie = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002564
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002565 wilc_optaining_ip = false;
2566 del_timer(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002567 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002568 /*Set WILC_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/
2569 if (g_ptk_keys_saved && g_gtk_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002570 wilc_set_machw_change_vir_if(dev, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002571 }
2572
2573 switch (type) {
2574 case NL80211_IFTYPE_STATION:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002575 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002576 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002577
2578 /* send delba over wlan interface */
2579
2580
2581 dev->ieee80211_ptr->iftype = type;
2582 priv->wdev->iftype = type;
2583 nic->monitor_flag = 0;
2584 nic->iftype = STATION_MODE;
2585
2586 /*Remove the enteries of the previously connected clients*/
2587 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002588 interface_type = nic->iftype;
2589 nic->iftype = STATION_MODE;
2590
Glen Lee299382c2015-10-20 17:13:56 +09002591 if (wl->initialized) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002592 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2593 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002594 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002595 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002596
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002597 /*Eliminate host interface blocking state*/
Glen Lee299382c2015-10-20 17:13:56 +09002598 up(&wl->cfg_event);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002599
Glen Lee53dc0cf2015-10-20 17:13:57 +09002600 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002601 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002602 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002603 nic->iftype = interface_type;
2604
2605 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002606 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2607 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002608 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002609 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002610
2611 /*Add saved WEP keys, if any*/
2612 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002613 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002614 g_key_wep_params.key_idx);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002615 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002616 g_key_wep_params.key,
2617 g_key_wep_params.key_len,
2618 g_key_wep_params.key_idx);
2619 }
2620
2621 /*No matter the driver handler passed here, it will be overwriiten*/
2622 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002623 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002624
2625 /*Add saved PTK and GTK keys, if any*/
2626 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2627 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2628 g_key_ptk_params.key[1],
2629 g_key_ptk_params.key[2]);
2630 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2631 g_key_gtk_params.key[1],
2632 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002633 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2634 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002635 g_add_ptk_key_params.key_idx,
2636 g_add_ptk_key_params.pairwise,
2637 g_add_ptk_key_params.mac_addr,
2638 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002639
Glen Lee299382c2015-10-20 17:13:56 +09002640 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2641 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002642 g_add_gtk_key_params.key_idx,
2643 g_add_gtk_key_params.pairwise,
2644 g_add_gtk_key_params.mac_addr,
2645 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002646 }
2647
Glen Lee299382c2015-10-20 17:13:56 +09002648 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002649 for (i = 0; i < num_reg_frame; i++) {
2650 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2651 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002652 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002653 nic->g_struct_frame_reg[i].frame_type,
2654 nic->g_struct_frame_reg[i].reg);
2655 }
2656 }
2657
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002658 wilc_enable_ps = true;
2659 wilc_set_power_mgmt(priv->hWILCWFIDrv, 1, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002660 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002661 break;
2662
2663 case NL80211_IFTYPE_P2P_CLIENT:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002664 wilc_enable_ps = false;
2665 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
2666 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002667 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002668
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002669 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2670 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002671
2672 dev->ieee80211_ptr->iftype = type;
2673 priv->wdev->iftype = type;
2674 nic->monitor_flag = 0;
2675
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002676 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2677 nic->iftype = CLIENT_MODE;
2678
2679
Glen Lee299382c2015-10-20 17:13:56 +09002680 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002681 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002682 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002683
Glen Lee53dc0cf2015-10-20 17:13:57 +09002684 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002685 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002686 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002687
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002688 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2689 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002690 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002691 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002692
2693 /*Add saved WEP keys, if any*/
2694 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002695 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2696 g_key_wep_params.key_idx);
2697 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
2698 g_key_wep_params.key,
2699 g_key_wep_params.key_len,
2700 g_key_wep_params.key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002701 }
2702
2703 /*No matter the driver handler passed here, it will be overwriiten*/
2704 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002705 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002706
2707 /*Add saved PTK and GTK keys, if any*/
2708 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2709 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2710 g_key_ptk_params.key[1],
2711 g_key_ptk_params.key[2]);
2712 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2713 g_key_gtk_params.key[1],
2714 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002715 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2716 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002717 g_add_ptk_key_params.key_idx,
2718 g_add_ptk_key_params.pairwise,
2719 g_add_ptk_key_params.mac_addr,
2720 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002721
Glen Lee299382c2015-10-20 17:13:56 +09002722 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2723 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002724 g_add_gtk_key_params.key_idx,
2725 g_add_gtk_key_params.pairwise,
2726 g_add_gtk_key_params.mac_addr,
2727 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002728 }
2729
2730 /*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 +09002731 refresh_scan(priv, 1, true);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002732 wilc_set_machw_change_vir_if(dev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002733
Glen Lee299382c2015-10-20 17:13:56 +09002734 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002735 for (i = 0; i < num_reg_frame; i++) {
2736 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2737 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002738 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002739 nic->g_struct_frame_reg[i].frame_type,
2740 nic->g_struct_frame_reg[i].reg);
2741 }
2742 }
2743 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002744 break;
2745
2746 case NL80211_IFTYPE_AP:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002747 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002748 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002749 dev->ieee80211_ptr->iftype = type;
2750 priv->wdev->iftype = type;
2751 nic->iftype = AP_MODE;
Johnny Kim8a143302015-06-10 17:06:46 +09002752 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002753
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002754 PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002755 wilc_wlan_get_firmware(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002756 /*If wilc is running, then close-open to actually get new firmware running (serves P2P)*/
Glen Lee299382c2015-10-20 17:13:56 +09002757 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002758 nic->iftype = AP_MODE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002759 wilc_mac_close(dev);
2760 wilc_mac_open(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002761
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002762 for (i = 0; i < num_reg_frame; i++) {
2763 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2764 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002765 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002766 nic->g_struct_frame_reg[i].frame_type,
2767 nic->g_struct_frame_reg[i].reg);
2768 }
2769 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002770 break;
2771
2772 case NL80211_IFTYPE_P2P_GO:
2773 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
2774
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002775 wilc_optaining_ip = true;
2776 mod_timer(&wilc_during_ip_timer, jiffies + msecs_to_jiffies(duringIP_TIME));
2777 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002778 /*Delete block ack has to be the latest config packet*/
2779 /*sent before downloading new FW. This is because it blocks on*/
2780 /*hWaitResponse semaphore, which allows previous config*/
2781 /*packets to actually take action on old FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002782 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2783 wl->vif[0].bssid, TID);
2784 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002785 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002786 dev->ieee80211_ptr->iftype = type;
2787 priv->wdev->iftype = type;
2788
Johnny Kim8a143302015-06-10 17:06:46 +09002789 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002790
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002791 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2792
2793
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002794 nic->iftype = GO_MODE;
2795
2796 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002797 wilc_wait_msg_queue_idle();
Glen Lee53dc0cf2015-10-20 17:13:57 +09002798 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002799 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002800 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002801
2802
2803 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002804 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2805 wilc_set_mac_address(wl->vif[0].hif_drv,
2806 wl->vif[0].src_addr);
2807 wilc_set_operation_mode(priv->hWILCWFIDrv, AP_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002808
2809 /*Add saved WEP keys, if any*/
2810 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002811 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2812 g_key_wep_params.key_idx);
2813 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002814 g_key_wep_params.key,
2815 g_key_wep_params.key_len,
2816 g_key_wep_params.key_idx);
2817 }
2818
2819 /*No matter the driver handler passed here, it will be overwriiten*/
2820 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002821 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002822
2823 /*Add saved PTK and GTK keys, if any*/
2824 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2825 PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0],
2826 g_key_ptk_params.key[1],
2827 g_key_ptk_params.key[2],
2828 g_key_ptk_params.cipher);
2829 PRINT_D(CFG80211_DBG, "gtk %x %x %x cipher %x\n", g_key_gtk_params.key[0],
2830 g_key_gtk_params.key[1],
2831 g_key_gtk_params.key[2],
2832 g_key_gtk_params.cipher);
Glen Lee299382c2015-10-20 17:13:56 +09002833 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2834 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002835 g_add_ptk_key_params.key_idx,
2836 g_add_ptk_key_params.pairwise,
2837 g_add_ptk_key_params.mac_addr,
2838 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002839
Glen Lee299382c2015-10-20 17:13:56 +09002840 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2841 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002842 g_add_gtk_key_params.key_idx,
2843 g_add_gtk_key_params.pairwise,
2844 g_add_gtk_key_params.mac_addr,
2845 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002846 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002847
Glen Lee299382c2015-10-20 17:13:56 +09002848 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002849 for (i = 0; i < num_reg_frame; i++) {
2850 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2851 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002852 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002853 nic->g_struct_frame_reg[i].frame_type,
2854 nic->g_struct_frame_reg[i].reg);
2855 }
2856 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002857 break;
2858
2859 default:
2860 PRINT_ER("Unknown interface type= %d\n", type);
Leo Kimaaed3292015-10-12 16:55:38 +09002861 return -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002862 }
2863
Leo Kimaaed3292015-10-12 16:55:38 +09002864 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002865}
2866
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002867/* (austin.2013-07-23)
2868 *
2869 * To support revised cfg80211_ops
2870 *
2871 * add_beacon --> start_ap
2872 * set_beacon --> change_beacon
2873 * del_beacon --> stop_ap
2874 *
2875 * beacon_parameters --> cfg80211_ap_settings
2876 * cfg80211_beacon_data
2877 *
2878 * applicable for linux kernel 3.4+
2879 */
2880
2881/**
Chaehyun Lima13168d2015-09-14 12:24:12 +09002882 * @brief start_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002883 * @details Add a beacon with given parameters, @head, @interval
2884 * and @dtim_period will be valid, @tail is optional.
2885 * @param[in] wiphy
2886 * @param[in] dev The net device structure
2887 * @param[in] settings cfg80211_ap_settings parameters for the beacon to be added
2888 * @return int : Return 0 on Success.
2889 * @author austin
2890 * @date 23 JUL 2013
2891 * @version 1.0
2892 */
Chaehyun Lima13168d2015-09-14 12:24:12 +09002893static int start_ap(struct wiphy *wiphy, struct net_device *dev,
2894 struct cfg80211_ap_settings *settings)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002895{
2896 struct cfg80211_beacon_data *beacon = &(settings->beacon);
Chaehyun Lim27268872015-09-15 14:06:13 +09002897 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002898 s32 s32Error = 0;
Glen Lee684dc182015-10-20 17:14:02 +09002899 struct wilc *wl;
2900 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002901
2902 priv = wiphy_priv(wiphy);
Glen Lee684dc182015-10-20 17:14:02 +09002903 nic = netdev_priv(dev);
2904 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002905 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
2906
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302907 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 +09002908 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
2909
Chaehyun Lim80785a92015-09-14 12:24:01 +09002910 s32Error = set_channel(wiphy, &settings->chandef);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002911
Leo Kime6e12662015-09-16 18:36:03 +09002912 if (s32Error != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002913 PRINT_ER("Error in setting channel\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002914
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002915 wilc_wlan_set_bssid(dev, wl->vif[0].src_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002916
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002917 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002918 settings->beacon_interval,
2919 settings->dtim_period,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002920 beacon->head_len, (u8 *)beacon->head,
2921 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002922
2923 return s32Error;
2924}
2925
2926/**
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002927 * @brief change_beacon
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002928 * @details Add a beacon with given parameters, @head, @interval
2929 * and @dtim_period will be valid, @tail is optional.
2930 * @param[in] wiphy
2931 * @param[in] dev The net device structure
2932 * @param[in] beacon cfg80211_beacon_data for the beacon to be changed
2933 * @return int : Return 0 on Success.
2934 * @author austin
2935 * @date 23 JUL 2013
2936 * @version 1.0
2937 */
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002938static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
2939 struct cfg80211_beacon_data *beacon)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002940{
Chaehyun Lim27268872015-09-15 14:06:13 +09002941 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002942 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002943
2944 priv = wiphy_priv(wiphy);
2945 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
2946
2947
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002948 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002949 0,
2950 0,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002951 beacon->head_len, (u8 *)beacon->head,
2952 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002953
2954 return s32Error;
2955}
2956
2957/**
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002958 * @brief stop_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002959 * @details Remove beacon configuration and stop sending the beacon.
2960 * @param[in]
2961 * @return int : Return 0 on Success.
2962 * @author austin
2963 * @date 23 JUL 2013
2964 * @version 1.0
2965 */
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002966static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002967{
Leo Kime6e12662015-09-16 18:36:03 +09002968 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002969 struct wilc_priv *priv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002970 u8 NullBssid[ETH_ALEN] = {0};
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002971
Leo Kim7ae43362015-09-16 18:35:59 +09002972 if (!wiphy)
2973 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002974
2975 priv = wiphy_priv(wiphy);
2976
2977 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
2978
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002979 wilc_wlan_set_bssid(dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002980
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002981 s32Error = wilc_del_beacon(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002982
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002983 if (s32Error)
2984 PRINT_ER("Host delete beacon fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002985
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002986 return s32Error;
2987}
2988
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002989/**
Chaehyun Limed269552015-09-14 12:24:15 +09002990 * @brief add_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002991 * @details Add a new station.
2992 * @param[in]
2993 * @return int : Return 0 on Success.
2994 * @author mdaftedar
2995 * @date 01 MAR 2012
2996 * @version 1.0
2997 */
Chaehyun Limed269552015-09-14 12:24:15 +09002998static int add_station(struct wiphy *wiphy, struct net_device *dev,
2999 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003000{
Leo Kime6e12662015-09-16 18:36:03 +09003001 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003002 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09003003 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003004 perInterface_wlan_t *nic;
3005
Leo Kim7ae43362015-09-16 18:35:59 +09003006 if (!wiphy)
3007 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003008
3009 priv = wiphy_priv(wiphy);
3010 nic = netdev_priv(dev);
3011
3012 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003013 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09003014 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003015 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003016 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003017 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003018
3019 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
3020
3021 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],
3022 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003023 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003024 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3025 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003026
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003027 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003028 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003029 } else {
Leo Kim22520122015-10-29 12:05:45 +09003030 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003031 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003032 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003033 memcpy(strStaParams.ht_supp_mcs_set,
3034 &params->ht_capa->mcs,
3035 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003036 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003037 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003038 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003039 }
3040
Leo Kimf676e172015-10-29 12:05:52 +09003041 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003042 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003043
Leo Kim22520122015-10-29 12:05:45 +09003044 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3045 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003046 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3047 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003048 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3049 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003050 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3051 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003052 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3053 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003054 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3055 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003056 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3057 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003058 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3059 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003060
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003061 s32Error = wilc_add_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003062 if (s32Error)
3063 PRINT_ER("Host add station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003064 }
3065
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003066 return s32Error;
3067}
3068
3069/**
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003070 * @brief del_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003071 * @details Remove a station; @mac may be NULL to remove all stations.
3072 * @param[in]
3073 * @return int : Return 0 on Success.
3074 * @author mdaftedar
3075 * @date 01 MAR 2012
3076 * @version 1.0
3077 */
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003078static int del_station(struct wiphy *wiphy, struct net_device *dev,
3079 struct station_del_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003080{
Arnd Bergmann057d1e92015-06-01 21:06:44 +02003081 const u8 *mac = params->mac;
Leo Kime6e12662015-09-16 18:36:03 +09003082 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003083 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003084 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003085
Leo Kim7ae43362015-09-16 18:35:59 +09003086 if (!wiphy)
3087 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003088
3089 priv = wiphy_priv(wiphy);
3090 nic = netdev_priv(dev);
3091
3092 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
3093 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
3094
3095
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003096 if (mac == NULL) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05303097 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003098 s32Error = wilc_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003099 } else {
3100 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]);
3101 }
3102
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003103 s32Error = wilc_del_station(priv->hWILCWFIDrv, mac);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003104
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003105 if (s32Error)
3106 PRINT_ER("Host delete station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003107 }
3108 return s32Error;
3109}
3110
3111/**
Chaehyun Lim14b42082015-09-14 12:24:17 +09003112 * @brief change_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003113 * @details Modify a given station.
3114 * @param[in]
3115 * @return int : Return 0 on Success.
3116 * @author mdaftedar
3117 * @date 01 MAR 2012
3118 * @version 1.0
3119 */
Chaehyun Lim14b42082015-09-14 12:24:17 +09003120static int change_station(struct wiphy *wiphy, struct net_device *dev,
3121 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003122{
Leo Kime6e12662015-09-16 18:36:03 +09003123 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003124 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09003125 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003126 perInterface_wlan_t *nic;
3127
3128
3129 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
3130
Leo Kim7ae43362015-09-16 18:35:59 +09003131 if (!wiphy)
3132 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003133
3134 priv = wiphy_priv(wiphy);
3135 nic = netdev_priv(dev);
3136
3137 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003138 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003139 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003140 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003141 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003142
Leo Kim2353c382015-10-29 12:05:41 +09003143 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n",
3144 strStaParams.bssid[0], strStaParams.bssid[1],
3145 strStaParams.bssid[2], strStaParams.bssid[3],
3146 strStaParams.bssid[4], strStaParams.bssid[5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003147 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003148 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3149 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003150
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003151 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003152 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003153 } else {
Leo Kim22520122015-10-29 12:05:45 +09003154 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003155 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003156 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003157 memcpy(strStaParams.ht_supp_mcs_set,
3158 &params->ht_capa->mcs,
3159 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003160 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003161 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003162 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003163 }
3164
Leo Kimf676e172015-10-29 12:05:52 +09003165 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003166 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003167
Leo Kim22520122015-10-29 12:05:45 +09003168 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3169 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003170 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3171 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003172 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3173 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003174 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3175 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003176 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3177 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003178 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3179 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003180 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3181 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003182 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3183 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003184
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003185 s32Error = wilc_edit_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003186 if (s32Error)
3187 PRINT_ER("Host edit station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003188 }
3189 return s32Error;
3190}
3191
3192
3193/**
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003194 * @brief add_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003195 * @details
3196 * @param[in]
3197 * @return int : Return 0 on Success.
3198 * @author mdaftedar
3199 * @date 01 JUL 2012
3200 * @version 1.0
3201 */
Chaehyun Lim37316e82015-09-22 18:34:52 +09003202static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
3203 const char *name,
3204 unsigned char name_assign_type,
3205 enum nl80211_iftype type,
3206 u32 *flags,
3207 struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003208{
3209 perInterface_wlan_t *nic;
Chaehyun Lim27268872015-09-15 14:06:13 +09003210 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003211 struct net_device *new_ifc = NULL;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003212
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003213 priv = wiphy_priv(wiphy);
3214
3215
3216
3217 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
3218
3219 nic = netdev_priv(priv->wdev->netdev);
3220
3221
3222 if (type == NL80211_IFTYPE_MONITOR) {
3223 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
3224 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", nic->wilc_netdev);
3225 new_ifc = WILC_WFI_init_mon_interface(name, nic->wilc_netdev);
3226 if (new_ifc != NULL) {
3227 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003228 nic = netdev_priv(priv->wdev->netdev);
3229 nic->monitor_flag = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003230 } else
3231 PRINT_ER("Error in initializing monitor interface\n ");
3232 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003233 return priv->wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003234}
3235
3236/**
Chaehyun Limb4a73352015-09-14 12:24:10 +09003237 * @brief del_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003238 * @details
3239 * @param[in]
3240 * @return int : Return 0 on Success.
3241 * @author mdaftedar
3242 * @date 01 JUL 2012
3243 * @version 1.0
3244 */
Chaehyun Lim956d7212015-09-22 18:34:49 +09003245static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003246{
3247 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
Leo Kime6e12662015-09-16 18:36:03 +09003248 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003249}
3250
Chaehyun Lim08241922015-09-15 14:06:12 +09003251static struct cfg80211_ops wilc_cfg80211_ops = {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003252
Chaehyun Lim80785a92015-09-14 12:24:01 +09003253 .set_monitor_channel = set_channel,
Chaehyun Lim0e30d062015-09-14 12:24:02 +09003254 .scan = scan,
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +09003255 .connect = connect,
Chaehyun Limb027cde2015-09-14 12:24:04 +09003256 .disconnect = disconnect,
Chaehyun Lim953d4172015-09-14 12:24:05 +09003257 .add_key = add_key,
Chaehyun Lim3044ba72015-09-14 12:24:06 +09003258 .del_key = del_key,
Chaehyun Limf4893df2015-09-14 12:24:07 +09003259 .get_key = get_key,
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09003260 .set_default_key = set_default_key,
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003261 .add_virtual_intf = add_virtual_intf,
Chaehyun Limb4a73352015-09-14 12:24:10 +09003262 .del_virtual_intf = del_virtual_intf,
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09003263 .change_virtual_intf = change_virtual_intf,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003264
Chaehyun Lima13168d2015-09-14 12:24:12 +09003265 .start_ap = start_ap,
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09003266 .change_beacon = change_beacon,
Chaehyun Limc8cddd72015-09-14 12:24:14 +09003267 .stop_ap = stop_ap,
Chaehyun Limed269552015-09-14 12:24:15 +09003268 .add_station = add_station,
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003269 .del_station = del_station,
Chaehyun Lim14b42082015-09-14 12:24:17 +09003270 .change_station = change_station,
Chaehyun Limf06f5622015-09-14 12:24:18 +09003271 .get_station = get_station,
Chaehyun Limbdb63382015-09-14 12:24:19 +09003272 .dump_station = dump_station,
Chaehyun Lima5f7db62015-09-14 12:24:20 +09003273 .change_bss = change_bss,
Chaehyun Lima76b63e2015-09-14 12:24:21 +09003274 .set_wiphy_params = set_wiphy_params,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003275
Chaehyun Lim4d466572015-09-14 12:24:22 +09003276 .set_pmksa = set_pmksa,
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09003277 .del_pmksa = del_pmksa,
Chaehyun Limb33c39b2015-09-14 12:24:24 +09003278 .flush_pmksa = flush_pmksa,
Chaehyun Lim6d19d692015-09-14 12:24:25 +09003279 .remain_on_channel = remain_on_channel,
Chaehyun Lim1dd54402015-09-14 12:24:26 +09003280 .cancel_remain_on_channel = cancel_remain_on_channel,
Chaehyun Lim4a2f9b32015-09-14 12:24:27 +09003281 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
Chaehyun Lim12a26a32015-09-14 12:24:28 +09003282 .mgmt_tx = mgmt_tx,
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09003283 .mgmt_frame_register = wilc_mgmt_frame_register,
Chaehyun Lim46530672015-09-22 18:34:46 +09003284 .set_power_mgmt = set_power_mgmt,
Chaehyun Lima8047e22015-09-22 18:34:48 +09003285 .set_cqm_rssi_config = set_cqm_rssi_config,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003286
3287};
3288
3289
3290
3291
3292
3293/**
3294 * @brief WILC_WFI_update_stats
3295 * @details Modify parameters for a given BSS.
3296 * @param[in]
3297 * @return int : Return 0 on Success.
3298 * @author mdaftedar
3299 * @date 01 MAR 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09003300 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003301 */
3302int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
3303{
3304
Chaehyun Lim27268872015-09-15 14:06:13 +09003305 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003306
3307 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003308 switch (changed) {
3309
3310 case WILC_WFI_RX_PKT:
3311 {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003312 priv->netstats.rx_packets++;
3313 priv->netstats.rx_bytes += pktlen;
3314 priv->netstats.rx_time = get_jiffies_64();
3315 }
3316 break;
3317
3318 case WILC_WFI_TX_PKT:
3319 {
3320 priv->netstats.tx_packets++;
3321 priv->netstats.tx_bytes += pktlen;
3322 priv->netstats.tx_time = get_jiffies_64();
3323
3324 }
3325 break;
3326
3327 default:
3328 break;
3329 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003330 return 0;
3331}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003332
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003333/**
3334 * @brief WILC_WFI_CfgAlloc
3335 * @details Allocation of the wireless device structure and assigning it
3336 * to the cfg80211 operations structure.
3337 * @param[in] NONE
3338 * @return wireless_dev : Returns pointer to wireless_dev structure.
3339 * @author mdaftedar
3340 * @date 01 MAR 2012
3341 * @version 1.0
3342 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01003343static struct wireless_dev *WILC_WFI_CfgAlloc(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003344{
3345
3346 struct wireless_dev *wdev;
3347
3348
3349 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
3350 /*Allocating the wireless device structure*/
3351 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
3352 if (!wdev) {
3353 PRINT_ER("Cannot allocate wireless device\n");
3354 goto _fail_;
3355 }
3356
3357 /*Creating a new wiphy, linking wireless structure with the wiphy structure*/
Chaehyun Lim27268872015-09-15 14:06:13 +09003358 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003359 if (!wdev->wiphy) {
3360 PRINT_ER("Cannot allocate wiphy\n");
3361 goto _fail_mem_;
3362
3363 }
3364
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003365 /* enable 802.11n HT */
3366 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
3367 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
3368 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3369 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
3370 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003371
3372 /*wiphy bands*/
3373 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
3374
3375 return wdev;
3376
3377_fail_mem_:
3378 kfree(wdev);
3379_fail_:
3380 return NULL;
3381
3382}
3383/**
Chaehyun Lim8459fd52015-09-20 15:51:09 +09003384 * @brief wilc_create_wiphy
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003385 * @details Registering of the wiphy structure and interface modes
3386 * @param[in] NONE
3387 * @return NONE
3388 * @author mdaftedar
3389 * @date 01 MAR 2012
3390 * @version 1.0
3391 */
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01003392struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003393{
Chaehyun Lim27268872015-09-15 14:06:13 +09003394 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003395 struct wireless_dev *wdev;
Leo Kime6e12662015-09-16 18:36:03 +09003396 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003397
3398 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
3399
3400 wdev = WILC_WFI_CfgAlloc();
3401 if (wdev == NULL) {
3402 PRINT_ER("CfgAlloc Failed\n");
3403 return NULL;
3404 }
3405
3406
3407 /*Return hardware description structure (wiphy)'s priv*/
3408 priv = wdev_priv(wdev);
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003409 sema_init(&(priv->SemHandleUpdateStats), 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003410
3411 /*Link the wiphy with wireless structure*/
3412 priv->wdev = wdev;
3413
3414 /*Maximum number of probed ssid to be added by user for the scan request*/
3415 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003416 /*Maximum number of pmkids to be cashed*/
3417 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
3418 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003419
3420 wdev->wiphy->max_scan_ie_len = 1000;
3421
3422 /*signal strength in mBm (100*dBm) */
3423 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3424
3425 /*Set the availaible cipher suites*/
3426 wdev->wiphy->cipher_suites = cipher_suites;
3427 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003428 /*Setting default managment types: for register action frame: */
3429 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003430
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003431 wdev->wiphy->max_remain_on_channel_duration = 500;
3432 /*Setting the wiphy interfcae mode and type before registering the wiphy*/
3433 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
3434 BIT(NL80211_IFTYPE_P2P_CLIENT);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003435 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003436 wdev->iftype = NL80211_IFTYPE_STATION;
3437
3438
3439
3440 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
3441 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
3442 wdev->wiphy->interface_modes, wdev->iftype);
3443
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01003444 set_wiphy_dev(wdev->wiphy, dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003445
3446 /*Register wiphy structure*/
3447 s32Error = wiphy_register(wdev->wiphy);
3448 if (s32Error) {
3449 PRINT_ER("Cannot register wiphy device\n");
3450 /*should define what action to be taken in such failure*/
3451 } else {
3452 PRINT_D(CFG80211_DBG, "Successful Registering\n");
3453 }
3454
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003455 priv->dev = net;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003456 return wdev;
3457
3458
3459}
3460/**
3461 * @brief WILC_WFI_WiphyFree
3462 * @details Freeing allocation of the wireless device structure
3463 * @param[in] NONE
3464 * @return NONE
3465 * @author mdaftedar
3466 * @date 01 MAR 2012
3467 * @version 1.0
3468 */
Chaehyun Limdd4b6a82015-09-20 15:51:25 +09003469int wilc_init_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003470{
3471
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003472 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003473
Chaehyun Lim27268872015-09-15 14:06:13 +09003474 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003475
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003476 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
3477 priv = wdev_priv(net->ieee80211_ptr);
3478 if (op_ifcs == 0) {
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -07003479 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003480 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003481 }
3482 op_ifcs++;
3483 if (s32Error < 0) {
3484 PRINT_ER("Failed to creat refresh Timer\n");
3485 return s32Error;
3486 }
3487
Dean Lee72ed4dc2015-06-12 14:11:44 +09003488 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003489
Dean Lee72ed4dc2015-06-12 14:11:44 +09003490 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003491
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003492 sema_init(&(priv->hSemScanReq), 1);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003493 s32Error = wilc_init(net, &priv->hWILCWFIDrv);
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003494 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003495 PRINT_ER("Error while initializing hostinterface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003496
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003497 return s32Error;
3498}
3499
3500/**
3501 * @brief WILC_WFI_WiphyFree
3502 * @details Freeing allocation of the wireless device structure
3503 * @param[in] NONE
3504 * @return NONE
3505 * @author mdaftedar
3506 * @date 01 MAR 2012
3507 * @version 1.0
3508 */
Chaehyun Lima9a16822015-09-20 15:51:24 +09003509int wilc_deinit_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003510{
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003511 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003512
Chaehyun Lim27268872015-09-15 14:06:13 +09003513 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003514
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003515 priv = wdev_priv(net->ieee80211_ptr);
3516
Dean Lee72ed4dc2015-06-12 14:11:44 +09003517 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003518
Dean Lee72ed4dc2015-06-12 14:11:44 +09003519 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003520
3521 op_ifcs--;
3522
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003523 s32Error = wilc_deinit(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003524
3525 /* Clear the Shadow scan */
3526 clear_shadow_scan(priv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003527 if (op_ifcs == 0) {
3528 PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003529 del_timer_sync(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003530 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003531
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003532 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003533 PRINT_ER("Error while deintializing host interface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003534
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003535 return s32Error;
3536}
3537
3538
3539/**
3540 * @brief WILC_WFI_WiphyFree
3541 * @details Freeing allocation of the wireless device structure
3542 * @param[in] NONE
3543 * @return NONE
3544 * @author mdaftedar
3545 * @date 01 MAR 2012
3546 * @version 1.0
3547 */
Chaehyun Lim96da20a2015-09-20 15:51:08 +09003548void wilc_free_wiphy(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003549{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003550 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
3551
Chaehyun Lim619837a2015-09-20 15:51:10 +09003552 if (!net) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003553 PRINT_D(INIT_DBG, "net_device is NULL\n");
3554 return;
3555 }
3556
Chaehyun Lim619837a2015-09-20 15:51:10 +09003557 if (!net->ieee80211_ptr) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003558 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
3559 return;
3560 }
3561
Chaehyun Lim619837a2015-09-20 15:51:10 +09003562 if (!net->ieee80211_ptr->wiphy) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003563 PRINT_D(INIT_DBG, "wiphy is NULL\n");
3564 return;
3565 }
3566
3567 wiphy_unregister(net->ieee80211_ptr->wiphy);
3568
3569 PRINT_D(INIT_DBG, "Freeing wiphy\n");
3570 wiphy_free(net->ieee80211_ptr->wiphy);
3571 kfree(net->ieee80211_ptr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003572}