blob: 0a7226c4c5c6721f13f31c3b30b24302dc4d4387 [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};
Leo Kim583d9722015-11-19 15:56:16 +0900175static u8 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +0900176static u8 p2p_recv_random = 0x00;
Leo Kim86685942015-11-19 15:56:18 +0900177static u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
Arnd Bergmann1608c402015-11-16 15:04:53 +0100178static 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);
Leo Kim583d9722015-11-19 15:56:16 +0900644 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +0900645 p2p_recv_random = 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
Leo Kim583d9722015-11-19 15:56:16 +09001074 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +09001075 p2p_recv_random = 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++) {
Leo Kim86685942015-11-19 15:56:18 +09002003 if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002004 p2p_recv_random = buff[i + 6];
Dean Lee72ed4dc2015-06-12 14:11:44 +09002005 bWilc_ie = true;
Leo Kimb84a3ac2015-11-19 15:56:17 +09002006 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", p2p_recv_random);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002007 break;
2008 }
2009 }
2010 }
2011 }
Leo Kimb84a3ac2015-11-19 15:56:17 +09002012 if (p2p_local_random > p2p_recv_random) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002013 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 }
Leo Kim583d9722015-11-19 15:56:16 +09002022 } else {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002023 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
Leo Kim583d9722015-11-19 15:56:16 +09002024 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002025 }
2026
2027
2028 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (bWilc_ie)) {
2029 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
2030 /* extra attribute for sig_dbm: signal strength in mBm, or 0 if unknown */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002031 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002032 return;
2033 }
2034 break;
2035
2036 default:
2037 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
2038 break;
2039 }
2040 }
2041 }
2042
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002043 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002044 }
2045}
2046
2047/**
2048 * @brief WILC_WFI_mgmt_tx_complete
2049 * @details Returns result of writing mgmt frame to VMM (Tx buffers are freed here)
2050 * @param[in] priv
2051 * transmitting status
2052 * @return None
2053 * @author Amr Abdelmoghny
2054 * @date 20 MAY 2013
2055 * @version 1.0
2056 */
2057static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
2058{
2059 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
2060
2061
2062 kfree(pv_data->buff);
2063 kfree(pv_data);
2064}
2065
2066/**
2067 * @brief WILC_WFI_RemainOnChannelReady
2068 * @details Callback function, called from handle_remain_on_channel on being ready on channel
2069 * @param
2070 * @return none
2071 * @author Amr abdelmoghny
2072 * @date 9 JUNE 2013
2073 * @version
2074 */
2075
2076static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
2077{
Chaehyun Lim27268872015-09-15 14:06:13 +09002078 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002079
Chaehyun Lim27268872015-09-15 14:06:13 +09002080 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002081
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302082 PRINT_D(HOSTINF_DBG, "Remain on channel ready\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002083
Dean Lee72ed4dc2015-06-12 14:11:44 +09002084 priv->bInP2PlistenState = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002085
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002086 cfg80211_ready_on_channel(priv->wdev,
2087 priv->strRemainOnChanParams.u64ListenCookie,
2088 priv->strRemainOnChanParams.pstrListenChan,
2089 priv->strRemainOnChanParams.u32ListenDuration,
2090 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002091}
2092
2093/**
2094 * @brief WILC_WFI_RemainOnChannelExpired
2095 * @details Callback function, called on expiration of remain-on-channel duration
2096 * @param
2097 * @return none
2098 * @author Amr abdelmoghny
2099 * @date 15 MAY 2013
2100 * @version
2101 */
2102
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002103static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002104{
Chaehyun Lim27268872015-09-15 14:06:13 +09002105 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002106
Chaehyun Lim27268872015-09-15 14:06:13 +09002107 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002108
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002109 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302110 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002111
Dean Lee72ed4dc2015-06-12 14:11:44 +09002112 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002113
2114 /*Inform wpas of remain-on-channel expiration*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002115 cfg80211_remain_on_channel_expired(priv->wdev,
2116 priv->strRemainOnChanParams.u64ListenCookie,
2117 priv->strRemainOnChanParams.pstrListenChan,
2118 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002119 } else {
2120 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
2121 , priv->strRemainOnChanParams.u32ListenSessionID);
2122 }
2123}
2124
2125
2126/**
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002127 * @brief remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002128 * @details Request the driver to remain awake on the specified
2129 * channel for the specified duration to complete an off-channel
2130 * operation (e.g., public action frame exchange). When the driver is
2131 * ready on the requested channel, it must indicate this with an event
2132 * notification by calling cfg80211_ready_on_channel().
2133 * @param[in]
2134 * @return int : Return 0 on Success
2135 * @author mdaftedar
2136 * @date 01 MAR 2012
2137 * @version 1.0
2138 */
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002139static int remain_on_channel(struct wiphy *wiphy,
2140 struct wireless_dev *wdev,
2141 struct ieee80211_channel *chan,
2142 unsigned int duration, u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002143{
Leo Kime6e12662015-09-16 18:36:03 +09002144 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002145 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002146
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002147 priv = wiphy_priv(wiphy);
2148
2149 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
2150
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002151
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002152 if (wdev->iftype == NL80211_IFTYPE_AP) {
2153 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
2154 return s32Error;
2155 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002156
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002157 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002158
2159 /*Setting params needed by WILC_WFI_RemainOnChannelExpired()*/
2160 priv->strRemainOnChanParams.pstrListenChan = chan;
2161 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002162 priv->strRemainOnChanParams.u32ListenDuration = duration;
2163 priv->strRemainOnChanParams.u32ListenSessionID++;
2164
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002165 s32Error = wilc_remain_on_channel(priv->hWILCWFIDrv
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002166 , priv->strRemainOnChanParams.u32ListenSessionID
2167 , duration
2168 , chan->hw_value
2169 , WILC_WFI_RemainOnChannelExpired
2170 , WILC_WFI_RemainOnChannelReady
2171 , (void *)priv);
2172
2173 return s32Error;
2174}
2175
2176/**
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002177 * @brief cancel_remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002178 * @details Cancel an on-going remain-on-channel operation.
2179 * This allows the operation to be terminated prior to timeout based on
2180 * the duration value.
2181 * @param[in] struct wiphy *wiphy,
2182 * @param[in] struct net_device *dev
2183 * @param[in] u64 cookie,
2184 * @return int : Return 0 on Success
2185 * @author mdaftedar
2186 * @date 01 MAR 2012
2187 * @version 1.0
2188 */
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002189static int cancel_remain_on_channel(struct wiphy *wiphy,
2190 struct wireless_dev *wdev,
2191 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002192{
Leo Kime6e12662015-09-16 18:36:03 +09002193 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002194 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002195
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002196 priv = wiphy_priv(wiphy);
2197
2198 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
2199
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002200 s32Error = wilc_listen_state_expired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002201 return s32Error;
2202}
2203/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002204 * @brief WILC_WFI_mgmt_tx_frame
2205 * @details
2206 *
2207 * @param[in]
2208 * @return NONE.
2209 * @author mdaftedar
2210 * @date 01 JUL 2012
2211 * @version
2212 */
Chaehyun Limc1560322015-09-22 18:34:51 +09002213static int mgmt_tx(struct wiphy *wiphy,
2214 struct wireless_dev *wdev,
2215 struct cfg80211_mgmt_tx_params *params,
2216 u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002217{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002218 struct ieee80211_channel *chan = params->chan;
2219 unsigned int wait = params->wait;
2220 const u8 *buf = params->buf;
2221 size_t len = params->len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002222 const struct ieee80211_mgmt *mgmt;
2223 struct p2p_mgmt_data *mgmt_tx;
Chaehyun Lim27268872015-09-15 14:06:13 +09002224 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002225 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002226 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002227 perInterface_wlan_t *nic;
Leo Kim86685942015-11-19 15:56:18 +09002228 u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002229
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002230 nic = netdev_priv(wdev->netdev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002231 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002232 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002233
2234 *cookie = (unsigned long)buf;
2235 priv->u64tx_cookie = *cookie;
2236 mgmt = (const struct ieee80211_mgmt *) buf;
2237
2238 if (ieee80211_is_mgmt(mgmt->frame_control)) {
2239
2240 /*mgmt frame allocation*/
Glen Leef3052582015-09-10 12:03:04 +09002241 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002242 if (mgmt_tx == NULL) {
2243 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
Leo Kime6e12662015-09-16 18:36:03 +09002244 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002245 }
Glen Leef3052582015-09-10 12:03:04 +09002246 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002247 if (mgmt_tx->buff == NULL) {
2248 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
Tony Chof638dd32015-09-07 19:09:31 +09002249 kfree(mgmt_tx);
Leo Kime6e12662015-09-16 18:36:03 +09002250 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002251 }
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09002252 memcpy(mgmt_tx->buff, buf, len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002253 mgmt_tx->size = len;
2254
2255
2256 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
2257 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
2258 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002259 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002260 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002261 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002262 } else if (ieee80211_is_action(mgmt->frame_control)) {
Chaehyun Limd85f5322015-06-11 14:35:54 +09002263 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002264
2265
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002266 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002267 /*Only set the channel, if not a negotiation confirmation frame
2268 * (If Negotiation confirmation frame, force it
2269 * to be transmitted on the same negotiation channel)*/
2270
2271 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
2272 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
2273 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002274 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002275 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002276 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002277 }
2278 switch (buf[ACTION_SUBTYPE_ID]) {
2279 case GAS_INTIAL_REQ:
2280 {
2281 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
2282 break;
2283 }
2284
2285 case GAS_INTIAL_RSP:
2286 {
2287 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
2288 break;
2289 }
2290
2291 case PUBLIC_ACT_VENDORSPEC:
2292 {
Leo Kim881eb5d2015-11-19 15:56:15 +09002293 if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002294 /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/
2295 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002296 if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
Leo Kim583d9722015-11-19 15:56:16 +09002297 get_random_bytes(&p2p_local_random, 1);
2298 p2p_local_random++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002299 }
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)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002304 if (p2p_local_random > p2p_recv_random) {
2305 PRINT_D(GENERIC_DBG, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002306
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 */
Leo Kim86685942015-11-19 15:56:18 +09002326 memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
2327 mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002328 mgmt_tx->size = buf_len;
2329 }
Leo Kim583d9722015-11-19 15:56:16 +09002330 } else {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002331 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", p2p_local_random, p2p_recv_random);
Leo Kim583d9722015-11-19 15:56:16 +09002332 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002333 }
2334
2335 } else {
2336 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
2337 }
2338
2339 break;
2340 }
2341
2342 default:
2343 {
2344 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
2345 break;
2346 }
2347 }
2348
2349 }
2350
2351 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 +09002352 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002353
Leo Kim1229b1a2015-10-29 12:05:39 +09002354 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n",
2355 jiffies, pstrWFIDrv->p2p_timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002356 }
2357
Glen Lee829c4772015-10-29 12:18:44 +09002358 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
2359 mgmt_tx->buff, mgmt_tx->size,
Glen Leec9d48342015-10-01 16:03:43 +09002360 WILC_WFI_mgmt_tx_complete);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002361 } else {
2362 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
2363 }
Leo Kimaaed3292015-10-12 16:55:38 +09002364 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002365}
2366
Chaehyun Lim85c587a2015-09-22 18:34:50 +09002367static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
2368 struct wireless_dev *wdev,
2369 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002370{
Chaehyun Lim27268872015-09-15 14:06:13 +09002371 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002372 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002373
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002374 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002375 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002376
2377
2378 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
Leo Kim1229b1a2015-10-29 12:05:39 +09002379 pstrWFIDrv->p2p_timeout = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002380
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +01002381 if (!priv->bInP2PlistenState) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002382 cfg80211_remain_on_channel_expired(priv->wdev,
2383 priv->strRemainOnChanParams.u64ListenCookie,
2384 priv->strRemainOnChanParams.pstrListenChan,
2385 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002386 }
2387
2388 return 0;
2389}
2390
2391/**
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002392 * @brief wilc_mgmt_frame_register
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002393 * @details Notify driver that a management frame type was
2394 * registered. Note that this callback may not sleep, and cannot run
2395 * concurrently with itself.
2396 * @param[in]
2397 * @return NONE.
2398 * @author mdaftedar
2399 * @date 01 JUL 2012
2400 * @version
2401 */
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002402void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
2403 u16 frame_type, bool reg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002404{
2405
Chaehyun Lim27268872015-09-15 14:06:13 +09002406 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002407 perInterface_wlan_t *nic;
Glen Lee1b869352015-10-20 17:14:01 +09002408 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002409
2410 priv = wiphy_priv(wiphy);
2411 nic = netdev_priv(priv->wdev->netdev);
Glen Lee1b869352015-10-20 17:14:01 +09002412 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002413
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002414 if (!frame_type)
2415 return;
2416
2417 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
2418 switch (frame_type) {
2419 case PROBE_REQ:
2420 {
2421 nic->g_struct_frame_reg[0].frame_type = frame_type;
2422 nic->g_struct_frame_reg[0].reg = reg;
2423 }
2424 break;
2425
2426 case ACTION:
2427 {
2428 nic->g_struct_frame_reg[1].frame_type = frame_type;
2429 nic->g_struct_frame_reg[1].reg = reg;
2430 }
2431 break;
2432
2433 default:
2434 {
2435 break;
2436 }
2437
2438 }
2439 /*If mac is closed, then return*/
Glen Lee1b869352015-10-20 17:14:01 +09002440 if (!wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002441 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
2442 return;
2443 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002444 wilc_frame_register(priv->hWILCWFIDrv, frame_type, reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002445
2446
2447}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002448
2449/**
Chaehyun Lima8047e22015-09-22 18:34:48 +09002450 * @brief set_cqm_rssi_config
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002451 * @details Configure connection quality monitor RSSI threshold.
2452 * @param[in] struct wiphy *wiphy:
2453 * @param[in] struct net_device *dev:
2454 * @param[in] s32 rssi_thold:
2455 * @param[in] u32 rssi_hyst:
2456 * @return int : Return 0 on Success
2457 * @author mdaftedar
2458 * @date 01 MAR 2012
2459 * @version 1.0
2460 */
Chaehyun Lima8047e22015-09-22 18:34:48 +09002461static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
2462 s32 rssi_thold, u32 rssi_hyst)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002463{
2464 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2465 return 0;
2466
2467}
2468/**
Chaehyun Limbdb63382015-09-14 12:24:19 +09002469 * @brief dump_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002470 * @details Configure connection quality monitor RSSI threshold.
2471 * @param[in] struct wiphy *wiphy:
2472 * @param[in] struct net_device *dev
2473 * @param[in] int idx
2474 * @param[in] u8 *mac
2475 * @param[in] struct station_info *sinfo
2476 * @return int : Return 0 on Success
2477 * @author mdaftedar
2478 * @date 01 MAR 2012
2479 * @version 1.0
2480 */
Chaehyun Limbdb63382015-09-14 12:24:19 +09002481static int dump_station(struct wiphy *wiphy, struct net_device *dev,
2482 int idx, u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002483{
Chaehyun Lim27268872015-09-15 14:06:13 +09002484 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002485
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002486 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2487
2488 if (idx != 0)
2489 return -ENOENT;
2490
2491 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002492
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002493 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002494
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002495 wilc_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002496
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002497 return 0;
2498
2499}
2500
2501
2502/**
Chaehyun Lim46530672015-09-22 18:34:46 +09002503 * @brief set_power_mgmt
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002504 * @details
2505 * @param[in]
2506 * @return int : Return 0 on Success.
2507 * @author mdaftedar
2508 * @date 01 JUL 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09002509 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002510 */
Chaehyun Lim46530672015-09-22 18:34:46 +09002511static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2512 bool enabled, int timeout)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002513{
Chaehyun Lim27268872015-09-15 14:06:13 +09002514 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002515
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002516 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2517
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002518 if (wiphy == NULL)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002519 return -ENOENT;
2520
2521 priv = wiphy_priv(wiphy);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002522 if (priv->hWILCWFIDrv == NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002523 PRINT_ER("Driver is NULL\n");
2524 return -EIO;
2525 }
2526
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002527 if (wilc_enable_ps)
2528 wilc_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002529
2530
Leo Kime6e12662015-09-16 18:36:03 +09002531 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002532
2533}
Glen Lee108b3432015-09-16 18:53:20 +09002534
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002535/**
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002536 * @brief change_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002537 * @details Change type/configuration of virtual interface,
2538 * keep the struct wireless_dev's iftype updated.
2539 * @param[in] NONE
2540 * @return int : Return 0 on Success.
2541 * @author mdaftedar
2542 * @date 01 MAR 2012
2543 * @version 1.0
2544 */
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002545static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2546 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002547{
Chaehyun Lim27268872015-09-15 14:06:13 +09002548 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002549 perInterface_wlan_t *nic;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002550 u8 interface_type;
Chaehyun Limd85f5322015-06-11 14:35:54 +09002551 u16 TID = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002552 u8 i;
Glen Lee299382c2015-10-20 17:13:56 +09002553 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002554
2555 nic = netdev_priv(dev);
2556 priv = wiphy_priv(wiphy);
Glen Lee299382c2015-10-20 17:13:56 +09002557 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002558
2559 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2560 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
Leo Kim583d9722015-11-19 15:56:16 +09002561 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +09002562 p2p_recv_random = 0x00;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002563
Dean Lee72ed4dc2015-06-12 14:11:44 +09002564 bWilc_ie = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002565
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002566 wilc_optaining_ip = false;
2567 del_timer(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002568 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002569 /*Set WILC_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/
2570 if (g_ptk_keys_saved && g_gtk_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002571 wilc_set_machw_change_vir_if(dev, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002572 }
2573
2574 switch (type) {
2575 case NL80211_IFTYPE_STATION:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002576 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002577 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002578
2579 /* send delba over wlan interface */
2580
2581
2582 dev->ieee80211_ptr->iftype = type;
2583 priv->wdev->iftype = type;
2584 nic->monitor_flag = 0;
2585 nic->iftype = STATION_MODE;
2586
2587 /*Remove the enteries of the previously connected clients*/
2588 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002589 interface_type = nic->iftype;
2590 nic->iftype = STATION_MODE;
2591
Glen Lee299382c2015-10-20 17:13:56 +09002592 if (wl->initialized) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002593 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2594 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002595 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002596 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002597
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002598 /*Eliminate host interface blocking state*/
Glen Lee299382c2015-10-20 17:13:56 +09002599 up(&wl->cfg_event);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002600
Glen Lee53dc0cf2015-10-20 17:13:57 +09002601 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002602 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002603 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002604 nic->iftype = interface_type;
2605
2606 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002607 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2608 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002609 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002610 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002611
2612 /*Add saved WEP keys, if any*/
2613 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002614 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002615 g_key_wep_params.key_idx);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002616 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002617 g_key_wep_params.key,
2618 g_key_wep_params.key_len,
2619 g_key_wep_params.key_idx);
2620 }
2621
2622 /*No matter the driver handler passed here, it will be overwriiten*/
2623 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002624 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002625
2626 /*Add saved PTK and GTK keys, if any*/
2627 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2628 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2629 g_key_ptk_params.key[1],
2630 g_key_ptk_params.key[2]);
2631 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2632 g_key_gtk_params.key[1],
2633 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002634 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2635 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002636 g_add_ptk_key_params.key_idx,
2637 g_add_ptk_key_params.pairwise,
2638 g_add_ptk_key_params.mac_addr,
2639 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002640
Glen Lee299382c2015-10-20 17:13:56 +09002641 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2642 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002643 g_add_gtk_key_params.key_idx,
2644 g_add_gtk_key_params.pairwise,
2645 g_add_gtk_key_params.mac_addr,
2646 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002647 }
2648
Glen Lee299382c2015-10-20 17:13:56 +09002649 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002650 for (i = 0; i < num_reg_frame; i++) {
2651 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2652 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002653 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002654 nic->g_struct_frame_reg[i].frame_type,
2655 nic->g_struct_frame_reg[i].reg);
2656 }
2657 }
2658
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002659 wilc_enable_ps = true;
2660 wilc_set_power_mgmt(priv->hWILCWFIDrv, 1, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002661 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002662 break;
2663
2664 case NL80211_IFTYPE_P2P_CLIENT:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002665 wilc_enable_ps = false;
2666 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
2667 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002668 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002669
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002670 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2671 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002672
2673 dev->ieee80211_ptr->iftype = type;
2674 priv->wdev->iftype = type;
2675 nic->monitor_flag = 0;
2676
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002677 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2678 nic->iftype = CLIENT_MODE;
2679
2680
Glen Lee299382c2015-10-20 17:13:56 +09002681 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002682 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002683 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002684
Glen Lee53dc0cf2015-10-20 17:13:57 +09002685 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002686 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002687 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002688
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002689 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2690 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002691 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002692 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002693
2694 /*Add saved WEP keys, if any*/
2695 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002696 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2697 g_key_wep_params.key_idx);
2698 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
2699 g_key_wep_params.key,
2700 g_key_wep_params.key_len,
2701 g_key_wep_params.key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002702 }
2703
2704 /*No matter the driver handler passed here, it will be overwriiten*/
2705 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002706 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002707
2708 /*Add saved PTK and GTK keys, if any*/
2709 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2710 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2711 g_key_ptk_params.key[1],
2712 g_key_ptk_params.key[2]);
2713 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2714 g_key_gtk_params.key[1],
2715 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002716 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2717 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002718 g_add_ptk_key_params.key_idx,
2719 g_add_ptk_key_params.pairwise,
2720 g_add_ptk_key_params.mac_addr,
2721 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002722
Glen Lee299382c2015-10-20 17:13:56 +09002723 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2724 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002725 g_add_gtk_key_params.key_idx,
2726 g_add_gtk_key_params.pairwise,
2727 g_add_gtk_key_params.mac_addr,
2728 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002729 }
2730
2731 /*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 +09002732 refresh_scan(priv, 1, true);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002733 wilc_set_machw_change_vir_if(dev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002734
Glen Lee299382c2015-10-20 17:13:56 +09002735 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002736 for (i = 0; i < num_reg_frame; i++) {
2737 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2738 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002739 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002740 nic->g_struct_frame_reg[i].frame_type,
2741 nic->g_struct_frame_reg[i].reg);
2742 }
2743 }
2744 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002745 break;
2746
2747 case NL80211_IFTYPE_AP:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002748 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002749 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002750 dev->ieee80211_ptr->iftype = type;
2751 priv->wdev->iftype = type;
2752 nic->iftype = AP_MODE;
Johnny Kim8a143302015-06-10 17:06:46 +09002753 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002754
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002755 PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002756 wilc_wlan_get_firmware(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002757 /*If wilc is running, then close-open to actually get new firmware running (serves P2P)*/
Glen Lee299382c2015-10-20 17:13:56 +09002758 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002759 nic->iftype = AP_MODE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002760 wilc_mac_close(dev);
2761 wilc_mac_open(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002762
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002763 for (i = 0; i < num_reg_frame; i++) {
2764 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2765 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002766 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002767 nic->g_struct_frame_reg[i].frame_type,
2768 nic->g_struct_frame_reg[i].reg);
2769 }
2770 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002771 break;
2772
2773 case NL80211_IFTYPE_P2P_GO:
2774 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
2775
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002776 wilc_optaining_ip = true;
2777 mod_timer(&wilc_during_ip_timer, jiffies + msecs_to_jiffies(duringIP_TIME));
2778 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002779 /*Delete block ack has to be the latest config packet*/
2780 /*sent before downloading new FW. This is because it blocks on*/
2781 /*hWaitResponse semaphore, which allows previous config*/
2782 /*packets to actually take action on old FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002783 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2784 wl->vif[0].bssid, TID);
2785 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002786 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002787 dev->ieee80211_ptr->iftype = type;
2788 priv->wdev->iftype = type;
2789
Johnny Kim8a143302015-06-10 17:06:46 +09002790 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002791
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002792 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2793
2794
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002795 nic->iftype = GO_MODE;
2796
2797 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002798 wilc_wait_msg_queue_idle();
Glen Lee53dc0cf2015-10-20 17:13:57 +09002799 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002800 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002801 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002802
2803
2804 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002805 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2806 wilc_set_mac_address(wl->vif[0].hif_drv,
2807 wl->vif[0].src_addr);
2808 wilc_set_operation_mode(priv->hWILCWFIDrv, AP_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002809
2810 /*Add saved WEP keys, if any*/
2811 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002812 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2813 g_key_wep_params.key_idx);
2814 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002815 g_key_wep_params.key,
2816 g_key_wep_params.key_len,
2817 g_key_wep_params.key_idx);
2818 }
2819
2820 /*No matter the driver handler passed here, it will be overwriiten*/
2821 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002822 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002823
2824 /*Add saved PTK and GTK keys, if any*/
2825 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2826 PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0],
2827 g_key_ptk_params.key[1],
2828 g_key_ptk_params.key[2],
2829 g_key_ptk_params.cipher);
2830 PRINT_D(CFG80211_DBG, "gtk %x %x %x cipher %x\n", g_key_gtk_params.key[0],
2831 g_key_gtk_params.key[1],
2832 g_key_gtk_params.key[2],
2833 g_key_gtk_params.cipher);
Glen Lee299382c2015-10-20 17:13:56 +09002834 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2835 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002836 g_add_ptk_key_params.key_idx,
2837 g_add_ptk_key_params.pairwise,
2838 g_add_ptk_key_params.mac_addr,
2839 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002840
Glen Lee299382c2015-10-20 17:13:56 +09002841 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2842 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002843 g_add_gtk_key_params.key_idx,
2844 g_add_gtk_key_params.pairwise,
2845 g_add_gtk_key_params.mac_addr,
2846 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002847 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002848
Glen Lee299382c2015-10-20 17:13:56 +09002849 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002850 for (i = 0; i < num_reg_frame; i++) {
2851 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2852 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002853 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002854 nic->g_struct_frame_reg[i].frame_type,
2855 nic->g_struct_frame_reg[i].reg);
2856 }
2857 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002858 break;
2859
2860 default:
2861 PRINT_ER("Unknown interface type= %d\n", type);
Leo Kimaaed3292015-10-12 16:55:38 +09002862 return -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002863 }
2864
Leo Kimaaed3292015-10-12 16:55:38 +09002865 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002866}
2867
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002868/* (austin.2013-07-23)
2869 *
2870 * To support revised cfg80211_ops
2871 *
2872 * add_beacon --> start_ap
2873 * set_beacon --> change_beacon
2874 * del_beacon --> stop_ap
2875 *
2876 * beacon_parameters --> cfg80211_ap_settings
2877 * cfg80211_beacon_data
2878 *
2879 * applicable for linux kernel 3.4+
2880 */
2881
2882/**
Chaehyun Lima13168d2015-09-14 12:24:12 +09002883 * @brief start_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002884 * @details Add a beacon with given parameters, @head, @interval
2885 * and @dtim_period will be valid, @tail is optional.
2886 * @param[in] wiphy
2887 * @param[in] dev The net device structure
2888 * @param[in] settings cfg80211_ap_settings parameters for the beacon to be added
2889 * @return int : Return 0 on Success.
2890 * @author austin
2891 * @date 23 JUL 2013
2892 * @version 1.0
2893 */
Chaehyun Lima13168d2015-09-14 12:24:12 +09002894static int start_ap(struct wiphy *wiphy, struct net_device *dev,
2895 struct cfg80211_ap_settings *settings)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002896{
2897 struct cfg80211_beacon_data *beacon = &(settings->beacon);
Chaehyun Lim27268872015-09-15 14:06:13 +09002898 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002899 s32 s32Error = 0;
Glen Lee684dc182015-10-20 17:14:02 +09002900 struct wilc *wl;
2901 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002902
2903 priv = wiphy_priv(wiphy);
Glen Lee684dc182015-10-20 17:14:02 +09002904 nic = netdev_priv(dev);
2905 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002906 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
2907
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302908 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 +09002909 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
2910
Chaehyun Lim80785a92015-09-14 12:24:01 +09002911 s32Error = set_channel(wiphy, &settings->chandef);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002912
Leo Kime6e12662015-09-16 18:36:03 +09002913 if (s32Error != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002914 PRINT_ER("Error in setting channel\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002915
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002916 wilc_wlan_set_bssid(dev, wl->vif[0].src_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002917
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002918 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002919 settings->beacon_interval,
2920 settings->dtim_period,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002921 beacon->head_len, (u8 *)beacon->head,
2922 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002923
2924 return s32Error;
2925}
2926
2927/**
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002928 * @brief change_beacon
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002929 * @details Add a beacon with given parameters, @head, @interval
2930 * and @dtim_period will be valid, @tail is optional.
2931 * @param[in] wiphy
2932 * @param[in] dev The net device structure
2933 * @param[in] beacon cfg80211_beacon_data for the beacon to be changed
2934 * @return int : Return 0 on Success.
2935 * @author austin
2936 * @date 23 JUL 2013
2937 * @version 1.0
2938 */
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002939static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
2940 struct cfg80211_beacon_data *beacon)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002941{
Chaehyun Lim27268872015-09-15 14:06:13 +09002942 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002943 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002944
2945 priv = wiphy_priv(wiphy);
2946 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
2947
2948
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002949 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002950 0,
2951 0,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002952 beacon->head_len, (u8 *)beacon->head,
2953 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002954
2955 return s32Error;
2956}
2957
2958/**
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002959 * @brief stop_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002960 * @details Remove beacon configuration and stop sending the beacon.
2961 * @param[in]
2962 * @return int : Return 0 on Success.
2963 * @author austin
2964 * @date 23 JUL 2013
2965 * @version 1.0
2966 */
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002967static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002968{
Leo Kime6e12662015-09-16 18:36:03 +09002969 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002970 struct wilc_priv *priv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002971 u8 NullBssid[ETH_ALEN] = {0};
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002972
Leo Kim7ae43362015-09-16 18:35:59 +09002973 if (!wiphy)
2974 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002975
2976 priv = wiphy_priv(wiphy);
2977
2978 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
2979
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002980 wilc_wlan_set_bssid(dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002981
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002982 s32Error = wilc_del_beacon(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002983
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002984 if (s32Error)
2985 PRINT_ER("Host delete beacon fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002986
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002987 return s32Error;
2988}
2989
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002990/**
Chaehyun Limed269552015-09-14 12:24:15 +09002991 * @brief add_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002992 * @details Add a new station.
2993 * @param[in]
2994 * @return int : Return 0 on Success.
2995 * @author mdaftedar
2996 * @date 01 MAR 2012
2997 * @version 1.0
2998 */
Chaehyun Limed269552015-09-14 12:24:15 +09002999static int add_station(struct wiphy *wiphy, struct net_device *dev,
3000 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003001{
Leo Kime6e12662015-09-16 18:36:03 +09003002 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003003 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09003004 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003005 perInterface_wlan_t *nic;
3006
Leo Kim7ae43362015-09-16 18:35:59 +09003007 if (!wiphy)
3008 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003009
3010 priv = wiphy_priv(wiphy);
3011 nic = netdev_priv(dev);
3012
3013 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003014 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09003015 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003016 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003017 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003018 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003019
3020 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
3021
3022 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],
3023 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003024 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003025 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3026 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003027
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003028 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003029 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003030 } else {
Leo Kim22520122015-10-29 12:05:45 +09003031 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003032 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003033 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003034 memcpy(strStaParams.ht_supp_mcs_set,
3035 &params->ht_capa->mcs,
3036 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003037 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003038 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003039 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003040 }
3041
Leo Kimf676e172015-10-29 12:05:52 +09003042 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003043 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003044
Leo Kim22520122015-10-29 12:05:45 +09003045 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3046 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003047 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3048 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003049 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3050 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003051 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3052 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003053 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3054 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003055 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3056 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003057 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3058 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003059 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3060 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003061
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003062 s32Error = wilc_add_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003063 if (s32Error)
3064 PRINT_ER("Host add station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003065 }
3066
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003067 return s32Error;
3068}
3069
3070/**
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003071 * @brief del_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003072 * @details Remove a station; @mac may be NULL to remove all stations.
3073 * @param[in]
3074 * @return int : Return 0 on Success.
3075 * @author mdaftedar
3076 * @date 01 MAR 2012
3077 * @version 1.0
3078 */
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003079static int del_station(struct wiphy *wiphy, struct net_device *dev,
3080 struct station_del_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003081{
Arnd Bergmann057d1e92015-06-01 21:06:44 +02003082 const u8 *mac = params->mac;
Leo Kime6e12662015-09-16 18:36:03 +09003083 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003084 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003085 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003086
Leo Kim7ae43362015-09-16 18:35:59 +09003087 if (!wiphy)
3088 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003089
3090 priv = wiphy_priv(wiphy);
3091 nic = netdev_priv(dev);
3092
3093 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
3094 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
3095
3096
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003097 if (mac == NULL) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05303098 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003099 s32Error = wilc_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003100 } else {
3101 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]);
3102 }
3103
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003104 s32Error = wilc_del_station(priv->hWILCWFIDrv, mac);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003105
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003106 if (s32Error)
3107 PRINT_ER("Host delete station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003108 }
3109 return s32Error;
3110}
3111
3112/**
Chaehyun Lim14b42082015-09-14 12:24:17 +09003113 * @brief change_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003114 * @details Modify a given station.
3115 * @param[in]
3116 * @return int : Return 0 on Success.
3117 * @author mdaftedar
3118 * @date 01 MAR 2012
3119 * @version 1.0
3120 */
Chaehyun Lim14b42082015-09-14 12:24:17 +09003121static int change_station(struct wiphy *wiphy, struct net_device *dev,
3122 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003123{
Leo Kime6e12662015-09-16 18:36:03 +09003124 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003125 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09003126 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003127 perInterface_wlan_t *nic;
3128
3129
3130 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
3131
Leo Kim7ae43362015-09-16 18:35:59 +09003132 if (!wiphy)
3133 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003134
3135 priv = wiphy_priv(wiphy);
3136 nic = netdev_priv(dev);
3137
3138 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003139 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003140 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003141 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003142 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003143
Leo Kim2353c382015-10-29 12:05:41 +09003144 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n",
3145 strStaParams.bssid[0], strStaParams.bssid[1],
3146 strStaParams.bssid[2], strStaParams.bssid[3],
3147 strStaParams.bssid[4], strStaParams.bssid[5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003148 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003149 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3150 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003151
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003152 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003153 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003154 } else {
Leo Kim22520122015-10-29 12:05:45 +09003155 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003156 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003157 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003158 memcpy(strStaParams.ht_supp_mcs_set,
3159 &params->ht_capa->mcs,
3160 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003161 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003162 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003163 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003164 }
3165
Leo Kimf676e172015-10-29 12:05:52 +09003166 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003167 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003168
Leo Kim22520122015-10-29 12:05:45 +09003169 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3170 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003171 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3172 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003173 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3174 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003175 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3176 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003177 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3178 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003179 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3180 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003181 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3182 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003183 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3184 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003185
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003186 s32Error = wilc_edit_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003187 if (s32Error)
3188 PRINT_ER("Host edit station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003189 }
3190 return s32Error;
3191}
3192
3193
3194/**
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003195 * @brief add_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003196 * @details
3197 * @param[in]
3198 * @return int : Return 0 on Success.
3199 * @author mdaftedar
3200 * @date 01 JUL 2012
3201 * @version 1.0
3202 */
Chaehyun Lim37316e82015-09-22 18:34:52 +09003203static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
3204 const char *name,
3205 unsigned char name_assign_type,
3206 enum nl80211_iftype type,
3207 u32 *flags,
3208 struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003209{
3210 perInterface_wlan_t *nic;
Chaehyun Lim27268872015-09-15 14:06:13 +09003211 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003212 struct net_device *new_ifc = NULL;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003213
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003214 priv = wiphy_priv(wiphy);
3215
3216
3217
3218 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
3219
3220 nic = netdev_priv(priv->wdev->netdev);
3221
3222
3223 if (type == NL80211_IFTYPE_MONITOR) {
3224 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
3225 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", nic->wilc_netdev);
3226 new_ifc = WILC_WFI_init_mon_interface(name, nic->wilc_netdev);
3227 if (new_ifc != NULL) {
3228 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003229 nic = netdev_priv(priv->wdev->netdev);
3230 nic->monitor_flag = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003231 } else
3232 PRINT_ER("Error in initializing monitor interface\n ");
3233 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003234 return priv->wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003235}
3236
3237/**
Chaehyun Limb4a73352015-09-14 12:24:10 +09003238 * @brief del_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003239 * @details
3240 * @param[in]
3241 * @return int : Return 0 on Success.
3242 * @author mdaftedar
3243 * @date 01 JUL 2012
3244 * @version 1.0
3245 */
Chaehyun Lim956d7212015-09-22 18:34:49 +09003246static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003247{
3248 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
Leo Kime6e12662015-09-16 18:36:03 +09003249 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003250}
3251
Chaehyun Lim08241922015-09-15 14:06:12 +09003252static struct cfg80211_ops wilc_cfg80211_ops = {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003253
Chaehyun Lim80785a92015-09-14 12:24:01 +09003254 .set_monitor_channel = set_channel,
Chaehyun Lim0e30d062015-09-14 12:24:02 +09003255 .scan = scan,
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +09003256 .connect = connect,
Chaehyun Limb027cde2015-09-14 12:24:04 +09003257 .disconnect = disconnect,
Chaehyun Lim953d4172015-09-14 12:24:05 +09003258 .add_key = add_key,
Chaehyun Lim3044ba72015-09-14 12:24:06 +09003259 .del_key = del_key,
Chaehyun Limf4893df2015-09-14 12:24:07 +09003260 .get_key = get_key,
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09003261 .set_default_key = set_default_key,
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003262 .add_virtual_intf = add_virtual_intf,
Chaehyun Limb4a73352015-09-14 12:24:10 +09003263 .del_virtual_intf = del_virtual_intf,
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09003264 .change_virtual_intf = change_virtual_intf,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003265
Chaehyun Lima13168d2015-09-14 12:24:12 +09003266 .start_ap = start_ap,
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09003267 .change_beacon = change_beacon,
Chaehyun Limc8cddd72015-09-14 12:24:14 +09003268 .stop_ap = stop_ap,
Chaehyun Limed269552015-09-14 12:24:15 +09003269 .add_station = add_station,
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003270 .del_station = del_station,
Chaehyun Lim14b42082015-09-14 12:24:17 +09003271 .change_station = change_station,
Chaehyun Limf06f5622015-09-14 12:24:18 +09003272 .get_station = get_station,
Chaehyun Limbdb63382015-09-14 12:24:19 +09003273 .dump_station = dump_station,
Chaehyun Lima5f7db62015-09-14 12:24:20 +09003274 .change_bss = change_bss,
Chaehyun Lima76b63e2015-09-14 12:24:21 +09003275 .set_wiphy_params = set_wiphy_params,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003276
Chaehyun Lim4d466572015-09-14 12:24:22 +09003277 .set_pmksa = set_pmksa,
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09003278 .del_pmksa = del_pmksa,
Chaehyun Limb33c39b2015-09-14 12:24:24 +09003279 .flush_pmksa = flush_pmksa,
Chaehyun Lim6d19d692015-09-14 12:24:25 +09003280 .remain_on_channel = remain_on_channel,
Chaehyun Lim1dd54402015-09-14 12:24:26 +09003281 .cancel_remain_on_channel = cancel_remain_on_channel,
Chaehyun Lim4a2f9b32015-09-14 12:24:27 +09003282 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
Chaehyun Lim12a26a32015-09-14 12:24:28 +09003283 .mgmt_tx = mgmt_tx,
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09003284 .mgmt_frame_register = wilc_mgmt_frame_register,
Chaehyun Lim46530672015-09-22 18:34:46 +09003285 .set_power_mgmt = set_power_mgmt,
Chaehyun Lima8047e22015-09-22 18:34:48 +09003286 .set_cqm_rssi_config = set_cqm_rssi_config,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003287
3288};
3289
3290
3291
3292
3293
3294/**
3295 * @brief WILC_WFI_update_stats
3296 * @details Modify parameters for a given BSS.
3297 * @param[in]
3298 * @return int : Return 0 on Success.
3299 * @author mdaftedar
3300 * @date 01 MAR 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09003301 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003302 */
3303int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
3304{
3305
Chaehyun Lim27268872015-09-15 14:06:13 +09003306 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003307
3308 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003309 switch (changed) {
3310
3311 case WILC_WFI_RX_PKT:
3312 {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003313 priv->netstats.rx_packets++;
3314 priv->netstats.rx_bytes += pktlen;
3315 priv->netstats.rx_time = get_jiffies_64();
3316 }
3317 break;
3318
3319 case WILC_WFI_TX_PKT:
3320 {
3321 priv->netstats.tx_packets++;
3322 priv->netstats.tx_bytes += pktlen;
3323 priv->netstats.tx_time = get_jiffies_64();
3324
3325 }
3326 break;
3327
3328 default:
3329 break;
3330 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003331 return 0;
3332}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003333
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003334/**
3335 * @brief WILC_WFI_CfgAlloc
3336 * @details Allocation of the wireless device structure and assigning it
3337 * to the cfg80211 operations structure.
3338 * @param[in] NONE
3339 * @return wireless_dev : Returns pointer to wireless_dev structure.
3340 * @author mdaftedar
3341 * @date 01 MAR 2012
3342 * @version 1.0
3343 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01003344static struct wireless_dev *WILC_WFI_CfgAlloc(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003345{
3346
3347 struct wireless_dev *wdev;
3348
3349
3350 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
3351 /*Allocating the wireless device structure*/
3352 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
3353 if (!wdev) {
3354 PRINT_ER("Cannot allocate wireless device\n");
3355 goto _fail_;
3356 }
3357
3358 /*Creating a new wiphy, linking wireless structure with the wiphy structure*/
Chaehyun Lim27268872015-09-15 14:06:13 +09003359 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003360 if (!wdev->wiphy) {
3361 PRINT_ER("Cannot allocate wiphy\n");
3362 goto _fail_mem_;
3363
3364 }
3365
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003366 /* enable 802.11n HT */
3367 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
3368 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
3369 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3370 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
3371 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003372
3373 /*wiphy bands*/
3374 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
3375
3376 return wdev;
3377
3378_fail_mem_:
3379 kfree(wdev);
3380_fail_:
3381 return NULL;
3382
3383}
3384/**
Chaehyun Lim8459fd52015-09-20 15:51:09 +09003385 * @brief wilc_create_wiphy
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003386 * @details Registering of the wiphy structure and interface modes
3387 * @param[in] NONE
3388 * @return NONE
3389 * @author mdaftedar
3390 * @date 01 MAR 2012
3391 * @version 1.0
3392 */
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01003393struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003394{
Chaehyun Lim27268872015-09-15 14:06:13 +09003395 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003396 struct wireless_dev *wdev;
Leo Kime6e12662015-09-16 18:36:03 +09003397 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003398
3399 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
3400
3401 wdev = WILC_WFI_CfgAlloc();
3402 if (wdev == NULL) {
3403 PRINT_ER("CfgAlloc Failed\n");
3404 return NULL;
3405 }
3406
3407
3408 /*Return hardware description structure (wiphy)'s priv*/
3409 priv = wdev_priv(wdev);
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003410 sema_init(&(priv->SemHandleUpdateStats), 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003411
3412 /*Link the wiphy with wireless structure*/
3413 priv->wdev = wdev;
3414
3415 /*Maximum number of probed ssid to be added by user for the scan request*/
3416 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003417 /*Maximum number of pmkids to be cashed*/
3418 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
3419 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003420
3421 wdev->wiphy->max_scan_ie_len = 1000;
3422
3423 /*signal strength in mBm (100*dBm) */
3424 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3425
3426 /*Set the availaible cipher suites*/
3427 wdev->wiphy->cipher_suites = cipher_suites;
3428 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003429 /*Setting default managment types: for register action frame: */
3430 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003431
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003432 wdev->wiphy->max_remain_on_channel_duration = 500;
3433 /*Setting the wiphy interfcae mode and type before registering the wiphy*/
3434 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
3435 BIT(NL80211_IFTYPE_P2P_CLIENT);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003436 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003437 wdev->iftype = NL80211_IFTYPE_STATION;
3438
3439
3440
3441 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
3442 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
3443 wdev->wiphy->interface_modes, wdev->iftype);
3444
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01003445 set_wiphy_dev(wdev->wiphy, dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003446
3447 /*Register wiphy structure*/
3448 s32Error = wiphy_register(wdev->wiphy);
3449 if (s32Error) {
3450 PRINT_ER("Cannot register wiphy device\n");
3451 /*should define what action to be taken in such failure*/
3452 } else {
3453 PRINT_D(CFG80211_DBG, "Successful Registering\n");
3454 }
3455
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003456 priv->dev = net;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003457 return wdev;
3458
3459
3460}
3461/**
3462 * @brief WILC_WFI_WiphyFree
3463 * @details Freeing allocation of the wireless device structure
3464 * @param[in] NONE
3465 * @return NONE
3466 * @author mdaftedar
3467 * @date 01 MAR 2012
3468 * @version 1.0
3469 */
Chaehyun Limdd4b6a82015-09-20 15:51:25 +09003470int wilc_init_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003471{
3472
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003473 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003474
Chaehyun Lim27268872015-09-15 14:06:13 +09003475 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003476
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003477 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
3478 priv = wdev_priv(net->ieee80211_ptr);
3479 if (op_ifcs == 0) {
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -07003480 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003481 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003482 }
3483 op_ifcs++;
3484 if (s32Error < 0) {
3485 PRINT_ER("Failed to creat refresh Timer\n");
3486 return s32Error;
3487 }
3488
Dean Lee72ed4dc2015-06-12 14:11:44 +09003489 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003490
Dean Lee72ed4dc2015-06-12 14:11:44 +09003491 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003492
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003493 sema_init(&(priv->hSemScanReq), 1);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003494 s32Error = wilc_init(net, &priv->hWILCWFIDrv);
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003495 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003496 PRINT_ER("Error while initializing hostinterface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003497
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003498 return s32Error;
3499}
3500
3501/**
3502 * @brief WILC_WFI_WiphyFree
3503 * @details Freeing allocation of the wireless device structure
3504 * @param[in] NONE
3505 * @return NONE
3506 * @author mdaftedar
3507 * @date 01 MAR 2012
3508 * @version 1.0
3509 */
Chaehyun Lima9a16822015-09-20 15:51:24 +09003510int wilc_deinit_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003511{
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003512 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003513
Chaehyun Lim27268872015-09-15 14:06:13 +09003514 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003515
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003516 priv = wdev_priv(net->ieee80211_ptr);
3517
Dean Lee72ed4dc2015-06-12 14:11:44 +09003518 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003519
Dean Lee72ed4dc2015-06-12 14:11:44 +09003520 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003521
3522 op_ifcs--;
3523
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003524 s32Error = wilc_deinit(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003525
3526 /* Clear the Shadow scan */
3527 clear_shadow_scan(priv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003528 if (op_ifcs == 0) {
3529 PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003530 del_timer_sync(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003531 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003532
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003533 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003534 PRINT_ER("Error while deintializing host interface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003535
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003536 return s32Error;
3537}
3538
3539
3540/**
3541 * @brief WILC_WFI_WiphyFree
3542 * @details Freeing allocation of the wireless device structure
3543 * @param[in] NONE
3544 * @return NONE
3545 * @author mdaftedar
3546 * @date 01 MAR 2012
3547 * @version 1.0
3548 */
Chaehyun Lim96da20a2015-09-20 15:51:08 +09003549void wilc_free_wiphy(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003550{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003551 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
3552
Chaehyun Lim619837a2015-09-20 15:51:10 +09003553 if (!net) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003554 PRINT_D(INIT_DBG, "net_device is NULL\n");
3555 return;
3556 }
3557
Chaehyun Lim619837a2015-09-20 15:51:10 +09003558 if (!net->ieee80211_ptr) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003559 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
3560 return;
3561 }
3562
Chaehyun Lim619837a2015-09-20 15:51:10 +09003563 if (!net->ieee80211_ptr->wiphy) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003564 PRINT_D(INIT_DBG, "wiphy is NULL\n");
3565 return;
3566 }
3567
3568 wiphy_unregister(net->ieee80211_ptr->wiphy);
3569
3570 PRINT_D(INIT_DBG, "Freeing wiphy\n");
3571 wiphy_free(net->ieee80211_ptr->wiphy);
3572 kfree(net->ieee80211_ptr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003573}