blob: 6f79662728f2d193c3b3f18d2ebcbc5387d40e0a [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
Leo Kim48ee7ba2015-11-19 15:56:24 +0900240static void refresh_scan(void *user_void, u8 all, bool direct_scan)
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
Leo Kim84df0e62015-11-19 15:56:23 +0900248 priv = (struct wilc_priv *)user_void;
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);
Leo Kim48ee7ba2015-11-19 15:56:24 +0900266 if (memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7) ||
267 direct_scan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900268 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
269 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900270 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900271 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900272 }
273 }
274
275 }
276 }
277
278}
279
Arnd Bergmann1608c402015-11-16 15:04:53 +0100280static void reset_shadow_found(void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900281{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900282 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900283
Leo Kim771fbae2015-11-19 15:56:10 +0900284 for (i = 0; i < last_scanned_cnt; i++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900285 last_scanned_shadow[i].u8Found = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900286}
287
Arnd Bergmann1608c402015-11-16 15:04:53 +0100288static void update_scan_time(void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900289{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900290 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900291
Leo Kim771fbae2015-11-19 15:56:10 +0900292 for (i = 0; i < last_scanned_cnt; i++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900293 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900294}
295
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700296static void remove_network_from_shadow(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900297{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900298 unsigned long now = jiffies;
299 int i, j;
300
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900301
Leo Kim771fbae2015-11-19 15:56:10 +0900302 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900303 if (time_after(now, last_scanned_shadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) {
304 PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", last_scanned_shadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900305
Leo Kimf1ab1172015-11-19 15:56:11 +0900306 kfree(last_scanned_shadow[i].pu8IEs);
307 last_scanned_shadow[i].pu8IEs = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900308
Leo Kimf1ab1172015-11-19 15:56:11 +0900309 wilc_free_join_params(last_scanned_shadow[i].pJoinParams);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900310
Leo Kim771fbae2015-11-19 15:56:10 +0900311 for (j = i; (j < last_scanned_cnt - 1); j++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900312 last_scanned_shadow[j] = last_scanned_shadow[j + 1];
Leo Kim771fbae2015-11-19 15:56:10 +0900313
314 last_scanned_cnt--;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900315 }
316 }
317
Leo Kim771fbae2015-11-19 15:56:10 +0900318 PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n",
319 last_scanned_cnt);
320 if (last_scanned_cnt != 0) {
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700321 hAgingTimer.data = arg;
322 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
323 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900324 PRINT_D(CFG80211_DBG, "No need to restart Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700325 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900326}
327
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700328static void clear_duringIP(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900329{
330 PRINT_D(GENERIC_DBG, "GO:IP Obtained , enable scan\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100331 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900332}
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900333
Arnd Bergmann1608c402015-11-16 15:04:53 +0100334static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900335{
Chaehyun Lima74cc6b2015-10-02 16:41:17 +0900336 int state = -1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900337 int i;
338
Leo Kim771fbae2015-11-19 15:56:10 +0900339 if (last_scanned_cnt == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900340 PRINT_D(CFG80211_DBG, "Starting Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700341 hAgingTimer.data = (unsigned long)pUserVoid;
342 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900343 state = -1;
344 } else {
345 /* Linear search for now */
Leo Kim771fbae2015-11-19 15:56:10 +0900346 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900347 if (memcmp(last_scanned_shadow[i].au8bssid,
348 pstrNetworkInfo->au8bssid, 6) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900349 state = i;
350 break;
351 }
352 }
353 }
354 return state;
355}
356
Arnd Bergmann1608c402015-11-16 15:04:53 +0100357static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900358{
Chaehyun Lima74cc6b2015-10-02 16:41:17 +0900359 int ap_found = is_network_in_shadow(pstrNetworkInfo, pUserVoid);
Chaehyun Limfbc2fe12015-09-15 14:06:16 +0900360 u32 ap_index = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900361 u8 rssi_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900362
Leo Kim771fbae2015-11-19 15:56:10 +0900363 if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900364 PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
365 return;
366 }
367 if (ap_found == -1) {
Leo Kim771fbae2015-11-19 15:56:10 +0900368 ap_index = last_scanned_cnt;
369 last_scanned_cnt++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900370
371 } else {
372 ap_index = ap_found;
373 }
Leo Kimf1ab1172015-11-19 15:56:11 +0900374 rssi_index = last_scanned_shadow[ap_index].strRssi.u8Index;
375 last_scanned_shadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900376 if (rssi_index == NUM_RSSI) {
377 rssi_index = 0;
Leo Kimf1ab1172015-11-19 15:56:11 +0900378 last_scanned_shadow[ap_index].strRssi.u8Full = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900379 }
Leo Kimf1ab1172015-11-19 15:56:11 +0900380 last_scanned_shadow[ap_index].strRssi.u8Index = rssi_index;
381 last_scanned_shadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
382 last_scanned_shadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
383 last_scanned_shadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
384 memcpy(last_scanned_shadow[ap_index].au8ssid,
385 pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
386 memcpy(last_scanned_shadow[ap_index].au8bssid,
387 pstrNetworkInfo->au8bssid, ETH_ALEN);
388 last_scanned_shadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
389 last_scanned_shadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
390 last_scanned_shadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
391 last_scanned_shadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
392 last_scanned_shadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900393 if (ap_found != -1)
Leo Kimf1ab1172015-11-19 15:56:11 +0900394 kfree(last_scanned_shadow[ap_index].pu8IEs);
395 last_scanned_shadow[ap_index].pu8IEs =
Glen Leef3052582015-09-10 12:03:04 +0900396 kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL); /* will be deallocated by the WILC_WFI_CfgScan() function */
Leo Kimf1ab1172015-11-19 15:56:11 +0900397 memcpy(last_scanned_shadow[ap_index].pu8IEs,
398 pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
399 last_scanned_shadow[ap_index].u32TimeRcvdInScan = jiffies;
400 last_scanned_shadow[ap_index].u32TimeRcvdInScanCached = jiffies;
401 last_scanned_shadow[ap_index].u8Found = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900402 if (ap_found != -1)
Leo Kimf1ab1172015-11-19 15:56:11 +0900403 wilc_free_join_params(last_scanned_shadow[ap_index].pJoinParams);
404 last_scanned_shadow[ap_index].pJoinParams = pJoinParams;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900405}
406
407
408/**
409 * @brief CfgScanResult
410 * @details Callback function which returns the scan results found
411 *
412 * @param[in] tenuScanEvent enuScanEvent: enum, indicating the scan event triggered, whether that is
413 * SCAN_EVENT_NETWORK_FOUND or SCAN_EVENT_DONE
414 * tstrNetworkInfo* pstrNetworkInfo: structure holding the scan results information
415 * void* pUserVoid: Private structure associated with the wireless interface
416 * @return NONE
417 * @author mabubakr
418 * @date
419 * @version 1.0
420 */
Leo Kim1ec38152015-10-12 16:55:59 +0900421static void CfgScanResult(enum scan_event enuScanEvent, tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900422{
Chaehyun Lim27268872015-09-15 14:06:13 +0900423 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900424 struct wiphy *wiphy;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900425 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900426 struct ieee80211_channel *channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900427 struct cfg80211_bss *bss = NULL;
428
Chaehyun Lim27268872015-09-15 14:06:13 +0900429 priv = (struct wilc_priv *)pUserVoid;
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100430 if (priv->bCfgScanning) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900431 if (enuScanEvent == SCAN_EVENT_NETWORK_FOUND) {
432 wiphy = priv->dev->ieee80211_ptr->wiphy;
Leo Kim7ae43362015-09-16 18:35:59 +0900433
434 if (!wiphy)
435 return;
436
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900437 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC
438 &&
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900439 ((((s32)pstrNetworkInfo->s8rssi) * 100) < 0
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900440 ||
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900441 (((s32)pstrNetworkInfo->s8rssi) * 100) > 100)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900442 ) {
Leo Kim24db7132015-09-16 18:36:01 +0900443 PRINT_ER("wiphy signal type fial\n");
444 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900445 }
446
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900447 if (pstrNetworkInfo != NULL) {
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900448 s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900449 channel = ieee80211_get_channel(wiphy, s32Freq);
450
Leo Kim7ae43362015-09-16 18:35:59 +0900451 if (!channel)
452 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900453
454 PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530455 "BeaconPeriod: %d\n", channel->center_freq, (((s32)pstrNetworkInfo->s8rssi) * 100),
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900456 pstrNetworkInfo->u16CapInfo, pstrNetworkInfo->u16BeaconPeriod);
457
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100458 if (pstrNetworkInfo->bNewNetwork) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900459 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
460 /* max_scan_ssids */
461 PRINT_D(CFG80211_DBG, "Network %s found\n", pstrNetworkInfo->au8ssid);
462
463
464 priv->u32RcvdChCount++;
465
466
467
468 if (pJoinParams == NULL) {
469 PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n");
470 }
471 add_network_to_shadow(pstrNetworkInfo, priv, pJoinParams);
472
473 /*P2P peers are sent to WPA supplicant and added to shadow table*/
474
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900475 if (!(memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900476 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
477 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900478 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)pstrNetworkInfo->s8rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900479 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900480 }
481
482
483 } else {
484 PRINT_ER("Discovered networks exceeded the max limit\n");
485 }
486 } else {
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900487 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900488 /* So this network is discovered before, we'll just update its RSSI */
489 for (i = 0; i < priv->u32RcvdChCount; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900490 if (memcmp(last_scanned_shadow[i].au8bssid, pstrNetworkInfo->au8bssid, 6) == 0) {
491 PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", last_scanned_shadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900492
Leo Kimf1ab1172015-11-19 15:56:11 +0900493 last_scanned_shadow[i].s8rssi = pstrNetworkInfo->s8rssi;
494 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900495 break;
496 }
497 }
498 }
499 }
500 } else if (enuScanEvent == SCAN_EVENT_DONE) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530501 PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev);
502 PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n");
Dean Lee72ed4dc2015-06-12 14:11:44 +0900503 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900504
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530505 if (priv->u32RcvdChCount > 0)
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530506 PRINT_D(CFG80211_DBG, "%d Network(s) found\n", priv->u32RcvdChCount);
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530507 else
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530508 PRINT_D(CFG80211_DBG, "No networks found\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900509
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200510 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900511
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900512 if (priv->pstrScanReq != NULL) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900513 cfg80211_scan_done(priv->pstrScanReq, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900514 priv->u32RcvdChCount = 0;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900515 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900516 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900517 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200518 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900519
520 }
521 /*Aborting any scan operation during mac close*/
522 else if (enuScanEvent == SCAN_EVENT_ABORTED) {
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200523 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900524
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530525 PRINT_D(CFG80211_DBG, "Scan Aborted\n");
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900526 if (priv->pstrScanReq != NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900527
528 update_scan_time(priv);
Dean Lee72ed4dc2015-06-12 14:11:44 +0900529 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900530
Dean Lee72ed4dc2015-06-12 14:11:44 +0900531 cfg80211_scan_done(priv->pstrScanReq, false);
532 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900533 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900534 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200535 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900536 }
537 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900538}
539
540
541/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900542 * @brief CfgConnectResult
543 * @details
544 * @param[in] tenuConnDisconnEvent enuConnDisconnEvent: Type of connection response either
545 * connection response or disconnection notification.
546 * tstrConnectInfo* pstrConnectInfo: COnnection information.
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900547 * u8 u8MacStatus: Mac Status from firmware
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900548 * tstrDisconnectNotifInfo* pstrDisconnectNotifInfo: Disconnection Notification
549 * void* pUserVoid: Private data associated with wireless interface
550 * @return NONE
551 * @author mabubakr
552 * @date 01 MAR 2012
553 * @version 1.0
554 */
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100555int wilc_connecting;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900556
Leo Kimed3f0372015-10-12 16:56:01 +0900557static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900558 tstrConnectInfo *pstrConnectInfo,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900559 u8 u8MacStatus,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900560 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
561 void *pUserVoid)
562{
Chaehyun Lim27268872015-09-15 14:06:13 +0900563 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900564 struct net_device *dev;
Leo Kim441dc602015-10-12 16:55:35 +0900565 struct host_if_drv *pstrWFIDrv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900566 u8 NullBssid[ETH_ALEN] = {0};
Glen Leec1ec2c12015-10-20 17:13:58 +0900567 struct wilc *wl;
568 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900569
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100570 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900571
Chaehyun Lim27268872015-09-15 14:06:13 +0900572 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900573 dev = priv->dev;
Glen Leec1ec2c12015-10-20 17:13:58 +0900574 nic = netdev_priv(dev);
575 wl = nic->wilc;
Leo Kim441dc602015-10-12 16:55:35 +0900576 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900577
578 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
579 /*Initialization*/
Amitoj Kaur Chawlababa7c72015-10-15 13:48:29 +0530580 u16 u16ConnectStatus;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900581
582 u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
583
584 PRINT_D(CFG80211_DBG, " Connection response received = %d\n", u8MacStatus);
585
586 if ((u8MacStatus == MAC_DISCONNECTED) &&
587 (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
588 /* The case here is that our station was waiting for association response frame and has just received it containing status code
589 * = SUCCESSFUL_STATUSCODE, while mac status is MAC_DISCONNECTED (which means something wrong happened) */
590 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100591 wilc_wlan_set_bssid(priv->dev, NullBssid);
Leo Kime554a302015-11-19 15:56:21 +0900592 eth_zero_addr(wilc_connected_ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900593
Leo Kimab16ec02015-10-29 12:05:40 +0900594 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900595 wlan_channel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900596
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530597 PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d\n", u16ConnectStatus, u8MacStatus);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900598 }
599
600 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900601 bool bNeedScanRefresh = false;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900602 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900603
604 PRINT_INFO(CFG80211_DBG, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo->au8bssid[0],
605 pstrConnectInfo->au8bssid[1], pstrConnectInfo->au8bssid[2], pstrConnectInfo->au8bssid[3], pstrConnectInfo->au8bssid[4], pstrConnectInfo->au8bssid[5]);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900606 memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900607
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900608
Leo Kim771fbae2015-11-19 15:56:10 +0900609 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900610 if (memcmp(last_scanned_shadow[i].au8bssid,
611 pstrConnectInfo->au8bssid, ETH_ALEN) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900612 unsigned long now = jiffies;
613
614 if (time_after(now,
Leo Kimf1ab1172015-11-19 15:56:11 +0900615 last_scanned_shadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900616 bNeedScanRefresh = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900617 }
618
619 break;
620 }
621 }
622
Abdul Hussain5a66bf22015-06-16 09:44:06 +0000623 if (bNeedScanRefresh) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900624 /*Also, refrsh DIRECT- results if */
Dean Lee72ed4dc2015-06-12 14:11:44 +0900625 refresh_scan(priv, 1, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900626
627 }
628
629 }
630
631
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530632 PRINT_D(CFG80211_DBG, "Association request info elements length = %zu\n", pstrConnectInfo->ReqIEsLen);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900633
634 PRINT_D(CFG80211_DBG, "Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen);
635
636 cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
637 pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
638 pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
639 u16ConnectStatus, GFP_KERNEL); /* TODO: mostafa: u16ConnectStatus to */
640 /* be replaced by pstrConnectInfo->u16ConnectStatus */
641 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100642 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900643 PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n",
644 pstrDisconnectNotifInfo->u16reason, priv->dev);
Leo Kim583d9722015-11-19 15:56:16 +0900645 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +0900646 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +0900647 wilc_ie = false;
Shraddha Barkebcf02652015-10-05 17:00:32 +0530648 eth_zero_addr(priv->au8AssociatedBss);
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100649 wilc_wlan_set_bssid(priv->dev, NullBssid);
Leo Kime554a302015-11-19 15:56:21 +0900650 eth_zero_addr(wilc_connected_ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900651
Leo Kimab16ec02015-10-29 12:05:40 +0900652 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900653 wlan_channel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900654 /*Incase "P2P CLIENT Connected" send deauthentication reason by 3 to force the WPA_SUPPLICANT to directly change
655 * virtual interface to station*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900656 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900657 pstrDisconnectNotifInfo->u16reason = 3;
658 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900659 /*Incase "P2P CLIENT during connection(not connected)" send deauthentication reason by 1 to force the WPA_SUPPLICANT
660 * to scan again and retry the connection*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900661 else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900662 pstrDisconnectNotifInfo->u16reason = 1;
663 }
664 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
Sudip Mukherjeee26bb712015-06-30 13:51:51 +0530665 pstrDisconnectNotifInfo->ie_len, false,
666 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900667
668 }
669
670}
671
672
673/**
Chaehyun Lim80785a92015-09-14 12:24:01 +0900674 * @brief set_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900675 * @details Set channel for a given wireless interface. Some devices
676 * may support multi-channel operation (by channel hopping) so cfg80211
677 * doesn't verify much. Note, however, that the passed netdev may be
678 * %NULL as well if the user requested changing the channel for the
679 * device itself, or for a monitor interface.
680 * @param[in]
681 * @return int : Return 0 on Success
682 * @author mdaftedar
683 * @date 01 MAR 2012
684 * @version 1.0
685 */
Chaehyun Lim80785a92015-09-14 12:24:01 +0900686static int set_channel(struct wiphy *wiphy,
687 struct cfg80211_chan_def *chandef)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900688{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900689 u32 channelnum = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +0900690 struct wilc_priv *priv;
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900691 int result = 0;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900692
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900693 priv = wiphy_priv(wiphy);
694
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900695 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
696 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900697
Chaehyun Lim866a2c22015-10-02 16:41:21 +0900698 curr_channel = channelnum;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100699 result = wilc_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900700
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900701 if (result != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900702 PRINT_ER("Error in setting channel %d\n", channelnum);
703
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900704 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900705}
706
707/**
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900708 * @brief scan
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900709 * @details Request to do a scan. If returning zero, the scan request is given
710 * the driver, and will be valid until passed to cfg80211_scan_done().
711 * For scan results, call cfg80211_inform_bss(); you can call this outside
712 * the scan/scan_done bracket too.
713 * @param[in]
714 * @return int : Return 0 on Success
715 * @author mabubakr
716 * @date 01 MAR 2012
717 * @version 1.0
718 */
719
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900720static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900721{
Chaehyun Lim27268872015-09-15 14:06:13 +0900722 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900723 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +0900724 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900725 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
Leo Kim607db442015-10-05 15:25:37 +0900726 struct hidden_network strHiddenNetwork;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900727
728 priv = wiphy_priv(wiphy);
729
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900730 priv->pstrScanReq = request;
731
732 priv->u32RcvdChCount = 0;
733
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100734 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900735
736
737 reset_shadow_found(priv);
738
Dean Lee72ed4dc2015-06-12 14:11:44 +0900739 priv->bCfgScanning = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900740 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
741 /* max_scan_ssids */
742 for (i = 0; i < request->n_channels; i++) {
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900743 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900744 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
745 }
746
747 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530748 PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900749
750 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
751
752 if (request->n_ssids >= 1) {
753
754
Leo Kim607db442015-10-05 15:25:37 +0900755 strHiddenNetwork.pstrHiddenNetworkInfo = kmalloc(request->n_ssids * sizeof(struct hidden_network), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900756 strHiddenNetwork.u8ssidnum = request->n_ssids;
757
758
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900759 for (i = 0; i < request->n_ssids; i++) {
760
761 if (request->ssids[i].ssid != NULL && request->ssids[i].ssid_len != 0) {
Glen Leef3052582015-09-10 12:03:04 +0900762 strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900763 memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900764 strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len;
765 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530766 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900767 strHiddenNetwork.u8ssidnum -= 1;
768 }
769 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530770 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100771 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900772 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900773 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900774 CfgScanResult, (void *)priv, &strHiddenNetwork);
775 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530776 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100777 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900778 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900779 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900780 CfgScanResult, (void *)priv, NULL);
781 }
782
783 } else {
784 PRINT_ER("Requested num of scanned channels is greater than the max, supported"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530785 " channels\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900786 }
787
Leo Kime6e12662015-09-16 18:36:03 +0900788 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900789 s32Error = -EBUSY;
790 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
791 }
792
793 return s32Error;
794}
795
796/**
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900797 * @brief connect
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900798 * @details Connect to the ESS with the specified parameters. When connected,
799 * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
800 * If the connection fails for some reason, call cfg80211_connect_result()
801 * with the status from the AP.
802 * @param[in]
803 * @return int : Return 0 on Success
804 * @author mabubakr
805 * @date 01 MAR 2012
806 * @version 1.0
807 */
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900808static int connect(struct wiphy *wiphy, struct net_device *dev,
809 struct cfg80211_connect_params *sme)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900810{
Leo Kime6e12662015-09-16 18:36:03 +0900811 s32 s32Error = 0;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900812 u32 i;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900813 u8 u8security = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +0900814 enum AUTHTYPE tenuAuth_type = ANY;
Dean Lee576917a2015-06-15 11:58:57 +0900815 char *pcgroup_encrypt_val = NULL;
816 char *pccipher_group = NULL;
817 char *pcwpa_version = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900818
Chaehyun Lim27268872015-09-15 14:06:13 +0900819 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +0900820 struct host_if_drv *pstrWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900821 tstrNetworkInfo *pstrNetworkInfo = NULL;
822
823
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100824 wilc_connecting = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900825 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +0900826 pstrWFIDrv = (struct host_if_drv *)(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900827
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100828 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900829
Johnny Kim8a143302015-06-10 17:06:46 +0900830 PRINT_D(CFG80211_DBG, "Connecting to SSID [%s] on netdev [%p] host if [%p]\n", sme->ssid, dev, priv->hWILCWFIDrv);
Chaehyun Lim3f882892015-08-10 11:33:17 +0900831 if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900832 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
Leo Kimab16ec02015-10-29 12:05:40 +0900833 pstrWFIDrv->p2p_connect = 1;
834 } else {
835 pstrWFIDrv->p2p_connect = 0;
836 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530837 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900838
Leo Kim771fbae2015-11-19 15:56:10 +0900839 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900840 if ((sme->ssid_len == last_scanned_shadow[i].u8SsidLen) &&
841 memcmp(last_scanned_shadow[i].au8ssid,
842 sme->ssid,
843 sme->ssid_len) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900844 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
845 if (sme->bssid == NULL) {
846 /* BSSID is not passed from the user, so decision of matching
847 * is done by SSID only */
848 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
849 break;
850 } else {
851 /* BSSID is also passed from the user, so decision of matching
852 * should consider also this passed BSSID */
Leo Kimf1ab1172015-11-19 15:56:11 +0900853 if (memcmp(last_scanned_shadow[i].au8bssid,
854 sme->bssid,
855 ETH_ALEN) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900856 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
857 break;
858 }
859 }
860 }
861 }
862
Leo Kim771fbae2015-11-19 15:56:10 +0900863 if (i < last_scanned_cnt) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900864 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
865
Leo Kimf1ab1172015-11-19 15:56:11 +0900866 pstrNetworkInfo = &last_scanned_shadow[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900867
868 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
869 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
870 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
871 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
872 } else {
873 s32Error = -ENOENT;
Leo Kim771fbae2015-11-19 15:56:10 +0900874 if (last_scanned_cnt == 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900875 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
876 else
877 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
878
879 goto done;
880 }
881
882 priv->WILC_WFI_wep_default = 0;
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900883 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
884 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900885
886 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
887 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
888
889 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
890
891 if (INFO) {
892 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
893 PRINT_D(CORECONFIG_DBG, "sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]);
894 }
895
896 if (sme->crypto.cipher_group != NO_ENCRYPT) {
897 /* To determine the u8security value, first we check the group cipher suite then {in case of WPA or WPA2}
898 * we will add to it the pairwise cipher suite(s) */
899 pcwpa_version = "Default";
900 PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900901 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900902 u8security = ENCRYPT_ENABLED | WEP;
903 pcgroup_encrypt_val = "WEP40";
904 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
905 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
906
907 if (INFO) {
908 for (i = 0; i < sme->key_len; i++)
909 PRINT_D(CORECONFIG_DBG, "WEP Key Value[%d] = %d\n", i, sme->key[i]);
910 }
911 priv->WILC_WFI_wep_default = sme->key_idx;
912 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900913 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900914
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900915 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900916 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900917 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
918 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900919 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900920
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100921 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
922 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900923 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900924 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
925 pcgroup_encrypt_val = "WEP104";
926 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
927
928 priv->WILC_WFI_wep_default = sme->key_idx;
929 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900930 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900931
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900932 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900933 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900934 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
935 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900936 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900937
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100938 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
939 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900940 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900941 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900942 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
943 pcgroup_encrypt_val = "WPA2_TKIP";
944 pccipher_group = "TKIP";
945 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
946 /* tenuSecurity_t = WPA2_AES; */
947 u8security = ENCRYPT_ENABLED | WPA2 | AES;
948 pcgroup_encrypt_val = "WPA2_AES";
949 pccipher_group = "AES";
950 }
951 pcwpa_version = "WPA_VERSION_2";
952 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
953 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900954 u8security = ENCRYPT_ENABLED | WPA | TKIP;
955 pcgroup_encrypt_val = "WPA_TKIP";
956 pccipher_group = "TKIP";
957 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
958 /* tenuSecurity_t = WPA_AES; */
959 u8security = ENCRYPT_ENABLED | WPA | AES;
960 pcgroup_encrypt_val = "WPA_AES";
961 pccipher_group = "AES";
962
963 }
964 pcwpa_version = "WPA_VERSION_1";
965
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900966 } else {
967 s32Error = -ENOTSUPP;
968 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
969
970 goto done;
971 }
972
973 }
974
975 /* After we set the u8security value from checking the group cipher suite, {in case of WPA or WPA2} we will
976 * add to it the pairwise cipher suite(s) */
977 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
978 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
979 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
980 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
981 u8security = u8security | TKIP;
982 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
983 u8security = u8security | AES;
984 }
985 }
986 }
987
988 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
989
990 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
991 switch (sme->auth_type) {
992 case NL80211_AUTHTYPE_OPEN_SYSTEM:
993 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
994 tenuAuth_type = OPEN_SYSTEM;
995 break;
996
997 case NL80211_AUTHTYPE_SHARED_KEY:
998 tenuAuth_type = SHARED_KEY;
999 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
1000 break;
1001
1002 default:
1003 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
1004 }
1005
1006
1007 /* ai: key_mgmt: enterprise case */
1008 if (sme->crypto.n_akm_suites) {
1009 switch (sme->crypto.akm_suites[0]) {
1010 case WLAN_AKM_SUITE_8021X:
1011 tenuAuth_type = IEEE8021;
1012 break;
1013
1014 default:
1015 break;
1016 }
1017 }
1018
1019
1020 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
1021
1022 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
1023 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
1024
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001025 curr_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001026
Leo Kimab16ec02015-10-29 12:05:40 +09001027 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +09001028 wlan_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001029
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001030 wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001031
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001032 s32Error = wilc_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001033 sme->ssid_len, sme->ie, sme->ie_len,
1034 CfgConnectResult, (void *)priv, u8security,
1035 tenuAuth_type, pstrNetworkInfo->u8channel,
1036 pstrNetworkInfo->pJoinParams);
Leo Kime6e12662015-09-16 18:36:03 +09001037 if (s32Error != 0) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001038 PRINT_ER("wilc_set_join_req(): Error(%d)\n", s32Error);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001039 s32Error = -ENOENT;
1040 goto done;
1041 }
1042
1043done:
1044
1045 return s32Error;
1046}
1047
1048
1049/**
Chaehyun Limb027cde2015-09-14 12:24:04 +09001050 * @brief disconnect
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001051 * @details Disconnect from the BSS/ESS.
1052 * @param[in]
1053 * @return int : Return 0 on Success
1054 * @author mdaftedar
1055 * @date 01 MAR 2012
1056 * @version 1.0
1057 */
Chaehyun Limb027cde2015-09-14 12:24:04 +09001058static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001059{
Leo Kime6e12662015-09-16 18:36:03 +09001060 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09001061 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09001062 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim51e825f2015-09-15 14:06:14 +09001063 u8 NullBssid[ETH_ALEN] = {0};
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001064
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001065 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001066 priv = wiphy_priv(wiphy);
1067
Leo Kim441dc602015-10-12 16:55:35 +09001068 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Leo Kimab16ec02015-10-29 12:05:40 +09001069 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +09001070 wlan_channel = INVALID_CHANNEL;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001071 wilc_wlan_set_bssid(priv->dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001072
1073 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
1074
Leo Kim583d9722015-11-19 15:56:16 +09001075 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +09001076 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +09001077 wilc_ie = false;
Leo Kim1229b1a2015-10-29 12:05:39 +09001078 pstrWFIDrv->p2p_timeout = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001079
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001080 s32Error = wilc_disconnect(priv->hWILCWFIDrv, reason_code);
Leo Kime6e12662015-09-16 18:36:03 +09001081 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001082 PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
1083 s32Error = -EINVAL;
1084 }
1085
1086 return s32Error;
1087}
1088
1089/**
Chaehyun Lim953d4172015-09-14 12:24:05 +09001090 * @brief add_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001091 * @details Add a key with the given parameters. @mac_addr will be %NULL
1092 * when adding a group key.
1093 * @param[in] key : key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, 8-byte Rx Mic Key
1094 * @return int : Return 0 on Success
1095 * @author mdaftedar
1096 * @date 01 MAR 2012
1097 * @version 1.0
1098 */
Chaehyun Lim953d4172015-09-14 12:24:05 +09001099static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1100 bool pairwise,
1101 const u8 *mac_addr, struct key_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001102
1103{
Leo Kime6e12662015-09-16 18:36:03 +09001104 s32 s32Error = 0, KeyLen = params->key_len;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001105 u32 i;
Chaehyun Lim27268872015-09-15 14:06:13 +09001106 struct wilc_priv *priv;
Arnd Bergmann057d1e92015-06-01 21:06:44 +02001107 const u8 *pu8RxMic = NULL;
1108 const u8 *pu8TxMic = NULL;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001109 u8 u8mode = NO_ENCRYPT;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001110 u8 u8gmode = NO_ENCRYPT;
1111 u8 u8pmode = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +09001112 enum AUTHTYPE tenuAuth_type = ANY;
Glen Lee76469202015-10-20 17:13:59 +09001113 struct wilc *wl;
1114 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001115
1116 priv = wiphy_priv(wiphy);
Glen Lee76469202015-10-20 17:13:59 +09001117 nic = netdev_priv(netdev);
1118 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001119
1120 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
1121
Johnny Kim8a143302015-06-10 17:06:46 +09001122 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001123
1124 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
1125 params->key[1],
1126 params->key[2]);
1127
1128
1129 switch (params->cipher) {
1130 case WLAN_CIPHER_SUITE_WEP40:
1131 case WLAN_CIPHER_SUITE_WEP104:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001132 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
1133
1134 priv->WILC_WFI_wep_default = key_index;
1135 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001136 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001137
1138 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
1139 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
1140
1141 for (i = 0; i < params->key_len; i++)
1142 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
1143
1144 tenuAuth_type = OPEN_SYSTEM;
1145
1146 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
1147 u8mode = ENCRYPT_ENABLED | WEP;
1148 else
1149 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
1150
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001151 wilc_add_wep_key_bss_ap(priv->hWILCWFIDrv, params->key, params->key_len, key_index, u8mode, tenuAuth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001152 break;
1153 }
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001154 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001155 priv->WILC_WFI_wep_default = key_index;
1156 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001157 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001158
1159 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
1160 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
1161 if (INFO) {
1162 for (i = 0; i < params->key_len; i++)
1163 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
1164 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001165 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001166 }
1167
1168 break;
1169
1170 case WLAN_CIPHER_SUITE_TKIP:
1171 case WLAN_CIPHER_SUITE_CCMP:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001172 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
1173
1174 if (priv->wilc_gtk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001175 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001176 priv->wilc_gtk[key_index]->key = NULL;
1177 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001178
1179 }
1180 if (priv->wilc_ptk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001181 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001182 priv->wilc_ptk[key_index]->key = NULL;
1183 priv->wilc_ptk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001184 }
1185
1186
1187
Daniel Machon19132212015-08-05 08:18:31 +02001188 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001189 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1190 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1191 else
1192 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1193
1194 priv->wilc_groupkey = u8gmode;
1195
1196 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1197
1198 pu8TxMic = params->key + 24;
1199 pu8RxMic = params->key + 16;
1200 KeyLen = params->key_len - 16;
1201 }
1202 /* if there has been previous allocation for the same index through its key, free that memory and allocate again*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301203 kfree(priv->wilc_gtk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001204
Glen Leef3052582015-09-10 12:03:04 +09001205 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001206 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001207
1208 /* if there has been previous allocation for the same index through its seq, free that memory and allocate again*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301209 kfree(priv->wilc_gtk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001210
1211 if ((params->seq_len) > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001212 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001213 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001214 }
1215
1216 priv->wilc_gtk[key_index]->cipher = params->cipher;
1217 priv->wilc_gtk[key_index]->key_len = params->key_len;
1218 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1219
1220 if (INFO) {
1221 for (i = 0; i < params->key_len; i++)
1222 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1223 for (i = 0; i < params->seq_len; i++)
1224 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1225 }
1226
1227
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001228 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001229 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode);
1230
1231 } else {
1232 PRINT_INFO(CFG80211_DBG, "STA Address: %x%x%x%x%x\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4]);
1233
1234 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1235 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1236 else
1237 u8pmode = priv->wilc_groupkey | AES;
1238
1239
1240 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1241
1242 pu8TxMic = params->key + 24;
1243 pu8RxMic = params->key + 16;
1244 KeyLen = params->key_len - 16;
1245 }
1246
Shraddha Barkecccfc392015-10-12 20:49:19 +05301247 kfree(priv->wilc_ptk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001248
Glen Leef3052582015-09-10 12:03:04 +09001249 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001250
Shraddha Barkecccfc392015-10-12 20:49:19 +05301251 kfree(priv->wilc_ptk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001252
1253 if ((params->seq_len) > 0)
Glen Leef3052582015-09-10 12:03:04 +09001254 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001255
1256 if (INFO) {
1257 for (i = 0; i < params->key_len; i++)
1258 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1259
1260 for (i = 0; i < params->seq_len; i++)
1261 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1262 }
1263
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001264 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001265
1266 if ((params->seq_len) > 0)
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001267 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001268
1269 priv->wilc_ptk[key_index]->cipher = params->cipher;
1270 priv->wilc_ptk[key_index]->key_len = params->key_len;
1271 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1272
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001273 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001274 pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index);
1275 }
1276 break;
1277 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001278
1279 {
1280 u8mode = 0;
Daniel Machon19132212015-08-05 08:18:31 +02001281 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001282 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1283 /* swap the tx mic by rx mic */
1284 pu8RxMic = params->key + 24;
1285 pu8TxMic = params->key + 16;
1286 KeyLen = params->key_len - 16;
1287 }
1288
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001289 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001290 if (!g_gtk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001291 g_add_gtk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001292 g_add_gtk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001293 if (!mac_addr) {
1294 g_add_gtk_key_params.mac_addr = NULL;
1295 } else {
Glen Leef3052582015-09-10 12:03:04 +09001296 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001297 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1298 }
1299 g_key_gtk_params.key_len = params->key_len;
1300 g_key_gtk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001301 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001302 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1303 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001304 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001305 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1306 }
1307 g_key_gtk_params.cipher = params->cipher;
1308
1309 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1310 g_key_gtk_params.key[1],
1311 g_key_gtk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001312 g_gtk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001313 }
1314
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001315 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001316 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001317 } else {
1318 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1319 /* swap the tx mic by rx mic */
1320 pu8RxMic = params->key + 24;
1321 pu8TxMic = params->key + 16;
1322 KeyLen = params->key_len - 16;
1323 }
1324
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001325 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001326 if (!g_ptk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001327 g_add_ptk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001328 g_add_ptk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001329 if (!mac_addr) {
1330 g_add_ptk_key_params.mac_addr = NULL;
1331 } else {
Glen Leef3052582015-09-10 12:03:04 +09001332 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001333 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1334 }
1335 g_key_ptk_params.key_len = params->key_len;
1336 g_key_ptk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001337 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001338 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1339 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001340 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001341 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1342 }
1343 g_key_ptk_params.cipher = params->cipher;
1344
1345 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1346 g_key_ptk_params.key[1],
1347 g_key_ptk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001348 g_ptk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001349 }
1350
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001351 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001352 pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index);
1353 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1354 if (INFO) {
1355 for (i = 0; i < params->key_len; i++)
1356 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1357 }
1358 }
1359 }
1360 break;
1361
1362 default:
1363 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
1364 s32Error = -ENOTSUPP;
1365
1366 }
1367
1368 return s32Error;
1369}
1370
1371/**
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001372 * @brief del_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001373 * @details Remove a key given the @mac_addr (%NULL for a group key)
1374 * and @key_index, return -ENOENT if the key doesn't exist.
1375 * @param[in]
1376 * @return int : Return 0 on Success
1377 * @author mdaftedar
1378 * @date 01 MAR 2012
1379 * @version 1.0
1380 */
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001381static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1382 u8 key_index,
1383 bool pairwise,
1384 const u8 *mac_addr)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001385{
Chaehyun Lim27268872015-09-15 14:06:13 +09001386 struct wilc_priv *priv;
Glen Lee692e2ac2015-10-20 17:14:00 +09001387 struct wilc *wl;
1388 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001389
1390 priv = wiphy_priv(wiphy);
Glen Lee692e2ac2015-10-20 17:14:00 +09001391 nic = netdev_priv(netdev);
1392 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001393
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001394 /*delete saved keys, if any*/
Glen Lee692e2ac2015-10-20 17:14:00 +09001395 if (netdev == wl->vif[0].ndev) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09001396 g_ptk_keys_saved = false;
1397 g_gtk_keys_saved = false;
1398 g_wep_keys_saved = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001399
1400 /*Delete saved WEP keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301401 kfree(g_key_wep_params.key);
1402 g_key_wep_params.key = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001403
1404 /*freeing memory allocated by "wilc_gtk" and "wilc_ptk" in "WILC_WIFI_ADD_KEY"*/
1405
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001406 if ((priv->wilc_gtk[key_index]) != NULL) {
1407
Shraddha Barkecccfc392015-10-12 20:49:19 +05301408 kfree(priv->wilc_gtk[key_index]->key);
1409 priv->wilc_gtk[key_index]->key = NULL;
1410 kfree(priv->wilc_gtk[key_index]->seq);
1411 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001412
Chaehyun Lim49188af2015-08-11 10:32:41 +09001413 kfree(priv->wilc_gtk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001414 priv->wilc_gtk[key_index] = NULL;
1415
1416 }
1417
1418 if ((priv->wilc_ptk[key_index]) != NULL) {
1419
Shraddha Barkecccfc392015-10-12 20:49:19 +05301420 kfree(priv->wilc_ptk[key_index]->key);
1421 priv->wilc_ptk[key_index]->key = NULL;
1422 kfree(priv->wilc_ptk[key_index]->seq);
1423 priv->wilc_ptk[key_index]->seq = NULL;
Chaehyun Lim49188af2015-08-11 10:32:41 +09001424 kfree(priv->wilc_ptk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001425 priv->wilc_ptk[key_index] = NULL;
1426 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001427
1428 /*Delete saved PTK and GTK keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301429 kfree(g_key_ptk_params.key);
1430 g_key_ptk_params.key = NULL;
1431 kfree(g_key_ptk_params.seq);
1432 g_key_ptk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001433
Shraddha Barkecccfc392015-10-12 20:49:19 +05301434 kfree(g_key_gtk_params.key);
1435 g_key_gtk_params.key = NULL;
1436 kfree(g_key_gtk_params.seq);
1437 g_key_gtk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001438
1439 /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001440 wilc_set_machw_change_vir_if(netdev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001441 }
1442
1443 if (key_index >= 0 && key_index <= 3) {
Chaehyun Lim2cc46832015-08-07 09:02:01 +09001444 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001445 priv->WILC_WFI_wep_key_len[key_index] = 0;
1446
1447 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001448 wilc_remove_wep_key(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001449 } else {
1450 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001451 wilc_remove_key(priv->hWILCWFIDrv, mac_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001452 }
1453
Leo Kimaaed3292015-10-12 16:55:38 +09001454 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001455}
1456
1457/**
Chaehyun Limf4893df2015-09-14 12:24:07 +09001458 * @brief get_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001459 * @details Get information about the key with the given parameters.
1460 * @mac_addr will be %NULL when requesting information for a group
1461 * key. All pointers given to the @callback function need not be valid
1462 * after it returns. This function should return an error if it is
1463 * not possible to retrieve the key, -ENOENT if it doesn't exist.
1464 * @param[in]
1465 * @return int : Return 0 on Success
1466 * @author mdaftedar
1467 * @date 01 MAR 2012
1468 * @version 1.0
1469 */
Chaehyun Limf4893df2015-09-14 12:24:07 +09001470static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1471 bool pairwise,
1472 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001473{
Chaehyun Lim27268872015-09-15 14:06:13 +09001474 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001475 struct key_params key_params;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001476 u32 i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001477
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001478 priv = wiphy_priv(wiphy);
1479
1480
Alison Schofield3604af52015-10-12 13:22:44 -07001481 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001482 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1483
1484 key_params.key = priv->wilc_gtk[key_index]->key;
1485 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1486 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1487 key_params.seq = priv->wilc_gtk[key_index]->seq;
1488 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1489 if (INFO) {
1490 for (i = 0; i < key_params.key_len; i++)
1491 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1492 }
1493 } else {
1494 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1495
1496 key_params.key = priv->wilc_ptk[key_index]->key;
1497 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1498 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1499 key_params.seq = priv->wilc_ptk[key_index]->seq;
1500 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1501 }
1502
1503 callback(cookie, &key_params);
1504
Leo Kimaaed3292015-10-12 16:55:38 +09001505 return 0; /* priv->wilc_gtk->key_len ?0 : -ENOENT; */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001506}
1507
1508/**
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001509 * @brief set_default_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001510 * @details Set the default management frame key on an interface
1511 * @param[in]
1512 * @return int : Return 0 on Success.
1513 * @author mdaftedar
1514 * @date 01 MAR 2012
1515 * @version 1.0
1516 */
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001517static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1518 bool unicast, bool multicast)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001519{
Chaehyun Lim27268872015-09-15 14:06:13 +09001520 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001521
1522
1523 priv = wiphy_priv(wiphy);
1524
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301525 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001526
1527 if (key_index != priv->WILC_WFI_wep_default) {
1528
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001529 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001530 }
1531
Leo Kimaaed3292015-10-12 16:55:38 +09001532 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001533}
1534
1535/**
Chaehyun Limf06f5622015-09-14 12:24:18 +09001536 * @brief get_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001537 * @details Get station information for the station identified by @mac
1538 * @param[in] NONE
1539 * @return int : Return 0 on Success.
1540 * @author mdaftedar
1541 * @date 01 MAR 2012
1542 * @version 1.0
1543 */
1544
Chaehyun Limf06f5622015-09-14 12:24:18 +09001545static int get_station(struct wiphy *wiphy, struct net_device *dev,
1546 const u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001547{
Chaehyun Lim27268872015-09-15 14:06:13 +09001548 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001549 perInterface_wlan_t *nic;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001550 u32 i = 0;
1551 u32 associatedsta = 0;
1552 u32 inactive_time = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001553 priv = wiphy_priv(wiphy);
1554 nic = netdev_priv(dev);
1555
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001556 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
1557 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1558
1559 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1560
1561 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1562
1563 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1564 associatedsta = i;
1565 break;
1566 }
1567
1568 }
1569
1570 if (associatedsta == -1) {
Leo Kimaaed3292015-10-12 16:55:38 +09001571 PRINT_ER("Station required is not associated\n");
1572 return -ENOENT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001573 }
1574
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001575 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001576
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001577 wilc_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001578 sinfo->inactive_time = 1000 * inactive_time;
1579 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
1580
1581 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001582
1583 if (nic->iftype == STATION_MODE) {
Leo Kim03e7b9c2015-10-12 16:55:58 +09001584 struct rf_info strStatistics;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001585
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001586 wilc_get_statistics(priv->hWILCWFIDrv, &strStatistics);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001587
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001588 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
Chandra S Gorentla62129902015-08-05 22:11:57 +05301589 BIT(NL80211_STA_INFO_RX_PACKETS) |
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001590 BIT(NL80211_STA_INFO_TX_PACKETS) |
1591 BIT(NL80211_STA_INFO_TX_FAILED) |
1592 BIT(NL80211_STA_INFO_TX_BITRATE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001593
Leo Kim00c8dfc2015-10-29 12:05:30 +09001594 sinfo->signal = strStatistics.rssi;
Leo Kim9b992742015-10-29 12:05:32 +09001595 sinfo->rx_packets = strStatistics.rx_cnt;
Leo Kim54160372015-10-29 12:05:33 +09001596 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1597 sinfo->tx_failed = strStatistics.tx_fail_cnt;
Leo Kim5babeec2015-10-29 12:05:29 +09001598 sinfo->txrate.legacy = strStatistics.link_speed * 10;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001599
Leo Kim5babeec2015-10-29 12:05:29 +09001600 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1601 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001602 wilc_enable_tcp_ack_filter(true);
Leo Kim5babeec2015-10-29 12:05:29 +09001603 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001604 wilc_enable_tcp_ack_filter(false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001605
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001606 PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
1607 sinfo->tx_failed, sinfo->txrate.legacy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001608 }
Leo Kimaaed3292015-10-12 16:55:38 +09001609 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001610}
1611
1612
1613/**
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001614 * @brief change_bss
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001615 * @details Modify parameters for a given BSS.
1616 * @param[in]
1617 * -use_cts_prot: Whether to use CTS protection
1618 * (0 = no, 1 = yes, -1 = do not change)
1619 * -use_short_preamble: Whether the use of short preambles is allowed
1620 * (0 = no, 1 = yes, -1 = do not change)
1621 * -use_short_slot_time: Whether the use of short slot time is allowed
1622 * (0 = no, 1 = yes, -1 = do not change)
1623 * -basic_rates: basic rates in IEEE 802.11 format
1624 * (or NULL for no change)
1625 * -basic_rates_len: number of basic rates
1626 * -ap_isolate: do not forward packets between connected stations
1627 * -ht_opmode: HT Operation mode
1628 * (u16 = opmode, -1 = do not change)
1629 * @return int : Return 0 on Success.
1630 * @author mdaftedar
1631 * @date 01 MAR 2012
1632 * @version 1.0
1633 */
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001634static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1635 struct bss_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001636{
1637 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1638 return 0;
1639}
1640
1641/**
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001642 * @brief set_wiphy_params
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001643 * @details Notify that wiphy parameters have changed;
1644 * @param[in] Changed bitfield (see &enum wiphy_params_flags) describes which values
1645 * have changed.
1646 * @return int : Return 0 on Success
1647 * @author mdaftedar
1648 * @date 01 MAR 2012
1649 * @version 1.0
1650 */
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001651static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001652{
Leo Kime6e12662015-09-16 18:36:03 +09001653 s32 s32Error = 0;
Leo Kim95296502015-10-05 15:25:46 +09001654 struct cfg_param_val pstrCfgParamVal;
Chaehyun Lim27268872015-09-15 14:06:13 +09001655 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001656
1657 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001658
Tony Cho87c05b22015-10-12 16:56:07 +09001659 pstrCfgParamVal.flag = 0;
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301660 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001661
1662 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1663 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1664 priv->dev->ieee80211_ptr->wiphy->retry_short);
Tony Cho87c05b22015-10-12 16:56:07 +09001665 pstrCfgParamVal.flag |= RETRY_SHORT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001666 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1667 }
1668 if (changed & WIPHY_PARAM_RETRY_LONG) {
1669
1670 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_LONG %d\n", priv->dev->ieee80211_ptr->wiphy->retry_long);
Tony Cho87c05b22015-10-12 16:56:07 +09001671 pstrCfgParamVal.flag |= RETRY_LONG;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001672 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1673
1674 }
1675 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1676 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_FRAG_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->frag_threshold);
Tony Cho87c05b22015-10-12 16:56:07 +09001677 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001678 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1679
1680 }
1681
1682 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1683 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1684
Tony Cho87c05b22015-10-12 16:56:07 +09001685 pstrCfgParamVal.flag |= RTS_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001686 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1687
1688 }
1689
1690 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001691 s32Error = wilc_hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001692 if (s32Error)
1693 PRINT_ER("Error in setting WIPHY PARAMS\n");
1694
1695
1696 return s32Error;
1697}
Arnd Bergmanne5af0562015-05-29 22:52:12 +02001698
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001699/**
Chaehyun Lim4d466572015-09-14 12:24:22 +09001700 * @brief set_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001701 * @details Cache a PMKID for a BSSID. This is mostly useful for fullmac
1702 * devices running firmwares capable of generating the (re) association
1703 * RSN IE. It allows for faster roaming between WPA2 BSSIDs.
1704 * @param[in]
1705 * @return int : Return 0 on Success
1706 * @author mdaftedar
1707 * @date 01 MAR 2012
1708 * @version 1.0
1709 */
Chaehyun Lim4d466572015-09-14 12:24:22 +09001710static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1711 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001712{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001713 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001714 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001715 u8 flag = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001716
Chaehyun Lim27268872015-09-15 14:06:13 +09001717 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001718
1719 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1720
1721
1722 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001723 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001724 ETH_ALEN)) {
1725 /*If bssid already exists and pmkid value needs to reset*/
1726 flag = PMKID_FOUND;
1727 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1728 break;
1729 }
1730 }
1731 if (i < WILC_MAX_NUM_PMKIDS) {
1732 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001733 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001734 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001735 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001736 PMKID_LEN);
1737 if (!(flag == PMKID_FOUND))
1738 priv->pmkid_list.numpmkid++;
1739 } else {
1740 PRINT_ER("Invalid PMKID index\n");
1741 s32Error = -EINVAL;
1742 }
1743
1744 if (!s32Error) {
1745 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001746 s32Error = wilc_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001747 }
1748 return s32Error;
1749}
1750
1751/**
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001752 * @brief del_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001753 * @details Delete a cached PMKID.
1754 * @param[in]
1755 * @return int : Return 0 on Success
1756 * @author mdaftedar
1757 * @date 01 MAR 2012
1758 * @version 1.0
1759 */
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001760static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1761 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001762{
1763
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001764 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001765 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001766
Chaehyun Lim27268872015-09-15 14:06:13 +09001767 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001768
1769 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1770
1771 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001772 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001773 ETH_ALEN)) {
1774 /*If bssid is found, reset the values*/
1775 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
Leo Kimcd1e6cb2015-10-05 15:25:45 +09001776 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001777 break;
1778 }
1779 }
1780
1781 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1782 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001783 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001784 priv->pmkid_list.pmkidlist[i + 1].bssid,
1785 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001786 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001787 priv->pmkid_list.pmkidlist[i].pmkid,
1788 PMKID_LEN);
1789 }
1790 priv->pmkid_list.numpmkid--;
1791 } else {
1792 s32Error = -EINVAL;
1793 }
1794
1795 return s32Error;
1796}
1797
1798/**
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001799 * @brief flush_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001800 * @details Flush all cached PMKIDs.
1801 * @param[in]
1802 * @return int : Return 0 on Success
1803 * @author mdaftedar
1804 * @date 01 MAR 2012
1805 * @version 1.0
1806 */
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001807static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001808{
Chaehyun Lim27268872015-09-15 14:06:13 +09001809 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001810
1811 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
1812
1813 /*Get cashed Pmkids and set all with zeros*/
Leo Kima949f902015-10-05 15:25:44 +09001814 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001815
1816 return 0;
1817}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001818
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001819
1820/**
1821 * @brief WILC_WFI_CfgParseRxAction
1822 * @details Function parses the received frames and modifies the following attributes:
1823 * -GO Intent
1824 * -Channel list
1825 * -Operating Channel
1826 *
1827 * @param[in] u8* Buffer, u32 length
1828 * @return NONE.
1829 * @author mdaftedar
1830 * @date 12 DEC 2012
1831 * @version
1832 */
1833
Arnd Bergmann1608c402015-11-16 15:04:53 +01001834static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001835{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001836 u32 index = 0;
1837 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001838
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001839 u8 op_channel_attr_index = 0;
1840 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001841
1842 while (index < len) {
1843 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001844 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001845 }
1846
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301847 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001848 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301849 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001850 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001851 index += buf[index + 1] + 3; /* ID,Length byte */
1852 }
Leo Kim0bd82742015-11-19 15:56:14 +09001853 if (wlan_channel != INVALID_CHANNEL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001854 /*Modify channel list attribute*/
1855 if (channel_list_attr_index) {
1856 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1857 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1858 if (buf[i] == 0x51) {
1859 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
Leo Kim0bd82742015-11-19 15:56:14 +09001860 buf[j] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001861 }
1862 break;
1863 }
1864 }
1865 }
1866 /*Modify operating channel attribute*/
1867 if (op_channel_attr_index) {
1868 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1869 buf[op_channel_attr_index + 6] = 0x51;
Leo Kim0bd82742015-11-19 15:56:14 +09001870 buf[op_channel_attr_index + 7] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001871 }
1872 }
1873}
1874
1875/**
1876 * @brief WILC_WFI_CfgParseTxAction
1877 * @details Function parses the transmitted action frames and modifies the
1878 * GO Intent attribute
1879 * @param[in] u8* Buffer, u32 length, bool bOperChan, u8 iftype
1880 * @return NONE.
1881 * @author mdaftedar
1882 * @date 12 DEC 2012
1883 * @version
1884 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01001885static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001886{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001887 u32 index = 0;
1888 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001889
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001890 u8 op_channel_attr_index = 0;
1891 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001892
1893 while (index < len) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001894 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001895 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001896
1897 break;
1898 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001899
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301900 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001901 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301902 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001903 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001904 index += buf[index + 1] + 3; /* ID,Length byte */
1905 }
Leo Kim0bd82742015-11-19 15:56:14 +09001906 if (wlan_channel != INVALID_CHANNEL && bOperChan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001907 /*Modify channel list attribute*/
1908 if (channel_list_attr_index) {
1909 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1910 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1911 if (buf[i] == 0x51) {
1912 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
Leo Kim0bd82742015-11-19 15:56:14 +09001913 buf[j] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001914 }
1915 break;
1916 }
1917 }
1918 }
1919 /*Modify operating channel attribute*/
1920 if (op_channel_attr_index) {
1921 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1922 buf[op_channel_attr_index + 6] = 0x51;
Leo Kim0bd82742015-11-19 15:56:14 +09001923 buf[op_channel_attr_index + 7] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001924 }
1925 }
1926}
1927
1928/* @brief WILC_WFI_p2p_rx
1929 * @details
1930 * @param[in]
1931 *
1932 * @return None
1933 * @author Mai Daftedar
1934 * @date 2 JUN 2013
1935 * @version 1.0
1936 */
1937
Chaehyun Limfbc2fe12015-09-15 14:06:16 +09001938void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001939{
1940
Chaehyun Lim27268872015-09-15 14:06:13 +09001941 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001942 u32 header, pkt_offset;
Leo Kim441dc602015-10-12 16:55:35 +09001943 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001944 u32 i = 0;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001945 s32 s32Freq;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001946
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001947 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001948 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001949
1950 /* Get WILC header */
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001951 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001952
1953 /* The packet offset field conain info about what type of managment frame */
1954 /* we are dealing with and ack status */
1955 pkt_offset = GET_PKT_OFFSET(header);
1956
1957 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1958 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1959 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001960 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001961 return;
1962 } else {
1963 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
1964 PRINT_D(GENERIC_DBG, "Success Ack - Action frame category: %x Action Subtype: %d Dialog T: %x OR %x\n", buff[ACTION_CAT_ID], buff[ACTION_SUBTYPE_ID],
1965 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001966 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001967 } else {
1968 PRINT_D(GENERIC_DBG, "Fail Ack - Action frame category: %x Action Subtype: %d Dialog T: %x OR %x\n", buff[ACTION_CAT_ID], buff[ACTION_SUBTYPE_ID],
1969 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001970 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001971 }
1972 return;
1973 }
1974 } else {
1975
1976 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
1977
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001978 /*Upper layer is informed that the frame is received on this freq*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001979 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001980
1981 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1982 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
1983
Leo Kim1229b1a2015-10-29 12:05:39 +09001984 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001985 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
1986 return;
1987 }
1988 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1989
1990 switch (buff[ACTION_SUBTYPE_ID]) {
1991 case GAS_INTIAL_REQ:
1992 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
1993 break;
1994
1995 case GAS_INTIAL_RSP:
1996 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
1997 break;
1998
1999 case PUBLIC_ACT_VENDORSPEC:
Leo Kim881eb5d2015-11-19 15:56:15 +09002000 if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002001 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
Leo Kima25d5182015-11-19 15:56:19 +09002002 if (!wilc_ie) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002003 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
Leo Kim86685942015-11-19 15:56:18 +09002004 if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002005 p2p_recv_random = buff[i + 6];
Leo Kima25d5182015-11-19 15:56:19 +09002006 wilc_ie = true;
Leo Kimb84a3ac2015-11-19 15:56:17 +09002007 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", p2p_recv_random);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002008 break;
2009 }
2010 }
2011 }
2012 }
Leo Kimb84a3ac2015-11-19 15:56:17 +09002013 if (p2p_local_random > p2p_recv_random) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002014 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2015 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2016 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
Leo Kim881eb5d2015-11-19 15:56:15 +09002017 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002018 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
2019 break;
2020 }
2021 }
2022 }
Leo Kim583d9722015-11-19 15:56:16 +09002023 } else {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002024 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 +09002025 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002026 }
2027
2028
Leo Kima25d5182015-11-19 15:56:19 +09002029 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 +09002030 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
2031 /* extra attribute for sig_dbm: signal strength in mBm, or 0 if unknown */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002032 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002033 return;
2034 }
2035 break;
2036
2037 default:
2038 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
2039 break;
2040 }
2041 }
2042 }
2043
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002044 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002045 }
2046}
2047
2048/**
2049 * @brief WILC_WFI_mgmt_tx_complete
2050 * @details Returns result of writing mgmt frame to VMM (Tx buffers are freed here)
2051 * @param[in] priv
2052 * transmitting status
2053 * @return None
2054 * @author Amr Abdelmoghny
2055 * @date 20 MAY 2013
2056 * @version 1.0
2057 */
2058static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
2059{
2060 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
2061
2062
2063 kfree(pv_data->buff);
2064 kfree(pv_data);
2065}
2066
2067/**
2068 * @brief WILC_WFI_RemainOnChannelReady
2069 * @details Callback function, called from handle_remain_on_channel on being ready on channel
2070 * @param
2071 * @return none
2072 * @author Amr abdelmoghny
2073 * @date 9 JUNE 2013
2074 * @version
2075 */
2076
2077static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
2078{
Chaehyun Lim27268872015-09-15 14:06:13 +09002079 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002080
Chaehyun Lim27268872015-09-15 14:06:13 +09002081 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002082
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302083 PRINT_D(HOSTINF_DBG, "Remain on channel ready\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002084
Dean Lee72ed4dc2015-06-12 14:11:44 +09002085 priv->bInP2PlistenState = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002086
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002087 cfg80211_ready_on_channel(priv->wdev,
2088 priv->strRemainOnChanParams.u64ListenCookie,
2089 priv->strRemainOnChanParams.pstrListenChan,
2090 priv->strRemainOnChanParams.u32ListenDuration,
2091 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002092}
2093
2094/**
2095 * @brief WILC_WFI_RemainOnChannelExpired
2096 * @details Callback function, called on expiration of remain-on-channel duration
2097 * @param
2098 * @return none
2099 * @author Amr abdelmoghny
2100 * @date 15 MAY 2013
2101 * @version
2102 */
2103
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002104static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002105{
Chaehyun Lim27268872015-09-15 14:06:13 +09002106 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002107
Chaehyun Lim27268872015-09-15 14:06:13 +09002108 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002109
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002110 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302111 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002112
Dean Lee72ed4dc2015-06-12 14:11:44 +09002113 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002114
2115 /*Inform wpas of remain-on-channel expiration*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002116 cfg80211_remain_on_channel_expired(priv->wdev,
2117 priv->strRemainOnChanParams.u64ListenCookie,
2118 priv->strRemainOnChanParams.pstrListenChan,
2119 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002120 } else {
2121 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
2122 , priv->strRemainOnChanParams.u32ListenSessionID);
2123 }
2124}
2125
2126
2127/**
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002128 * @brief remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002129 * @details Request the driver to remain awake on the specified
2130 * channel for the specified duration to complete an off-channel
2131 * operation (e.g., public action frame exchange). When the driver is
2132 * ready on the requested channel, it must indicate this with an event
2133 * notification by calling cfg80211_ready_on_channel().
2134 * @param[in]
2135 * @return int : Return 0 on Success
2136 * @author mdaftedar
2137 * @date 01 MAR 2012
2138 * @version 1.0
2139 */
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002140static int remain_on_channel(struct wiphy *wiphy,
2141 struct wireless_dev *wdev,
2142 struct ieee80211_channel *chan,
2143 unsigned int duration, u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002144{
Leo Kime6e12662015-09-16 18:36:03 +09002145 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002146 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002147
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002148 priv = wiphy_priv(wiphy);
2149
2150 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
2151
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002152
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002153 if (wdev->iftype == NL80211_IFTYPE_AP) {
2154 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
2155 return s32Error;
2156 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002157
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002158 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002159
2160 /*Setting params needed by WILC_WFI_RemainOnChannelExpired()*/
2161 priv->strRemainOnChanParams.pstrListenChan = chan;
2162 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002163 priv->strRemainOnChanParams.u32ListenDuration = duration;
2164 priv->strRemainOnChanParams.u32ListenSessionID++;
2165
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002166 s32Error = wilc_remain_on_channel(priv->hWILCWFIDrv
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002167 , priv->strRemainOnChanParams.u32ListenSessionID
2168 , duration
2169 , chan->hw_value
2170 , WILC_WFI_RemainOnChannelExpired
2171 , WILC_WFI_RemainOnChannelReady
2172 , (void *)priv);
2173
2174 return s32Error;
2175}
2176
2177/**
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002178 * @brief cancel_remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002179 * @details Cancel an on-going remain-on-channel operation.
2180 * This allows the operation to be terminated prior to timeout based on
2181 * the duration value.
2182 * @param[in] struct wiphy *wiphy,
2183 * @param[in] struct net_device *dev
2184 * @param[in] u64 cookie,
2185 * @return int : Return 0 on Success
2186 * @author mdaftedar
2187 * @date 01 MAR 2012
2188 * @version 1.0
2189 */
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002190static int cancel_remain_on_channel(struct wiphy *wiphy,
2191 struct wireless_dev *wdev,
2192 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002193{
Leo Kime6e12662015-09-16 18:36:03 +09002194 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002195 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002196
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002197 priv = wiphy_priv(wiphy);
2198
2199 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
2200
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002201 s32Error = wilc_listen_state_expired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002202 return s32Error;
2203}
2204/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002205 * @brief WILC_WFI_mgmt_tx_frame
2206 * @details
2207 *
2208 * @param[in]
2209 * @return NONE.
2210 * @author mdaftedar
2211 * @date 01 JUL 2012
2212 * @version
2213 */
Chaehyun Limc1560322015-09-22 18:34:51 +09002214static int mgmt_tx(struct wiphy *wiphy,
2215 struct wireless_dev *wdev,
2216 struct cfg80211_mgmt_tx_params *params,
2217 u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002218{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002219 struct ieee80211_channel *chan = params->chan;
2220 unsigned int wait = params->wait;
2221 const u8 *buf = params->buf;
2222 size_t len = params->len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002223 const struct ieee80211_mgmt *mgmt;
2224 struct p2p_mgmt_data *mgmt_tx;
Chaehyun Lim27268872015-09-15 14:06:13 +09002225 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002226 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002227 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002228 perInterface_wlan_t *nic;
Leo Kim86685942015-11-19 15:56:18 +09002229 u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002230
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002231 nic = netdev_priv(wdev->netdev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002232 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002233 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002234
2235 *cookie = (unsigned long)buf;
2236 priv->u64tx_cookie = *cookie;
2237 mgmt = (const struct ieee80211_mgmt *) buf;
2238
2239 if (ieee80211_is_mgmt(mgmt->frame_control)) {
2240
2241 /*mgmt frame allocation*/
Glen Leef3052582015-09-10 12:03:04 +09002242 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002243 if (mgmt_tx == NULL) {
2244 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
Leo Kime6e12662015-09-16 18:36:03 +09002245 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002246 }
Glen Leef3052582015-09-10 12:03:04 +09002247 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002248 if (mgmt_tx->buff == NULL) {
2249 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
Tony Chof638dd32015-09-07 19:09:31 +09002250 kfree(mgmt_tx);
Leo Kime6e12662015-09-16 18:36:03 +09002251 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002252 }
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09002253 memcpy(mgmt_tx->buff, buf, len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002254 mgmt_tx->size = len;
2255
2256
2257 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
2258 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
2259 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002260 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002261 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002262 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002263 } else if (ieee80211_is_action(mgmt->frame_control)) {
Chaehyun Limd85f5322015-06-11 14:35:54 +09002264 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002265
2266
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002267 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002268 /*Only set the channel, if not a negotiation confirmation frame
2269 * (If Negotiation confirmation frame, force it
2270 * to be transmitted on the same negotiation channel)*/
2271
2272 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
2273 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
2274 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002275 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002276 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002277 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002278 }
2279 switch (buf[ACTION_SUBTYPE_ID]) {
2280 case GAS_INTIAL_REQ:
2281 {
2282 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
2283 break;
2284 }
2285
2286 case GAS_INTIAL_RSP:
2287 {
2288 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
2289 break;
2290 }
2291
2292 case PUBLIC_ACT_VENDORSPEC:
2293 {
Leo Kim881eb5d2015-11-19 15:56:15 +09002294 if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002295 /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/
2296 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002297 if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
Leo Kim583d9722015-11-19 15:56:16 +09002298 get_random_bytes(&p2p_local_random, 1);
2299 p2p_local_random++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002300 }
2301 }
2302
2303 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2304 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002305 if (p2p_local_random > p2p_recv_random) {
2306 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 +09002307
2308 /*Search for the p2p information information element , after the Public action subtype theres a byte for teh dialog token, skip that*/
2309 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
Leo Kim881eb5d2015-11-19 15:56:15 +09002310 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002311 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
Dean Lee72ed4dc2015-06-12 14:11:44 +09002312 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002313
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002314 /*If using supplicant go intent, no need at all*/
2315 /*to parse transmitted negotiation frames*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002316 else
Dean Lee72ed4dc2015-06-12 14:11:44 +09002317 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002318 break;
2319 }
2320 }
2321
2322 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
Shivani Bhardwajd8060fc2015-10-29 00:30:01 +05302323 /*
2324 * Adding WILC information element to allow two WILC devices to
2325 * identify each other and connect
2326 */
Leo Kim86685942015-11-19 15:56:18 +09002327 memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
2328 mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002329 mgmt_tx->size = buf_len;
2330 }
Leo Kim583d9722015-11-19 15:56:16 +09002331 } else {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002332 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 +09002333 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002334 }
2335
2336 } else {
2337 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
2338 }
2339
2340 break;
2341 }
2342
2343 default:
2344 {
2345 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
2346 break;
2347 }
2348 }
2349
2350 }
2351
2352 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 +09002353 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002354
Leo Kim1229b1a2015-10-29 12:05:39 +09002355 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n",
2356 jiffies, pstrWFIDrv->p2p_timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002357 }
2358
Glen Lee829c4772015-10-29 12:18:44 +09002359 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
2360 mgmt_tx->buff, mgmt_tx->size,
Glen Leec9d48342015-10-01 16:03:43 +09002361 WILC_WFI_mgmt_tx_complete);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002362 } else {
2363 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
2364 }
Leo Kimaaed3292015-10-12 16:55:38 +09002365 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002366}
2367
Chaehyun Lim85c587a2015-09-22 18:34:50 +09002368static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
2369 struct wireless_dev *wdev,
2370 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002371{
Chaehyun Lim27268872015-09-15 14:06:13 +09002372 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002373 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002374
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002375 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002376 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002377
2378
2379 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
Leo Kim1229b1a2015-10-29 12:05:39 +09002380 pstrWFIDrv->p2p_timeout = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002381
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +01002382 if (!priv->bInP2PlistenState) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002383 cfg80211_remain_on_channel_expired(priv->wdev,
2384 priv->strRemainOnChanParams.u64ListenCookie,
2385 priv->strRemainOnChanParams.pstrListenChan,
2386 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002387 }
2388
2389 return 0;
2390}
2391
2392/**
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002393 * @brief wilc_mgmt_frame_register
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002394 * @details Notify driver that a management frame type was
2395 * registered. Note that this callback may not sleep, and cannot run
2396 * concurrently with itself.
2397 * @param[in]
2398 * @return NONE.
2399 * @author mdaftedar
2400 * @date 01 JUL 2012
2401 * @version
2402 */
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002403void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
2404 u16 frame_type, bool reg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002405{
2406
Chaehyun Lim27268872015-09-15 14:06:13 +09002407 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002408 perInterface_wlan_t *nic;
Glen Lee1b869352015-10-20 17:14:01 +09002409 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002410
2411 priv = wiphy_priv(wiphy);
2412 nic = netdev_priv(priv->wdev->netdev);
Glen Lee1b869352015-10-20 17:14:01 +09002413 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002414
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002415 if (!frame_type)
2416 return;
2417
2418 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
2419 switch (frame_type) {
2420 case PROBE_REQ:
2421 {
2422 nic->g_struct_frame_reg[0].frame_type = frame_type;
2423 nic->g_struct_frame_reg[0].reg = reg;
2424 }
2425 break;
2426
2427 case ACTION:
2428 {
2429 nic->g_struct_frame_reg[1].frame_type = frame_type;
2430 nic->g_struct_frame_reg[1].reg = reg;
2431 }
2432 break;
2433
2434 default:
2435 {
2436 break;
2437 }
2438
2439 }
2440 /*If mac is closed, then return*/
Glen Lee1b869352015-10-20 17:14:01 +09002441 if (!wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002442 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
2443 return;
2444 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002445 wilc_frame_register(priv->hWILCWFIDrv, frame_type, reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002446
2447
2448}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002449
2450/**
Chaehyun Lima8047e22015-09-22 18:34:48 +09002451 * @brief set_cqm_rssi_config
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002452 * @details Configure connection quality monitor RSSI threshold.
2453 * @param[in] struct wiphy *wiphy:
2454 * @param[in] struct net_device *dev:
2455 * @param[in] s32 rssi_thold:
2456 * @param[in] u32 rssi_hyst:
2457 * @return int : Return 0 on Success
2458 * @author mdaftedar
2459 * @date 01 MAR 2012
2460 * @version 1.0
2461 */
Chaehyun Lima8047e22015-09-22 18:34:48 +09002462static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
2463 s32 rssi_thold, u32 rssi_hyst)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002464{
2465 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2466 return 0;
2467
2468}
2469/**
Chaehyun Limbdb63382015-09-14 12:24:19 +09002470 * @brief dump_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002471 * @details Configure connection quality monitor RSSI threshold.
2472 * @param[in] struct wiphy *wiphy:
2473 * @param[in] struct net_device *dev
2474 * @param[in] int idx
2475 * @param[in] u8 *mac
2476 * @param[in] struct station_info *sinfo
2477 * @return int : Return 0 on Success
2478 * @author mdaftedar
2479 * @date 01 MAR 2012
2480 * @version 1.0
2481 */
Chaehyun Limbdb63382015-09-14 12:24:19 +09002482static int dump_station(struct wiphy *wiphy, struct net_device *dev,
2483 int idx, u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002484{
Chaehyun Lim27268872015-09-15 14:06:13 +09002485 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002486
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002487 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2488
2489 if (idx != 0)
2490 return -ENOENT;
2491
2492 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002493
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002494 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002495
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002496 wilc_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002497
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002498 return 0;
2499
2500}
2501
2502
2503/**
Chaehyun Lim46530672015-09-22 18:34:46 +09002504 * @brief set_power_mgmt
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002505 * @details
2506 * @param[in]
2507 * @return int : Return 0 on Success.
2508 * @author mdaftedar
2509 * @date 01 JUL 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09002510 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002511 */
Chaehyun Lim46530672015-09-22 18:34:46 +09002512static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2513 bool enabled, int timeout)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002514{
Chaehyun Lim27268872015-09-15 14:06:13 +09002515 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002516
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002517 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2518
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002519 if (wiphy == NULL)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002520 return -ENOENT;
2521
2522 priv = wiphy_priv(wiphy);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002523 if (priv->hWILCWFIDrv == NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002524 PRINT_ER("Driver is NULL\n");
2525 return -EIO;
2526 }
2527
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002528 if (wilc_enable_ps)
2529 wilc_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002530
2531
Leo Kime6e12662015-09-16 18:36:03 +09002532 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002533
2534}
Glen Lee108b3432015-09-16 18:53:20 +09002535
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002536/**
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002537 * @brief change_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002538 * @details Change type/configuration of virtual interface,
2539 * keep the struct wireless_dev's iftype updated.
2540 * @param[in] NONE
2541 * @return int : Return 0 on Success.
2542 * @author mdaftedar
2543 * @date 01 MAR 2012
2544 * @version 1.0
2545 */
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002546static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2547 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002548{
Chaehyun Lim27268872015-09-15 14:06:13 +09002549 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002550 perInterface_wlan_t *nic;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002551 u8 interface_type;
Chaehyun Limd85f5322015-06-11 14:35:54 +09002552 u16 TID = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002553 u8 i;
Glen Lee299382c2015-10-20 17:13:56 +09002554 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002555
2556 nic = netdev_priv(dev);
2557 priv = wiphy_priv(wiphy);
Glen Lee299382c2015-10-20 17:13:56 +09002558 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002559
2560 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2561 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
Leo Kim583d9722015-11-19 15:56:16 +09002562 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +09002563 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +09002564 wilc_ie = false;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002565 wilc_optaining_ip = false;
2566 del_timer(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002567 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002568 /*Set WILC_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/
2569 if (g_ptk_keys_saved && g_gtk_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002570 wilc_set_machw_change_vir_if(dev, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002571 }
2572
2573 switch (type) {
2574 case NL80211_IFTYPE_STATION:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002575 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002576 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002577
2578 /* send delba over wlan interface */
2579
2580
2581 dev->ieee80211_ptr->iftype = type;
2582 priv->wdev->iftype = type;
2583 nic->monitor_flag = 0;
2584 nic->iftype = STATION_MODE;
2585
2586 /*Remove the enteries of the previously connected clients*/
2587 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002588 interface_type = nic->iftype;
2589 nic->iftype = STATION_MODE;
2590
Glen Lee299382c2015-10-20 17:13:56 +09002591 if (wl->initialized) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002592 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2593 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002594 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002595 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002596
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002597 /*Eliminate host interface blocking state*/
Glen Lee299382c2015-10-20 17:13:56 +09002598 up(&wl->cfg_event);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002599
Glen Lee53dc0cf2015-10-20 17:13:57 +09002600 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002601 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002602 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002603 nic->iftype = interface_type;
2604
2605 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002606 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2607 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002608 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002609 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002610
2611 /*Add saved WEP keys, if any*/
2612 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002613 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002614 g_key_wep_params.key_idx);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002615 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002616 g_key_wep_params.key,
2617 g_key_wep_params.key_len,
2618 g_key_wep_params.key_idx);
2619 }
2620
2621 /*No matter the driver handler passed here, it will be overwriiten*/
2622 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002623 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002624
2625 /*Add saved PTK and GTK keys, if any*/
2626 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2627 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2628 g_key_ptk_params.key[1],
2629 g_key_ptk_params.key[2]);
2630 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2631 g_key_gtk_params.key[1],
2632 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002633 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2634 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002635 g_add_ptk_key_params.key_idx,
2636 g_add_ptk_key_params.pairwise,
2637 g_add_ptk_key_params.mac_addr,
2638 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002639
Glen Lee299382c2015-10-20 17:13:56 +09002640 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2641 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002642 g_add_gtk_key_params.key_idx,
2643 g_add_gtk_key_params.pairwise,
2644 g_add_gtk_key_params.mac_addr,
2645 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002646 }
2647
Glen Lee299382c2015-10-20 17:13:56 +09002648 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002649 for (i = 0; i < num_reg_frame; i++) {
2650 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2651 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002652 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002653 nic->g_struct_frame_reg[i].frame_type,
2654 nic->g_struct_frame_reg[i].reg);
2655 }
2656 }
2657
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002658 wilc_enable_ps = true;
2659 wilc_set_power_mgmt(priv->hWILCWFIDrv, 1, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002660 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002661 break;
2662
2663 case NL80211_IFTYPE_P2P_CLIENT:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002664 wilc_enable_ps = false;
2665 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
2666 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002667 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002668
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002669 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2670 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002671
2672 dev->ieee80211_ptr->iftype = type;
2673 priv->wdev->iftype = type;
2674 nic->monitor_flag = 0;
2675
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002676 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2677 nic->iftype = CLIENT_MODE;
2678
2679
Glen Lee299382c2015-10-20 17:13:56 +09002680 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002681 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002682 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002683
Glen Lee53dc0cf2015-10-20 17:13:57 +09002684 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002685 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002686 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002687
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002688 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2689 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002690 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002691 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002692
2693 /*Add saved WEP keys, if any*/
2694 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002695 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2696 g_key_wep_params.key_idx);
2697 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
2698 g_key_wep_params.key,
2699 g_key_wep_params.key_len,
2700 g_key_wep_params.key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002701 }
2702
2703 /*No matter the driver handler passed here, it will be overwriiten*/
2704 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002705 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002706
2707 /*Add saved PTK and GTK keys, if any*/
2708 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2709 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2710 g_key_ptk_params.key[1],
2711 g_key_ptk_params.key[2]);
2712 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2713 g_key_gtk_params.key[1],
2714 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002715 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2716 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002717 g_add_ptk_key_params.key_idx,
2718 g_add_ptk_key_params.pairwise,
2719 g_add_ptk_key_params.mac_addr,
2720 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002721
Glen Lee299382c2015-10-20 17:13:56 +09002722 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2723 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002724 g_add_gtk_key_params.key_idx,
2725 g_add_gtk_key_params.pairwise,
2726 g_add_gtk_key_params.mac_addr,
2727 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002728 }
2729
2730 /*Refresh scan, to refresh the scan results to the wpa_supplicant. Set MachHw to false to enable further key installments*/
Dean Lee72ed4dc2015-06-12 14:11:44 +09002731 refresh_scan(priv, 1, true);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002732 wilc_set_machw_change_vir_if(dev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002733
Glen Lee299382c2015-10-20 17:13:56 +09002734 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002735 for (i = 0; i < num_reg_frame; i++) {
2736 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2737 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002738 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002739 nic->g_struct_frame_reg[i].frame_type,
2740 nic->g_struct_frame_reg[i].reg);
2741 }
2742 }
2743 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002744 break;
2745
2746 case NL80211_IFTYPE_AP:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002747 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002748 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002749 dev->ieee80211_ptr->iftype = type;
2750 priv->wdev->iftype = type;
2751 nic->iftype = AP_MODE;
Johnny Kim8a143302015-06-10 17:06:46 +09002752 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002753
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002754 PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002755 wilc_wlan_get_firmware(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002756 /*If wilc is running, then close-open to actually get new firmware running (serves P2P)*/
Glen Lee299382c2015-10-20 17:13:56 +09002757 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002758 nic->iftype = AP_MODE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002759 wilc_mac_close(dev);
2760 wilc_mac_open(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002761
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002762 for (i = 0; i < num_reg_frame; i++) {
2763 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2764 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002765 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002766 nic->g_struct_frame_reg[i].frame_type,
2767 nic->g_struct_frame_reg[i].reg);
2768 }
2769 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002770 break;
2771
2772 case NL80211_IFTYPE_P2P_GO:
2773 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
2774
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002775 wilc_optaining_ip = true;
Leo Kim7e872df2015-11-19 15:56:20 +09002776 mod_timer(&wilc_during_ip_timer,
2777 jiffies + msecs_to_jiffies(during_ip_time));
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002778 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002779 /*Delete block ack has to be the latest config packet*/
2780 /*sent before downloading new FW. This is because it blocks on*/
2781 /*hWaitResponse semaphore, which allows previous config*/
2782 /*packets to actually take action on old FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002783 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2784 wl->vif[0].bssid, TID);
2785 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002786 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002787 dev->ieee80211_ptr->iftype = type;
2788 priv->wdev->iftype = type;
2789
Johnny Kim8a143302015-06-10 17:06:46 +09002790 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002791
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002792 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2793
2794
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002795 nic->iftype = GO_MODE;
2796
2797 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002798 wilc_wait_msg_queue_idle();
Glen Lee53dc0cf2015-10-20 17:13:57 +09002799 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002800 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002801 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002802
2803
2804 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002805 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2806 wilc_set_mac_address(wl->vif[0].hif_drv,
2807 wl->vif[0].src_addr);
2808 wilc_set_operation_mode(priv->hWILCWFIDrv, AP_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002809
2810 /*Add saved WEP keys, if any*/
2811 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002812 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2813 g_key_wep_params.key_idx);
2814 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002815 g_key_wep_params.key,
2816 g_key_wep_params.key_len,
2817 g_key_wep_params.key_idx);
2818 }
2819
2820 /*No matter the driver handler passed here, it will be overwriiten*/
2821 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002822 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002823
2824 /*Add saved PTK and GTK keys, if any*/
2825 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2826 PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0],
2827 g_key_ptk_params.key[1],
2828 g_key_ptk_params.key[2],
2829 g_key_ptk_params.cipher);
2830 PRINT_D(CFG80211_DBG, "gtk %x %x %x cipher %x\n", g_key_gtk_params.key[0],
2831 g_key_gtk_params.key[1],
2832 g_key_gtk_params.key[2],
2833 g_key_gtk_params.cipher);
Glen Lee299382c2015-10-20 17:13:56 +09002834 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2835 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002836 g_add_ptk_key_params.key_idx,
2837 g_add_ptk_key_params.pairwise,
2838 g_add_ptk_key_params.mac_addr,
2839 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002840
Glen Lee299382c2015-10-20 17:13:56 +09002841 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2842 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002843 g_add_gtk_key_params.key_idx,
2844 g_add_gtk_key_params.pairwise,
2845 g_add_gtk_key_params.mac_addr,
2846 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002847 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002848
Glen Lee299382c2015-10-20 17:13:56 +09002849 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002850 for (i = 0; i < num_reg_frame; i++) {
2851 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2852 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002853 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002854 nic->g_struct_frame_reg[i].frame_type,
2855 nic->g_struct_frame_reg[i].reg);
2856 }
2857 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002858 break;
2859
2860 default:
2861 PRINT_ER("Unknown interface type= %d\n", type);
Leo Kimaaed3292015-10-12 16:55:38 +09002862 return -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002863 }
2864
Leo Kimaaed3292015-10-12 16:55:38 +09002865 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002866}
2867
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002868/* (austin.2013-07-23)
2869 *
2870 * To support revised cfg80211_ops
2871 *
2872 * add_beacon --> start_ap
2873 * set_beacon --> change_beacon
2874 * del_beacon --> stop_ap
2875 *
2876 * beacon_parameters --> cfg80211_ap_settings
2877 * cfg80211_beacon_data
2878 *
2879 * applicable for linux kernel 3.4+
2880 */
2881
2882/**
Chaehyun Lima13168d2015-09-14 12:24:12 +09002883 * @brief start_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002884 * @details Add a beacon with given parameters, @head, @interval
2885 * and @dtim_period will be valid, @tail is optional.
2886 * @param[in] wiphy
2887 * @param[in] dev The net device structure
2888 * @param[in] settings cfg80211_ap_settings parameters for the beacon to be added
2889 * @return int : Return 0 on Success.
2890 * @author austin
2891 * @date 23 JUL 2013
2892 * @version 1.0
2893 */
Chaehyun Lima13168d2015-09-14 12:24:12 +09002894static int start_ap(struct wiphy *wiphy, struct net_device *dev,
2895 struct cfg80211_ap_settings *settings)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002896{
2897 struct cfg80211_beacon_data *beacon = &(settings->beacon);
Chaehyun Lim27268872015-09-15 14:06:13 +09002898 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002899 s32 s32Error = 0;
Glen Lee684dc182015-10-20 17:14:02 +09002900 struct wilc *wl;
2901 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002902
2903 priv = wiphy_priv(wiphy);
Glen Lee684dc182015-10-20 17:14:02 +09002904 nic = netdev_priv(dev);
2905 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002906 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
2907
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302908 PRINT_D(HOSTAPD_DBG, "Interval = %d\n DTIM period = %d\n Head length = %zu Tail length = %zu\n",
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002909 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
2910
Chaehyun Lim80785a92015-09-14 12:24:01 +09002911 s32Error = set_channel(wiphy, &settings->chandef);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002912
Leo Kime6e12662015-09-16 18:36:03 +09002913 if (s32Error != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002914 PRINT_ER("Error in setting channel\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002915
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002916 wilc_wlan_set_bssid(dev, wl->vif[0].src_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002917
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002918 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002919 settings->beacon_interval,
2920 settings->dtim_period,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002921 beacon->head_len, (u8 *)beacon->head,
2922 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002923
2924 return s32Error;
2925}
2926
2927/**
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002928 * @brief change_beacon
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002929 * @details Add a beacon with given parameters, @head, @interval
2930 * and @dtim_period will be valid, @tail is optional.
2931 * @param[in] wiphy
2932 * @param[in] dev The net device structure
2933 * @param[in] beacon cfg80211_beacon_data for the beacon to be changed
2934 * @return int : Return 0 on Success.
2935 * @author austin
2936 * @date 23 JUL 2013
2937 * @version 1.0
2938 */
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002939static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
2940 struct cfg80211_beacon_data *beacon)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002941{
Chaehyun Lim27268872015-09-15 14:06:13 +09002942 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002943 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002944
2945 priv = wiphy_priv(wiphy);
2946 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
2947
2948
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002949 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002950 0,
2951 0,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002952 beacon->head_len, (u8 *)beacon->head,
2953 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002954
2955 return s32Error;
2956}
2957
2958/**
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002959 * @brief stop_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002960 * @details Remove beacon configuration and stop sending the beacon.
2961 * @param[in]
2962 * @return int : Return 0 on Success.
2963 * @author austin
2964 * @date 23 JUL 2013
2965 * @version 1.0
2966 */
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002967static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002968{
Leo Kime6e12662015-09-16 18:36:03 +09002969 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002970 struct wilc_priv *priv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002971 u8 NullBssid[ETH_ALEN] = {0};
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002972
Leo Kim7ae43362015-09-16 18:35:59 +09002973 if (!wiphy)
2974 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002975
2976 priv = wiphy_priv(wiphy);
2977
2978 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
2979
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002980 wilc_wlan_set_bssid(dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002981
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002982 s32Error = wilc_del_beacon(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002983
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002984 if (s32Error)
2985 PRINT_ER("Host delete beacon fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002986
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002987 return s32Error;
2988}
2989
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002990/**
Chaehyun Limed269552015-09-14 12:24:15 +09002991 * @brief add_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002992 * @details Add a new station.
2993 * @param[in]
2994 * @return int : Return 0 on Success.
2995 * @author mdaftedar
2996 * @date 01 MAR 2012
2997 * @version 1.0
2998 */
Chaehyun Limed269552015-09-14 12:24:15 +09002999static int add_station(struct wiphy *wiphy, struct net_device *dev,
3000 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003001{
Leo Kime6e12662015-09-16 18:36:03 +09003002 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003003 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09003004 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003005 perInterface_wlan_t *nic;
3006
Leo Kim7ae43362015-09-16 18:35:59 +09003007 if (!wiphy)
3008 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003009
3010 priv = wiphy_priv(wiphy);
3011 nic = netdev_priv(dev);
3012
3013 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003014 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09003015 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003016 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003017 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003018 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003019
3020 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
3021
3022 PRINT_D(CFG80211_DBG, "BSSID = %x%x%x%x%x%x\n", priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][0], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][1], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][2], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][3], priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][4],
3023 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003024 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003025 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3026 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003027
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003028 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003029 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003030 } else {
Leo Kim22520122015-10-29 12:05:45 +09003031 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003032 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003033 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003034 memcpy(strStaParams.ht_supp_mcs_set,
3035 &params->ht_capa->mcs,
3036 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003037 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003038 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003039 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003040 }
3041
Leo Kimf676e172015-10-29 12:05:52 +09003042 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003043 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003044
Leo Kim22520122015-10-29 12:05:45 +09003045 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3046 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003047 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3048 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003049 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3050 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003051 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3052 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003053 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3054 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003055 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3056 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003057 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3058 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003059 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3060 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003061
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003062 s32Error = wilc_add_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003063 if (s32Error)
3064 PRINT_ER("Host add station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003065 }
3066
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003067 return s32Error;
3068}
3069
3070/**
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003071 * @brief del_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003072 * @details Remove a station; @mac may be NULL to remove all stations.
3073 * @param[in]
3074 * @return int : Return 0 on Success.
3075 * @author mdaftedar
3076 * @date 01 MAR 2012
3077 * @version 1.0
3078 */
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003079static int del_station(struct wiphy *wiphy, struct net_device *dev,
3080 struct station_del_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003081{
Arnd Bergmann057d1e92015-06-01 21:06:44 +02003082 const u8 *mac = params->mac;
Leo Kime6e12662015-09-16 18:36:03 +09003083 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003084 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003085 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003086
Leo Kim7ae43362015-09-16 18:35:59 +09003087 if (!wiphy)
3088 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003089
3090 priv = wiphy_priv(wiphy);
3091 nic = netdev_priv(dev);
3092
3093 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
3094 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
3095
3096
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003097 if (mac == NULL) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05303098 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003099 s32Error = wilc_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003100 } else {
3101 PRINT_D(HOSTAPD_DBG, "With mac address: %x%x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
3102 }
3103
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003104 s32Error = wilc_del_station(priv->hWILCWFIDrv, mac);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003105
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003106 if (s32Error)
3107 PRINT_ER("Host delete station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003108 }
3109 return s32Error;
3110}
3111
3112/**
Chaehyun Lim14b42082015-09-14 12:24:17 +09003113 * @brief change_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003114 * @details Modify a given station.
3115 * @param[in]
3116 * @return int : Return 0 on Success.
3117 * @author mdaftedar
3118 * @date 01 MAR 2012
3119 * @version 1.0
3120 */
Chaehyun Lim14b42082015-09-14 12:24:17 +09003121static int change_station(struct wiphy *wiphy, struct net_device *dev,
3122 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003123{
Leo Kime6e12662015-09-16 18:36:03 +09003124 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003125 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09003126 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003127 perInterface_wlan_t *nic;
3128
3129
3130 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
3131
Leo Kim7ae43362015-09-16 18:35:59 +09003132 if (!wiphy)
3133 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003134
3135 priv = wiphy_priv(wiphy);
3136 nic = netdev_priv(dev);
3137
3138 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003139 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003140 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003141 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003142 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003143
Leo Kim2353c382015-10-29 12:05:41 +09003144 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n",
3145 strStaParams.bssid[0], strStaParams.bssid[1],
3146 strStaParams.bssid[2], strStaParams.bssid[3],
3147 strStaParams.bssid[4], strStaParams.bssid[5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003148 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003149 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3150 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003151
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003152 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003153 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003154 } else {
Leo Kim22520122015-10-29 12:05:45 +09003155 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003156 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003157 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003158 memcpy(strStaParams.ht_supp_mcs_set,
3159 &params->ht_capa->mcs,
3160 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003161 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003162 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003163 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003164 }
3165
Leo Kimf676e172015-10-29 12:05:52 +09003166 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003167 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003168
Leo Kim22520122015-10-29 12:05:45 +09003169 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3170 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003171 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3172 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003173 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3174 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003175 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3176 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003177 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3178 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003179 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3180 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003181 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3182 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003183 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3184 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003185
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003186 s32Error = wilc_edit_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003187 if (s32Error)
3188 PRINT_ER("Host edit station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003189 }
3190 return s32Error;
3191}
3192
3193
3194/**
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003195 * @brief add_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003196 * @details
3197 * @param[in]
3198 * @return int : Return 0 on Success.
3199 * @author mdaftedar
3200 * @date 01 JUL 2012
3201 * @version 1.0
3202 */
Chaehyun Lim37316e82015-09-22 18:34:52 +09003203static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
3204 const char *name,
3205 unsigned char name_assign_type,
3206 enum nl80211_iftype type,
3207 u32 *flags,
3208 struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003209{
3210 perInterface_wlan_t *nic;
Chaehyun Lim27268872015-09-15 14:06:13 +09003211 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003212 struct net_device *new_ifc = NULL;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003213
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003214 priv = wiphy_priv(wiphy);
3215
3216
3217
3218 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
3219
3220 nic = netdev_priv(priv->wdev->netdev);
3221
3222
3223 if (type == NL80211_IFTYPE_MONITOR) {
3224 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
3225 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", nic->wilc_netdev);
3226 new_ifc = WILC_WFI_init_mon_interface(name, nic->wilc_netdev);
3227 if (new_ifc != NULL) {
3228 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003229 nic = netdev_priv(priv->wdev->netdev);
3230 nic->monitor_flag = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003231 } else
3232 PRINT_ER("Error in initializing monitor interface\n ");
3233 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003234 return priv->wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003235}
3236
3237/**
Chaehyun Limb4a73352015-09-14 12:24:10 +09003238 * @brief del_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003239 * @details
3240 * @param[in]
3241 * @return int : Return 0 on Success.
3242 * @author mdaftedar
3243 * @date 01 JUL 2012
3244 * @version 1.0
3245 */
Chaehyun Lim956d7212015-09-22 18:34:49 +09003246static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003247{
3248 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
Leo Kime6e12662015-09-16 18:36:03 +09003249 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003250}
3251
Chaehyun Lim08241922015-09-15 14:06:12 +09003252static struct cfg80211_ops wilc_cfg80211_ops = {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003253
Chaehyun Lim80785a92015-09-14 12:24:01 +09003254 .set_monitor_channel = set_channel,
Chaehyun Lim0e30d062015-09-14 12:24:02 +09003255 .scan = scan,
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +09003256 .connect = connect,
Chaehyun Limb027cde2015-09-14 12:24:04 +09003257 .disconnect = disconnect,
Chaehyun Lim953d4172015-09-14 12:24:05 +09003258 .add_key = add_key,
Chaehyun Lim3044ba72015-09-14 12:24:06 +09003259 .del_key = del_key,
Chaehyun Limf4893df2015-09-14 12:24:07 +09003260 .get_key = get_key,
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09003261 .set_default_key = set_default_key,
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003262 .add_virtual_intf = add_virtual_intf,
Chaehyun Limb4a73352015-09-14 12:24:10 +09003263 .del_virtual_intf = del_virtual_intf,
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09003264 .change_virtual_intf = change_virtual_intf,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003265
Chaehyun Lima13168d2015-09-14 12:24:12 +09003266 .start_ap = start_ap,
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09003267 .change_beacon = change_beacon,
Chaehyun Limc8cddd72015-09-14 12:24:14 +09003268 .stop_ap = stop_ap,
Chaehyun Limed269552015-09-14 12:24:15 +09003269 .add_station = add_station,
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003270 .del_station = del_station,
Chaehyun Lim14b42082015-09-14 12:24:17 +09003271 .change_station = change_station,
Chaehyun Limf06f5622015-09-14 12:24:18 +09003272 .get_station = get_station,
Chaehyun Limbdb63382015-09-14 12:24:19 +09003273 .dump_station = dump_station,
Chaehyun Lima5f7db62015-09-14 12:24:20 +09003274 .change_bss = change_bss,
Chaehyun Lima76b63e2015-09-14 12:24:21 +09003275 .set_wiphy_params = set_wiphy_params,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003276
Chaehyun Lim4d466572015-09-14 12:24:22 +09003277 .set_pmksa = set_pmksa,
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09003278 .del_pmksa = del_pmksa,
Chaehyun Limb33c39b2015-09-14 12:24:24 +09003279 .flush_pmksa = flush_pmksa,
Chaehyun Lim6d19d692015-09-14 12:24:25 +09003280 .remain_on_channel = remain_on_channel,
Chaehyun Lim1dd54402015-09-14 12:24:26 +09003281 .cancel_remain_on_channel = cancel_remain_on_channel,
Chaehyun Lim4a2f9b32015-09-14 12:24:27 +09003282 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
Chaehyun Lim12a26a32015-09-14 12:24:28 +09003283 .mgmt_tx = mgmt_tx,
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09003284 .mgmt_frame_register = wilc_mgmt_frame_register,
Chaehyun Lim46530672015-09-22 18:34:46 +09003285 .set_power_mgmt = set_power_mgmt,
Chaehyun Lima8047e22015-09-22 18:34:48 +09003286 .set_cqm_rssi_config = set_cqm_rssi_config,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003287
3288};
3289
3290
3291
3292
3293
3294/**
3295 * @brief WILC_WFI_update_stats
3296 * @details Modify parameters for a given BSS.
3297 * @param[in]
3298 * @return int : Return 0 on Success.
3299 * @author mdaftedar
3300 * @date 01 MAR 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09003301 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003302 */
3303int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
3304{
3305
Chaehyun Lim27268872015-09-15 14:06:13 +09003306 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003307
3308 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003309 switch (changed) {
3310
3311 case WILC_WFI_RX_PKT:
3312 {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003313 priv->netstats.rx_packets++;
3314 priv->netstats.rx_bytes += pktlen;
3315 priv->netstats.rx_time = get_jiffies_64();
3316 }
3317 break;
3318
3319 case WILC_WFI_TX_PKT:
3320 {
3321 priv->netstats.tx_packets++;
3322 priv->netstats.tx_bytes += pktlen;
3323 priv->netstats.tx_time = get_jiffies_64();
3324
3325 }
3326 break;
3327
3328 default:
3329 break;
3330 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003331 return 0;
3332}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003333
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003334/**
3335 * @brief WILC_WFI_CfgAlloc
3336 * @details Allocation of the wireless device structure and assigning it
3337 * to the cfg80211 operations structure.
3338 * @param[in] NONE
3339 * @return wireless_dev : Returns pointer to wireless_dev structure.
3340 * @author mdaftedar
3341 * @date 01 MAR 2012
3342 * @version 1.0
3343 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01003344static struct wireless_dev *WILC_WFI_CfgAlloc(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003345{
3346
3347 struct wireless_dev *wdev;
3348
3349
3350 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
3351 /*Allocating the wireless device structure*/
3352 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
3353 if (!wdev) {
3354 PRINT_ER("Cannot allocate wireless device\n");
3355 goto _fail_;
3356 }
3357
3358 /*Creating a new wiphy, linking wireless structure with the wiphy structure*/
Chaehyun Lim27268872015-09-15 14:06:13 +09003359 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003360 if (!wdev->wiphy) {
3361 PRINT_ER("Cannot allocate wiphy\n");
3362 goto _fail_mem_;
3363
3364 }
3365
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003366 /* enable 802.11n HT */
3367 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
3368 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
3369 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3370 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
3371 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003372
3373 /*wiphy bands*/
3374 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
3375
3376 return wdev;
3377
3378_fail_mem_:
3379 kfree(wdev);
3380_fail_:
3381 return NULL;
3382
3383}
3384/**
Chaehyun Lim8459fd52015-09-20 15:51:09 +09003385 * @brief wilc_create_wiphy
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003386 * @details Registering of the wiphy structure and interface modes
3387 * @param[in] NONE
3388 * @return NONE
3389 * @author mdaftedar
3390 * @date 01 MAR 2012
3391 * @version 1.0
3392 */
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01003393struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003394{
Chaehyun Lim27268872015-09-15 14:06:13 +09003395 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003396 struct wireless_dev *wdev;
Leo Kime6e12662015-09-16 18:36:03 +09003397 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003398
3399 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
3400
3401 wdev = WILC_WFI_CfgAlloc();
3402 if (wdev == NULL) {
3403 PRINT_ER("CfgAlloc Failed\n");
3404 return NULL;
3405 }
3406
3407
3408 /*Return hardware description structure (wiphy)'s priv*/
3409 priv = wdev_priv(wdev);
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003410 sema_init(&(priv->SemHandleUpdateStats), 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003411
3412 /*Link the wiphy with wireless structure*/
3413 priv->wdev = wdev;
3414
3415 /*Maximum number of probed ssid to be added by user for the scan request*/
3416 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003417 /*Maximum number of pmkids to be cashed*/
3418 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
3419 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003420
3421 wdev->wiphy->max_scan_ie_len = 1000;
3422
3423 /*signal strength in mBm (100*dBm) */
3424 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3425
3426 /*Set the availaible cipher suites*/
3427 wdev->wiphy->cipher_suites = cipher_suites;
3428 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003429 /*Setting default managment types: for register action frame: */
3430 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003431
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003432 wdev->wiphy->max_remain_on_channel_duration = 500;
3433 /*Setting the wiphy interfcae mode and type before registering the wiphy*/
3434 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
3435 BIT(NL80211_IFTYPE_P2P_CLIENT);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003436 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003437 wdev->iftype = NL80211_IFTYPE_STATION;
3438
3439
3440
3441 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
3442 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
3443 wdev->wiphy->interface_modes, wdev->iftype);
3444
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01003445 set_wiphy_dev(wdev->wiphy, dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003446
3447 /*Register wiphy structure*/
3448 s32Error = wiphy_register(wdev->wiphy);
3449 if (s32Error) {
3450 PRINT_ER("Cannot register wiphy device\n");
3451 /*should define what action to be taken in such failure*/
3452 } else {
3453 PRINT_D(CFG80211_DBG, "Successful Registering\n");
3454 }
3455
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003456 priv->dev = net;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003457 return wdev;
3458
3459
3460}
3461/**
3462 * @brief WILC_WFI_WiphyFree
3463 * @details Freeing allocation of the wireless device structure
3464 * @param[in] NONE
3465 * @return NONE
3466 * @author mdaftedar
3467 * @date 01 MAR 2012
3468 * @version 1.0
3469 */
Chaehyun Limdd4b6a82015-09-20 15:51:25 +09003470int wilc_init_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003471{
3472
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003473 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003474
Chaehyun Lim27268872015-09-15 14:06:13 +09003475 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003476
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003477 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
3478 priv = wdev_priv(net->ieee80211_ptr);
3479 if (op_ifcs == 0) {
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -07003480 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003481 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003482 }
3483 op_ifcs++;
3484 if (s32Error < 0) {
3485 PRINT_ER("Failed to creat refresh Timer\n");
3486 return s32Error;
3487 }
3488
Dean Lee72ed4dc2015-06-12 14:11:44 +09003489 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003490
Dean Lee72ed4dc2015-06-12 14:11:44 +09003491 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003492
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003493 sema_init(&(priv->hSemScanReq), 1);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003494 s32Error = wilc_init(net, &priv->hWILCWFIDrv);
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003495 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003496 PRINT_ER("Error while initializing hostinterface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003497
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003498 return s32Error;
3499}
3500
3501/**
3502 * @brief WILC_WFI_WiphyFree
3503 * @details Freeing allocation of the wireless device structure
3504 * @param[in] NONE
3505 * @return NONE
3506 * @author mdaftedar
3507 * @date 01 MAR 2012
3508 * @version 1.0
3509 */
Chaehyun Lima9a16822015-09-20 15:51:24 +09003510int wilc_deinit_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003511{
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003512 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003513
Chaehyun Lim27268872015-09-15 14:06:13 +09003514 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003515
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003516 priv = wdev_priv(net->ieee80211_ptr);
3517
Dean Lee72ed4dc2015-06-12 14:11:44 +09003518 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003519
Dean Lee72ed4dc2015-06-12 14:11:44 +09003520 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003521
3522 op_ifcs--;
3523
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003524 s32Error = wilc_deinit(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003525
3526 /* Clear the Shadow scan */
Leo Kimd14991a2015-11-19 15:56:22 +09003527 clear_shadow_scan();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003528 if (op_ifcs == 0) {
3529 PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003530 del_timer_sync(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003531 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003532
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003533 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003534 PRINT_ER("Error while deintializing host interface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003535
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003536 return s32Error;
3537}
3538
3539
3540/**
3541 * @brief WILC_WFI_WiphyFree
3542 * @details Freeing allocation of the wireless device structure
3543 * @param[in] NONE
3544 * @return NONE
3545 * @author mdaftedar
3546 * @date 01 MAR 2012
3547 * @version 1.0
3548 */
Chaehyun Lim96da20a2015-09-20 15:51:08 +09003549void wilc_free_wiphy(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003550{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003551 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
3552
Chaehyun Lim619837a2015-09-20 15:51:10 +09003553 if (!net) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003554 PRINT_D(INIT_DBG, "net_device is NULL\n");
3555 return;
3556 }
3557
Chaehyun Lim619837a2015-09-20 15:51:10 +09003558 if (!net->ieee80211_ptr) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003559 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
3560 return;
3561 }
3562
Chaehyun Lim619837a2015-09-20 15:51:10 +09003563 if (!net->ieee80211_ptr->wiphy) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003564 PRINT_D(INIT_DBG, "wiphy is NULL\n");
3565 return;
3566 }
3567
3568 wiphy_unregister(net->ieee80211_ptr->wiphy);
3569
3570 PRINT_D(INIT_DBG, "Freeing wiphy\n");
3571 wiphy_free(net->ieee80211_ptr->wiphy);
3572 kfree(net->ieee80211_ptr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003573}