blob: 3b072ef27e68bcc55fa39de49c3a0219e9998777 [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;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900174
Arnd Bergmann1608c402015-11-16 15:04:53 +0100175static u8 u8P2P_oui[] = {0x50, 0x6f, 0x9A, 0x09};
176static u8 u8P2Plocalrandom = 0x01;
177static u8 u8P2Precvrandom = 0x00;
178static u8 u8P2P_vendorspec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
179static bool bWilc_ie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900180
181static struct ieee80211_supported_band WILC_WFI_band_2ghz = {
Leo Kim2736f472015-11-19 15:56:12 +0900182 .channels = ieee80211_2ghz_channels,
183 .n_channels = ARRAY_SIZE(ieee80211_2ghz_channels),
Leo Kim8d48b5b2015-11-19 15:56:13 +0900184 .bitrates = ieee80211_bitrates,
185 .n_bitrates = ARRAY_SIZE(ieee80211_bitrates),
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900186};
187
188
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900189struct add_key_params {
190 u8 key_idx;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900191 bool pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900192 u8 *mac_addr;
193};
Arnd Bergmann1608c402015-11-16 15:04:53 +0100194static struct add_key_params g_add_gtk_key_params;
195static struct wilc_wfi_key g_key_gtk_params;
196static struct add_key_params g_add_ptk_key_params;
197static struct wilc_wfi_key g_key_ptk_params;
198static struct wilc_wfi_wep_key g_key_wep_params;
199static bool g_ptk_keys_saved;
200static bool g_gtk_keys_saved;
201static bool g_wep_keys_saved;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900202
203#define AGING_TIME (9 * 1000)
204#define duringIP_TIME 15000
205
Arnd Bergmann1608c402015-11-16 15:04:53 +0100206static void clear_shadow_scan(void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900207{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900208 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900209
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900210 if (op_ifcs == 0) {
Greg Kroah-Hartman4183e972015-08-14 20:11:16 -0700211 del_timer_sync(&hAgingTimer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900212 PRINT_INFO(CORECONFIG_DBG, "destroy aging timer\n");
213
Leo Kim771fbae2015-11-19 15:56:10 +0900214 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900215 if (last_scanned_shadow[last_scanned_cnt].pu8IEs) {
216 kfree(last_scanned_shadow[i].pu8IEs);
217 last_scanned_shadow[last_scanned_cnt].pu8IEs = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900218 }
219
Leo Kimf1ab1172015-11-19 15:56:11 +0900220 wilc_free_join_params(last_scanned_shadow[i].pJoinParams);
221 last_scanned_shadow[i].pJoinParams = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900222 }
Leo Kim771fbae2015-11-19 15:56:10 +0900223 last_scanned_cnt = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900224 }
225
226}
227
Arnd Bergmann1608c402015-11-16 15:04:53 +0100228static u32 get_rssi_avg(tstrNetworkInfo *pstrNetworkInfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900229{
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900230 u8 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900231 int rssi_v = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900232 u8 num_rssi = (pstrNetworkInfo->strRssi.u8Full) ? NUM_RSSI : (pstrNetworkInfo->strRssi.u8Index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900233
234 for (i = 0; i < num_rssi; i++)
235 rssi_v += pstrNetworkInfo->strRssi.as8RSSI[i];
236
237 rssi_v /= num_rssi;
238 return rssi_v;
239}
240
Arnd Bergmann1608c402015-11-16 15:04:53 +0100241static void refresh_scan(void *pUserVoid, u8 all, bool bDirectScan)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900242{
Chaehyun Lim27268872015-09-15 14:06:13 +0900243 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900244 struct wiphy *wiphy;
245 struct cfg80211_bss *bss = NULL;
246 int i;
247 int rssi = 0;
248
Chaehyun Lim27268872015-09-15 14:06:13 +0900249 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900250 wiphy = priv->dev->ieee80211_ptr->wiphy;
251
Leo Kim771fbae2015-11-19 15:56:10 +0900252 for (i = 0; i < last_scanned_cnt; i++) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900253 tstrNetworkInfo *pstrNetworkInfo;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900254
Leo Kimf1ab1172015-11-19 15:56:11 +0900255 pstrNetworkInfo = &last_scanned_shadow[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900256
257 if ((!pstrNetworkInfo->u8Found) || all) {
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900258 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900259 struct ieee80211_channel *channel;
260
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900261 if (pstrNetworkInfo != NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900262
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900263 s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900264 channel = ieee80211_get_channel(wiphy, s32Freq);
265
266 rssi = get_rssi_avg(pstrNetworkInfo);
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900267 if (memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7) || bDirectScan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900268 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
269 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900270 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900271 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900272 }
273 }
274
275 }
276 }
277
278}
279
Arnd Bergmann1608c402015-11-16 15:04:53 +0100280static void reset_shadow_found(void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900281{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900282 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900283
Leo Kim771fbae2015-11-19 15:56:10 +0900284 for (i = 0; i < last_scanned_cnt; i++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900285 last_scanned_shadow[i].u8Found = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900286}
287
Arnd Bergmann1608c402015-11-16 15:04:53 +0100288static void update_scan_time(void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900289{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900290 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900291
Leo Kim771fbae2015-11-19 15:56:10 +0900292 for (i = 0; i < last_scanned_cnt; i++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900293 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900294}
295
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700296static void remove_network_from_shadow(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900297{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900298 unsigned long now = jiffies;
299 int i, j;
300
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900301
Leo Kim771fbae2015-11-19 15:56:10 +0900302 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900303 if (time_after(now, last_scanned_shadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) {
304 PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", last_scanned_shadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900305
Leo Kimf1ab1172015-11-19 15:56:11 +0900306 kfree(last_scanned_shadow[i].pu8IEs);
307 last_scanned_shadow[i].pu8IEs = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900308
Leo Kimf1ab1172015-11-19 15:56:11 +0900309 wilc_free_join_params(last_scanned_shadow[i].pJoinParams);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900310
Leo Kim771fbae2015-11-19 15:56:10 +0900311 for (j = i; (j < last_scanned_cnt - 1); j++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900312 last_scanned_shadow[j] = last_scanned_shadow[j + 1];
Leo Kim771fbae2015-11-19 15:56:10 +0900313
314 last_scanned_cnt--;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900315 }
316 }
317
Leo Kim771fbae2015-11-19 15:56:10 +0900318 PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n",
319 last_scanned_cnt);
320 if (last_scanned_cnt != 0) {
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700321 hAgingTimer.data = arg;
322 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
323 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900324 PRINT_D(CFG80211_DBG, "No need to restart Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700325 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900326}
327
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700328static void clear_duringIP(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900329{
330 PRINT_D(GENERIC_DBG, "GO:IP Obtained , enable scan\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100331 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900332}
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900333
Arnd Bergmann1608c402015-11-16 15:04:53 +0100334static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900335{
Chaehyun Lima74cc6b2015-10-02 16:41:17 +0900336 int state = -1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900337 int i;
338
Leo Kim771fbae2015-11-19 15:56:10 +0900339 if (last_scanned_cnt == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900340 PRINT_D(CFG80211_DBG, "Starting Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700341 hAgingTimer.data = (unsigned long)pUserVoid;
342 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900343 state = -1;
344 } else {
345 /* Linear search for now */
Leo Kim771fbae2015-11-19 15:56:10 +0900346 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900347 if (memcmp(last_scanned_shadow[i].au8bssid,
348 pstrNetworkInfo->au8bssid, 6) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900349 state = i;
350 break;
351 }
352 }
353 }
354 return state;
355}
356
Arnd Bergmann1608c402015-11-16 15:04:53 +0100357static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900358{
Chaehyun Lima74cc6b2015-10-02 16:41:17 +0900359 int ap_found = is_network_in_shadow(pstrNetworkInfo, pUserVoid);
Chaehyun Limfbc2fe12015-09-15 14:06:16 +0900360 u32 ap_index = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900361 u8 rssi_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900362
Leo Kim771fbae2015-11-19 15:56:10 +0900363 if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900364 PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
365 return;
366 }
367 if (ap_found == -1) {
Leo Kim771fbae2015-11-19 15:56:10 +0900368 ap_index = last_scanned_cnt;
369 last_scanned_cnt++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900370
371 } else {
372 ap_index = ap_found;
373 }
Leo Kimf1ab1172015-11-19 15:56:11 +0900374 rssi_index = last_scanned_shadow[ap_index].strRssi.u8Index;
375 last_scanned_shadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900376 if (rssi_index == NUM_RSSI) {
377 rssi_index = 0;
Leo Kimf1ab1172015-11-19 15:56:11 +0900378 last_scanned_shadow[ap_index].strRssi.u8Full = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900379 }
Leo Kimf1ab1172015-11-19 15:56:11 +0900380 last_scanned_shadow[ap_index].strRssi.u8Index = rssi_index;
381 last_scanned_shadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
382 last_scanned_shadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
383 last_scanned_shadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
384 memcpy(last_scanned_shadow[ap_index].au8ssid,
385 pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
386 memcpy(last_scanned_shadow[ap_index].au8bssid,
387 pstrNetworkInfo->au8bssid, ETH_ALEN);
388 last_scanned_shadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
389 last_scanned_shadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
390 last_scanned_shadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
391 last_scanned_shadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
392 last_scanned_shadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900393 if (ap_found != -1)
Leo Kimf1ab1172015-11-19 15:56:11 +0900394 kfree(last_scanned_shadow[ap_index].pu8IEs);
395 last_scanned_shadow[ap_index].pu8IEs =
Glen Leef3052582015-09-10 12:03:04 +0900396 kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL); /* will be deallocated by the WILC_WFI_CfgScan() function */
Leo Kimf1ab1172015-11-19 15:56:11 +0900397 memcpy(last_scanned_shadow[ap_index].pu8IEs,
398 pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
399 last_scanned_shadow[ap_index].u32TimeRcvdInScan = jiffies;
400 last_scanned_shadow[ap_index].u32TimeRcvdInScanCached = jiffies;
401 last_scanned_shadow[ap_index].u8Found = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900402 if (ap_found != -1)
Leo Kimf1ab1172015-11-19 15:56:11 +0900403 wilc_free_join_params(last_scanned_shadow[ap_index].pJoinParams);
404 last_scanned_shadow[ap_index].pJoinParams = pJoinParams;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900405}
406
407
408/**
409 * @brief CfgScanResult
410 * @details Callback function which returns the scan results found
411 *
412 * @param[in] tenuScanEvent enuScanEvent: enum, indicating the scan event triggered, whether that is
413 * SCAN_EVENT_NETWORK_FOUND or SCAN_EVENT_DONE
414 * tstrNetworkInfo* pstrNetworkInfo: structure holding the scan results information
415 * void* pUserVoid: Private structure associated with the wireless interface
416 * @return NONE
417 * @author mabubakr
418 * @date
419 * @version 1.0
420 */
Leo Kim1ec38152015-10-12 16:55:59 +0900421static void CfgScanResult(enum scan_event enuScanEvent, tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900422{
Chaehyun Lim27268872015-09-15 14:06:13 +0900423 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900424 struct wiphy *wiphy;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900425 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900426 struct ieee80211_channel *channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900427 struct cfg80211_bss *bss = NULL;
428
Chaehyun Lim27268872015-09-15 14:06:13 +0900429 priv = (struct wilc_priv *)pUserVoid;
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100430 if (priv->bCfgScanning) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900431 if (enuScanEvent == SCAN_EVENT_NETWORK_FOUND) {
432 wiphy = priv->dev->ieee80211_ptr->wiphy;
Leo Kim7ae43362015-09-16 18:35:59 +0900433
434 if (!wiphy)
435 return;
436
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900437 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC
438 &&
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900439 ((((s32)pstrNetworkInfo->s8rssi) * 100) < 0
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900440 ||
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900441 (((s32)pstrNetworkInfo->s8rssi) * 100) > 100)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900442 ) {
Leo Kim24db7132015-09-16 18:36:01 +0900443 PRINT_ER("wiphy signal type fial\n");
444 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900445 }
446
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900447 if (pstrNetworkInfo != NULL) {
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900448 s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900449 channel = ieee80211_get_channel(wiphy, s32Freq);
450
Leo Kim7ae43362015-09-16 18:35:59 +0900451 if (!channel)
452 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900453
454 PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530455 "BeaconPeriod: %d\n", channel->center_freq, (((s32)pstrNetworkInfo->s8rssi) * 100),
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900456 pstrNetworkInfo->u16CapInfo, pstrNetworkInfo->u16BeaconPeriod);
457
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100458 if (pstrNetworkInfo->bNewNetwork) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900459 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
460 /* max_scan_ssids */
461 PRINT_D(CFG80211_DBG, "Network %s found\n", pstrNetworkInfo->au8ssid);
462
463
464 priv->u32RcvdChCount++;
465
466
467
468 if (pJoinParams == NULL) {
469 PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n");
470 }
471 add_network_to_shadow(pstrNetworkInfo, priv, pJoinParams);
472
473 /*P2P peers are sent to WPA supplicant and added to shadow table*/
474
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900475 if (!(memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900476 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
477 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900478 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)pstrNetworkInfo->s8rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900479 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900480 }
481
482
483 } else {
484 PRINT_ER("Discovered networks exceeded the max limit\n");
485 }
486 } else {
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900487 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900488 /* So this network is discovered before, we'll just update its RSSI */
489 for (i = 0; i < priv->u32RcvdChCount; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900490 if (memcmp(last_scanned_shadow[i].au8bssid, pstrNetworkInfo->au8bssid, 6) == 0) {
491 PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", last_scanned_shadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900492
Leo Kimf1ab1172015-11-19 15:56:11 +0900493 last_scanned_shadow[i].s8rssi = pstrNetworkInfo->s8rssi;
494 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900495 break;
496 }
497 }
498 }
499 }
500 } else if (enuScanEvent == SCAN_EVENT_DONE) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530501 PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev);
502 PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n");
Dean Lee72ed4dc2015-06-12 14:11:44 +0900503 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900504
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530505 if (priv->u32RcvdChCount > 0)
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530506 PRINT_D(CFG80211_DBG, "%d Network(s) found\n", priv->u32RcvdChCount);
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530507 else
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530508 PRINT_D(CFG80211_DBG, "No networks found\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900509
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200510 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900511
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900512 if (priv->pstrScanReq != NULL) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900513 cfg80211_scan_done(priv->pstrScanReq, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900514 priv->u32RcvdChCount = 0;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900515 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900516 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900517 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200518 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900519
520 }
521 /*Aborting any scan operation during mac close*/
522 else if (enuScanEvent == SCAN_EVENT_ABORTED) {
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200523 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900524
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530525 PRINT_D(CFG80211_DBG, "Scan Aborted\n");
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900526 if (priv->pstrScanReq != NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900527
528 update_scan_time(priv);
Dean Lee72ed4dc2015-06-12 14:11:44 +0900529 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900530
Dean Lee72ed4dc2015-06-12 14:11:44 +0900531 cfg80211_scan_done(priv->pstrScanReq, false);
532 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900533 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900534 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200535 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900536 }
537 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900538}
539
540
541/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900542 * @brief CfgConnectResult
543 * @details
544 * @param[in] tenuConnDisconnEvent enuConnDisconnEvent: Type of connection response either
545 * connection response or disconnection notification.
546 * tstrConnectInfo* pstrConnectInfo: COnnection information.
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900547 * u8 u8MacStatus: Mac Status from firmware
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900548 * tstrDisconnectNotifInfo* pstrDisconnectNotifInfo: Disconnection Notification
549 * void* pUserVoid: Private data associated with wireless interface
550 * @return NONE
551 * @author mabubakr
552 * @date 01 MAR 2012
553 * @version 1.0
554 */
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100555int wilc_connecting;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900556
Leo Kimed3f0372015-10-12 16:56:01 +0900557static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900558 tstrConnectInfo *pstrConnectInfo,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900559 u8 u8MacStatus,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900560 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
561 void *pUserVoid)
562{
Chaehyun Lim27268872015-09-15 14:06:13 +0900563 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900564 struct net_device *dev;
Leo Kim441dc602015-10-12 16:55:35 +0900565 struct host_if_drv *pstrWFIDrv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900566 u8 NullBssid[ETH_ALEN] = {0};
Glen Leec1ec2c12015-10-20 17:13:58 +0900567 struct wilc *wl;
568 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900569
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100570 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900571
Chaehyun Lim27268872015-09-15 14:06:13 +0900572 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900573 dev = priv->dev;
Glen Leec1ec2c12015-10-20 17:13:58 +0900574 nic = netdev_priv(dev);
575 wl = nic->wilc;
Leo Kim441dc602015-10-12 16:55:35 +0900576 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900577
578 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
579 /*Initialization*/
Amitoj Kaur Chawlababa7c72015-10-15 13:48:29 +0530580 u16 u16ConnectStatus;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900581
582 u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
583
584 PRINT_D(CFG80211_DBG, " Connection response received = %d\n", u8MacStatus);
585
586 if ((u8MacStatus == MAC_DISCONNECTED) &&
587 (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
588 /* The case here is that our station was waiting for association response frame and has just received it containing status code
589 * = SUCCESSFUL_STATUSCODE, while mac status is MAC_DISCONNECTED (which means something wrong happened) */
590 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100591 wilc_wlan_set_bssid(priv->dev, NullBssid);
592 eth_zero_addr(wilc_connected_SSID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900593
Leo Kimab16ec02015-10-29 12:05:40 +0900594 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900595 wlan_channel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900596
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530597 PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d\n", u16ConnectStatus, u8MacStatus);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900598 }
599
600 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900601 bool bNeedScanRefresh = false;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900602 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900603
604 PRINT_INFO(CFG80211_DBG, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo->au8bssid[0],
605 pstrConnectInfo->au8bssid[1], pstrConnectInfo->au8bssid[2], pstrConnectInfo->au8bssid[3], pstrConnectInfo->au8bssid[4], pstrConnectInfo->au8bssid[5]);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900606 memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900607
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900608
Leo Kim771fbae2015-11-19 15:56:10 +0900609 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900610 if (memcmp(last_scanned_shadow[i].au8bssid,
611 pstrConnectInfo->au8bssid, ETH_ALEN) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900612 unsigned long now = jiffies;
613
614 if (time_after(now,
Leo Kimf1ab1172015-11-19 15:56:11 +0900615 last_scanned_shadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900616 bNeedScanRefresh = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900617 }
618
619 break;
620 }
621 }
622
Abdul Hussain5a66bf22015-06-16 09:44:06 +0000623 if (bNeedScanRefresh) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900624 /*Also, refrsh DIRECT- results if */
Dean Lee72ed4dc2015-06-12 14:11:44 +0900625 refresh_scan(priv, 1, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900626
627 }
628
629 }
630
631
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530632 PRINT_D(CFG80211_DBG, "Association request info elements length = %zu\n", pstrConnectInfo->ReqIEsLen);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900633
634 PRINT_D(CFG80211_DBG, "Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen);
635
636 cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
637 pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
638 pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
639 u16ConnectStatus, GFP_KERNEL); /* TODO: mostafa: u16ConnectStatus to */
640 /* be replaced by pstrConnectInfo->u16ConnectStatus */
641 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100642 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900643 PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n",
644 pstrDisconnectNotifInfo->u16reason, priv->dev);
645 u8P2Plocalrandom = 0x01;
646 u8P2Precvrandom = 0x00;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900647 bWilc_ie = false;
Shraddha Barkebcf02652015-10-05 17:00:32 +0530648 eth_zero_addr(priv->au8AssociatedBss);
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100649 wilc_wlan_set_bssid(priv->dev, NullBssid);
650 eth_zero_addr(wilc_connected_SSID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900651
Leo Kimab16ec02015-10-29 12:05:40 +0900652 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900653 wlan_channel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900654 /*Incase "P2P CLIENT Connected" send deauthentication reason by 3 to force the WPA_SUPPLICANT to directly change
655 * virtual interface to station*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900656 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900657 pstrDisconnectNotifInfo->u16reason = 3;
658 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900659 /*Incase "P2P CLIENT during connection(not connected)" send deauthentication reason by 1 to force the WPA_SUPPLICANT
660 * to scan again and retry the connection*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900661 else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900662 pstrDisconnectNotifInfo->u16reason = 1;
663 }
664 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
Sudip Mukherjeee26bb712015-06-30 13:51:51 +0530665 pstrDisconnectNotifInfo->ie_len, false,
666 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900667
668 }
669
670}
671
672
673/**
Chaehyun Lim80785a92015-09-14 12:24:01 +0900674 * @brief set_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900675 * @details Set channel for a given wireless interface. Some devices
676 * may support multi-channel operation (by channel hopping) so cfg80211
677 * doesn't verify much. Note, however, that the passed netdev may be
678 * %NULL as well if the user requested changing the channel for the
679 * device itself, or for a monitor interface.
680 * @param[in]
681 * @return int : Return 0 on Success
682 * @author mdaftedar
683 * @date 01 MAR 2012
684 * @version 1.0
685 */
Chaehyun Lim80785a92015-09-14 12:24:01 +0900686static int set_channel(struct wiphy *wiphy,
687 struct cfg80211_chan_def *chandef)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900688{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900689 u32 channelnum = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +0900690 struct wilc_priv *priv;
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900691 int result = 0;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900692
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900693 priv = wiphy_priv(wiphy);
694
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900695 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
696 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900697
Chaehyun Lim866a2c22015-10-02 16:41:21 +0900698 curr_channel = channelnum;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100699 result = wilc_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900700
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900701 if (result != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900702 PRINT_ER("Error in setting channel %d\n", channelnum);
703
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900704 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900705}
706
707/**
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900708 * @brief scan
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900709 * @details Request to do a scan. If returning zero, the scan request is given
710 * the driver, and will be valid until passed to cfg80211_scan_done().
711 * For scan results, call cfg80211_inform_bss(); you can call this outside
712 * the scan/scan_done bracket too.
713 * @param[in]
714 * @return int : Return 0 on Success
715 * @author mabubakr
716 * @date 01 MAR 2012
717 * @version 1.0
718 */
719
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900720static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900721{
Chaehyun Lim27268872015-09-15 14:06:13 +0900722 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900723 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +0900724 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900725 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
Leo Kim607db442015-10-05 15:25:37 +0900726 struct hidden_network strHiddenNetwork;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900727
728 priv = wiphy_priv(wiphy);
729
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900730 priv->pstrScanReq = request;
731
732 priv->u32RcvdChCount = 0;
733
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100734 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900735
736
737 reset_shadow_found(priv);
738
Dean Lee72ed4dc2015-06-12 14:11:44 +0900739 priv->bCfgScanning = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900740 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
741 /* max_scan_ssids */
742 for (i = 0; i < request->n_channels; i++) {
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900743 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900744 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
745 }
746
747 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530748 PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900749
750 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
751
752 if (request->n_ssids >= 1) {
753
754
Leo Kim607db442015-10-05 15:25:37 +0900755 strHiddenNetwork.pstrHiddenNetworkInfo = kmalloc(request->n_ssids * sizeof(struct hidden_network), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900756 strHiddenNetwork.u8ssidnum = request->n_ssids;
757
758
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900759 for (i = 0; i < request->n_ssids; i++) {
760
761 if (request->ssids[i].ssid != NULL && request->ssids[i].ssid_len != 0) {
Glen Leef3052582015-09-10 12:03:04 +0900762 strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900763 memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900764 strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len;
765 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530766 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900767 strHiddenNetwork.u8ssidnum -= 1;
768 }
769 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530770 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100771 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900772 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900773 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900774 CfgScanResult, (void *)priv, &strHiddenNetwork);
775 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530776 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100777 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900778 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900779 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900780 CfgScanResult, (void *)priv, NULL);
781 }
782
783 } else {
784 PRINT_ER("Requested num of scanned channels is greater than the max, supported"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530785 " channels\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900786 }
787
Leo Kime6e12662015-09-16 18:36:03 +0900788 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900789 s32Error = -EBUSY;
790 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
791 }
792
793 return s32Error;
794}
795
796/**
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900797 * @brief connect
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900798 * @details Connect to the ESS with the specified parameters. When connected,
799 * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
800 * If the connection fails for some reason, call cfg80211_connect_result()
801 * with the status from the AP.
802 * @param[in]
803 * @return int : Return 0 on Success
804 * @author mabubakr
805 * @date 01 MAR 2012
806 * @version 1.0
807 */
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900808static int connect(struct wiphy *wiphy, struct net_device *dev,
809 struct cfg80211_connect_params *sme)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900810{
Leo Kime6e12662015-09-16 18:36:03 +0900811 s32 s32Error = 0;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900812 u32 i;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900813 u8 u8security = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +0900814 enum AUTHTYPE tenuAuth_type = ANY;
Dean Lee576917a2015-06-15 11:58:57 +0900815 char *pcgroup_encrypt_val = NULL;
816 char *pccipher_group = NULL;
817 char *pcwpa_version = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900818
Chaehyun Lim27268872015-09-15 14:06:13 +0900819 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +0900820 struct host_if_drv *pstrWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900821 tstrNetworkInfo *pstrNetworkInfo = NULL;
822
823
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100824 wilc_connecting = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900825 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +0900826 pstrWFIDrv = (struct host_if_drv *)(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900827
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100828 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900829
Johnny Kim8a143302015-06-10 17:06:46 +0900830 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 +0900831 if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900832 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
Leo Kimab16ec02015-10-29 12:05:40 +0900833 pstrWFIDrv->p2p_connect = 1;
834 } else {
835 pstrWFIDrv->p2p_connect = 0;
836 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530837 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900838
Leo Kim771fbae2015-11-19 15:56:10 +0900839 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900840 if ((sme->ssid_len == last_scanned_shadow[i].u8SsidLen) &&
841 memcmp(last_scanned_shadow[i].au8ssid,
842 sme->ssid,
843 sme->ssid_len) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900844 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
845 if (sme->bssid == NULL) {
846 /* BSSID is not passed from the user, so decision of matching
847 * is done by SSID only */
848 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
849 break;
850 } else {
851 /* BSSID is also passed from the user, so decision of matching
852 * should consider also this passed BSSID */
Leo Kimf1ab1172015-11-19 15:56:11 +0900853 if (memcmp(last_scanned_shadow[i].au8bssid,
854 sme->bssid,
855 ETH_ALEN) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900856 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
857 break;
858 }
859 }
860 }
861 }
862
Leo Kim771fbae2015-11-19 15:56:10 +0900863 if (i < last_scanned_cnt) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900864 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
865
Leo Kimf1ab1172015-11-19 15:56:11 +0900866 pstrNetworkInfo = &last_scanned_shadow[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900867
868 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
869 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
870 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
871 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
872 } else {
873 s32Error = -ENOENT;
Leo Kim771fbae2015-11-19 15:56:10 +0900874 if (last_scanned_cnt == 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900875 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
876 else
877 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
878
879 goto done;
880 }
881
882 priv->WILC_WFI_wep_default = 0;
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900883 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
884 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900885
886 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
887 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
888
889 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
890
891 if (INFO) {
892 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
893 PRINT_D(CORECONFIG_DBG, "sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]);
894 }
895
896 if (sme->crypto.cipher_group != NO_ENCRYPT) {
897 /* To determine the u8security value, first we check the group cipher suite then {in case of WPA or WPA2}
898 * we will add to it the pairwise cipher suite(s) */
899 pcwpa_version = "Default";
900 PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900901 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900902 u8security = ENCRYPT_ENABLED | WEP;
903 pcgroup_encrypt_val = "WEP40";
904 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
905 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
906
907 if (INFO) {
908 for (i = 0; i < sme->key_len; i++)
909 PRINT_D(CORECONFIG_DBG, "WEP Key Value[%d] = %d\n", i, sme->key[i]);
910 }
911 priv->WILC_WFI_wep_default = sme->key_idx;
912 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900913 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900914
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900915 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900916 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900917 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
918 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900919 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900920
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100921 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
922 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900923 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900924 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
925 pcgroup_encrypt_val = "WEP104";
926 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
927
928 priv->WILC_WFI_wep_default = sme->key_idx;
929 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900930 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900931
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900932 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900933 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900934 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
935 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900936 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900937
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100938 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
939 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900940 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900941 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900942 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
943 pcgroup_encrypt_val = "WPA2_TKIP";
944 pccipher_group = "TKIP";
945 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
946 /* tenuSecurity_t = WPA2_AES; */
947 u8security = ENCRYPT_ENABLED | WPA2 | AES;
948 pcgroup_encrypt_val = "WPA2_AES";
949 pccipher_group = "AES";
950 }
951 pcwpa_version = "WPA_VERSION_2";
952 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
953 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900954 u8security = ENCRYPT_ENABLED | WPA | TKIP;
955 pcgroup_encrypt_val = "WPA_TKIP";
956 pccipher_group = "TKIP";
957 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
958 /* tenuSecurity_t = WPA_AES; */
959 u8security = ENCRYPT_ENABLED | WPA | AES;
960 pcgroup_encrypt_val = "WPA_AES";
961 pccipher_group = "AES";
962
963 }
964 pcwpa_version = "WPA_VERSION_1";
965
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900966 } else {
967 s32Error = -ENOTSUPP;
968 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
969
970 goto done;
971 }
972
973 }
974
975 /* After we set the u8security value from checking the group cipher suite, {in case of WPA or WPA2} we will
976 * add to it the pairwise cipher suite(s) */
977 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
978 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
979 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
980 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
981 u8security = u8security | TKIP;
982 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
983 u8security = u8security | AES;
984 }
985 }
986 }
987
988 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
989
990 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
991 switch (sme->auth_type) {
992 case NL80211_AUTHTYPE_OPEN_SYSTEM:
993 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
994 tenuAuth_type = OPEN_SYSTEM;
995 break;
996
997 case NL80211_AUTHTYPE_SHARED_KEY:
998 tenuAuth_type = SHARED_KEY;
999 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
1000 break;
1001
1002 default:
1003 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
1004 }
1005
1006
1007 /* ai: key_mgmt: enterprise case */
1008 if (sme->crypto.n_akm_suites) {
1009 switch (sme->crypto.akm_suites[0]) {
1010 case WLAN_AKM_SUITE_8021X:
1011 tenuAuth_type = IEEE8021;
1012 break;
1013
1014 default:
1015 break;
1016 }
1017 }
1018
1019
1020 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
1021
1022 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
1023 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
1024
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001025 curr_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001026
Leo Kimab16ec02015-10-29 12:05:40 +09001027 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +09001028 wlan_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001029
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001030 wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001031
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001032 s32Error = wilc_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001033 sme->ssid_len, sme->ie, sme->ie_len,
1034 CfgConnectResult, (void *)priv, u8security,
1035 tenuAuth_type, pstrNetworkInfo->u8channel,
1036 pstrNetworkInfo->pJoinParams);
Leo Kime6e12662015-09-16 18:36:03 +09001037 if (s32Error != 0) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001038 PRINT_ER("wilc_set_join_req(): Error(%d)\n", s32Error);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001039 s32Error = -ENOENT;
1040 goto done;
1041 }
1042
1043done:
1044
1045 return s32Error;
1046}
1047
1048
1049/**
Chaehyun Limb027cde2015-09-14 12:24:04 +09001050 * @brief disconnect
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001051 * @details Disconnect from the BSS/ESS.
1052 * @param[in]
1053 * @return int : Return 0 on Success
1054 * @author mdaftedar
1055 * @date 01 MAR 2012
1056 * @version 1.0
1057 */
Chaehyun Limb027cde2015-09-14 12:24:04 +09001058static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001059{
Leo Kime6e12662015-09-16 18:36:03 +09001060 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09001061 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09001062 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim51e825f2015-09-15 14:06:14 +09001063 u8 NullBssid[ETH_ALEN] = {0};
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001064
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001065 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001066 priv = wiphy_priv(wiphy);
1067
Leo Kim441dc602015-10-12 16:55:35 +09001068 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Leo Kimab16ec02015-10-29 12:05:40 +09001069 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +09001070 wlan_channel = INVALID_CHANNEL;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001071 wilc_wlan_set_bssid(priv->dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001072
1073 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
1074
1075 u8P2Plocalrandom = 0x01;
1076 u8P2Precvrandom = 0x00;
Dean Lee72ed4dc2015-06-12 14:11:44 +09001077 bWilc_ie = false;
Leo Kim1229b1a2015-10-29 12:05:39 +09001078 pstrWFIDrv->p2p_timeout = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001079
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001080 s32Error = wilc_disconnect(priv->hWILCWFIDrv, reason_code);
Leo Kime6e12662015-09-16 18:36:03 +09001081 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001082 PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
1083 s32Error = -EINVAL;
1084 }
1085
1086 return s32Error;
1087}
1088
1089/**
Chaehyun Lim953d4172015-09-14 12:24:05 +09001090 * @brief add_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001091 * @details Add a key with the given parameters. @mac_addr will be %NULL
1092 * when adding a group key.
1093 * @param[in] key : key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, 8-byte Rx Mic Key
1094 * @return int : Return 0 on Success
1095 * @author mdaftedar
1096 * @date 01 MAR 2012
1097 * @version 1.0
1098 */
Chaehyun Lim953d4172015-09-14 12:24:05 +09001099static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1100 bool pairwise,
1101 const u8 *mac_addr, struct key_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001102
1103{
Leo Kime6e12662015-09-16 18:36:03 +09001104 s32 s32Error = 0, KeyLen = params->key_len;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001105 u32 i;
Chaehyun Lim27268872015-09-15 14:06:13 +09001106 struct wilc_priv *priv;
Arnd Bergmann057d1e92015-06-01 21:06:44 +02001107 const u8 *pu8RxMic = NULL;
1108 const u8 *pu8TxMic = NULL;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001109 u8 u8mode = NO_ENCRYPT;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001110 u8 u8gmode = NO_ENCRYPT;
1111 u8 u8pmode = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +09001112 enum AUTHTYPE tenuAuth_type = ANY;
Glen Lee76469202015-10-20 17:13:59 +09001113 struct wilc *wl;
1114 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001115
1116 priv = wiphy_priv(wiphy);
Glen Lee76469202015-10-20 17:13:59 +09001117 nic = netdev_priv(netdev);
1118 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001119
1120 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
1121
Johnny Kim8a143302015-06-10 17:06:46 +09001122 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001123
1124 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
1125 params->key[1],
1126 params->key[2]);
1127
1128
1129 switch (params->cipher) {
1130 case WLAN_CIPHER_SUITE_WEP40:
1131 case WLAN_CIPHER_SUITE_WEP104:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001132 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
1133
1134 priv->WILC_WFI_wep_default = key_index;
1135 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001136 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001137
1138 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
1139 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
1140
1141 for (i = 0; i < params->key_len; i++)
1142 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
1143
1144 tenuAuth_type = OPEN_SYSTEM;
1145
1146 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
1147 u8mode = ENCRYPT_ENABLED | WEP;
1148 else
1149 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
1150
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001151 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 +09001152 break;
1153 }
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001154 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001155 priv->WILC_WFI_wep_default = key_index;
1156 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001157 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001158
1159 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
1160 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
1161 if (INFO) {
1162 for (i = 0; i < params->key_len; i++)
1163 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
1164 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001165 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001166 }
1167
1168 break;
1169
1170 case WLAN_CIPHER_SUITE_TKIP:
1171 case WLAN_CIPHER_SUITE_CCMP:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001172 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
1173
1174 if (priv->wilc_gtk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001175 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001176 priv->wilc_gtk[key_index]->key = NULL;
1177 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001178
1179 }
1180 if (priv->wilc_ptk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001181 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001182 priv->wilc_ptk[key_index]->key = NULL;
1183 priv->wilc_ptk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001184 }
1185
1186
1187
Daniel Machon19132212015-08-05 08:18:31 +02001188 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001189 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1190 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1191 else
1192 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1193
1194 priv->wilc_groupkey = u8gmode;
1195
1196 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1197
1198 pu8TxMic = params->key + 24;
1199 pu8RxMic = params->key + 16;
1200 KeyLen = params->key_len - 16;
1201 }
1202 /* 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 +05301203 kfree(priv->wilc_gtk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001204
Glen Leef3052582015-09-10 12:03:04 +09001205 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001206 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001207
1208 /* 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 +05301209 kfree(priv->wilc_gtk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001210
1211 if ((params->seq_len) > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001212 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001213 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001214 }
1215
1216 priv->wilc_gtk[key_index]->cipher = params->cipher;
1217 priv->wilc_gtk[key_index]->key_len = params->key_len;
1218 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1219
1220 if (INFO) {
1221 for (i = 0; i < params->key_len; i++)
1222 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1223 for (i = 0; i < params->seq_len; i++)
1224 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1225 }
1226
1227
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001228 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001229 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode);
1230
1231 } else {
1232 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]);
1233
1234 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1235 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1236 else
1237 u8pmode = priv->wilc_groupkey | AES;
1238
1239
1240 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1241
1242 pu8TxMic = params->key + 24;
1243 pu8RxMic = params->key + 16;
1244 KeyLen = params->key_len - 16;
1245 }
1246
Shraddha Barkecccfc392015-10-12 20:49:19 +05301247 kfree(priv->wilc_ptk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001248
Glen Leef3052582015-09-10 12:03:04 +09001249 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001250
Shraddha Barkecccfc392015-10-12 20:49:19 +05301251 kfree(priv->wilc_ptk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001252
1253 if ((params->seq_len) > 0)
Glen Leef3052582015-09-10 12:03:04 +09001254 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001255
1256 if (INFO) {
1257 for (i = 0; i < params->key_len; i++)
1258 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1259
1260 for (i = 0; i < params->seq_len; i++)
1261 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1262 }
1263
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001264 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001265
1266 if ((params->seq_len) > 0)
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001267 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001268
1269 priv->wilc_ptk[key_index]->cipher = params->cipher;
1270 priv->wilc_ptk[key_index]->key_len = params->key_len;
1271 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1272
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001273 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001274 pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index);
1275 }
1276 break;
1277 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001278
1279 {
1280 u8mode = 0;
Daniel Machon19132212015-08-05 08:18:31 +02001281 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001282 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1283 /* swap the tx mic by rx mic */
1284 pu8RxMic = params->key + 24;
1285 pu8TxMic = params->key + 16;
1286 KeyLen = params->key_len - 16;
1287 }
1288
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001289 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001290 if (!g_gtk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001291 g_add_gtk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001292 g_add_gtk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001293 if (!mac_addr) {
1294 g_add_gtk_key_params.mac_addr = NULL;
1295 } else {
Glen Leef3052582015-09-10 12:03:04 +09001296 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001297 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1298 }
1299 g_key_gtk_params.key_len = params->key_len;
1300 g_key_gtk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001301 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001302 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1303 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001304 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001305 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1306 }
1307 g_key_gtk_params.cipher = params->cipher;
1308
1309 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1310 g_key_gtk_params.key[1],
1311 g_key_gtk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001312 g_gtk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001313 }
1314
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001315 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001316 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001317 } else {
1318 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1319 /* swap the tx mic by rx mic */
1320 pu8RxMic = params->key + 24;
1321 pu8TxMic = params->key + 16;
1322 KeyLen = params->key_len - 16;
1323 }
1324
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001325 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001326 if (!g_ptk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001327 g_add_ptk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001328 g_add_ptk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001329 if (!mac_addr) {
1330 g_add_ptk_key_params.mac_addr = NULL;
1331 } else {
Glen Leef3052582015-09-10 12:03:04 +09001332 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001333 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1334 }
1335 g_key_ptk_params.key_len = params->key_len;
1336 g_key_ptk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001337 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001338 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1339 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001340 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001341 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1342 }
1343 g_key_ptk_params.cipher = params->cipher;
1344
1345 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1346 g_key_ptk_params.key[1],
1347 g_key_ptk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001348 g_ptk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001349 }
1350
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001351 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001352 pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index);
1353 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1354 if (INFO) {
1355 for (i = 0; i < params->key_len; i++)
1356 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1357 }
1358 }
1359 }
1360 break;
1361
1362 default:
1363 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
1364 s32Error = -ENOTSUPP;
1365
1366 }
1367
1368 return s32Error;
1369}
1370
1371/**
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001372 * @brief del_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001373 * @details Remove a key given the @mac_addr (%NULL for a group key)
1374 * and @key_index, return -ENOENT if the key doesn't exist.
1375 * @param[in]
1376 * @return int : Return 0 on Success
1377 * @author mdaftedar
1378 * @date 01 MAR 2012
1379 * @version 1.0
1380 */
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001381static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1382 u8 key_index,
1383 bool pairwise,
1384 const u8 *mac_addr)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001385{
Chaehyun Lim27268872015-09-15 14:06:13 +09001386 struct wilc_priv *priv;
Glen Lee692e2ac2015-10-20 17:14:00 +09001387 struct wilc *wl;
1388 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001389
1390 priv = wiphy_priv(wiphy);
Glen Lee692e2ac2015-10-20 17:14:00 +09001391 nic = netdev_priv(netdev);
1392 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001393
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001394 /*delete saved keys, if any*/
Glen Lee692e2ac2015-10-20 17:14:00 +09001395 if (netdev == wl->vif[0].ndev) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09001396 g_ptk_keys_saved = false;
1397 g_gtk_keys_saved = false;
1398 g_wep_keys_saved = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001399
1400 /*Delete saved WEP keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301401 kfree(g_key_wep_params.key);
1402 g_key_wep_params.key = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001403
1404 /*freeing memory allocated by "wilc_gtk" and "wilc_ptk" in "WILC_WIFI_ADD_KEY"*/
1405
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001406 if ((priv->wilc_gtk[key_index]) != NULL) {
1407
Shraddha Barkecccfc392015-10-12 20:49:19 +05301408 kfree(priv->wilc_gtk[key_index]->key);
1409 priv->wilc_gtk[key_index]->key = NULL;
1410 kfree(priv->wilc_gtk[key_index]->seq);
1411 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001412
Chaehyun Lim49188af2015-08-11 10:32:41 +09001413 kfree(priv->wilc_gtk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001414 priv->wilc_gtk[key_index] = NULL;
1415
1416 }
1417
1418 if ((priv->wilc_ptk[key_index]) != NULL) {
1419
Shraddha Barkecccfc392015-10-12 20:49:19 +05301420 kfree(priv->wilc_ptk[key_index]->key);
1421 priv->wilc_ptk[key_index]->key = NULL;
1422 kfree(priv->wilc_ptk[key_index]->seq);
1423 priv->wilc_ptk[key_index]->seq = NULL;
Chaehyun Lim49188af2015-08-11 10:32:41 +09001424 kfree(priv->wilc_ptk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001425 priv->wilc_ptk[key_index] = NULL;
1426 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001427
1428 /*Delete saved PTK and GTK keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301429 kfree(g_key_ptk_params.key);
1430 g_key_ptk_params.key = NULL;
1431 kfree(g_key_ptk_params.seq);
1432 g_key_ptk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001433
Shraddha Barkecccfc392015-10-12 20:49:19 +05301434 kfree(g_key_gtk_params.key);
1435 g_key_gtk_params.key = NULL;
1436 kfree(g_key_gtk_params.seq);
1437 g_key_gtk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001438
1439 /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001440 wilc_set_machw_change_vir_if(netdev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001441 }
1442
1443 if (key_index >= 0 && key_index <= 3) {
Chaehyun Lim2cc46832015-08-07 09:02:01 +09001444 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001445 priv->WILC_WFI_wep_key_len[key_index] = 0;
1446
1447 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001448 wilc_remove_wep_key(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001449 } else {
1450 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001451 wilc_remove_key(priv->hWILCWFIDrv, mac_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001452 }
1453
Leo Kimaaed3292015-10-12 16:55:38 +09001454 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001455}
1456
1457/**
Chaehyun Limf4893df2015-09-14 12:24:07 +09001458 * @brief get_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001459 * @details Get information about the key with the given parameters.
1460 * @mac_addr will be %NULL when requesting information for a group
1461 * key. All pointers given to the @callback function need not be valid
1462 * after it returns. This function should return an error if it is
1463 * not possible to retrieve the key, -ENOENT if it doesn't exist.
1464 * @param[in]
1465 * @return int : Return 0 on Success
1466 * @author mdaftedar
1467 * @date 01 MAR 2012
1468 * @version 1.0
1469 */
Chaehyun Limf4893df2015-09-14 12:24:07 +09001470static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1471 bool pairwise,
1472 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001473{
Chaehyun Lim27268872015-09-15 14:06:13 +09001474 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001475 struct key_params key_params;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001476 u32 i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001477
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001478 priv = wiphy_priv(wiphy);
1479
1480
Alison Schofield3604af52015-10-12 13:22:44 -07001481 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001482 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1483
1484 key_params.key = priv->wilc_gtk[key_index]->key;
1485 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1486 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1487 key_params.seq = priv->wilc_gtk[key_index]->seq;
1488 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1489 if (INFO) {
1490 for (i = 0; i < key_params.key_len; i++)
1491 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1492 }
1493 } else {
1494 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1495
1496 key_params.key = priv->wilc_ptk[key_index]->key;
1497 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1498 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1499 key_params.seq = priv->wilc_ptk[key_index]->seq;
1500 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1501 }
1502
1503 callback(cookie, &key_params);
1504
Leo Kimaaed3292015-10-12 16:55:38 +09001505 return 0; /* priv->wilc_gtk->key_len ?0 : -ENOENT; */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001506}
1507
1508/**
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001509 * @brief set_default_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001510 * @details Set the default management frame key on an interface
1511 * @param[in]
1512 * @return int : Return 0 on Success.
1513 * @author mdaftedar
1514 * @date 01 MAR 2012
1515 * @version 1.0
1516 */
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001517static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1518 bool unicast, bool multicast)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001519{
Chaehyun Lim27268872015-09-15 14:06:13 +09001520 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001521
1522
1523 priv = wiphy_priv(wiphy);
1524
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301525 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001526
1527 if (key_index != priv->WILC_WFI_wep_default) {
1528
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001529 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001530 }
1531
Leo Kimaaed3292015-10-12 16:55:38 +09001532 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001533}
1534
1535/**
Chaehyun Limf06f5622015-09-14 12:24:18 +09001536 * @brief get_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001537 * @details Get station information for the station identified by @mac
1538 * @param[in] NONE
1539 * @return int : Return 0 on Success.
1540 * @author mdaftedar
1541 * @date 01 MAR 2012
1542 * @version 1.0
1543 */
1544
Chaehyun Limf06f5622015-09-14 12:24:18 +09001545static int get_station(struct wiphy *wiphy, struct net_device *dev,
1546 const u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001547{
Chaehyun Lim27268872015-09-15 14:06:13 +09001548 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001549 perInterface_wlan_t *nic;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001550 u32 i = 0;
1551 u32 associatedsta = 0;
1552 u32 inactive_time = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001553 priv = wiphy_priv(wiphy);
1554 nic = netdev_priv(dev);
1555
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001556 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
1557 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1558
1559 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1560
1561 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1562
1563 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1564 associatedsta = i;
1565 break;
1566 }
1567
1568 }
1569
1570 if (associatedsta == -1) {
Leo Kimaaed3292015-10-12 16:55:38 +09001571 PRINT_ER("Station required is not associated\n");
1572 return -ENOENT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001573 }
1574
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001575 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001576
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001577 wilc_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001578 sinfo->inactive_time = 1000 * inactive_time;
1579 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
1580
1581 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001582
1583 if (nic->iftype == STATION_MODE) {
Leo Kim03e7b9c2015-10-12 16:55:58 +09001584 struct rf_info strStatistics;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001585
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001586 wilc_get_statistics(priv->hWILCWFIDrv, &strStatistics);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001587
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001588 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
Chandra S Gorentla62129902015-08-05 22:11:57 +05301589 BIT(NL80211_STA_INFO_RX_PACKETS) |
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001590 BIT(NL80211_STA_INFO_TX_PACKETS) |
1591 BIT(NL80211_STA_INFO_TX_FAILED) |
1592 BIT(NL80211_STA_INFO_TX_BITRATE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001593
Leo Kim00c8dfc2015-10-29 12:05:30 +09001594 sinfo->signal = strStatistics.rssi;
Leo Kim9b992742015-10-29 12:05:32 +09001595 sinfo->rx_packets = strStatistics.rx_cnt;
Leo Kim54160372015-10-29 12:05:33 +09001596 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1597 sinfo->tx_failed = strStatistics.tx_fail_cnt;
Leo Kim5babeec2015-10-29 12:05:29 +09001598 sinfo->txrate.legacy = strStatistics.link_speed * 10;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001599
Leo Kim5babeec2015-10-29 12:05:29 +09001600 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1601 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001602 wilc_enable_tcp_ack_filter(true);
Leo Kim5babeec2015-10-29 12:05:29 +09001603 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001604 wilc_enable_tcp_ack_filter(false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001605
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001606 PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
1607 sinfo->tx_failed, sinfo->txrate.legacy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001608 }
Leo Kimaaed3292015-10-12 16:55:38 +09001609 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001610}
1611
1612
1613/**
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001614 * @brief change_bss
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001615 * @details Modify parameters for a given BSS.
1616 * @param[in]
1617 * -use_cts_prot: Whether to use CTS protection
1618 * (0 = no, 1 = yes, -1 = do not change)
1619 * -use_short_preamble: Whether the use of short preambles is allowed
1620 * (0 = no, 1 = yes, -1 = do not change)
1621 * -use_short_slot_time: Whether the use of short slot time is allowed
1622 * (0 = no, 1 = yes, -1 = do not change)
1623 * -basic_rates: basic rates in IEEE 802.11 format
1624 * (or NULL for no change)
1625 * -basic_rates_len: number of basic rates
1626 * -ap_isolate: do not forward packets between connected stations
1627 * -ht_opmode: HT Operation mode
1628 * (u16 = opmode, -1 = do not change)
1629 * @return int : Return 0 on Success.
1630 * @author mdaftedar
1631 * @date 01 MAR 2012
1632 * @version 1.0
1633 */
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001634static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1635 struct bss_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001636{
1637 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1638 return 0;
1639}
1640
1641/**
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001642 * @brief set_wiphy_params
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001643 * @details Notify that wiphy parameters have changed;
1644 * @param[in] Changed bitfield (see &enum wiphy_params_flags) describes which values
1645 * have changed.
1646 * @return int : Return 0 on Success
1647 * @author mdaftedar
1648 * @date 01 MAR 2012
1649 * @version 1.0
1650 */
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001651static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001652{
Leo Kime6e12662015-09-16 18:36:03 +09001653 s32 s32Error = 0;
Leo Kim95296502015-10-05 15:25:46 +09001654 struct cfg_param_val pstrCfgParamVal;
Chaehyun Lim27268872015-09-15 14:06:13 +09001655 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001656
1657 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001658
Tony Cho87c05b22015-10-12 16:56:07 +09001659 pstrCfgParamVal.flag = 0;
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301660 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001661
1662 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1663 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1664 priv->dev->ieee80211_ptr->wiphy->retry_short);
Tony Cho87c05b22015-10-12 16:56:07 +09001665 pstrCfgParamVal.flag |= RETRY_SHORT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001666 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1667 }
1668 if (changed & WIPHY_PARAM_RETRY_LONG) {
1669
1670 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 +09001671 pstrCfgParamVal.flag |= RETRY_LONG;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001672 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1673
1674 }
1675 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1676 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 +09001677 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001678 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1679
1680 }
1681
1682 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1683 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1684
Tony Cho87c05b22015-10-12 16:56:07 +09001685 pstrCfgParamVal.flag |= RTS_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001686 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1687
1688 }
1689
1690 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001691 s32Error = wilc_hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001692 if (s32Error)
1693 PRINT_ER("Error in setting WIPHY PARAMS\n");
1694
1695
1696 return s32Error;
1697}
Arnd Bergmanne5af0562015-05-29 22:52:12 +02001698
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001699/**
Chaehyun Lim4d466572015-09-14 12:24:22 +09001700 * @brief set_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001701 * @details Cache a PMKID for a BSSID. This is mostly useful for fullmac
1702 * devices running firmwares capable of generating the (re) association
1703 * RSN IE. It allows for faster roaming between WPA2 BSSIDs.
1704 * @param[in]
1705 * @return int : Return 0 on Success
1706 * @author mdaftedar
1707 * @date 01 MAR 2012
1708 * @version 1.0
1709 */
Chaehyun Lim4d466572015-09-14 12:24:22 +09001710static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1711 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001712{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001713 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001714 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001715 u8 flag = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001716
Chaehyun Lim27268872015-09-15 14:06:13 +09001717 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001718
1719 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1720
1721
1722 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001723 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001724 ETH_ALEN)) {
1725 /*If bssid already exists and pmkid value needs to reset*/
1726 flag = PMKID_FOUND;
1727 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1728 break;
1729 }
1730 }
1731 if (i < WILC_MAX_NUM_PMKIDS) {
1732 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001733 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001734 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001735 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001736 PMKID_LEN);
1737 if (!(flag == PMKID_FOUND))
1738 priv->pmkid_list.numpmkid++;
1739 } else {
1740 PRINT_ER("Invalid PMKID index\n");
1741 s32Error = -EINVAL;
1742 }
1743
1744 if (!s32Error) {
1745 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001746 s32Error = wilc_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001747 }
1748 return s32Error;
1749}
1750
1751/**
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001752 * @brief del_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001753 * @details Delete a cached PMKID.
1754 * @param[in]
1755 * @return int : Return 0 on Success
1756 * @author mdaftedar
1757 * @date 01 MAR 2012
1758 * @version 1.0
1759 */
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001760static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1761 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001762{
1763
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001764 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001765 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001766
Chaehyun Lim27268872015-09-15 14:06:13 +09001767 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001768
1769 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1770
1771 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001772 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001773 ETH_ALEN)) {
1774 /*If bssid is found, reset the values*/
1775 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
Leo Kimcd1e6cb2015-10-05 15:25:45 +09001776 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001777 break;
1778 }
1779 }
1780
1781 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1782 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001783 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001784 priv->pmkid_list.pmkidlist[i + 1].bssid,
1785 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001786 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001787 priv->pmkid_list.pmkidlist[i].pmkid,
1788 PMKID_LEN);
1789 }
1790 priv->pmkid_list.numpmkid--;
1791 } else {
1792 s32Error = -EINVAL;
1793 }
1794
1795 return s32Error;
1796}
1797
1798/**
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001799 * @brief flush_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001800 * @details Flush all cached PMKIDs.
1801 * @param[in]
1802 * @return int : Return 0 on Success
1803 * @author mdaftedar
1804 * @date 01 MAR 2012
1805 * @version 1.0
1806 */
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001807static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001808{
Chaehyun Lim27268872015-09-15 14:06:13 +09001809 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001810
1811 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
1812
1813 /*Get cashed Pmkids and set all with zeros*/
Leo Kima949f902015-10-05 15:25:44 +09001814 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001815
1816 return 0;
1817}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001818
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001819
1820/**
1821 * @brief WILC_WFI_CfgParseRxAction
1822 * @details Function parses the received frames and modifies the following attributes:
1823 * -GO Intent
1824 * -Channel list
1825 * -Operating Channel
1826 *
1827 * @param[in] u8* Buffer, u32 length
1828 * @return NONE.
1829 * @author mdaftedar
1830 * @date 12 DEC 2012
1831 * @version
1832 */
1833
Arnd Bergmann1608c402015-11-16 15:04:53 +01001834static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001835{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001836 u32 index = 0;
1837 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001838
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001839 u8 op_channel_attr_index = 0;
1840 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001841
1842 while (index < len) {
1843 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001844 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001845 }
1846
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301847 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001848 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301849 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001850 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001851 index += buf[index + 1] + 3; /* ID,Length byte */
1852 }
Leo Kim0bd82742015-11-19 15:56:14 +09001853 if (wlan_channel != INVALID_CHANNEL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001854 /*Modify channel list attribute*/
1855 if (channel_list_attr_index) {
1856 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1857 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1858 if (buf[i] == 0x51) {
1859 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
Leo Kim0bd82742015-11-19 15:56:14 +09001860 buf[j] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001861 }
1862 break;
1863 }
1864 }
1865 }
1866 /*Modify operating channel attribute*/
1867 if (op_channel_attr_index) {
1868 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1869 buf[op_channel_attr_index + 6] = 0x51;
Leo Kim0bd82742015-11-19 15:56:14 +09001870 buf[op_channel_attr_index + 7] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001871 }
1872 }
1873}
1874
1875/**
1876 * @brief WILC_WFI_CfgParseTxAction
1877 * @details Function parses the transmitted action frames and modifies the
1878 * GO Intent attribute
1879 * @param[in] u8* Buffer, u32 length, bool bOperChan, u8 iftype
1880 * @return NONE.
1881 * @author mdaftedar
1882 * @date 12 DEC 2012
1883 * @version
1884 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01001885static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001886{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001887 u32 index = 0;
1888 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001889
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001890 u8 op_channel_attr_index = 0;
1891 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001892
1893 while (index < len) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001894 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001895 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001896
1897 break;
1898 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001899
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301900 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001901 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301902 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001903 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001904 index += buf[index + 1] + 3; /* ID,Length byte */
1905 }
Leo Kim0bd82742015-11-19 15:56:14 +09001906 if (wlan_channel != INVALID_CHANNEL && bOperChan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001907 /*Modify channel list attribute*/
1908 if (channel_list_attr_index) {
1909 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1910 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1911 if (buf[i] == 0x51) {
1912 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
Leo Kim0bd82742015-11-19 15:56:14 +09001913 buf[j] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001914 }
1915 break;
1916 }
1917 }
1918 }
1919 /*Modify operating channel attribute*/
1920 if (op_channel_attr_index) {
1921 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1922 buf[op_channel_attr_index + 6] = 0x51;
Leo Kim0bd82742015-11-19 15:56:14 +09001923 buf[op_channel_attr_index + 7] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001924 }
1925 }
1926}
1927
1928/* @brief WILC_WFI_p2p_rx
1929 * @details
1930 * @param[in]
1931 *
1932 * @return None
1933 * @author Mai Daftedar
1934 * @date 2 JUN 2013
1935 * @version 1.0
1936 */
1937
Chaehyun Limfbc2fe12015-09-15 14:06:16 +09001938void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001939{
1940
Chaehyun Lim27268872015-09-15 14:06:13 +09001941 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001942 u32 header, pkt_offset;
Leo Kim441dc602015-10-12 16:55:35 +09001943 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001944 u32 i = 0;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001945 s32 s32Freq;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001946
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001947 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001948 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001949
1950 /* Get WILC header */
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001951 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001952
1953 /* The packet offset field conain info about what type of managment frame */
1954 /* we are dealing with and ack status */
1955 pkt_offset = GET_PKT_OFFSET(header);
1956
1957 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1958 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1959 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001960 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001961 return;
1962 } else {
1963 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
1964 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],
1965 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001966 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001967 } else {
1968 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],
1969 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001970 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001971 }
1972 return;
1973 }
1974 } else {
1975
1976 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
1977
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001978 /*Upper layer is informed that the frame is received on this freq*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001979 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001980
1981 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1982 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
1983
Leo Kim1229b1a2015-10-29 12:05:39 +09001984 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001985 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
1986 return;
1987 }
1988 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1989
1990 switch (buff[ACTION_SUBTYPE_ID]) {
1991 case GAS_INTIAL_REQ:
1992 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
1993 break;
1994
1995 case GAS_INTIAL_RSP:
1996 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
1997 break;
1998
1999 case PUBLIC_ACT_VENDORSPEC:
2000 /*Now we have a public action vendor specific action frame, check if its a p2p public action frame
2001 * based on the standard its should have the p2p_oui attribute with the following values 50 6f 9A 09*/
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002002 if (!memcmp(u8P2P_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002003 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
2004 if (!bWilc_ie) {
2005 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002006 if (!memcmp(u8P2P_vendorspec, &buff[i], 6)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002007 u8P2Precvrandom = buff[i + 6];
Dean Lee72ed4dc2015-06-12 14:11:44 +09002008 bWilc_ie = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002009 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", u8P2Precvrandom);
2010 break;
2011 }
2012 }
2013 }
2014 }
2015 if (u8P2Plocalrandom > u8P2Precvrandom) {
2016 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2017 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2018 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002019 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(u8P2P_oui, &buff[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002020 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
2021 break;
2022 }
2023 }
2024 }
2025 } else
2026 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2027 }
2028
2029
2030 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP) && (bWilc_ie)) {
2031 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
2032 /* extra attribute for sig_dbm: signal strength in mBm, or 0 if unknown */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002033 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002034 return;
2035 }
2036 break;
2037
2038 default:
2039 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
2040 break;
2041 }
2042 }
2043 }
2044
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002045 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002046 }
2047}
2048
2049/**
2050 * @brief WILC_WFI_mgmt_tx_complete
2051 * @details Returns result of writing mgmt frame to VMM (Tx buffers are freed here)
2052 * @param[in] priv
2053 * transmitting status
2054 * @return None
2055 * @author Amr Abdelmoghny
2056 * @date 20 MAY 2013
2057 * @version 1.0
2058 */
2059static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
2060{
2061 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
2062
2063
2064 kfree(pv_data->buff);
2065 kfree(pv_data);
2066}
2067
2068/**
2069 * @brief WILC_WFI_RemainOnChannelReady
2070 * @details Callback function, called from handle_remain_on_channel on being ready on channel
2071 * @param
2072 * @return none
2073 * @author Amr abdelmoghny
2074 * @date 9 JUNE 2013
2075 * @version
2076 */
2077
2078static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
2079{
Chaehyun Lim27268872015-09-15 14:06:13 +09002080 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002081
Chaehyun Lim27268872015-09-15 14:06:13 +09002082 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002083
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302084 PRINT_D(HOSTINF_DBG, "Remain on channel ready\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002085
Dean Lee72ed4dc2015-06-12 14:11:44 +09002086 priv->bInP2PlistenState = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002087
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002088 cfg80211_ready_on_channel(priv->wdev,
2089 priv->strRemainOnChanParams.u64ListenCookie,
2090 priv->strRemainOnChanParams.pstrListenChan,
2091 priv->strRemainOnChanParams.u32ListenDuration,
2092 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002093}
2094
2095/**
2096 * @brief WILC_WFI_RemainOnChannelExpired
2097 * @details Callback function, called on expiration of remain-on-channel duration
2098 * @param
2099 * @return none
2100 * @author Amr abdelmoghny
2101 * @date 15 MAY 2013
2102 * @version
2103 */
2104
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002105static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002106{
Chaehyun Lim27268872015-09-15 14:06:13 +09002107 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002108
Chaehyun Lim27268872015-09-15 14:06:13 +09002109 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002110
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002111 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302112 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002113
Dean Lee72ed4dc2015-06-12 14:11:44 +09002114 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002115
2116 /*Inform wpas of remain-on-channel expiration*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002117 cfg80211_remain_on_channel_expired(priv->wdev,
2118 priv->strRemainOnChanParams.u64ListenCookie,
2119 priv->strRemainOnChanParams.pstrListenChan,
2120 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002121 } else {
2122 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
2123 , priv->strRemainOnChanParams.u32ListenSessionID);
2124 }
2125}
2126
2127
2128/**
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002129 * @brief remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002130 * @details Request the driver to remain awake on the specified
2131 * channel for the specified duration to complete an off-channel
2132 * operation (e.g., public action frame exchange). When the driver is
2133 * ready on the requested channel, it must indicate this with an event
2134 * notification by calling cfg80211_ready_on_channel().
2135 * @param[in]
2136 * @return int : Return 0 on Success
2137 * @author mdaftedar
2138 * @date 01 MAR 2012
2139 * @version 1.0
2140 */
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002141static int remain_on_channel(struct wiphy *wiphy,
2142 struct wireless_dev *wdev,
2143 struct ieee80211_channel *chan,
2144 unsigned int duration, u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002145{
Leo Kime6e12662015-09-16 18:36:03 +09002146 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002147 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002148
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002149 priv = wiphy_priv(wiphy);
2150
2151 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
2152
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002153
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002154 if (wdev->iftype == NL80211_IFTYPE_AP) {
2155 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
2156 return s32Error;
2157 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002158
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002159 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002160
2161 /*Setting params needed by WILC_WFI_RemainOnChannelExpired()*/
2162 priv->strRemainOnChanParams.pstrListenChan = chan;
2163 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002164 priv->strRemainOnChanParams.u32ListenDuration = duration;
2165 priv->strRemainOnChanParams.u32ListenSessionID++;
2166
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002167 s32Error = wilc_remain_on_channel(priv->hWILCWFIDrv
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002168 , priv->strRemainOnChanParams.u32ListenSessionID
2169 , duration
2170 , chan->hw_value
2171 , WILC_WFI_RemainOnChannelExpired
2172 , WILC_WFI_RemainOnChannelReady
2173 , (void *)priv);
2174
2175 return s32Error;
2176}
2177
2178/**
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002179 * @brief cancel_remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002180 * @details Cancel an on-going remain-on-channel operation.
2181 * This allows the operation to be terminated prior to timeout based on
2182 * the duration value.
2183 * @param[in] struct wiphy *wiphy,
2184 * @param[in] struct net_device *dev
2185 * @param[in] u64 cookie,
2186 * @return int : Return 0 on Success
2187 * @author mdaftedar
2188 * @date 01 MAR 2012
2189 * @version 1.0
2190 */
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002191static int cancel_remain_on_channel(struct wiphy *wiphy,
2192 struct wireless_dev *wdev,
2193 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002194{
Leo Kime6e12662015-09-16 18:36:03 +09002195 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002196 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002197
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002198 priv = wiphy_priv(wiphy);
2199
2200 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
2201
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002202 s32Error = wilc_listen_state_expired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002203 return s32Error;
2204}
2205/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002206 * @brief WILC_WFI_mgmt_tx_frame
2207 * @details
2208 *
2209 * @param[in]
2210 * @return NONE.
2211 * @author mdaftedar
2212 * @date 01 JUL 2012
2213 * @version
2214 */
Chaehyun Limc1560322015-09-22 18:34:51 +09002215static int mgmt_tx(struct wiphy *wiphy,
2216 struct wireless_dev *wdev,
2217 struct cfg80211_mgmt_tx_params *params,
2218 u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002219{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002220 struct ieee80211_channel *chan = params->chan;
2221 unsigned int wait = params->wait;
2222 const u8 *buf = params->buf;
2223 size_t len = params->len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002224 const struct ieee80211_mgmt *mgmt;
2225 struct p2p_mgmt_data *mgmt_tx;
Chaehyun Lim27268872015-09-15 14:06:13 +09002226 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002227 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002228 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002229 perInterface_wlan_t *nic;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002230 u32 buf_len = len + sizeof(u8P2P_vendorspec) + sizeof(u8P2Plocalrandom);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002231
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002232 nic = netdev_priv(wdev->netdev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002233 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002234 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002235
2236 *cookie = (unsigned long)buf;
2237 priv->u64tx_cookie = *cookie;
2238 mgmt = (const struct ieee80211_mgmt *) buf;
2239
2240 if (ieee80211_is_mgmt(mgmt->frame_control)) {
2241
2242 /*mgmt frame allocation*/
Glen Leef3052582015-09-10 12:03:04 +09002243 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002244 if (mgmt_tx == NULL) {
2245 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
Leo Kime6e12662015-09-16 18:36:03 +09002246 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002247 }
Glen Leef3052582015-09-10 12:03:04 +09002248 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002249 if (mgmt_tx->buff == NULL) {
2250 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
Tony Chof638dd32015-09-07 19:09:31 +09002251 kfree(mgmt_tx);
Leo Kime6e12662015-09-16 18:36:03 +09002252 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002253 }
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09002254 memcpy(mgmt_tx->buff, buf, len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002255 mgmt_tx->size = len;
2256
2257
2258 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
2259 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
2260 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002261 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002262 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002263 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002264 } else if (ieee80211_is_action(mgmt->frame_control)) {
Chaehyun Limd85f5322015-06-11 14:35:54 +09002265 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002266
2267
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002268 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002269 /*Only set the channel, if not a negotiation confirmation frame
2270 * (If Negotiation confirmation frame, force it
2271 * to be transmitted on the same negotiation channel)*/
2272
2273 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
2274 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
2275 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002276 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002277 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002278 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002279 }
2280 switch (buf[ACTION_SUBTYPE_ID]) {
2281 case GAS_INTIAL_REQ:
2282 {
2283 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
2284 break;
2285 }
2286
2287 case GAS_INTIAL_RSP:
2288 {
2289 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
2290 break;
2291 }
2292
2293 case PUBLIC_ACT_VENDORSPEC:
2294 {
2295 /*Now we have a public action vendor specific action frame, check if its a p2p public action frame
2296 * based on the standard its should have the p2p_oui attribute with the following values 50 6f 9A 09*/
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002297 if (!memcmp(u8P2P_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002298 /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/
2299 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
2300 if (u8P2Plocalrandom == 1 && u8P2Precvrandom < u8P2Plocalrandom) {
2301 get_random_bytes(&u8P2Plocalrandom, 1);
2302 /*Increment the number to prevent if its 0*/
2303 u8P2Plocalrandom++;
2304 }
2305 }
2306
2307 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2308 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2309 if (u8P2Plocalrandom > u8P2Precvrandom) {
2310 PRINT_D(GENERIC_DBG, "LOCAL WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2311
2312 /*Search for the p2p information information element , after the Public action subtype theres a byte for teh dialog token, skip that*/
2313 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09002314 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(u8P2P_oui, &buf[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002315 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
Dean Lee72ed4dc2015-06-12 14:11:44 +09002316 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002317
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002318 /*If using supplicant go intent, no need at all*/
2319 /*to parse transmitted negotiation frames*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002320 else
Dean Lee72ed4dc2015-06-12 14:11:44 +09002321 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002322 break;
2323 }
2324 }
2325
2326 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
Shivani Bhardwajd8060fc2015-10-29 00:30:01 +05302327 /*
2328 * Adding WILC information element to allow two WILC devices to
2329 * identify each other and connect
2330 */
2331 memcpy(&mgmt_tx->buff[len], u8P2P_vendorspec, sizeof(u8P2P_vendorspec));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002332 mgmt_tx->buff[len + sizeof(u8P2P_vendorspec)] = u8P2Plocalrandom;
2333 mgmt_tx->size = buf_len;
2334 }
2335 } else
2336 PRINT_D(GENERIC_DBG, "PEER WILL BE GO LocaRand=%02x RecvRand %02x\n", u8P2Plocalrandom, u8P2Precvrandom);
2337 }
2338
2339 } else {
2340 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
2341 }
2342
2343 break;
2344 }
2345
2346 default:
2347 {
2348 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
2349 break;
2350 }
2351 }
2352
2353 }
2354
2355 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 +09002356 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002357
Leo Kim1229b1a2015-10-29 12:05:39 +09002358 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n",
2359 jiffies, pstrWFIDrv->p2p_timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002360 }
2361
Glen Lee829c4772015-10-29 12:18:44 +09002362 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
2363 mgmt_tx->buff, mgmt_tx->size,
Glen Leec9d48342015-10-01 16:03:43 +09002364 WILC_WFI_mgmt_tx_complete);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002365 } else {
2366 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
2367 }
Leo Kimaaed3292015-10-12 16:55:38 +09002368 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002369}
2370
Chaehyun Lim85c587a2015-09-22 18:34:50 +09002371static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
2372 struct wireless_dev *wdev,
2373 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002374{
Chaehyun Lim27268872015-09-15 14:06:13 +09002375 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002376 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002377
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002378 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002379 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002380
2381
2382 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
Leo Kim1229b1a2015-10-29 12:05:39 +09002383 pstrWFIDrv->p2p_timeout = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002384
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +01002385 if (!priv->bInP2PlistenState) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002386 cfg80211_remain_on_channel_expired(priv->wdev,
2387 priv->strRemainOnChanParams.u64ListenCookie,
2388 priv->strRemainOnChanParams.pstrListenChan,
2389 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002390 }
2391
2392 return 0;
2393}
2394
2395/**
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002396 * @brief wilc_mgmt_frame_register
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002397 * @details Notify driver that a management frame type was
2398 * registered. Note that this callback may not sleep, and cannot run
2399 * concurrently with itself.
2400 * @param[in]
2401 * @return NONE.
2402 * @author mdaftedar
2403 * @date 01 JUL 2012
2404 * @version
2405 */
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002406void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
2407 u16 frame_type, bool reg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002408{
2409
Chaehyun Lim27268872015-09-15 14:06:13 +09002410 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002411 perInterface_wlan_t *nic;
Glen Lee1b869352015-10-20 17:14:01 +09002412 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002413
2414 priv = wiphy_priv(wiphy);
2415 nic = netdev_priv(priv->wdev->netdev);
Glen Lee1b869352015-10-20 17:14:01 +09002416 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002417
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002418 if (!frame_type)
2419 return;
2420
2421 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
2422 switch (frame_type) {
2423 case PROBE_REQ:
2424 {
2425 nic->g_struct_frame_reg[0].frame_type = frame_type;
2426 nic->g_struct_frame_reg[0].reg = reg;
2427 }
2428 break;
2429
2430 case ACTION:
2431 {
2432 nic->g_struct_frame_reg[1].frame_type = frame_type;
2433 nic->g_struct_frame_reg[1].reg = reg;
2434 }
2435 break;
2436
2437 default:
2438 {
2439 break;
2440 }
2441
2442 }
2443 /*If mac is closed, then return*/
Glen Lee1b869352015-10-20 17:14:01 +09002444 if (!wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002445 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
2446 return;
2447 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002448 wilc_frame_register(priv->hWILCWFIDrv, frame_type, reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002449
2450
2451}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002452
2453/**
Chaehyun Lima8047e22015-09-22 18:34:48 +09002454 * @brief set_cqm_rssi_config
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002455 * @details Configure connection quality monitor RSSI threshold.
2456 * @param[in] struct wiphy *wiphy:
2457 * @param[in] struct net_device *dev:
2458 * @param[in] s32 rssi_thold:
2459 * @param[in] u32 rssi_hyst:
2460 * @return int : Return 0 on Success
2461 * @author mdaftedar
2462 * @date 01 MAR 2012
2463 * @version 1.0
2464 */
Chaehyun Lima8047e22015-09-22 18:34:48 +09002465static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
2466 s32 rssi_thold, u32 rssi_hyst)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002467{
2468 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2469 return 0;
2470
2471}
2472/**
Chaehyun Limbdb63382015-09-14 12:24:19 +09002473 * @brief dump_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002474 * @details Configure connection quality monitor RSSI threshold.
2475 * @param[in] struct wiphy *wiphy:
2476 * @param[in] struct net_device *dev
2477 * @param[in] int idx
2478 * @param[in] u8 *mac
2479 * @param[in] struct station_info *sinfo
2480 * @return int : Return 0 on Success
2481 * @author mdaftedar
2482 * @date 01 MAR 2012
2483 * @version 1.0
2484 */
Chaehyun Limbdb63382015-09-14 12:24:19 +09002485static int dump_station(struct wiphy *wiphy, struct net_device *dev,
2486 int idx, u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002487{
Chaehyun Lim27268872015-09-15 14:06:13 +09002488 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002489
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002490 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2491
2492 if (idx != 0)
2493 return -ENOENT;
2494
2495 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002496
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002497 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002498
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002499 wilc_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002500
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002501 return 0;
2502
2503}
2504
2505
2506/**
Chaehyun Lim46530672015-09-22 18:34:46 +09002507 * @brief set_power_mgmt
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002508 * @details
2509 * @param[in]
2510 * @return int : Return 0 on Success.
2511 * @author mdaftedar
2512 * @date 01 JUL 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09002513 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002514 */
Chaehyun Lim46530672015-09-22 18:34:46 +09002515static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2516 bool enabled, int timeout)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002517{
Chaehyun Lim27268872015-09-15 14:06:13 +09002518 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002519
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002520 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2521
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002522 if (wiphy == NULL)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002523 return -ENOENT;
2524
2525 priv = wiphy_priv(wiphy);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002526 if (priv->hWILCWFIDrv == NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002527 PRINT_ER("Driver is NULL\n");
2528 return -EIO;
2529 }
2530
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002531 if (wilc_enable_ps)
2532 wilc_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002533
2534
Leo Kime6e12662015-09-16 18:36:03 +09002535 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002536
2537}
Glen Lee108b3432015-09-16 18:53:20 +09002538
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002539/**
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002540 * @brief change_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002541 * @details Change type/configuration of virtual interface,
2542 * keep the struct wireless_dev's iftype updated.
2543 * @param[in] NONE
2544 * @return int : Return 0 on Success.
2545 * @author mdaftedar
2546 * @date 01 MAR 2012
2547 * @version 1.0
2548 */
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002549static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2550 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002551{
Chaehyun Lim27268872015-09-15 14:06:13 +09002552 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002553 perInterface_wlan_t *nic;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002554 u8 interface_type;
Chaehyun Limd85f5322015-06-11 14:35:54 +09002555 u16 TID = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002556 u8 i;
Glen Lee299382c2015-10-20 17:13:56 +09002557 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002558
2559 nic = netdev_priv(dev);
2560 priv = wiphy_priv(wiphy);
Glen Lee299382c2015-10-20 17:13:56 +09002561 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002562
2563 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2564 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
2565 u8P2Plocalrandom = 0x01;
2566 u8P2Precvrandom = 0x00;
2567
Dean Lee72ed4dc2015-06-12 14:11:44 +09002568 bWilc_ie = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002569
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002570 wilc_optaining_ip = false;
2571 del_timer(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002572 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002573 /*Set WILC_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/
2574 if (g_ptk_keys_saved && g_gtk_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002575 wilc_set_machw_change_vir_if(dev, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002576 }
2577
2578 switch (type) {
2579 case NL80211_IFTYPE_STATION:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002580 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002581 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002582
2583 /* send delba over wlan interface */
2584
2585
2586 dev->ieee80211_ptr->iftype = type;
2587 priv->wdev->iftype = type;
2588 nic->monitor_flag = 0;
2589 nic->iftype = STATION_MODE;
2590
2591 /*Remove the enteries of the previously connected clients*/
2592 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002593 interface_type = nic->iftype;
2594 nic->iftype = STATION_MODE;
2595
Glen Lee299382c2015-10-20 17:13:56 +09002596 if (wl->initialized) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002597 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2598 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002599 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002600 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002601
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002602 /*Eliminate host interface blocking state*/
Glen Lee299382c2015-10-20 17:13:56 +09002603 up(&wl->cfg_event);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002604
Glen Lee53dc0cf2015-10-20 17:13:57 +09002605 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002606 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002607 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002608 nic->iftype = interface_type;
2609
2610 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002611 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2612 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002613 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002614 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002615
2616 /*Add saved WEP keys, if any*/
2617 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002618 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002619 g_key_wep_params.key_idx);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002620 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002621 g_key_wep_params.key,
2622 g_key_wep_params.key_len,
2623 g_key_wep_params.key_idx);
2624 }
2625
2626 /*No matter the driver handler passed here, it will be overwriiten*/
2627 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002628 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002629
2630 /*Add saved PTK and GTK keys, if any*/
2631 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2632 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2633 g_key_ptk_params.key[1],
2634 g_key_ptk_params.key[2]);
2635 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2636 g_key_gtk_params.key[1],
2637 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002638 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2639 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002640 g_add_ptk_key_params.key_idx,
2641 g_add_ptk_key_params.pairwise,
2642 g_add_ptk_key_params.mac_addr,
2643 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002644
Glen Lee299382c2015-10-20 17:13:56 +09002645 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2646 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002647 g_add_gtk_key_params.key_idx,
2648 g_add_gtk_key_params.pairwise,
2649 g_add_gtk_key_params.mac_addr,
2650 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002651 }
2652
Glen Lee299382c2015-10-20 17:13:56 +09002653 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002654 for (i = 0; i < num_reg_frame; i++) {
2655 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2656 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002657 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002658 nic->g_struct_frame_reg[i].frame_type,
2659 nic->g_struct_frame_reg[i].reg);
2660 }
2661 }
2662
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002663 wilc_enable_ps = true;
2664 wilc_set_power_mgmt(priv->hWILCWFIDrv, 1, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002665 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002666 break;
2667
2668 case NL80211_IFTYPE_P2P_CLIENT:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002669 wilc_enable_ps = false;
2670 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
2671 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002672 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002673
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002674 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2675 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002676
2677 dev->ieee80211_ptr->iftype = type;
2678 priv->wdev->iftype = type;
2679 nic->monitor_flag = 0;
2680
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002681 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2682 nic->iftype = CLIENT_MODE;
2683
2684
Glen Lee299382c2015-10-20 17:13:56 +09002685 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002686 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002687 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002688
Glen Lee53dc0cf2015-10-20 17:13:57 +09002689 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002690 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002691 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002692
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002693 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2694 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002695 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002696 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002697
2698 /*Add saved WEP keys, if any*/
2699 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002700 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2701 g_key_wep_params.key_idx);
2702 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
2703 g_key_wep_params.key,
2704 g_key_wep_params.key_len,
2705 g_key_wep_params.key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002706 }
2707
2708 /*No matter the driver handler passed here, it will be overwriiten*/
2709 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002710 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002711
2712 /*Add saved PTK and GTK keys, if any*/
2713 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2714 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2715 g_key_ptk_params.key[1],
2716 g_key_ptk_params.key[2]);
2717 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2718 g_key_gtk_params.key[1],
2719 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002720 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2721 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002722 g_add_ptk_key_params.key_idx,
2723 g_add_ptk_key_params.pairwise,
2724 g_add_ptk_key_params.mac_addr,
2725 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002726
Glen Lee299382c2015-10-20 17:13:56 +09002727 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2728 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002729 g_add_gtk_key_params.key_idx,
2730 g_add_gtk_key_params.pairwise,
2731 g_add_gtk_key_params.mac_addr,
2732 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002733 }
2734
2735 /*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 +09002736 refresh_scan(priv, 1, true);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002737 wilc_set_machw_change_vir_if(dev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002738
Glen Lee299382c2015-10-20 17:13:56 +09002739 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002740 for (i = 0; i < num_reg_frame; i++) {
2741 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2742 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002743 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002744 nic->g_struct_frame_reg[i].frame_type,
2745 nic->g_struct_frame_reg[i].reg);
2746 }
2747 }
2748 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002749 break;
2750
2751 case NL80211_IFTYPE_AP:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002752 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002753 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002754 dev->ieee80211_ptr->iftype = type;
2755 priv->wdev->iftype = type;
2756 nic->iftype = AP_MODE;
Johnny Kim8a143302015-06-10 17:06:46 +09002757 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002758
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002759 PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002760 wilc_wlan_get_firmware(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002761 /*If wilc is running, then close-open to actually get new firmware running (serves P2P)*/
Glen Lee299382c2015-10-20 17:13:56 +09002762 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002763 nic->iftype = AP_MODE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002764 wilc_mac_close(dev);
2765 wilc_mac_open(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002766
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002767 for (i = 0; i < num_reg_frame; i++) {
2768 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2769 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002770 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002771 nic->g_struct_frame_reg[i].frame_type,
2772 nic->g_struct_frame_reg[i].reg);
2773 }
2774 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002775 break;
2776
2777 case NL80211_IFTYPE_P2P_GO:
2778 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
2779
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002780 wilc_optaining_ip = true;
2781 mod_timer(&wilc_during_ip_timer, jiffies + msecs_to_jiffies(duringIP_TIME));
2782 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002783 /*Delete block ack has to be the latest config packet*/
2784 /*sent before downloading new FW. This is because it blocks on*/
2785 /*hWaitResponse semaphore, which allows previous config*/
2786 /*packets to actually take action on old FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002787 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2788 wl->vif[0].bssid, TID);
2789 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002790 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002791 dev->ieee80211_ptr->iftype = type;
2792 priv->wdev->iftype = type;
2793
Johnny Kim8a143302015-06-10 17:06:46 +09002794 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002795
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002796 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2797
2798
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002799 nic->iftype = GO_MODE;
2800
2801 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002802 wilc_wait_msg_queue_idle();
Glen Lee53dc0cf2015-10-20 17:13:57 +09002803 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002804 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002805 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002806
2807
2808 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002809 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2810 wilc_set_mac_address(wl->vif[0].hif_drv,
2811 wl->vif[0].src_addr);
2812 wilc_set_operation_mode(priv->hWILCWFIDrv, AP_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002813
2814 /*Add saved WEP keys, if any*/
2815 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002816 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2817 g_key_wep_params.key_idx);
2818 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002819 g_key_wep_params.key,
2820 g_key_wep_params.key_len,
2821 g_key_wep_params.key_idx);
2822 }
2823
2824 /*No matter the driver handler passed here, it will be overwriiten*/
2825 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002826 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002827
2828 /*Add saved PTK and GTK keys, if any*/
2829 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2830 PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0],
2831 g_key_ptk_params.key[1],
2832 g_key_ptk_params.key[2],
2833 g_key_ptk_params.cipher);
2834 PRINT_D(CFG80211_DBG, "gtk %x %x %x cipher %x\n", g_key_gtk_params.key[0],
2835 g_key_gtk_params.key[1],
2836 g_key_gtk_params.key[2],
2837 g_key_gtk_params.cipher);
Glen Lee299382c2015-10-20 17:13:56 +09002838 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2839 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002840 g_add_ptk_key_params.key_idx,
2841 g_add_ptk_key_params.pairwise,
2842 g_add_ptk_key_params.mac_addr,
2843 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002844
Glen Lee299382c2015-10-20 17:13:56 +09002845 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2846 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002847 g_add_gtk_key_params.key_idx,
2848 g_add_gtk_key_params.pairwise,
2849 g_add_gtk_key_params.mac_addr,
2850 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002851 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002852
Glen Lee299382c2015-10-20 17:13:56 +09002853 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002854 for (i = 0; i < num_reg_frame; i++) {
2855 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2856 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002857 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002858 nic->g_struct_frame_reg[i].frame_type,
2859 nic->g_struct_frame_reg[i].reg);
2860 }
2861 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002862 break;
2863
2864 default:
2865 PRINT_ER("Unknown interface type= %d\n", type);
Leo Kimaaed3292015-10-12 16:55:38 +09002866 return -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002867 }
2868
Leo Kimaaed3292015-10-12 16:55:38 +09002869 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002870}
2871
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002872/* (austin.2013-07-23)
2873 *
2874 * To support revised cfg80211_ops
2875 *
2876 * add_beacon --> start_ap
2877 * set_beacon --> change_beacon
2878 * del_beacon --> stop_ap
2879 *
2880 * beacon_parameters --> cfg80211_ap_settings
2881 * cfg80211_beacon_data
2882 *
2883 * applicable for linux kernel 3.4+
2884 */
2885
2886/**
Chaehyun Lima13168d2015-09-14 12:24:12 +09002887 * @brief start_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002888 * @details Add a beacon with given parameters, @head, @interval
2889 * and @dtim_period will be valid, @tail is optional.
2890 * @param[in] wiphy
2891 * @param[in] dev The net device structure
2892 * @param[in] settings cfg80211_ap_settings parameters for the beacon to be added
2893 * @return int : Return 0 on Success.
2894 * @author austin
2895 * @date 23 JUL 2013
2896 * @version 1.0
2897 */
Chaehyun Lima13168d2015-09-14 12:24:12 +09002898static int start_ap(struct wiphy *wiphy, struct net_device *dev,
2899 struct cfg80211_ap_settings *settings)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002900{
2901 struct cfg80211_beacon_data *beacon = &(settings->beacon);
Chaehyun Lim27268872015-09-15 14:06:13 +09002902 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002903 s32 s32Error = 0;
Glen Lee684dc182015-10-20 17:14:02 +09002904 struct wilc *wl;
2905 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002906
2907 priv = wiphy_priv(wiphy);
Glen Lee684dc182015-10-20 17:14:02 +09002908 nic = netdev_priv(dev);
2909 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002910 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
2911
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302912 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 +09002913 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
2914
Chaehyun Lim80785a92015-09-14 12:24:01 +09002915 s32Error = set_channel(wiphy, &settings->chandef);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002916
Leo Kime6e12662015-09-16 18:36:03 +09002917 if (s32Error != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002918 PRINT_ER("Error in setting channel\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002919
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002920 wilc_wlan_set_bssid(dev, wl->vif[0].src_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002921
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002922 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002923 settings->beacon_interval,
2924 settings->dtim_period,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002925 beacon->head_len, (u8 *)beacon->head,
2926 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002927
2928 return s32Error;
2929}
2930
2931/**
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002932 * @brief change_beacon
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002933 * @details Add a beacon with given parameters, @head, @interval
2934 * and @dtim_period will be valid, @tail is optional.
2935 * @param[in] wiphy
2936 * @param[in] dev The net device structure
2937 * @param[in] beacon cfg80211_beacon_data for the beacon to be changed
2938 * @return int : Return 0 on Success.
2939 * @author austin
2940 * @date 23 JUL 2013
2941 * @version 1.0
2942 */
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002943static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
2944 struct cfg80211_beacon_data *beacon)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002945{
Chaehyun Lim27268872015-09-15 14:06:13 +09002946 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002947 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002948
2949 priv = wiphy_priv(wiphy);
2950 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
2951
2952
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002953 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002954 0,
2955 0,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002956 beacon->head_len, (u8 *)beacon->head,
2957 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002958
2959 return s32Error;
2960}
2961
2962/**
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002963 * @brief stop_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002964 * @details Remove beacon configuration and stop sending the beacon.
2965 * @param[in]
2966 * @return int : Return 0 on Success.
2967 * @author austin
2968 * @date 23 JUL 2013
2969 * @version 1.0
2970 */
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002971static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002972{
Leo Kime6e12662015-09-16 18:36:03 +09002973 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002974 struct wilc_priv *priv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002975 u8 NullBssid[ETH_ALEN] = {0};
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002976
Leo Kim7ae43362015-09-16 18:35:59 +09002977 if (!wiphy)
2978 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002979
2980 priv = wiphy_priv(wiphy);
2981
2982 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
2983
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002984 wilc_wlan_set_bssid(dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002985
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002986 s32Error = wilc_del_beacon(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002987
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002988 if (s32Error)
2989 PRINT_ER("Host delete beacon fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002990
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002991 return s32Error;
2992}
2993
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002994/**
Chaehyun Limed269552015-09-14 12:24:15 +09002995 * @brief add_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002996 * @details Add a new station.
2997 * @param[in]
2998 * @return int : Return 0 on Success.
2999 * @author mdaftedar
3000 * @date 01 MAR 2012
3001 * @version 1.0
3002 */
Chaehyun Limed269552015-09-14 12:24:15 +09003003static int add_station(struct wiphy *wiphy, struct net_device *dev,
3004 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003005{
Leo Kime6e12662015-09-16 18:36:03 +09003006 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003007 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09003008 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003009 perInterface_wlan_t *nic;
3010
Leo Kim7ae43362015-09-16 18:35:59 +09003011 if (!wiphy)
3012 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003013
3014 priv = wiphy_priv(wiphy);
3015 nic = netdev_priv(dev);
3016
3017 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003018 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09003019 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003020 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003021 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003022 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003023
3024 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
3025
3026 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],
3027 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003028 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003029 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3030 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003031
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003032 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003033 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003034 } else {
Leo Kim22520122015-10-29 12:05:45 +09003035 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003036 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003037 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003038 memcpy(strStaParams.ht_supp_mcs_set,
3039 &params->ht_capa->mcs,
3040 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003041 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003042 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003043 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003044 }
3045
Leo Kimf676e172015-10-29 12:05:52 +09003046 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003047 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003048
Leo Kim22520122015-10-29 12:05:45 +09003049 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3050 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003051 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3052 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003053 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3054 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003055 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3056 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003057 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3058 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003059 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3060 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003061 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3062 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003063 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3064 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003065
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003066 s32Error = wilc_add_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003067 if (s32Error)
3068 PRINT_ER("Host add station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003069 }
3070
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003071 return s32Error;
3072}
3073
3074/**
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003075 * @brief del_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003076 * @details Remove a station; @mac may be NULL to remove all stations.
3077 * @param[in]
3078 * @return int : Return 0 on Success.
3079 * @author mdaftedar
3080 * @date 01 MAR 2012
3081 * @version 1.0
3082 */
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003083static int del_station(struct wiphy *wiphy, struct net_device *dev,
3084 struct station_del_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003085{
Arnd Bergmann057d1e92015-06-01 21:06:44 +02003086 const u8 *mac = params->mac;
Leo Kime6e12662015-09-16 18:36:03 +09003087 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003088 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003089 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003090
Leo Kim7ae43362015-09-16 18:35:59 +09003091 if (!wiphy)
3092 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003093
3094 priv = wiphy_priv(wiphy);
3095 nic = netdev_priv(dev);
3096
3097 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
3098 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
3099
3100
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003101 if (mac == NULL) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05303102 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003103 s32Error = wilc_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003104 } else {
3105 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]);
3106 }
3107
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003108 s32Error = wilc_del_station(priv->hWILCWFIDrv, mac);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003109
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003110 if (s32Error)
3111 PRINT_ER("Host delete station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003112 }
3113 return s32Error;
3114}
3115
3116/**
Chaehyun Lim14b42082015-09-14 12:24:17 +09003117 * @brief change_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003118 * @details Modify a given station.
3119 * @param[in]
3120 * @return int : Return 0 on Success.
3121 * @author mdaftedar
3122 * @date 01 MAR 2012
3123 * @version 1.0
3124 */
Chaehyun Lim14b42082015-09-14 12:24:17 +09003125static int change_station(struct wiphy *wiphy, struct net_device *dev,
3126 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003127{
Leo Kime6e12662015-09-16 18:36:03 +09003128 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003129 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09003130 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003131 perInterface_wlan_t *nic;
3132
3133
3134 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
3135
Leo Kim7ae43362015-09-16 18:35:59 +09003136 if (!wiphy)
3137 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003138
3139 priv = wiphy_priv(wiphy);
3140 nic = netdev_priv(dev);
3141
3142 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003143 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003144 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003145 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003146 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003147
Leo Kim2353c382015-10-29 12:05:41 +09003148 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n",
3149 strStaParams.bssid[0], strStaParams.bssid[1],
3150 strStaParams.bssid[2], strStaParams.bssid[3],
3151 strStaParams.bssid[4], strStaParams.bssid[5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003152 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003153 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3154 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003155
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003156 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003157 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003158 } else {
Leo Kim22520122015-10-29 12:05:45 +09003159 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003160 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003161 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003162 memcpy(strStaParams.ht_supp_mcs_set,
3163 &params->ht_capa->mcs,
3164 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003165 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003166 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003167 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003168 }
3169
Leo Kimf676e172015-10-29 12:05:52 +09003170 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003171 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003172
Leo Kim22520122015-10-29 12:05:45 +09003173 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3174 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003175 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3176 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003177 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3178 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003179 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3180 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003181 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3182 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003183 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3184 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003185 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3186 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003187 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3188 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003189
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003190 s32Error = wilc_edit_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003191 if (s32Error)
3192 PRINT_ER("Host edit station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003193 }
3194 return s32Error;
3195}
3196
3197
3198/**
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003199 * @brief add_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003200 * @details
3201 * @param[in]
3202 * @return int : Return 0 on Success.
3203 * @author mdaftedar
3204 * @date 01 JUL 2012
3205 * @version 1.0
3206 */
Chaehyun Lim37316e82015-09-22 18:34:52 +09003207static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
3208 const char *name,
3209 unsigned char name_assign_type,
3210 enum nl80211_iftype type,
3211 u32 *flags,
3212 struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003213{
3214 perInterface_wlan_t *nic;
Chaehyun Lim27268872015-09-15 14:06:13 +09003215 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003216 struct net_device *new_ifc = NULL;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003217
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003218 priv = wiphy_priv(wiphy);
3219
3220
3221
3222 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
3223
3224 nic = netdev_priv(priv->wdev->netdev);
3225
3226
3227 if (type == NL80211_IFTYPE_MONITOR) {
3228 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
3229 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", nic->wilc_netdev);
3230 new_ifc = WILC_WFI_init_mon_interface(name, nic->wilc_netdev);
3231 if (new_ifc != NULL) {
3232 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003233 nic = netdev_priv(priv->wdev->netdev);
3234 nic->monitor_flag = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003235 } else
3236 PRINT_ER("Error in initializing monitor interface\n ");
3237 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003238 return priv->wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003239}
3240
3241/**
Chaehyun Limb4a73352015-09-14 12:24:10 +09003242 * @brief del_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003243 * @details
3244 * @param[in]
3245 * @return int : Return 0 on Success.
3246 * @author mdaftedar
3247 * @date 01 JUL 2012
3248 * @version 1.0
3249 */
Chaehyun Lim956d7212015-09-22 18:34:49 +09003250static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003251{
3252 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
Leo Kime6e12662015-09-16 18:36:03 +09003253 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003254}
3255
Chaehyun Lim08241922015-09-15 14:06:12 +09003256static struct cfg80211_ops wilc_cfg80211_ops = {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003257
Chaehyun Lim80785a92015-09-14 12:24:01 +09003258 .set_monitor_channel = set_channel,
Chaehyun Lim0e30d062015-09-14 12:24:02 +09003259 .scan = scan,
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +09003260 .connect = connect,
Chaehyun Limb027cde2015-09-14 12:24:04 +09003261 .disconnect = disconnect,
Chaehyun Lim953d4172015-09-14 12:24:05 +09003262 .add_key = add_key,
Chaehyun Lim3044ba72015-09-14 12:24:06 +09003263 .del_key = del_key,
Chaehyun Limf4893df2015-09-14 12:24:07 +09003264 .get_key = get_key,
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09003265 .set_default_key = set_default_key,
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003266 .add_virtual_intf = add_virtual_intf,
Chaehyun Limb4a73352015-09-14 12:24:10 +09003267 .del_virtual_intf = del_virtual_intf,
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09003268 .change_virtual_intf = change_virtual_intf,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003269
Chaehyun Lima13168d2015-09-14 12:24:12 +09003270 .start_ap = start_ap,
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09003271 .change_beacon = change_beacon,
Chaehyun Limc8cddd72015-09-14 12:24:14 +09003272 .stop_ap = stop_ap,
Chaehyun Limed269552015-09-14 12:24:15 +09003273 .add_station = add_station,
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003274 .del_station = del_station,
Chaehyun Lim14b42082015-09-14 12:24:17 +09003275 .change_station = change_station,
Chaehyun Limf06f5622015-09-14 12:24:18 +09003276 .get_station = get_station,
Chaehyun Limbdb63382015-09-14 12:24:19 +09003277 .dump_station = dump_station,
Chaehyun Lima5f7db62015-09-14 12:24:20 +09003278 .change_bss = change_bss,
Chaehyun Lima76b63e2015-09-14 12:24:21 +09003279 .set_wiphy_params = set_wiphy_params,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003280
Chaehyun Lim4d466572015-09-14 12:24:22 +09003281 .set_pmksa = set_pmksa,
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09003282 .del_pmksa = del_pmksa,
Chaehyun Limb33c39b2015-09-14 12:24:24 +09003283 .flush_pmksa = flush_pmksa,
Chaehyun Lim6d19d692015-09-14 12:24:25 +09003284 .remain_on_channel = remain_on_channel,
Chaehyun Lim1dd54402015-09-14 12:24:26 +09003285 .cancel_remain_on_channel = cancel_remain_on_channel,
Chaehyun Lim4a2f9b32015-09-14 12:24:27 +09003286 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
Chaehyun Lim12a26a32015-09-14 12:24:28 +09003287 .mgmt_tx = mgmt_tx,
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09003288 .mgmt_frame_register = wilc_mgmt_frame_register,
Chaehyun Lim46530672015-09-22 18:34:46 +09003289 .set_power_mgmt = set_power_mgmt,
Chaehyun Lima8047e22015-09-22 18:34:48 +09003290 .set_cqm_rssi_config = set_cqm_rssi_config,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003291
3292};
3293
3294
3295
3296
3297
3298/**
3299 * @brief WILC_WFI_update_stats
3300 * @details Modify parameters for a given BSS.
3301 * @param[in]
3302 * @return int : Return 0 on Success.
3303 * @author mdaftedar
3304 * @date 01 MAR 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09003305 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003306 */
3307int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
3308{
3309
Chaehyun Lim27268872015-09-15 14:06:13 +09003310 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003311
3312 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003313 switch (changed) {
3314
3315 case WILC_WFI_RX_PKT:
3316 {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003317 priv->netstats.rx_packets++;
3318 priv->netstats.rx_bytes += pktlen;
3319 priv->netstats.rx_time = get_jiffies_64();
3320 }
3321 break;
3322
3323 case WILC_WFI_TX_PKT:
3324 {
3325 priv->netstats.tx_packets++;
3326 priv->netstats.tx_bytes += pktlen;
3327 priv->netstats.tx_time = get_jiffies_64();
3328
3329 }
3330 break;
3331
3332 default:
3333 break;
3334 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003335 return 0;
3336}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003337
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003338/**
3339 * @brief WILC_WFI_CfgAlloc
3340 * @details Allocation of the wireless device structure and assigning it
3341 * to the cfg80211 operations structure.
3342 * @param[in] NONE
3343 * @return wireless_dev : Returns pointer to wireless_dev structure.
3344 * @author mdaftedar
3345 * @date 01 MAR 2012
3346 * @version 1.0
3347 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01003348static struct wireless_dev *WILC_WFI_CfgAlloc(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003349{
3350
3351 struct wireless_dev *wdev;
3352
3353
3354 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
3355 /*Allocating the wireless device structure*/
3356 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
3357 if (!wdev) {
3358 PRINT_ER("Cannot allocate wireless device\n");
3359 goto _fail_;
3360 }
3361
3362 /*Creating a new wiphy, linking wireless structure with the wiphy structure*/
Chaehyun Lim27268872015-09-15 14:06:13 +09003363 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003364 if (!wdev->wiphy) {
3365 PRINT_ER("Cannot allocate wiphy\n");
3366 goto _fail_mem_;
3367
3368 }
3369
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003370 /* enable 802.11n HT */
3371 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
3372 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
3373 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3374 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
3375 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003376
3377 /*wiphy bands*/
3378 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
3379
3380 return wdev;
3381
3382_fail_mem_:
3383 kfree(wdev);
3384_fail_:
3385 return NULL;
3386
3387}
3388/**
Chaehyun Lim8459fd52015-09-20 15:51:09 +09003389 * @brief wilc_create_wiphy
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003390 * @details Registering of the wiphy structure and interface modes
3391 * @param[in] NONE
3392 * @return NONE
3393 * @author mdaftedar
3394 * @date 01 MAR 2012
3395 * @version 1.0
3396 */
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01003397struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003398{
Chaehyun Lim27268872015-09-15 14:06:13 +09003399 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003400 struct wireless_dev *wdev;
Leo Kime6e12662015-09-16 18:36:03 +09003401 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003402
3403 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
3404
3405 wdev = WILC_WFI_CfgAlloc();
3406 if (wdev == NULL) {
3407 PRINT_ER("CfgAlloc Failed\n");
3408 return NULL;
3409 }
3410
3411
3412 /*Return hardware description structure (wiphy)'s priv*/
3413 priv = wdev_priv(wdev);
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003414 sema_init(&(priv->SemHandleUpdateStats), 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003415
3416 /*Link the wiphy with wireless structure*/
3417 priv->wdev = wdev;
3418
3419 /*Maximum number of probed ssid to be added by user for the scan request*/
3420 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003421 /*Maximum number of pmkids to be cashed*/
3422 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
3423 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003424
3425 wdev->wiphy->max_scan_ie_len = 1000;
3426
3427 /*signal strength in mBm (100*dBm) */
3428 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3429
3430 /*Set the availaible cipher suites*/
3431 wdev->wiphy->cipher_suites = cipher_suites;
3432 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003433 /*Setting default managment types: for register action frame: */
3434 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003435
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003436 wdev->wiphy->max_remain_on_channel_duration = 500;
3437 /*Setting the wiphy interfcae mode and type before registering the wiphy*/
3438 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
3439 BIT(NL80211_IFTYPE_P2P_CLIENT);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003440 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003441 wdev->iftype = NL80211_IFTYPE_STATION;
3442
3443
3444
3445 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
3446 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
3447 wdev->wiphy->interface_modes, wdev->iftype);
3448
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01003449 set_wiphy_dev(wdev->wiphy, dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003450
3451 /*Register wiphy structure*/
3452 s32Error = wiphy_register(wdev->wiphy);
3453 if (s32Error) {
3454 PRINT_ER("Cannot register wiphy device\n");
3455 /*should define what action to be taken in such failure*/
3456 } else {
3457 PRINT_D(CFG80211_DBG, "Successful Registering\n");
3458 }
3459
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003460 priv->dev = net;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003461 return wdev;
3462
3463
3464}
3465/**
3466 * @brief WILC_WFI_WiphyFree
3467 * @details Freeing allocation of the wireless device structure
3468 * @param[in] NONE
3469 * @return NONE
3470 * @author mdaftedar
3471 * @date 01 MAR 2012
3472 * @version 1.0
3473 */
Chaehyun Limdd4b6a82015-09-20 15:51:25 +09003474int wilc_init_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003475{
3476
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003477 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003478
Chaehyun Lim27268872015-09-15 14:06:13 +09003479 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003480
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003481 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
3482 priv = wdev_priv(net->ieee80211_ptr);
3483 if (op_ifcs == 0) {
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -07003484 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003485 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003486 }
3487 op_ifcs++;
3488 if (s32Error < 0) {
3489 PRINT_ER("Failed to creat refresh Timer\n");
3490 return s32Error;
3491 }
3492
Dean Lee72ed4dc2015-06-12 14:11:44 +09003493 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003494
Dean Lee72ed4dc2015-06-12 14:11:44 +09003495 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003496
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003497 sema_init(&(priv->hSemScanReq), 1);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003498 s32Error = wilc_init(net, &priv->hWILCWFIDrv);
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003499 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003500 PRINT_ER("Error while initializing hostinterface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003501
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003502 return s32Error;
3503}
3504
3505/**
3506 * @brief WILC_WFI_WiphyFree
3507 * @details Freeing allocation of the wireless device structure
3508 * @param[in] NONE
3509 * @return NONE
3510 * @author mdaftedar
3511 * @date 01 MAR 2012
3512 * @version 1.0
3513 */
Chaehyun Lima9a16822015-09-20 15:51:24 +09003514int wilc_deinit_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003515{
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003516 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003517
Chaehyun Lim27268872015-09-15 14:06:13 +09003518 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003519
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003520 priv = wdev_priv(net->ieee80211_ptr);
3521
Dean Lee72ed4dc2015-06-12 14:11:44 +09003522 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003523
Dean Lee72ed4dc2015-06-12 14:11:44 +09003524 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003525
3526 op_ifcs--;
3527
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003528 s32Error = wilc_deinit(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003529
3530 /* Clear the Shadow scan */
3531 clear_shadow_scan(priv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003532 if (op_ifcs == 0) {
3533 PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003534 del_timer_sync(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003535 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003536
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003537 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003538 PRINT_ER("Error while deintializing host interface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003539
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003540 return s32Error;
3541}
3542
3543
3544/**
3545 * @brief WILC_WFI_WiphyFree
3546 * @details Freeing allocation of the wireless device structure
3547 * @param[in] NONE
3548 * @return NONE
3549 * @author mdaftedar
3550 * @date 01 MAR 2012
3551 * @version 1.0
3552 */
Chaehyun Lim96da20a2015-09-20 15:51:08 +09003553void wilc_free_wiphy(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003554{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003555 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
3556
Chaehyun Lim619837a2015-09-20 15:51:10 +09003557 if (!net) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003558 PRINT_D(INIT_DBG, "net_device is NULL\n");
3559 return;
3560 }
3561
Chaehyun Lim619837a2015-09-20 15:51:10 +09003562 if (!net->ieee80211_ptr) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003563 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
3564 return;
3565 }
3566
Chaehyun Lim619837a2015-09-20 15:51:10 +09003567 if (!net->ieee80211_ptr->wiphy) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003568 PRINT_D(INIT_DBG, "wiphy is NULL\n");
3569 return;
3570 }
3571
3572 wiphy_unregister(net->ieee80211_ptr->wiphy);
3573
3574 PRINT_D(INIT_DBG, "Freeing wiphy\n");
3575 wiphy_free(net->ieee80211_ptr->wiphy);
3576 kfree(net->ieee80211_ptr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003577}