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