blob: b0d1ed36b66722fa279e496cc21449b79d94fef9 [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++) {
Leo Kimce3b1b52015-11-19 15:56:25 +0900252 tstrNetworkInfo *network_info;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900253
Leo Kimce3b1b52015-11-19 15:56:25 +0900254 network_info = &last_scanned_shadow[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900255
Leo Kimce3b1b52015-11-19 15:56:25 +0900256 if (!network_info->u8Found || all) {
Leo Kimc6f5e3a2015-11-19 15:56:26 +0900257 s32 freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900258 struct ieee80211_channel *channel;
259
Leo Kimce3b1b52015-11-19 15:56:25 +0900260 if (network_info) {
Leo Kimc6f5e3a2015-11-19 15:56:26 +0900261 freq = ieee80211_channel_to_frequency((s32)network_info->u8channel, IEEE80211_BAND_2GHZ);
262 channel = ieee80211_get_channel(wiphy, freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900263
Leo Kimce3b1b52015-11-19 15:56:25 +0900264 rssi = get_rssi_avg(network_info);
265 if (memcmp("DIRECT-", network_info->au8ssid, 7) ||
Leo Kim48ee7ba2015-11-19 15:56:24 +0900266 direct_scan) {
Leo Kimce3b1b52015-11-19 15:56:25 +0900267 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, network_info->au8bssid, network_info->u64Tsf, network_info->u16CapInfo,
268 network_info->u16BeaconPeriod, (const u8 *)network_info->pu8IEs,
269 (size_t)network_info->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900270 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900271 }
272 }
273
274 }
275 }
276
277}
278
Leo Kim12b01382015-11-19 15:56:27 +0900279static void reset_shadow_found(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900280{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900281 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900282
Leo Kim771fbae2015-11-19 15:56:10 +0900283 for (i = 0; i < last_scanned_cnt; i++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900284 last_scanned_shadow[i].u8Found = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900285}
286
Leo Kim5e51d8b2015-11-19 15:56:28 +0900287static void update_scan_time(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900288{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900289 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900290
Leo Kim771fbae2015-11-19 15:56:10 +0900291 for (i = 0; i < last_scanned_cnt; i++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900292 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900293}
294
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700295static void remove_network_from_shadow(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900296{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900297 unsigned long now = jiffies;
298 int i, j;
299
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900300
Leo Kim771fbae2015-11-19 15:56:10 +0900301 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900302 if (time_after(now, last_scanned_shadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) {
303 PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", last_scanned_shadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900304
Leo Kimf1ab1172015-11-19 15:56:11 +0900305 kfree(last_scanned_shadow[i].pu8IEs);
306 last_scanned_shadow[i].pu8IEs = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900307
Leo Kimf1ab1172015-11-19 15:56:11 +0900308 wilc_free_join_params(last_scanned_shadow[i].pJoinParams);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900309
Leo Kim771fbae2015-11-19 15:56:10 +0900310 for (j = i; (j < last_scanned_cnt - 1); j++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900311 last_scanned_shadow[j] = last_scanned_shadow[j + 1];
Leo Kim771fbae2015-11-19 15:56:10 +0900312
313 last_scanned_cnt--;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900314 }
315 }
316
Leo Kim771fbae2015-11-19 15:56:10 +0900317 PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n",
318 last_scanned_cnt);
319 if (last_scanned_cnt != 0) {
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700320 hAgingTimer.data = arg;
321 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
322 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900323 PRINT_D(CFG80211_DBG, "No need to restart Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700324 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900325}
326
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700327static void clear_duringIP(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900328{
329 PRINT_D(GENERIC_DBG, "GO:IP Obtained , enable scan\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100330 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900331}
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900332
Leo Kim157814f2015-11-19 15:56:29 +0900333static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo,
334 void *user_void)
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");
Leo Kim157814f2015-11-19 15:56:29 +0900341 hAgingTimer.data = (unsigned long)user_void;
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700342 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
Leo Kim5c4cf0d2015-11-19 15:56:30 +0900357static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo,
358 void *user_void, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900359{
Leo Kim5c4cf0d2015-11-19 15:56:30 +0900360 int ap_found = is_network_in_shadow(pstrNetworkInfo, user_void);
Chaehyun Limfbc2fe12015-09-15 14:06:16 +0900361 u32 ap_index = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900362 u8 rssi_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900363
Leo Kim771fbae2015-11-19 15:56:10 +0900364 if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900365 PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
366 return;
367 }
368 if (ap_found == -1) {
Leo Kim771fbae2015-11-19 15:56:10 +0900369 ap_index = last_scanned_cnt;
370 last_scanned_cnt++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900371
372 } else {
373 ap_index = ap_found;
374 }
Leo Kimf1ab1172015-11-19 15:56:11 +0900375 rssi_index = last_scanned_shadow[ap_index].strRssi.u8Index;
376 last_scanned_shadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900377 if (rssi_index == NUM_RSSI) {
378 rssi_index = 0;
Leo Kimf1ab1172015-11-19 15:56:11 +0900379 last_scanned_shadow[ap_index].strRssi.u8Full = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900380 }
Leo Kimf1ab1172015-11-19 15:56:11 +0900381 last_scanned_shadow[ap_index].strRssi.u8Index = rssi_index;
382 last_scanned_shadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
383 last_scanned_shadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
384 last_scanned_shadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
385 memcpy(last_scanned_shadow[ap_index].au8ssid,
386 pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
387 memcpy(last_scanned_shadow[ap_index].au8bssid,
388 pstrNetworkInfo->au8bssid, ETH_ALEN);
389 last_scanned_shadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
390 last_scanned_shadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
391 last_scanned_shadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
392 last_scanned_shadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
393 last_scanned_shadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900394 if (ap_found != -1)
Leo Kimf1ab1172015-11-19 15:56:11 +0900395 kfree(last_scanned_shadow[ap_index].pu8IEs);
396 last_scanned_shadow[ap_index].pu8IEs =
Glen Leef3052582015-09-10 12:03:04 +0900397 kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL); /* will be deallocated by the WILC_WFI_CfgScan() function */
Leo Kimf1ab1172015-11-19 15:56:11 +0900398 memcpy(last_scanned_shadow[ap_index].pu8IEs,
399 pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
400 last_scanned_shadow[ap_index].u32TimeRcvdInScan = jiffies;
401 last_scanned_shadow[ap_index].u32TimeRcvdInScanCached = jiffies;
402 last_scanned_shadow[ap_index].u8Found = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900403 if (ap_found != -1)
Leo Kimf1ab1172015-11-19 15:56:11 +0900404 wilc_free_join_params(last_scanned_shadow[ap_index].pJoinParams);
405 last_scanned_shadow[ap_index].pJoinParams = pJoinParams;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900406}
407
408
409/**
410 * @brief CfgScanResult
411 * @details Callback function which returns the scan results found
412 *
413 * @param[in] tenuScanEvent enuScanEvent: enum, indicating the scan event triggered, whether that is
414 * SCAN_EVENT_NETWORK_FOUND or SCAN_EVENT_DONE
415 * tstrNetworkInfo* pstrNetworkInfo: structure holding the scan results information
416 * void* pUserVoid: Private structure associated with the wireless interface
417 * @return NONE
418 * @author mabubakr
419 * @date
420 * @version 1.0
421 */
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900422static void CfgScanResult(enum scan_event scan_event,
Leo Kim0551a722015-11-19 15:56:32 +0900423 tstrNetworkInfo *network_info,
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900424 void *pUserVoid,
425 void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900426{
Chaehyun Lim27268872015-09-15 14:06:13 +0900427 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900428 struct wiphy *wiphy;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900429 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900430 struct ieee80211_channel *channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900431 struct cfg80211_bss *bss = NULL;
432
Chaehyun Lim27268872015-09-15 14:06:13 +0900433 priv = (struct wilc_priv *)pUserVoid;
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100434 if (priv->bCfgScanning) {
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900435 if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900436 wiphy = priv->dev->ieee80211_ptr->wiphy;
Leo Kim7ae43362015-09-16 18:35:59 +0900437
438 if (!wiphy)
439 return;
440
Leo Kim0551a722015-11-19 15:56:32 +0900441 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
442 (((s32)network_info->s8rssi * 100) < 0 ||
443 ((s32)network_info->s8rssi * 100) > 100)) {
Leo Kim24db7132015-09-16 18:36:01 +0900444 PRINT_ER("wiphy signal type fial\n");
445 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900446 }
447
Leo Kim0551a722015-11-19 15:56:32 +0900448 if (network_info) {
449 s32Freq = ieee80211_channel_to_frequency((s32)network_info->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900450 channel = ieee80211_get_channel(wiphy, s32Freq);
451
Leo Kim7ae43362015-09-16 18:35:59 +0900452 if (!channel)
453 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900454
455 PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
Leo Kim0551a722015-11-19 15:56:32 +0900456 "BeaconPeriod: %d\n", channel->center_freq, (((s32)network_info->s8rssi) * 100),
457 network_info->u16CapInfo, network_info->u16BeaconPeriod);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900458
Leo Kim0551a722015-11-19 15:56:32 +0900459 if (network_info->bNewNetwork) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900460 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
Leo Kim0551a722015-11-19 15:56:32 +0900461 PRINT_D(CFG80211_DBG, "Network %s found\n", network_info->au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900462 priv->u32RcvdChCount++;
463
464
465
466 if (pJoinParams == NULL) {
467 PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n");
468 }
Leo Kim0551a722015-11-19 15:56:32 +0900469 add_network_to_shadow(network_info, priv, pJoinParams);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900470
471 /*P2P peers are sent to WPA supplicant and added to shadow table*/
Leo Kim0551a722015-11-19 15:56:32 +0900472 if (!(memcmp("DIRECT-", network_info->au8ssid, 7))) {
473 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, network_info->au8bssid, network_info->u64Tsf, network_info->u16CapInfo,
474 network_info->u16BeaconPeriod, (const u8 *)network_info->pu8IEs,
475 (size_t)network_info->u16IEsLen, (((s32)network_info->s8rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900476 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900477 }
478
479
480 } else {
481 PRINT_ER("Discovered networks exceeded the max limit\n");
482 }
483 } else {
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900484 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900485 /* So this network is discovered before, we'll just update its RSSI */
486 for (i = 0; i < priv->u32RcvdChCount; i++) {
Leo Kim0551a722015-11-19 15:56:32 +0900487 if (memcmp(last_scanned_shadow[i].au8bssid, network_info->au8bssid, 6) == 0) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900488 PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", last_scanned_shadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900489
Leo Kim0551a722015-11-19 15:56:32 +0900490 last_scanned_shadow[i].s8rssi = network_info->s8rssi;
Leo Kimf1ab1172015-11-19 15:56:11 +0900491 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900492 break;
493 }
494 }
495 }
496 }
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900497 } else if (scan_event == SCAN_EVENT_DONE) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530498 PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev);
499 PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n");
Dean Lee72ed4dc2015-06-12 14:11:44 +0900500 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900501
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530502 if (priv->u32RcvdChCount > 0)
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530503 PRINT_D(CFG80211_DBG, "%d Network(s) found\n", priv->u32RcvdChCount);
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530504 else
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530505 PRINT_D(CFG80211_DBG, "No networks found\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900506
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200507 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900508
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900509 if (priv->pstrScanReq != NULL) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900510 cfg80211_scan_done(priv->pstrScanReq, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900511 priv->u32RcvdChCount = 0;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900512 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900513 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900514 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200515 up(&(priv->hSemScanReq));
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900516 } else if (scan_event == SCAN_EVENT_ABORTED) {
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200517 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900518
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530519 PRINT_D(CFG80211_DBG, "Scan Aborted\n");
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900520 if (priv->pstrScanReq != NULL) {
Leo Kim5e51d8b2015-11-19 15:56:28 +0900521 update_scan_time();
Dean Lee72ed4dc2015-06-12 14:11:44 +0900522 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900523
Dean Lee72ed4dc2015-06-12 14:11:44 +0900524 cfg80211_scan_done(priv->pstrScanReq, false);
525 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900526 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900527 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200528 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900529 }
530 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900531}
532
533
534/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900535 * @brief CfgConnectResult
536 * @details
537 * @param[in] tenuConnDisconnEvent enuConnDisconnEvent: Type of connection response either
538 * connection response or disconnection notification.
539 * tstrConnectInfo* pstrConnectInfo: COnnection information.
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900540 * u8 u8MacStatus: Mac Status from firmware
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900541 * tstrDisconnectNotifInfo* pstrDisconnectNotifInfo: Disconnection Notification
542 * void* pUserVoid: Private data associated with wireless interface
543 * @return NONE
544 * @author mabubakr
545 * @date 01 MAR 2012
546 * @version 1.0
547 */
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100548int wilc_connecting;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900549
Leo Kimed3f0372015-10-12 16:56:01 +0900550static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900551 tstrConnectInfo *pstrConnectInfo,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900552 u8 u8MacStatus,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900553 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
554 void *pUserVoid)
555{
Chaehyun Lim27268872015-09-15 14:06:13 +0900556 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900557 struct net_device *dev;
Leo Kim441dc602015-10-12 16:55:35 +0900558 struct host_if_drv *pstrWFIDrv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900559 u8 NullBssid[ETH_ALEN] = {0};
Glen Leec1ec2c12015-10-20 17:13:58 +0900560 struct wilc *wl;
561 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900562
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100563 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900564
Chaehyun Lim27268872015-09-15 14:06:13 +0900565 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900566 dev = priv->dev;
Glen Leec1ec2c12015-10-20 17:13:58 +0900567 nic = netdev_priv(dev);
568 wl = nic->wilc;
Leo Kim441dc602015-10-12 16:55:35 +0900569 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900570
571 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
572 /*Initialization*/
Amitoj Kaur Chawlababa7c72015-10-15 13:48:29 +0530573 u16 u16ConnectStatus;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900574
575 u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
576
577 PRINT_D(CFG80211_DBG, " Connection response received = %d\n", u8MacStatus);
578
579 if ((u8MacStatus == MAC_DISCONNECTED) &&
580 (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
581 /* The case here is that our station was waiting for association response frame and has just received it containing status code
582 * = SUCCESSFUL_STATUSCODE, while mac status is MAC_DISCONNECTED (which means something wrong happened) */
583 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100584 wilc_wlan_set_bssid(priv->dev, NullBssid);
Leo Kime554a302015-11-19 15:56:21 +0900585 eth_zero_addr(wilc_connected_ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900586
Leo Kimab16ec02015-10-29 12:05:40 +0900587 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900588 wlan_channel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900589
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530590 PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d\n", u16ConnectStatus, u8MacStatus);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900591 }
592
593 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900594 bool bNeedScanRefresh = false;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900595 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900596
597 PRINT_INFO(CFG80211_DBG, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo->au8bssid[0],
598 pstrConnectInfo->au8bssid[1], pstrConnectInfo->au8bssid[2], pstrConnectInfo->au8bssid[3], pstrConnectInfo->au8bssid[4], pstrConnectInfo->au8bssid[5]);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900599 memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900600
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900601
Leo Kim771fbae2015-11-19 15:56:10 +0900602 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900603 if (memcmp(last_scanned_shadow[i].au8bssid,
604 pstrConnectInfo->au8bssid, ETH_ALEN) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900605 unsigned long now = jiffies;
606
607 if (time_after(now,
Leo Kimf1ab1172015-11-19 15:56:11 +0900608 last_scanned_shadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900609 bNeedScanRefresh = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900610 }
611
612 break;
613 }
614 }
615
Abdul Hussain5a66bf22015-06-16 09:44:06 +0000616 if (bNeedScanRefresh) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900617 /*Also, refrsh DIRECT- results if */
Dean Lee72ed4dc2015-06-12 14:11:44 +0900618 refresh_scan(priv, 1, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900619
620 }
621
622 }
623
624
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530625 PRINT_D(CFG80211_DBG, "Association request info elements length = %zu\n", pstrConnectInfo->ReqIEsLen);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900626
627 PRINT_D(CFG80211_DBG, "Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen);
628
629 cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
630 pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
631 pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
632 u16ConnectStatus, GFP_KERNEL); /* TODO: mostafa: u16ConnectStatus to */
633 /* be replaced by pstrConnectInfo->u16ConnectStatus */
634 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100635 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900636 PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n",
637 pstrDisconnectNotifInfo->u16reason, priv->dev);
Leo Kim583d9722015-11-19 15:56:16 +0900638 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +0900639 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +0900640 wilc_ie = false;
Shraddha Barkebcf02652015-10-05 17:00:32 +0530641 eth_zero_addr(priv->au8AssociatedBss);
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100642 wilc_wlan_set_bssid(priv->dev, NullBssid);
Leo Kime554a302015-11-19 15:56:21 +0900643 eth_zero_addr(wilc_connected_ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900644
Leo Kimab16ec02015-10-29 12:05:40 +0900645 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900646 wlan_channel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900647 /*Incase "P2P CLIENT Connected" send deauthentication reason by 3 to force the WPA_SUPPLICANT to directly change
648 * virtual interface to station*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900649 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900650 pstrDisconnectNotifInfo->u16reason = 3;
651 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900652 /*Incase "P2P CLIENT during connection(not connected)" send deauthentication reason by 1 to force the WPA_SUPPLICANT
653 * to scan again and retry the connection*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900654 else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900655 pstrDisconnectNotifInfo->u16reason = 1;
656 }
657 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
Sudip Mukherjeee26bb712015-06-30 13:51:51 +0530658 pstrDisconnectNotifInfo->ie_len, false,
659 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900660
661 }
662
663}
664
665
666/**
Chaehyun Lim80785a92015-09-14 12:24:01 +0900667 * @brief set_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900668 * @details Set channel for a given wireless interface. Some devices
669 * may support multi-channel operation (by channel hopping) so cfg80211
670 * doesn't verify much. Note, however, that the passed netdev may be
671 * %NULL as well if the user requested changing the channel for the
672 * device itself, or for a monitor interface.
673 * @param[in]
674 * @return int : Return 0 on Success
675 * @author mdaftedar
676 * @date 01 MAR 2012
677 * @version 1.0
678 */
Chaehyun Lim80785a92015-09-14 12:24:01 +0900679static int set_channel(struct wiphy *wiphy,
680 struct cfg80211_chan_def *chandef)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900681{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900682 u32 channelnum = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +0900683 struct wilc_priv *priv;
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900684 int result = 0;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900685
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900686 priv = wiphy_priv(wiphy);
687
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900688 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
689 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900690
Chaehyun Lim866a2c22015-10-02 16:41:21 +0900691 curr_channel = channelnum;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100692 result = wilc_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900693
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900694 if (result != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900695 PRINT_ER("Error in setting channel %d\n", channelnum);
696
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900697 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900698}
699
700/**
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900701 * @brief scan
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900702 * @details Request to do a scan. If returning zero, the scan request is given
703 * the driver, and will be valid until passed to cfg80211_scan_done().
704 * For scan results, call cfg80211_inform_bss(); you can call this outside
705 * the scan/scan_done bracket too.
706 * @param[in]
707 * @return int : Return 0 on Success
708 * @author mabubakr
709 * @date 01 MAR 2012
710 * @version 1.0
711 */
712
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900713static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900714{
Chaehyun Lim27268872015-09-15 14:06:13 +0900715 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900716 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +0900717 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900718 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
Leo Kim607db442015-10-05 15:25:37 +0900719 struct hidden_network strHiddenNetwork;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900720
721 priv = wiphy_priv(wiphy);
722
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900723 priv->pstrScanReq = request;
724
725 priv->u32RcvdChCount = 0;
726
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100727 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Leo Kim12b01382015-11-19 15:56:27 +0900728 reset_shadow_found();
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900729
Dean Lee72ed4dc2015-06-12 14:11:44 +0900730 priv->bCfgScanning = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900731 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
732 /* max_scan_ssids */
733 for (i = 0; i < request->n_channels; i++) {
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900734 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900735 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
736 }
737
738 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530739 PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900740
741 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
742
743 if (request->n_ssids >= 1) {
744
745
Leo Kim607db442015-10-05 15:25:37 +0900746 strHiddenNetwork.pstrHiddenNetworkInfo = kmalloc(request->n_ssids * sizeof(struct hidden_network), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900747 strHiddenNetwork.u8ssidnum = request->n_ssids;
748
749
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900750 for (i = 0; i < request->n_ssids; i++) {
751
752 if (request->ssids[i].ssid != NULL && request->ssids[i].ssid_len != 0) {
Glen Leef3052582015-09-10 12:03:04 +0900753 strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900754 memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900755 strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len;
756 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530757 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900758 strHiddenNetwork.u8ssidnum -= 1;
759 }
760 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530761 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100762 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900763 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900764 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900765 CfgScanResult, (void *)priv, &strHiddenNetwork);
766 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530767 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100768 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900769 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900770 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900771 CfgScanResult, (void *)priv, NULL);
772 }
773
774 } else {
775 PRINT_ER("Requested num of scanned channels is greater than the max, supported"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530776 " channels\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900777 }
778
Leo Kime6e12662015-09-16 18:36:03 +0900779 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900780 s32Error = -EBUSY;
781 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
782 }
783
784 return s32Error;
785}
786
787/**
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900788 * @brief connect
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900789 * @details Connect to the ESS with the specified parameters. When connected,
790 * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
791 * If the connection fails for some reason, call cfg80211_connect_result()
792 * with the status from the AP.
793 * @param[in]
794 * @return int : Return 0 on Success
795 * @author mabubakr
796 * @date 01 MAR 2012
797 * @version 1.0
798 */
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900799static int connect(struct wiphy *wiphy, struct net_device *dev,
800 struct cfg80211_connect_params *sme)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900801{
Leo Kime6e12662015-09-16 18:36:03 +0900802 s32 s32Error = 0;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900803 u32 i;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900804 u8 u8security = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +0900805 enum AUTHTYPE tenuAuth_type = ANY;
Dean Lee576917a2015-06-15 11:58:57 +0900806 char *pcgroup_encrypt_val = NULL;
807 char *pccipher_group = NULL;
808 char *pcwpa_version = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900809
Chaehyun Lim27268872015-09-15 14:06:13 +0900810 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +0900811 struct host_if_drv *pstrWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900812 tstrNetworkInfo *pstrNetworkInfo = NULL;
813
814
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100815 wilc_connecting = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900816 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +0900817 pstrWFIDrv = (struct host_if_drv *)(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900818
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100819 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900820
Johnny Kim8a143302015-06-10 17:06:46 +0900821 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 +0900822 if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900823 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
Leo Kimab16ec02015-10-29 12:05:40 +0900824 pstrWFIDrv->p2p_connect = 1;
825 } else {
826 pstrWFIDrv->p2p_connect = 0;
827 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530828 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900829
Leo Kim771fbae2015-11-19 15:56:10 +0900830 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900831 if ((sme->ssid_len == last_scanned_shadow[i].u8SsidLen) &&
832 memcmp(last_scanned_shadow[i].au8ssid,
833 sme->ssid,
834 sme->ssid_len) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900835 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
836 if (sme->bssid == NULL) {
837 /* BSSID is not passed from the user, so decision of matching
838 * is done by SSID only */
839 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
840 break;
841 } else {
842 /* BSSID is also passed from the user, so decision of matching
843 * should consider also this passed BSSID */
Leo Kimf1ab1172015-11-19 15:56:11 +0900844 if (memcmp(last_scanned_shadow[i].au8bssid,
845 sme->bssid,
846 ETH_ALEN) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900847 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
848 break;
849 }
850 }
851 }
852 }
853
Leo Kim771fbae2015-11-19 15:56:10 +0900854 if (i < last_scanned_cnt) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900855 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
856
Leo Kimf1ab1172015-11-19 15:56:11 +0900857 pstrNetworkInfo = &last_scanned_shadow[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900858
859 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
860 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
861 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
862 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
863 } else {
864 s32Error = -ENOENT;
Leo Kim771fbae2015-11-19 15:56:10 +0900865 if (last_scanned_cnt == 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900866 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
867 else
868 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
869
870 goto done;
871 }
872
873 priv->WILC_WFI_wep_default = 0;
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900874 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
875 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900876
877 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
878 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
879
880 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
881
882 if (INFO) {
883 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
884 PRINT_D(CORECONFIG_DBG, "sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]);
885 }
886
887 if (sme->crypto.cipher_group != NO_ENCRYPT) {
888 /* To determine the u8security value, first we check the group cipher suite then {in case of WPA or WPA2}
889 * we will add to it the pairwise cipher suite(s) */
890 pcwpa_version = "Default";
891 PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900892 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900893 u8security = ENCRYPT_ENABLED | WEP;
894 pcgroup_encrypt_val = "WEP40";
895 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
896 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
897
898 if (INFO) {
899 for (i = 0; i < sme->key_len; i++)
900 PRINT_D(CORECONFIG_DBG, "WEP Key Value[%d] = %d\n", i, sme->key[i]);
901 }
902 priv->WILC_WFI_wep_default = sme->key_idx;
903 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900904 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900905
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900906 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900907 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900908 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
909 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900910 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900911
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100912 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
913 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900914 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900915 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
916 pcgroup_encrypt_val = "WEP104";
917 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
918
919 priv->WILC_WFI_wep_default = sme->key_idx;
920 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900921 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900922
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900923 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900924 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900925 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
926 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900927 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900928
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100929 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
930 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900931 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900932 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900933 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
934 pcgroup_encrypt_val = "WPA2_TKIP";
935 pccipher_group = "TKIP";
936 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
937 /* tenuSecurity_t = WPA2_AES; */
938 u8security = ENCRYPT_ENABLED | WPA2 | AES;
939 pcgroup_encrypt_val = "WPA2_AES";
940 pccipher_group = "AES";
941 }
942 pcwpa_version = "WPA_VERSION_2";
943 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
944 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900945 u8security = ENCRYPT_ENABLED | WPA | TKIP;
946 pcgroup_encrypt_val = "WPA_TKIP";
947 pccipher_group = "TKIP";
948 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
949 /* tenuSecurity_t = WPA_AES; */
950 u8security = ENCRYPT_ENABLED | WPA | AES;
951 pcgroup_encrypt_val = "WPA_AES";
952 pccipher_group = "AES";
953
954 }
955 pcwpa_version = "WPA_VERSION_1";
956
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900957 } else {
958 s32Error = -ENOTSUPP;
959 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
960
961 goto done;
962 }
963
964 }
965
966 /* After we set the u8security value from checking the group cipher suite, {in case of WPA or WPA2} we will
967 * add to it the pairwise cipher suite(s) */
968 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
969 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
970 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
971 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
972 u8security = u8security | TKIP;
973 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
974 u8security = u8security | AES;
975 }
976 }
977 }
978
979 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
980
981 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
982 switch (sme->auth_type) {
983 case NL80211_AUTHTYPE_OPEN_SYSTEM:
984 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
985 tenuAuth_type = OPEN_SYSTEM;
986 break;
987
988 case NL80211_AUTHTYPE_SHARED_KEY:
989 tenuAuth_type = SHARED_KEY;
990 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
991 break;
992
993 default:
994 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
995 }
996
997
998 /* ai: key_mgmt: enterprise case */
999 if (sme->crypto.n_akm_suites) {
1000 switch (sme->crypto.akm_suites[0]) {
1001 case WLAN_AKM_SUITE_8021X:
1002 tenuAuth_type = IEEE8021;
1003 break;
1004
1005 default:
1006 break;
1007 }
1008 }
1009
1010
1011 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
1012
1013 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
1014 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
1015
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001016 curr_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001017
Leo Kimab16ec02015-10-29 12:05:40 +09001018 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +09001019 wlan_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001020
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001021 wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001022
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001023 s32Error = wilc_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001024 sme->ssid_len, sme->ie, sme->ie_len,
1025 CfgConnectResult, (void *)priv, u8security,
1026 tenuAuth_type, pstrNetworkInfo->u8channel,
1027 pstrNetworkInfo->pJoinParams);
Leo Kime6e12662015-09-16 18:36:03 +09001028 if (s32Error != 0) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001029 PRINT_ER("wilc_set_join_req(): Error(%d)\n", s32Error);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001030 s32Error = -ENOENT;
1031 goto done;
1032 }
1033
1034done:
1035
1036 return s32Error;
1037}
1038
1039
1040/**
Chaehyun Limb027cde2015-09-14 12:24:04 +09001041 * @brief disconnect
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001042 * @details Disconnect from the BSS/ESS.
1043 * @param[in]
1044 * @return int : Return 0 on Success
1045 * @author mdaftedar
1046 * @date 01 MAR 2012
1047 * @version 1.0
1048 */
Chaehyun Limb027cde2015-09-14 12:24:04 +09001049static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001050{
Leo Kime6e12662015-09-16 18:36:03 +09001051 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09001052 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09001053 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim51e825f2015-09-15 14:06:14 +09001054 u8 NullBssid[ETH_ALEN] = {0};
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001055
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001056 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001057 priv = wiphy_priv(wiphy);
1058
Leo Kim441dc602015-10-12 16:55:35 +09001059 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Leo Kimab16ec02015-10-29 12:05:40 +09001060 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +09001061 wlan_channel = INVALID_CHANNEL;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001062 wilc_wlan_set_bssid(priv->dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001063
1064 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
1065
Leo Kim583d9722015-11-19 15:56:16 +09001066 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +09001067 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +09001068 wilc_ie = false;
Leo Kim1229b1a2015-10-29 12:05:39 +09001069 pstrWFIDrv->p2p_timeout = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001070
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001071 s32Error = wilc_disconnect(priv->hWILCWFIDrv, reason_code);
Leo Kime6e12662015-09-16 18:36:03 +09001072 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001073 PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
1074 s32Error = -EINVAL;
1075 }
1076
1077 return s32Error;
1078}
1079
1080/**
Chaehyun Lim953d4172015-09-14 12:24:05 +09001081 * @brief add_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001082 * @details Add a key with the given parameters. @mac_addr will be %NULL
1083 * when adding a group key.
1084 * @param[in] key : key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, 8-byte Rx Mic Key
1085 * @return int : Return 0 on Success
1086 * @author mdaftedar
1087 * @date 01 MAR 2012
1088 * @version 1.0
1089 */
Chaehyun Lim953d4172015-09-14 12:24:05 +09001090static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1091 bool pairwise,
1092 const u8 *mac_addr, struct key_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001093
1094{
Leo Kime6e12662015-09-16 18:36:03 +09001095 s32 s32Error = 0, KeyLen = params->key_len;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001096 u32 i;
Chaehyun Lim27268872015-09-15 14:06:13 +09001097 struct wilc_priv *priv;
Arnd Bergmann057d1e92015-06-01 21:06:44 +02001098 const u8 *pu8RxMic = NULL;
1099 const u8 *pu8TxMic = NULL;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001100 u8 u8mode = NO_ENCRYPT;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001101 u8 u8gmode = NO_ENCRYPT;
1102 u8 u8pmode = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +09001103 enum AUTHTYPE tenuAuth_type = ANY;
Glen Lee76469202015-10-20 17:13:59 +09001104 struct wilc *wl;
1105 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001106
1107 priv = wiphy_priv(wiphy);
Glen Lee76469202015-10-20 17:13:59 +09001108 nic = netdev_priv(netdev);
1109 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001110
1111 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
1112
Johnny Kim8a143302015-06-10 17:06:46 +09001113 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001114
1115 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
1116 params->key[1],
1117 params->key[2]);
1118
1119
1120 switch (params->cipher) {
1121 case WLAN_CIPHER_SUITE_WEP40:
1122 case WLAN_CIPHER_SUITE_WEP104:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001123 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
1124
1125 priv->WILC_WFI_wep_default = key_index;
1126 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001127 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001128
1129 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
1130 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
1131
1132 for (i = 0; i < params->key_len; i++)
1133 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
1134
1135 tenuAuth_type = OPEN_SYSTEM;
1136
1137 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
1138 u8mode = ENCRYPT_ENABLED | WEP;
1139 else
1140 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
1141
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001142 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 +09001143 break;
1144 }
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001145 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001146 priv->WILC_WFI_wep_default = key_index;
1147 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001148 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001149
1150 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
1151 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
1152 if (INFO) {
1153 for (i = 0; i < params->key_len; i++)
1154 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
1155 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001156 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001157 }
1158
1159 break;
1160
1161 case WLAN_CIPHER_SUITE_TKIP:
1162 case WLAN_CIPHER_SUITE_CCMP:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001163 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
1164
1165 if (priv->wilc_gtk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001166 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001167 priv->wilc_gtk[key_index]->key = NULL;
1168 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001169
1170 }
1171 if (priv->wilc_ptk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001172 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001173 priv->wilc_ptk[key_index]->key = NULL;
1174 priv->wilc_ptk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001175 }
1176
1177
1178
Daniel Machon19132212015-08-05 08:18:31 +02001179 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001180 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1181 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1182 else
1183 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1184
1185 priv->wilc_groupkey = u8gmode;
1186
1187 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1188
1189 pu8TxMic = params->key + 24;
1190 pu8RxMic = params->key + 16;
1191 KeyLen = params->key_len - 16;
1192 }
1193 /* 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 +05301194 kfree(priv->wilc_gtk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001195
Glen Leef3052582015-09-10 12:03:04 +09001196 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001197 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001198
1199 /* 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 +05301200 kfree(priv->wilc_gtk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001201
1202 if ((params->seq_len) > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001203 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001204 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001205 }
1206
1207 priv->wilc_gtk[key_index]->cipher = params->cipher;
1208 priv->wilc_gtk[key_index]->key_len = params->key_len;
1209 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1210
1211 if (INFO) {
1212 for (i = 0; i < params->key_len; i++)
1213 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1214 for (i = 0; i < params->seq_len; i++)
1215 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1216 }
1217
1218
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001219 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001220 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode);
1221
1222 } else {
1223 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]);
1224
1225 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1226 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1227 else
1228 u8pmode = priv->wilc_groupkey | AES;
1229
1230
1231 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1232
1233 pu8TxMic = params->key + 24;
1234 pu8RxMic = params->key + 16;
1235 KeyLen = params->key_len - 16;
1236 }
1237
Shraddha Barkecccfc392015-10-12 20:49:19 +05301238 kfree(priv->wilc_ptk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001239
Glen Leef3052582015-09-10 12:03:04 +09001240 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001241
Shraddha Barkecccfc392015-10-12 20:49:19 +05301242 kfree(priv->wilc_ptk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001243
1244 if ((params->seq_len) > 0)
Glen Leef3052582015-09-10 12:03:04 +09001245 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001246
1247 if (INFO) {
1248 for (i = 0; i < params->key_len; i++)
1249 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1250
1251 for (i = 0; i < params->seq_len; i++)
1252 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1253 }
1254
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001255 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001256
1257 if ((params->seq_len) > 0)
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001258 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001259
1260 priv->wilc_ptk[key_index]->cipher = params->cipher;
1261 priv->wilc_ptk[key_index]->key_len = params->key_len;
1262 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1263
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001264 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001265 pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index);
1266 }
1267 break;
1268 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001269
1270 {
1271 u8mode = 0;
Daniel Machon19132212015-08-05 08:18:31 +02001272 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001273 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1274 /* swap the tx mic by rx mic */
1275 pu8RxMic = params->key + 24;
1276 pu8TxMic = params->key + 16;
1277 KeyLen = params->key_len - 16;
1278 }
1279
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001280 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001281 if (!g_gtk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001282 g_add_gtk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001283 g_add_gtk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001284 if (!mac_addr) {
1285 g_add_gtk_key_params.mac_addr = NULL;
1286 } else {
Glen Leef3052582015-09-10 12:03:04 +09001287 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001288 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1289 }
1290 g_key_gtk_params.key_len = params->key_len;
1291 g_key_gtk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001292 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001293 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1294 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001295 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001296 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1297 }
1298 g_key_gtk_params.cipher = params->cipher;
1299
1300 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1301 g_key_gtk_params.key[1],
1302 g_key_gtk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001303 g_gtk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001304 }
1305
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001306 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001307 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001308 } else {
1309 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1310 /* swap the tx mic by rx mic */
1311 pu8RxMic = params->key + 24;
1312 pu8TxMic = params->key + 16;
1313 KeyLen = params->key_len - 16;
1314 }
1315
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001316 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001317 if (!g_ptk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001318 g_add_ptk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001319 g_add_ptk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001320 if (!mac_addr) {
1321 g_add_ptk_key_params.mac_addr = NULL;
1322 } else {
Glen Leef3052582015-09-10 12:03:04 +09001323 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001324 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1325 }
1326 g_key_ptk_params.key_len = params->key_len;
1327 g_key_ptk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001328 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001329 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1330 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001331 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001332 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1333 }
1334 g_key_ptk_params.cipher = params->cipher;
1335
1336 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1337 g_key_ptk_params.key[1],
1338 g_key_ptk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001339 g_ptk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001340 }
1341
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001342 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001343 pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index);
1344 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1345 if (INFO) {
1346 for (i = 0; i < params->key_len; i++)
1347 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1348 }
1349 }
1350 }
1351 break;
1352
1353 default:
1354 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
1355 s32Error = -ENOTSUPP;
1356
1357 }
1358
1359 return s32Error;
1360}
1361
1362/**
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001363 * @brief del_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001364 * @details Remove a key given the @mac_addr (%NULL for a group key)
1365 * and @key_index, return -ENOENT if the key doesn't exist.
1366 * @param[in]
1367 * @return int : Return 0 on Success
1368 * @author mdaftedar
1369 * @date 01 MAR 2012
1370 * @version 1.0
1371 */
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001372static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1373 u8 key_index,
1374 bool pairwise,
1375 const u8 *mac_addr)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001376{
Chaehyun Lim27268872015-09-15 14:06:13 +09001377 struct wilc_priv *priv;
Glen Lee692e2ac2015-10-20 17:14:00 +09001378 struct wilc *wl;
1379 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001380
1381 priv = wiphy_priv(wiphy);
Glen Lee692e2ac2015-10-20 17:14:00 +09001382 nic = netdev_priv(netdev);
1383 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001384
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001385 /*delete saved keys, if any*/
Glen Lee692e2ac2015-10-20 17:14:00 +09001386 if (netdev == wl->vif[0].ndev) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09001387 g_ptk_keys_saved = false;
1388 g_gtk_keys_saved = false;
1389 g_wep_keys_saved = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001390
1391 /*Delete saved WEP keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301392 kfree(g_key_wep_params.key);
1393 g_key_wep_params.key = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001394
1395 /*freeing memory allocated by "wilc_gtk" and "wilc_ptk" in "WILC_WIFI_ADD_KEY"*/
1396
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001397 if ((priv->wilc_gtk[key_index]) != NULL) {
1398
Shraddha Barkecccfc392015-10-12 20:49:19 +05301399 kfree(priv->wilc_gtk[key_index]->key);
1400 priv->wilc_gtk[key_index]->key = NULL;
1401 kfree(priv->wilc_gtk[key_index]->seq);
1402 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001403
Chaehyun Lim49188af2015-08-11 10:32:41 +09001404 kfree(priv->wilc_gtk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001405 priv->wilc_gtk[key_index] = NULL;
1406
1407 }
1408
1409 if ((priv->wilc_ptk[key_index]) != NULL) {
1410
Shraddha Barkecccfc392015-10-12 20:49:19 +05301411 kfree(priv->wilc_ptk[key_index]->key);
1412 priv->wilc_ptk[key_index]->key = NULL;
1413 kfree(priv->wilc_ptk[key_index]->seq);
1414 priv->wilc_ptk[key_index]->seq = NULL;
Chaehyun Lim49188af2015-08-11 10:32:41 +09001415 kfree(priv->wilc_ptk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001416 priv->wilc_ptk[key_index] = NULL;
1417 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001418
1419 /*Delete saved PTK and GTK keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301420 kfree(g_key_ptk_params.key);
1421 g_key_ptk_params.key = NULL;
1422 kfree(g_key_ptk_params.seq);
1423 g_key_ptk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001424
Shraddha Barkecccfc392015-10-12 20:49:19 +05301425 kfree(g_key_gtk_params.key);
1426 g_key_gtk_params.key = NULL;
1427 kfree(g_key_gtk_params.seq);
1428 g_key_gtk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001429
1430 /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001431 wilc_set_machw_change_vir_if(netdev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001432 }
1433
1434 if (key_index >= 0 && key_index <= 3) {
Chaehyun Lim2cc46832015-08-07 09:02:01 +09001435 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001436 priv->WILC_WFI_wep_key_len[key_index] = 0;
1437
1438 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001439 wilc_remove_wep_key(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001440 } else {
1441 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001442 wilc_remove_key(priv->hWILCWFIDrv, mac_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001443 }
1444
Leo Kimaaed3292015-10-12 16:55:38 +09001445 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001446}
1447
1448/**
Chaehyun Limf4893df2015-09-14 12:24:07 +09001449 * @brief get_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001450 * @details Get information about the key with the given parameters.
1451 * @mac_addr will be %NULL when requesting information for a group
1452 * key. All pointers given to the @callback function need not be valid
1453 * after it returns. This function should return an error if it is
1454 * not possible to retrieve the key, -ENOENT if it doesn't exist.
1455 * @param[in]
1456 * @return int : Return 0 on Success
1457 * @author mdaftedar
1458 * @date 01 MAR 2012
1459 * @version 1.0
1460 */
Chaehyun Limf4893df2015-09-14 12:24:07 +09001461static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1462 bool pairwise,
1463 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001464{
Chaehyun Lim27268872015-09-15 14:06:13 +09001465 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001466 struct key_params key_params;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001467 u32 i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001468
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001469 priv = wiphy_priv(wiphy);
1470
1471
Alison Schofield3604af52015-10-12 13:22:44 -07001472 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001473 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1474
1475 key_params.key = priv->wilc_gtk[key_index]->key;
1476 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1477 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1478 key_params.seq = priv->wilc_gtk[key_index]->seq;
1479 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1480 if (INFO) {
1481 for (i = 0; i < key_params.key_len; i++)
1482 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1483 }
1484 } else {
1485 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1486
1487 key_params.key = priv->wilc_ptk[key_index]->key;
1488 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1489 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1490 key_params.seq = priv->wilc_ptk[key_index]->seq;
1491 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1492 }
1493
1494 callback(cookie, &key_params);
1495
Leo Kimaaed3292015-10-12 16:55:38 +09001496 return 0; /* priv->wilc_gtk->key_len ?0 : -ENOENT; */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001497}
1498
1499/**
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001500 * @brief set_default_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001501 * @details Set the default management frame key on an interface
1502 * @param[in]
1503 * @return int : Return 0 on Success.
1504 * @author mdaftedar
1505 * @date 01 MAR 2012
1506 * @version 1.0
1507 */
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001508static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1509 bool unicast, bool multicast)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001510{
Chaehyun Lim27268872015-09-15 14:06:13 +09001511 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001512
1513
1514 priv = wiphy_priv(wiphy);
1515
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301516 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001517
1518 if (key_index != priv->WILC_WFI_wep_default) {
1519
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001520 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001521 }
1522
Leo Kimaaed3292015-10-12 16:55:38 +09001523 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001524}
1525
1526/**
Chaehyun Limf06f5622015-09-14 12:24:18 +09001527 * @brief get_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001528 * @details Get station information for the station identified by @mac
1529 * @param[in] NONE
1530 * @return int : Return 0 on Success.
1531 * @author mdaftedar
1532 * @date 01 MAR 2012
1533 * @version 1.0
1534 */
1535
Chaehyun Limf06f5622015-09-14 12:24:18 +09001536static int get_station(struct wiphy *wiphy, struct net_device *dev,
1537 const u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001538{
Chaehyun Lim27268872015-09-15 14:06:13 +09001539 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001540 perInterface_wlan_t *nic;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001541 u32 i = 0;
1542 u32 associatedsta = 0;
1543 u32 inactive_time = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001544 priv = wiphy_priv(wiphy);
1545 nic = netdev_priv(dev);
1546
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001547 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
1548 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1549
1550 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1551
1552 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1553
1554 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1555 associatedsta = i;
1556 break;
1557 }
1558
1559 }
1560
1561 if (associatedsta == -1) {
Leo Kimaaed3292015-10-12 16:55:38 +09001562 PRINT_ER("Station required is not associated\n");
1563 return -ENOENT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001564 }
1565
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001566 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001567
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001568 wilc_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001569 sinfo->inactive_time = 1000 * inactive_time;
1570 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
1571
1572 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001573
1574 if (nic->iftype == STATION_MODE) {
Leo Kim03e7b9c2015-10-12 16:55:58 +09001575 struct rf_info strStatistics;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001576
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001577 wilc_get_statistics(priv->hWILCWFIDrv, &strStatistics);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001578
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001579 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
Chandra S Gorentla62129902015-08-05 22:11:57 +05301580 BIT(NL80211_STA_INFO_RX_PACKETS) |
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001581 BIT(NL80211_STA_INFO_TX_PACKETS) |
1582 BIT(NL80211_STA_INFO_TX_FAILED) |
1583 BIT(NL80211_STA_INFO_TX_BITRATE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001584
Leo Kim00c8dfc2015-10-29 12:05:30 +09001585 sinfo->signal = strStatistics.rssi;
Leo Kim9b992742015-10-29 12:05:32 +09001586 sinfo->rx_packets = strStatistics.rx_cnt;
Leo Kim54160372015-10-29 12:05:33 +09001587 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1588 sinfo->tx_failed = strStatistics.tx_fail_cnt;
Leo Kim5babeec2015-10-29 12:05:29 +09001589 sinfo->txrate.legacy = strStatistics.link_speed * 10;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001590
Leo Kim5babeec2015-10-29 12:05:29 +09001591 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1592 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001593 wilc_enable_tcp_ack_filter(true);
Leo Kim5babeec2015-10-29 12:05:29 +09001594 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001595 wilc_enable_tcp_ack_filter(false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001596
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001597 PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
1598 sinfo->tx_failed, sinfo->txrate.legacy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001599 }
Leo Kimaaed3292015-10-12 16:55:38 +09001600 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001601}
1602
1603
1604/**
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001605 * @brief change_bss
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001606 * @details Modify parameters for a given BSS.
1607 * @param[in]
1608 * -use_cts_prot: Whether to use CTS protection
1609 * (0 = no, 1 = yes, -1 = do not change)
1610 * -use_short_preamble: Whether the use of short preambles is allowed
1611 * (0 = no, 1 = yes, -1 = do not change)
1612 * -use_short_slot_time: Whether the use of short slot time is allowed
1613 * (0 = no, 1 = yes, -1 = do not change)
1614 * -basic_rates: basic rates in IEEE 802.11 format
1615 * (or NULL for no change)
1616 * -basic_rates_len: number of basic rates
1617 * -ap_isolate: do not forward packets between connected stations
1618 * -ht_opmode: HT Operation mode
1619 * (u16 = opmode, -1 = do not change)
1620 * @return int : Return 0 on Success.
1621 * @author mdaftedar
1622 * @date 01 MAR 2012
1623 * @version 1.0
1624 */
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001625static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1626 struct bss_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001627{
1628 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1629 return 0;
1630}
1631
1632/**
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001633 * @brief set_wiphy_params
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001634 * @details Notify that wiphy parameters have changed;
1635 * @param[in] Changed bitfield (see &enum wiphy_params_flags) describes which values
1636 * have changed.
1637 * @return int : Return 0 on Success
1638 * @author mdaftedar
1639 * @date 01 MAR 2012
1640 * @version 1.0
1641 */
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001642static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001643{
Leo Kime6e12662015-09-16 18:36:03 +09001644 s32 s32Error = 0;
Leo Kim95296502015-10-05 15:25:46 +09001645 struct cfg_param_val pstrCfgParamVal;
Chaehyun Lim27268872015-09-15 14:06:13 +09001646 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001647
1648 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001649
Tony Cho87c05b22015-10-12 16:56:07 +09001650 pstrCfgParamVal.flag = 0;
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301651 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001652
1653 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1654 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1655 priv->dev->ieee80211_ptr->wiphy->retry_short);
Tony Cho87c05b22015-10-12 16:56:07 +09001656 pstrCfgParamVal.flag |= RETRY_SHORT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001657 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1658 }
1659 if (changed & WIPHY_PARAM_RETRY_LONG) {
1660
1661 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 +09001662 pstrCfgParamVal.flag |= RETRY_LONG;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001663 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1664
1665 }
1666 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1667 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 +09001668 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001669 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1670
1671 }
1672
1673 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1674 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1675
Tony Cho87c05b22015-10-12 16:56:07 +09001676 pstrCfgParamVal.flag |= RTS_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001677 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1678
1679 }
1680
1681 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001682 s32Error = wilc_hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001683 if (s32Error)
1684 PRINT_ER("Error in setting WIPHY PARAMS\n");
1685
1686
1687 return s32Error;
1688}
Arnd Bergmanne5af0562015-05-29 22:52:12 +02001689
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001690/**
Chaehyun Lim4d466572015-09-14 12:24:22 +09001691 * @brief set_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001692 * @details Cache a PMKID for a BSSID. This is mostly useful for fullmac
1693 * devices running firmwares capable of generating the (re) association
1694 * RSN IE. It allows for faster roaming between WPA2 BSSIDs.
1695 * @param[in]
1696 * @return int : Return 0 on Success
1697 * @author mdaftedar
1698 * @date 01 MAR 2012
1699 * @version 1.0
1700 */
Chaehyun Lim4d466572015-09-14 12:24:22 +09001701static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1702 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001703{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001704 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001705 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001706 u8 flag = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001707
Chaehyun Lim27268872015-09-15 14:06:13 +09001708 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001709
1710 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1711
1712
1713 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001714 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001715 ETH_ALEN)) {
1716 /*If bssid already exists and pmkid value needs to reset*/
1717 flag = PMKID_FOUND;
1718 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1719 break;
1720 }
1721 }
1722 if (i < WILC_MAX_NUM_PMKIDS) {
1723 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001724 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001725 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001726 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001727 PMKID_LEN);
1728 if (!(flag == PMKID_FOUND))
1729 priv->pmkid_list.numpmkid++;
1730 } else {
1731 PRINT_ER("Invalid PMKID index\n");
1732 s32Error = -EINVAL;
1733 }
1734
1735 if (!s32Error) {
1736 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001737 s32Error = wilc_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001738 }
1739 return s32Error;
1740}
1741
1742/**
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001743 * @brief del_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001744 * @details Delete a cached PMKID.
1745 * @param[in]
1746 * @return int : Return 0 on Success
1747 * @author mdaftedar
1748 * @date 01 MAR 2012
1749 * @version 1.0
1750 */
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001751static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1752 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001753{
1754
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001755 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001756 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001757
Chaehyun Lim27268872015-09-15 14:06:13 +09001758 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001759
1760 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1761
1762 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001763 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001764 ETH_ALEN)) {
1765 /*If bssid is found, reset the values*/
1766 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
Leo Kimcd1e6cb2015-10-05 15:25:45 +09001767 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001768 break;
1769 }
1770 }
1771
1772 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1773 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001774 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001775 priv->pmkid_list.pmkidlist[i + 1].bssid,
1776 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001777 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001778 priv->pmkid_list.pmkidlist[i].pmkid,
1779 PMKID_LEN);
1780 }
1781 priv->pmkid_list.numpmkid--;
1782 } else {
1783 s32Error = -EINVAL;
1784 }
1785
1786 return s32Error;
1787}
1788
1789/**
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001790 * @brief flush_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001791 * @details Flush all cached PMKIDs.
1792 * @param[in]
1793 * @return int : Return 0 on Success
1794 * @author mdaftedar
1795 * @date 01 MAR 2012
1796 * @version 1.0
1797 */
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001798static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001799{
Chaehyun Lim27268872015-09-15 14:06:13 +09001800 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001801
1802 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
1803
1804 /*Get cashed Pmkids and set all with zeros*/
Leo Kima949f902015-10-05 15:25:44 +09001805 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001806
1807 return 0;
1808}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001809
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001810
1811/**
1812 * @brief WILC_WFI_CfgParseRxAction
1813 * @details Function parses the received frames and modifies the following attributes:
1814 * -GO Intent
1815 * -Channel list
1816 * -Operating Channel
1817 *
1818 * @param[in] u8* Buffer, u32 length
1819 * @return NONE.
1820 * @author mdaftedar
1821 * @date 12 DEC 2012
1822 * @version
1823 */
1824
Arnd Bergmann1608c402015-11-16 15:04:53 +01001825static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001826{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001827 u32 index = 0;
1828 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001829
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001830 u8 op_channel_attr_index = 0;
1831 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001832
1833 while (index < len) {
1834 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001835 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001836 }
1837
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301838 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001839 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301840 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001841 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001842 index += buf[index + 1] + 3; /* ID,Length byte */
1843 }
Leo Kim0bd82742015-11-19 15:56:14 +09001844 if (wlan_channel != INVALID_CHANNEL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001845 /*Modify channel list attribute*/
1846 if (channel_list_attr_index) {
1847 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1848 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1849 if (buf[i] == 0x51) {
1850 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
Leo Kim0bd82742015-11-19 15:56:14 +09001851 buf[j] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001852 }
1853 break;
1854 }
1855 }
1856 }
1857 /*Modify operating channel attribute*/
1858 if (op_channel_attr_index) {
1859 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1860 buf[op_channel_attr_index + 6] = 0x51;
Leo Kim0bd82742015-11-19 15:56:14 +09001861 buf[op_channel_attr_index + 7] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001862 }
1863 }
1864}
1865
1866/**
1867 * @brief WILC_WFI_CfgParseTxAction
1868 * @details Function parses the transmitted action frames and modifies the
1869 * GO Intent attribute
1870 * @param[in] u8* Buffer, u32 length, bool bOperChan, u8 iftype
1871 * @return NONE.
1872 * @author mdaftedar
1873 * @date 12 DEC 2012
1874 * @version
1875 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01001876static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001877{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001878 u32 index = 0;
1879 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001880
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001881 u8 op_channel_attr_index = 0;
1882 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001883
1884 while (index < len) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001885 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001886 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001887
1888 break;
1889 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001890
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301891 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001892 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301893 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001894 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001895 index += buf[index + 1] + 3; /* ID,Length byte */
1896 }
Leo Kim0bd82742015-11-19 15:56:14 +09001897 if (wlan_channel != INVALID_CHANNEL && bOperChan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001898 /*Modify channel list attribute*/
1899 if (channel_list_attr_index) {
1900 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1901 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1902 if (buf[i] == 0x51) {
1903 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
Leo Kim0bd82742015-11-19 15:56:14 +09001904 buf[j] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001905 }
1906 break;
1907 }
1908 }
1909 }
1910 /*Modify operating channel attribute*/
1911 if (op_channel_attr_index) {
1912 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1913 buf[op_channel_attr_index + 6] = 0x51;
Leo Kim0bd82742015-11-19 15:56:14 +09001914 buf[op_channel_attr_index + 7] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001915 }
1916 }
1917}
1918
1919/* @brief WILC_WFI_p2p_rx
1920 * @details
1921 * @param[in]
1922 *
1923 * @return None
1924 * @author Mai Daftedar
1925 * @date 2 JUN 2013
1926 * @version 1.0
1927 */
1928
Chaehyun Limfbc2fe12015-09-15 14:06:16 +09001929void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001930{
1931
Chaehyun Lim27268872015-09-15 14:06:13 +09001932 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001933 u32 header, pkt_offset;
Leo Kim441dc602015-10-12 16:55:35 +09001934 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001935 u32 i = 0;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001936 s32 s32Freq;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001937
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001938 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001939 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001940
1941 /* Get WILC header */
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001942 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001943
1944 /* The packet offset field conain info about what type of managment frame */
1945 /* we are dealing with and ack status */
1946 pkt_offset = GET_PKT_OFFSET(header);
1947
1948 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1949 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1950 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001951 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001952 return;
1953 } else {
1954 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
1955 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],
1956 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001957 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001958 } else {
1959 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],
1960 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001961 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001962 }
1963 return;
1964 }
1965 } else {
1966
1967 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
1968
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001969 /*Upper layer is informed that the frame is received on this freq*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001970 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001971
1972 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1973 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
1974
Leo Kim1229b1a2015-10-29 12:05:39 +09001975 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001976 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
1977 return;
1978 }
1979 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1980
1981 switch (buff[ACTION_SUBTYPE_ID]) {
1982 case GAS_INTIAL_REQ:
1983 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
1984 break;
1985
1986 case GAS_INTIAL_RSP:
1987 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
1988 break;
1989
1990 case PUBLIC_ACT_VENDORSPEC:
Leo Kim881eb5d2015-11-19 15:56:15 +09001991 if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001992 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
Leo Kima25d5182015-11-19 15:56:19 +09001993 if (!wilc_ie) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001994 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
Leo Kim86685942015-11-19 15:56:18 +09001995 if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09001996 p2p_recv_random = buff[i + 6];
Leo Kima25d5182015-11-19 15:56:19 +09001997 wilc_ie = true;
Leo Kimb84a3ac2015-11-19 15:56:17 +09001998 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", p2p_recv_random);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001999 break;
2000 }
2001 }
2002 }
2003 }
Leo Kimb84a3ac2015-11-19 15:56:17 +09002004 if (p2p_local_random > p2p_recv_random) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002005 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2006 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2007 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
Leo Kim881eb5d2015-11-19 15:56:15 +09002008 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002009 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
2010 break;
2011 }
2012 }
2013 }
Leo Kim583d9722015-11-19 15:56:16 +09002014 } else {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002015 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 +09002016 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002017 }
2018
2019
Leo Kima25d5182015-11-19 15:56:19 +09002020 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 +09002021 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
2022 /* extra attribute for sig_dbm: signal strength in mBm, or 0 if unknown */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002023 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002024 return;
2025 }
2026 break;
2027
2028 default:
2029 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
2030 break;
2031 }
2032 }
2033 }
2034
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002035 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002036 }
2037}
2038
2039/**
2040 * @brief WILC_WFI_mgmt_tx_complete
2041 * @details Returns result of writing mgmt frame to VMM (Tx buffers are freed here)
2042 * @param[in] priv
2043 * transmitting status
2044 * @return None
2045 * @author Amr Abdelmoghny
2046 * @date 20 MAY 2013
2047 * @version 1.0
2048 */
2049static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
2050{
2051 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
2052
2053
2054 kfree(pv_data->buff);
2055 kfree(pv_data);
2056}
2057
2058/**
2059 * @brief WILC_WFI_RemainOnChannelReady
2060 * @details Callback function, called from handle_remain_on_channel on being ready on channel
2061 * @param
2062 * @return none
2063 * @author Amr abdelmoghny
2064 * @date 9 JUNE 2013
2065 * @version
2066 */
2067
2068static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
2069{
Chaehyun Lim27268872015-09-15 14:06:13 +09002070 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002071
Chaehyun Lim27268872015-09-15 14:06:13 +09002072 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002073
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302074 PRINT_D(HOSTINF_DBG, "Remain on channel ready\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002075
Dean Lee72ed4dc2015-06-12 14:11:44 +09002076 priv->bInP2PlistenState = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002077
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002078 cfg80211_ready_on_channel(priv->wdev,
2079 priv->strRemainOnChanParams.u64ListenCookie,
2080 priv->strRemainOnChanParams.pstrListenChan,
2081 priv->strRemainOnChanParams.u32ListenDuration,
2082 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002083}
2084
2085/**
2086 * @brief WILC_WFI_RemainOnChannelExpired
2087 * @details Callback function, called on expiration of remain-on-channel duration
2088 * @param
2089 * @return none
2090 * @author Amr abdelmoghny
2091 * @date 15 MAY 2013
2092 * @version
2093 */
2094
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002095static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002096{
Chaehyun Lim27268872015-09-15 14:06:13 +09002097 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002098
Chaehyun Lim27268872015-09-15 14:06:13 +09002099 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002100
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002101 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302102 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002103
Dean Lee72ed4dc2015-06-12 14:11:44 +09002104 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002105
2106 /*Inform wpas of remain-on-channel expiration*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002107 cfg80211_remain_on_channel_expired(priv->wdev,
2108 priv->strRemainOnChanParams.u64ListenCookie,
2109 priv->strRemainOnChanParams.pstrListenChan,
2110 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002111 } else {
2112 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
2113 , priv->strRemainOnChanParams.u32ListenSessionID);
2114 }
2115}
2116
2117
2118/**
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002119 * @brief remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002120 * @details Request the driver to remain awake on the specified
2121 * channel for the specified duration to complete an off-channel
2122 * operation (e.g., public action frame exchange). When the driver is
2123 * ready on the requested channel, it must indicate this with an event
2124 * notification by calling cfg80211_ready_on_channel().
2125 * @param[in]
2126 * @return int : Return 0 on Success
2127 * @author mdaftedar
2128 * @date 01 MAR 2012
2129 * @version 1.0
2130 */
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002131static int remain_on_channel(struct wiphy *wiphy,
2132 struct wireless_dev *wdev,
2133 struct ieee80211_channel *chan,
2134 unsigned int duration, u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002135{
Leo Kime6e12662015-09-16 18:36:03 +09002136 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002137 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002138
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002139 priv = wiphy_priv(wiphy);
2140
2141 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
2142
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002143
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002144 if (wdev->iftype == NL80211_IFTYPE_AP) {
2145 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
2146 return s32Error;
2147 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002148
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002149 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002150
2151 /*Setting params needed by WILC_WFI_RemainOnChannelExpired()*/
2152 priv->strRemainOnChanParams.pstrListenChan = chan;
2153 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002154 priv->strRemainOnChanParams.u32ListenDuration = duration;
2155 priv->strRemainOnChanParams.u32ListenSessionID++;
2156
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002157 s32Error = wilc_remain_on_channel(priv->hWILCWFIDrv
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002158 , priv->strRemainOnChanParams.u32ListenSessionID
2159 , duration
2160 , chan->hw_value
2161 , WILC_WFI_RemainOnChannelExpired
2162 , WILC_WFI_RemainOnChannelReady
2163 , (void *)priv);
2164
2165 return s32Error;
2166}
2167
2168/**
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002169 * @brief cancel_remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002170 * @details Cancel an on-going remain-on-channel operation.
2171 * This allows the operation to be terminated prior to timeout based on
2172 * the duration value.
2173 * @param[in] struct wiphy *wiphy,
2174 * @param[in] struct net_device *dev
2175 * @param[in] u64 cookie,
2176 * @return int : Return 0 on Success
2177 * @author mdaftedar
2178 * @date 01 MAR 2012
2179 * @version 1.0
2180 */
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002181static int cancel_remain_on_channel(struct wiphy *wiphy,
2182 struct wireless_dev *wdev,
2183 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002184{
Leo Kime6e12662015-09-16 18:36:03 +09002185 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002186 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002187
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002188 priv = wiphy_priv(wiphy);
2189
2190 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
2191
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002192 s32Error = wilc_listen_state_expired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002193 return s32Error;
2194}
2195/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002196 * @brief WILC_WFI_mgmt_tx_frame
2197 * @details
2198 *
2199 * @param[in]
2200 * @return NONE.
2201 * @author mdaftedar
2202 * @date 01 JUL 2012
2203 * @version
2204 */
Chaehyun Limc1560322015-09-22 18:34:51 +09002205static int mgmt_tx(struct wiphy *wiphy,
2206 struct wireless_dev *wdev,
2207 struct cfg80211_mgmt_tx_params *params,
2208 u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002209{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002210 struct ieee80211_channel *chan = params->chan;
2211 unsigned int wait = params->wait;
2212 const u8 *buf = params->buf;
2213 size_t len = params->len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002214 const struct ieee80211_mgmt *mgmt;
2215 struct p2p_mgmt_data *mgmt_tx;
Chaehyun Lim27268872015-09-15 14:06:13 +09002216 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002217 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002218 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002219 perInterface_wlan_t *nic;
Leo Kim86685942015-11-19 15:56:18 +09002220 u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002221
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002222 nic = netdev_priv(wdev->netdev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002223 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002224 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002225
2226 *cookie = (unsigned long)buf;
2227 priv->u64tx_cookie = *cookie;
2228 mgmt = (const struct ieee80211_mgmt *) buf;
2229
2230 if (ieee80211_is_mgmt(mgmt->frame_control)) {
2231
2232 /*mgmt frame allocation*/
Glen Leef3052582015-09-10 12:03:04 +09002233 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002234 if (mgmt_tx == NULL) {
2235 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
Leo Kime6e12662015-09-16 18:36:03 +09002236 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002237 }
Glen Leef3052582015-09-10 12:03:04 +09002238 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002239 if (mgmt_tx->buff == NULL) {
2240 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
Tony Chof638dd32015-09-07 19:09:31 +09002241 kfree(mgmt_tx);
Leo Kime6e12662015-09-16 18:36:03 +09002242 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002243 }
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09002244 memcpy(mgmt_tx->buff, buf, len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002245 mgmt_tx->size = len;
2246
2247
2248 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
2249 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
2250 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002251 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002252 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002253 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002254 } else if (ieee80211_is_action(mgmt->frame_control)) {
Chaehyun Limd85f5322015-06-11 14:35:54 +09002255 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002256
2257
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002258 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002259 /*Only set the channel, if not a negotiation confirmation frame
2260 * (If Negotiation confirmation frame, force it
2261 * to be transmitted on the same negotiation channel)*/
2262
2263 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
2264 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
2265 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002266 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002267 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002268 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002269 }
2270 switch (buf[ACTION_SUBTYPE_ID]) {
2271 case GAS_INTIAL_REQ:
2272 {
2273 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
2274 break;
2275 }
2276
2277 case GAS_INTIAL_RSP:
2278 {
2279 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
2280 break;
2281 }
2282
2283 case PUBLIC_ACT_VENDORSPEC:
2284 {
Leo Kim881eb5d2015-11-19 15:56:15 +09002285 if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002286 /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/
2287 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002288 if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
Leo Kim583d9722015-11-19 15:56:16 +09002289 get_random_bytes(&p2p_local_random, 1);
2290 p2p_local_random++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002291 }
2292 }
2293
2294 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2295 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002296 if (p2p_local_random > p2p_recv_random) {
2297 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 +09002298
2299 /*Search for the p2p information information element , after the Public action subtype theres a byte for teh dialog token, skip that*/
2300 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
Leo Kim881eb5d2015-11-19 15:56:15 +09002301 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002302 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
Dean Lee72ed4dc2015-06-12 14:11:44 +09002303 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002304
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002305 /*If using supplicant go intent, no need at all*/
2306 /*to parse transmitted negotiation frames*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002307 else
Dean Lee72ed4dc2015-06-12 14:11:44 +09002308 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002309 break;
2310 }
2311 }
2312
2313 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
Shivani Bhardwajd8060fc2015-10-29 00:30:01 +05302314 /*
2315 * Adding WILC information element to allow two WILC devices to
2316 * identify each other and connect
2317 */
Leo Kim86685942015-11-19 15:56:18 +09002318 memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
2319 mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002320 mgmt_tx->size = buf_len;
2321 }
Leo Kim583d9722015-11-19 15:56:16 +09002322 } else {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002323 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 +09002324 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002325 }
2326
2327 } else {
2328 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
2329 }
2330
2331 break;
2332 }
2333
2334 default:
2335 {
2336 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
2337 break;
2338 }
2339 }
2340
2341 }
2342
2343 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 +09002344 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002345
Leo Kim1229b1a2015-10-29 12:05:39 +09002346 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n",
2347 jiffies, pstrWFIDrv->p2p_timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002348 }
2349
Glen Lee829c4772015-10-29 12:18:44 +09002350 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
2351 mgmt_tx->buff, mgmt_tx->size,
Glen Leec9d48342015-10-01 16:03:43 +09002352 WILC_WFI_mgmt_tx_complete);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002353 } else {
2354 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
2355 }
Leo Kimaaed3292015-10-12 16:55:38 +09002356 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002357}
2358
Chaehyun Lim85c587a2015-09-22 18:34:50 +09002359static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
2360 struct wireless_dev *wdev,
2361 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002362{
Chaehyun Lim27268872015-09-15 14:06:13 +09002363 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002364 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002365
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002366 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002367 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002368
2369
2370 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
Leo Kim1229b1a2015-10-29 12:05:39 +09002371 pstrWFIDrv->p2p_timeout = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002372
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +01002373 if (!priv->bInP2PlistenState) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002374 cfg80211_remain_on_channel_expired(priv->wdev,
2375 priv->strRemainOnChanParams.u64ListenCookie,
2376 priv->strRemainOnChanParams.pstrListenChan,
2377 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002378 }
2379
2380 return 0;
2381}
2382
2383/**
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002384 * @brief wilc_mgmt_frame_register
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002385 * @details Notify driver that a management frame type was
2386 * registered. Note that this callback may not sleep, and cannot run
2387 * concurrently with itself.
2388 * @param[in]
2389 * @return NONE.
2390 * @author mdaftedar
2391 * @date 01 JUL 2012
2392 * @version
2393 */
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002394void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
2395 u16 frame_type, bool reg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002396{
2397
Chaehyun Lim27268872015-09-15 14:06:13 +09002398 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002399 perInterface_wlan_t *nic;
Glen Lee1b869352015-10-20 17:14:01 +09002400 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002401
2402 priv = wiphy_priv(wiphy);
2403 nic = netdev_priv(priv->wdev->netdev);
Glen Lee1b869352015-10-20 17:14:01 +09002404 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002405
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002406 if (!frame_type)
2407 return;
2408
2409 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
2410 switch (frame_type) {
2411 case PROBE_REQ:
2412 {
2413 nic->g_struct_frame_reg[0].frame_type = frame_type;
2414 nic->g_struct_frame_reg[0].reg = reg;
2415 }
2416 break;
2417
2418 case ACTION:
2419 {
2420 nic->g_struct_frame_reg[1].frame_type = frame_type;
2421 nic->g_struct_frame_reg[1].reg = reg;
2422 }
2423 break;
2424
2425 default:
2426 {
2427 break;
2428 }
2429
2430 }
2431 /*If mac is closed, then return*/
Glen Lee1b869352015-10-20 17:14:01 +09002432 if (!wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002433 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
2434 return;
2435 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002436 wilc_frame_register(priv->hWILCWFIDrv, frame_type, reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002437
2438
2439}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002440
2441/**
Chaehyun Lima8047e22015-09-22 18:34:48 +09002442 * @brief set_cqm_rssi_config
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002443 * @details Configure connection quality monitor RSSI threshold.
2444 * @param[in] struct wiphy *wiphy:
2445 * @param[in] struct net_device *dev:
2446 * @param[in] s32 rssi_thold:
2447 * @param[in] u32 rssi_hyst:
2448 * @return int : Return 0 on Success
2449 * @author mdaftedar
2450 * @date 01 MAR 2012
2451 * @version 1.0
2452 */
Chaehyun Lima8047e22015-09-22 18:34:48 +09002453static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
2454 s32 rssi_thold, u32 rssi_hyst)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002455{
2456 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2457 return 0;
2458
2459}
2460/**
Chaehyun Limbdb63382015-09-14 12:24:19 +09002461 * @brief dump_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002462 * @details Configure connection quality monitor RSSI threshold.
2463 * @param[in] struct wiphy *wiphy:
2464 * @param[in] struct net_device *dev
2465 * @param[in] int idx
2466 * @param[in] u8 *mac
2467 * @param[in] struct station_info *sinfo
2468 * @return int : Return 0 on Success
2469 * @author mdaftedar
2470 * @date 01 MAR 2012
2471 * @version 1.0
2472 */
Chaehyun Limbdb63382015-09-14 12:24:19 +09002473static int dump_station(struct wiphy *wiphy, struct net_device *dev,
2474 int idx, u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002475{
Chaehyun Lim27268872015-09-15 14:06:13 +09002476 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002477
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002478 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2479
2480 if (idx != 0)
2481 return -ENOENT;
2482
2483 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002484
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002485 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002486
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002487 wilc_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002488
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002489 return 0;
2490
2491}
2492
2493
2494/**
Chaehyun Lim46530672015-09-22 18:34:46 +09002495 * @brief set_power_mgmt
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002496 * @details
2497 * @param[in]
2498 * @return int : Return 0 on Success.
2499 * @author mdaftedar
2500 * @date 01 JUL 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09002501 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002502 */
Chaehyun Lim46530672015-09-22 18:34:46 +09002503static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2504 bool enabled, int timeout)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002505{
Chaehyun Lim27268872015-09-15 14:06:13 +09002506 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002507
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002508 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2509
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002510 if (wiphy == NULL)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002511 return -ENOENT;
2512
2513 priv = wiphy_priv(wiphy);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002514 if (priv->hWILCWFIDrv == NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002515 PRINT_ER("Driver is NULL\n");
2516 return -EIO;
2517 }
2518
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002519 if (wilc_enable_ps)
2520 wilc_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002521
2522
Leo Kime6e12662015-09-16 18:36:03 +09002523 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002524
2525}
Glen Lee108b3432015-09-16 18:53:20 +09002526
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002527/**
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002528 * @brief change_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002529 * @details Change type/configuration of virtual interface,
2530 * keep the struct wireless_dev's iftype updated.
2531 * @param[in] NONE
2532 * @return int : Return 0 on Success.
2533 * @author mdaftedar
2534 * @date 01 MAR 2012
2535 * @version 1.0
2536 */
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002537static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2538 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002539{
Chaehyun Lim27268872015-09-15 14:06:13 +09002540 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002541 perInterface_wlan_t *nic;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002542 u8 interface_type;
Chaehyun Limd85f5322015-06-11 14:35:54 +09002543 u16 TID = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002544 u8 i;
Glen Lee299382c2015-10-20 17:13:56 +09002545 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002546
2547 nic = netdev_priv(dev);
2548 priv = wiphy_priv(wiphy);
Glen Lee299382c2015-10-20 17:13:56 +09002549 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002550
2551 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2552 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
Leo Kim583d9722015-11-19 15:56:16 +09002553 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +09002554 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +09002555 wilc_ie = false;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002556 wilc_optaining_ip = false;
2557 del_timer(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002558 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002559 /*Set WILC_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/
2560 if (g_ptk_keys_saved && g_gtk_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002561 wilc_set_machw_change_vir_if(dev, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002562 }
2563
2564 switch (type) {
2565 case NL80211_IFTYPE_STATION:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002566 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002567 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002568
2569 /* send delba over wlan interface */
2570
2571
2572 dev->ieee80211_ptr->iftype = type;
2573 priv->wdev->iftype = type;
2574 nic->monitor_flag = 0;
2575 nic->iftype = STATION_MODE;
2576
2577 /*Remove the enteries of the previously connected clients*/
2578 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002579 interface_type = nic->iftype;
2580 nic->iftype = STATION_MODE;
2581
Glen Lee299382c2015-10-20 17:13:56 +09002582 if (wl->initialized) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002583 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2584 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002585 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002586 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002587
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002588 /*Eliminate host interface blocking state*/
Glen Lee299382c2015-10-20 17:13:56 +09002589 up(&wl->cfg_event);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002590
Glen Lee53dc0cf2015-10-20 17:13:57 +09002591 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002592 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002593 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002594 nic->iftype = interface_type;
2595
2596 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002597 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2598 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002599 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002600 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002601
2602 /*Add saved WEP keys, if any*/
2603 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002604 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002605 g_key_wep_params.key_idx);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002606 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002607 g_key_wep_params.key,
2608 g_key_wep_params.key_len,
2609 g_key_wep_params.key_idx);
2610 }
2611
2612 /*No matter the driver handler passed here, it will be overwriiten*/
2613 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002614 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002615
2616 /*Add saved PTK and GTK keys, if any*/
2617 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2618 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2619 g_key_ptk_params.key[1],
2620 g_key_ptk_params.key[2]);
2621 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2622 g_key_gtk_params.key[1],
2623 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002624 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2625 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002626 g_add_ptk_key_params.key_idx,
2627 g_add_ptk_key_params.pairwise,
2628 g_add_ptk_key_params.mac_addr,
2629 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002630
Glen Lee299382c2015-10-20 17:13:56 +09002631 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2632 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002633 g_add_gtk_key_params.key_idx,
2634 g_add_gtk_key_params.pairwise,
2635 g_add_gtk_key_params.mac_addr,
2636 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002637 }
2638
Glen Lee299382c2015-10-20 17:13:56 +09002639 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002640 for (i = 0; i < num_reg_frame; i++) {
2641 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2642 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002643 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002644 nic->g_struct_frame_reg[i].frame_type,
2645 nic->g_struct_frame_reg[i].reg);
2646 }
2647 }
2648
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002649 wilc_enable_ps = true;
2650 wilc_set_power_mgmt(priv->hWILCWFIDrv, 1, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002651 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002652 break;
2653
2654 case NL80211_IFTYPE_P2P_CLIENT:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002655 wilc_enable_ps = false;
2656 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
2657 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002658 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002659
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002660 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2661 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002662
2663 dev->ieee80211_ptr->iftype = type;
2664 priv->wdev->iftype = type;
2665 nic->monitor_flag = 0;
2666
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002667 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2668 nic->iftype = CLIENT_MODE;
2669
2670
Glen Lee299382c2015-10-20 17:13:56 +09002671 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002672 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002673 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002674
Glen Lee53dc0cf2015-10-20 17:13:57 +09002675 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002676 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002677 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002678
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002679 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2680 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002681 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002682 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002683
2684 /*Add saved WEP keys, if any*/
2685 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002686 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2687 g_key_wep_params.key_idx);
2688 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
2689 g_key_wep_params.key,
2690 g_key_wep_params.key_len,
2691 g_key_wep_params.key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002692 }
2693
2694 /*No matter the driver handler passed here, it will be overwriiten*/
2695 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002696 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002697
2698 /*Add saved PTK and GTK keys, if any*/
2699 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2700 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2701 g_key_ptk_params.key[1],
2702 g_key_ptk_params.key[2]);
2703 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2704 g_key_gtk_params.key[1],
2705 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002706 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2707 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002708 g_add_ptk_key_params.key_idx,
2709 g_add_ptk_key_params.pairwise,
2710 g_add_ptk_key_params.mac_addr,
2711 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002712
Glen Lee299382c2015-10-20 17:13:56 +09002713 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2714 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002715 g_add_gtk_key_params.key_idx,
2716 g_add_gtk_key_params.pairwise,
2717 g_add_gtk_key_params.mac_addr,
2718 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002719 }
2720
2721 /*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 +09002722 refresh_scan(priv, 1, true);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002723 wilc_set_machw_change_vir_if(dev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002724
Glen Lee299382c2015-10-20 17:13:56 +09002725 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002726 for (i = 0; i < num_reg_frame; i++) {
2727 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2728 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002729 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002730 nic->g_struct_frame_reg[i].frame_type,
2731 nic->g_struct_frame_reg[i].reg);
2732 }
2733 }
2734 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002735 break;
2736
2737 case NL80211_IFTYPE_AP:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002738 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002739 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002740 dev->ieee80211_ptr->iftype = type;
2741 priv->wdev->iftype = type;
2742 nic->iftype = AP_MODE;
Johnny Kim8a143302015-06-10 17:06:46 +09002743 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002744
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002745 PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002746 wilc_wlan_get_firmware(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002747 /*If wilc is running, then close-open to actually get new firmware running (serves P2P)*/
Glen Lee299382c2015-10-20 17:13:56 +09002748 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002749 nic->iftype = AP_MODE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002750 wilc_mac_close(dev);
2751 wilc_mac_open(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002752
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002753 for (i = 0; i < num_reg_frame; i++) {
2754 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2755 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002756 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002757 nic->g_struct_frame_reg[i].frame_type,
2758 nic->g_struct_frame_reg[i].reg);
2759 }
2760 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002761 break;
2762
2763 case NL80211_IFTYPE_P2P_GO:
2764 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
2765
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002766 wilc_optaining_ip = true;
Leo Kim7e872df2015-11-19 15:56:20 +09002767 mod_timer(&wilc_during_ip_timer,
2768 jiffies + msecs_to_jiffies(during_ip_time));
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002769 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002770 /*Delete block ack has to be the latest config packet*/
2771 /*sent before downloading new FW. This is because it blocks on*/
2772 /*hWaitResponse semaphore, which allows previous config*/
2773 /*packets to actually take action on old FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002774 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2775 wl->vif[0].bssid, TID);
2776 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002777 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002778 dev->ieee80211_ptr->iftype = type;
2779 priv->wdev->iftype = type;
2780
Johnny Kim8a143302015-06-10 17:06:46 +09002781 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002782
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002783 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2784
2785
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002786 nic->iftype = GO_MODE;
2787
2788 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002789 wilc_wait_msg_queue_idle();
Glen Lee53dc0cf2015-10-20 17:13:57 +09002790 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002791 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002792 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002793
2794
2795 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002796 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2797 wilc_set_mac_address(wl->vif[0].hif_drv,
2798 wl->vif[0].src_addr);
2799 wilc_set_operation_mode(priv->hWILCWFIDrv, AP_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002800
2801 /*Add saved WEP keys, if any*/
2802 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002803 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2804 g_key_wep_params.key_idx);
2805 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002806 g_key_wep_params.key,
2807 g_key_wep_params.key_len,
2808 g_key_wep_params.key_idx);
2809 }
2810
2811 /*No matter the driver handler passed here, it will be overwriiten*/
2812 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002813 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002814
2815 /*Add saved PTK and GTK keys, if any*/
2816 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2817 PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0],
2818 g_key_ptk_params.key[1],
2819 g_key_ptk_params.key[2],
2820 g_key_ptk_params.cipher);
2821 PRINT_D(CFG80211_DBG, "gtk %x %x %x cipher %x\n", g_key_gtk_params.key[0],
2822 g_key_gtk_params.key[1],
2823 g_key_gtk_params.key[2],
2824 g_key_gtk_params.cipher);
Glen Lee299382c2015-10-20 17:13:56 +09002825 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2826 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002827 g_add_ptk_key_params.key_idx,
2828 g_add_ptk_key_params.pairwise,
2829 g_add_ptk_key_params.mac_addr,
2830 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002831
Glen Lee299382c2015-10-20 17:13:56 +09002832 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2833 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002834 g_add_gtk_key_params.key_idx,
2835 g_add_gtk_key_params.pairwise,
2836 g_add_gtk_key_params.mac_addr,
2837 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002838 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002839
Glen Lee299382c2015-10-20 17:13:56 +09002840 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002841 for (i = 0; i < num_reg_frame; i++) {
2842 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2843 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002844 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002845 nic->g_struct_frame_reg[i].frame_type,
2846 nic->g_struct_frame_reg[i].reg);
2847 }
2848 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002849 break;
2850
2851 default:
2852 PRINT_ER("Unknown interface type= %d\n", type);
Leo Kimaaed3292015-10-12 16:55:38 +09002853 return -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002854 }
2855
Leo Kimaaed3292015-10-12 16:55:38 +09002856 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002857}
2858
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002859/* (austin.2013-07-23)
2860 *
2861 * To support revised cfg80211_ops
2862 *
2863 * add_beacon --> start_ap
2864 * set_beacon --> change_beacon
2865 * del_beacon --> stop_ap
2866 *
2867 * beacon_parameters --> cfg80211_ap_settings
2868 * cfg80211_beacon_data
2869 *
2870 * applicable for linux kernel 3.4+
2871 */
2872
2873/**
Chaehyun Lima13168d2015-09-14 12:24:12 +09002874 * @brief start_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002875 * @details Add a beacon with given parameters, @head, @interval
2876 * and @dtim_period will be valid, @tail is optional.
2877 * @param[in] wiphy
2878 * @param[in] dev The net device structure
2879 * @param[in] settings cfg80211_ap_settings parameters for the beacon to be added
2880 * @return int : Return 0 on Success.
2881 * @author austin
2882 * @date 23 JUL 2013
2883 * @version 1.0
2884 */
Chaehyun Lima13168d2015-09-14 12:24:12 +09002885static int start_ap(struct wiphy *wiphy, struct net_device *dev,
2886 struct cfg80211_ap_settings *settings)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002887{
2888 struct cfg80211_beacon_data *beacon = &(settings->beacon);
Chaehyun Lim27268872015-09-15 14:06:13 +09002889 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002890 s32 s32Error = 0;
Glen Lee684dc182015-10-20 17:14:02 +09002891 struct wilc *wl;
2892 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002893
2894 priv = wiphy_priv(wiphy);
Glen Lee684dc182015-10-20 17:14:02 +09002895 nic = netdev_priv(dev);
2896 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002897 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
2898
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302899 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 +09002900 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
2901
Chaehyun Lim80785a92015-09-14 12:24:01 +09002902 s32Error = set_channel(wiphy, &settings->chandef);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002903
Leo Kime6e12662015-09-16 18:36:03 +09002904 if (s32Error != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002905 PRINT_ER("Error in setting channel\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002906
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002907 wilc_wlan_set_bssid(dev, wl->vif[0].src_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002908
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002909 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002910 settings->beacon_interval,
2911 settings->dtim_period,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002912 beacon->head_len, (u8 *)beacon->head,
2913 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002914
2915 return s32Error;
2916}
2917
2918/**
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002919 * @brief change_beacon
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002920 * @details Add a beacon with given parameters, @head, @interval
2921 * and @dtim_period will be valid, @tail is optional.
2922 * @param[in] wiphy
2923 * @param[in] dev The net device structure
2924 * @param[in] beacon cfg80211_beacon_data for the beacon to be changed
2925 * @return int : Return 0 on Success.
2926 * @author austin
2927 * @date 23 JUL 2013
2928 * @version 1.0
2929 */
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002930static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
2931 struct cfg80211_beacon_data *beacon)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002932{
Chaehyun Lim27268872015-09-15 14:06:13 +09002933 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002934 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002935
2936 priv = wiphy_priv(wiphy);
2937 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
2938
2939
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002940 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002941 0,
2942 0,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002943 beacon->head_len, (u8 *)beacon->head,
2944 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002945
2946 return s32Error;
2947}
2948
2949/**
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002950 * @brief stop_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002951 * @details Remove beacon configuration and stop sending the beacon.
2952 * @param[in]
2953 * @return int : Return 0 on Success.
2954 * @author austin
2955 * @date 23 JUL 2013
2956 * @version 1.0
2957 */
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002958static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002959{
Leo Kime6e12662015-09-16 18:36:03 +09002960 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002961 struct wilc_priv *priv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002962 u8 NullBssid[ETH_ALEN] = {0};
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002963
Leo Kim7ae43362015-09-16 18:35:59 +09002964 if (!wiphy)
2965 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002966
2967 priv = wiphy_priv(wiphy);
2968
2969 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
2970
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002971 wilc_wlan_set_bssid(dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002972
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002973 s32Error = wilc_del_beacon(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002974
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002975 if (s32Error)
2976 PRINT_ER("Host delete beacon fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002977
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002978 return s32Error;
2979}
2980
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002981/**
Chaehyun Limed269552015-09-14 12:24:15 +09002982 * @brief add_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002983 * @details Add a new station.
2984 * @param[in]
2985 * @return int : Return 0 on Success.
2986 * @author mdaftedar
2987 * @date 01 MAR 2012
2988 * @version 1.0
2989 */
Chaehyun Limed269552015-09-14 12:24:15 +09002990static int add_station(struct wiphy *wiphy, struct net_device *dev,
2991 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002992{
Leo Kime6e12662015-09-16 18:36:03 +09002993 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002994 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09002995 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002996 perInterface_wlan_t *nic;
2997
Leo Kim7ae43362015-09-16 18:35:59 +09002998 if (!wiphy)
2999 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003000
3001 priv = wiphy_priv(wiphy);
3002 nic = netdev_priv(dev);
3003
3004 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003005 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09003006 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003007 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003008 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003009 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003010
3011 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
3012
3013 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],
3014 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003015 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003016 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3017 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003018
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003019 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003020 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003021 } else {
Leo Kim22520122015-10-29 12:05:45 +09003022 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003023 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003024 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003025 memcpy(strStaParams.ht_supp_mcs_set,
3026 &params->ht_capa->mcs,
3027 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003028 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003029 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003030 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003031 }
3032
Leo Kimf676e172015-10-29 12:05:52 +09003033 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003034 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003035
Leo Kim22520122015-10-29 12:05:45 +09003036 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3037 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003038 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3039 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003040 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3041 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003042 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3043 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003044 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3045 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003046 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3047 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003048 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3049 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003050 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3051 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003052
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003053 s32Error = wilc_add_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003054 if (s32Error)
3055 PRINT_ER("Host add station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003056 }
3057
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003058 return s32Error;
3059}
3060
3061/**
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003062 * @brief del_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003063 * @details Remove a station; @mac may be NULL to remove all stations.
3064 * @param[in]
3065 * @return int : Return 0 on Success.
3066 * @author mdaftedar
3067 * @date 01 MAR 2012
3068 * @version 1.0
3069 */
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003070static int del_station(struct wiphy *wiphy, struct net_device *dev,
3071 struct station_del_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003072{
Arnd Bergmann057d1e92015-06-01 21:06:44 +02003073 const u8 *mac = params->mac;
Leo Kime6e12662015-09-16 18:36:03 +09003074 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003075 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003076 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003077
Leo Kim7ae43362015-09-16 18:35:59 +09003078 if (!wiphy)
3079 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003080
3081 priv = wiphy_priv(wiphy);
3082 nic = netdev_priv(dev);
3083
3084 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
3085 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
3086
3087
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003088 if (mac == NULL) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05303089 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003090 s32Error = wilc_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003091 } else {
3092 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]);
3093 }
3094
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003095 s32Error = wilc_del_station(priv->hWILCWFIDrv, mac);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003096
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003097 if (s32Error)
3098 PRINT_ER("Host delete station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003099 }
3100 return s32Error;
3101}
3102
3103/**
Chaehyun Lim14b42082015-09-14 12:24:17 +09003104 * @brief change_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003105 * @details Modify a given station.
3106 * @param[in]
3107 * @return int : Return 0 on Success.
3108 * @author mdaftedar
3109 * @date 01 MAR 2012
3110 * @version 1.0
3111 */
Chaehyun Lim14b42082015-09-14 12:24:17 +09003112static int change_station(struct wiphy *wiphy, struct net_device *dev,
3113 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003114{
Leo Kime6e12662015-09-16 18:36:03 +09003115 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003116 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09003117 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003118 perInterface_wlan_t *nic;
3119
3120
3121 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
3122
Leo Kim7ae43362015-09-16 18:35:59 +09003123 if (!wiphy)
3124 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003125
3126 priv = wiphy_priv(wiphy);
3127 nic = netdev_priv(dev);
3128
3129 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003130 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003131 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003132 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003133 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003134
Leo Kim2353c382015-10-29 12:05:41 +09003135 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n",
3136 strStaParams.bssid[0], strStaParams.bssid[1],
3137 strStaParams.bssid[2], strStaParams.bssid[3],
3138 strStaParams.bssid[4], strStaParams.bssid[5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003139 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003140 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3141 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003142
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003143 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003144 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003145 } else {
Leo Kim22520122015-10-29 12:05:45 +09003146 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003147 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003148 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003149 memcpy(strStaParams.ht_supp_mcs_set,
3150 &params->ht_capa->mcs,
3151 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003152 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003153 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003154 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003155 }
3156
Leo Kimf676e172015-10-29 12:05:52 +09003157 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003158 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003159
Leo Kim22520122015-10-29 12:05:45 +09003160 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3161 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003162 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3163 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003164 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3165 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003166 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3167 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003168 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3169 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003170 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3171 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003172 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3173 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003174 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3175 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003176
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003177 s32Error = wilc_edit_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003178 if (s32Error)
3179 PRINT_ER("Host edit station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003180 }
3181 return s32Error;
3182}
3183
3184
3185/**
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003186 * @brief add_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003187 * @details
3188 * @param[in]
3189 * @return int : Return 0 on Success.
3190 * @author mdaftedar
3191 * @date 01 JUL 2012
3192 * @version 1.0
3193 */
Chaehyun Lim37316e82015-09-22 18:34:52 +09003194static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
3195 const char *name,
3196 unsigned char name_assign_type,
3197 enum nl80211_iftype type,
3198 u32 *flags,
3199 struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003200{
3201 perInterface_wlan_t *nic;
Chaehyun Lim27268872015-09-15 14:06:13 +09003202 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003203 struct net_device *new_ifc = NULL;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003204
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003205 priv = wiphy_priv(wiphy);
3206
3207
3208
3209 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
3210
3211 nic = netdev_priv(priv->wdev->netdev);
3212
3213
3214 if (type == NL80211_IFTYPE_MONITOR) {
3215 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
3216 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", nic->wilc_netdev);
3217 new_ifc = WILC_WFI_init_mon_interface(name, nic->wilc_netdev);
3218 if (new_ifc != NULL) {
3219 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003220 nic = netdev_priv(priv->wdev->netdev);
3221 nic->monitor_flag = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003222 } else
3223 PRINT_ER("Error in initializing monitor interface\n ");
3224 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003225 return priv->wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003226}
3227
3228/**
Chaehyun Limb4a73352015-09-14 12:24:10 +09003229 * @brief del_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003230 * @details
3231 * @param[in]
3232 * @return int : Return 0 on Success.
3233 * @author mdaftedar
3234 * @date 01 JUL 2012
3235 * @version 1.0
3236 */
Chaehyun Lim956d7212015-09-22 18:34:49 +09003237static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003238{
3239 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
Leo Kime6e12662015-09-16 18:36:03 +09003240 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003241}
3242
Chaehyun Lim08241922015-09-15 14:06:12 +09003243static struct cfg80211_ops wilc_cfg80211_ops = {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003244
Chaehyun Lim80785a92015-09-14 12:24:01 +09003245 .set_monitor_channel = set_channel,
Chaehyun Lim0e30d062015-09-14 12:24:02 +09003246 .scan = scan,
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +09003247 .connect = connect,
Chaehyun Limb027cde2015-09-14 12:24:04 +09003248 .disconnect = disconnect,
Chaehyun Lim953d4172015-09-14 12:24:05 +09003249 .add_key = add_key,
Chaehyun Lim3044ba72015-09-14 12:24:06 +09003250 .del_key = del_key,
Chaehyun Limf4893df2015-09-14 12:24:07 +09003251 .get_key = get_key,
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09003252 .set_default_key = set_default_key,
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003253 .add_virtual_intf = add_virtual_intf,
Chaehyun Limb4a73352015-09-14 12:24:10 +09003254 .del_virtual_intf = del_virtual_intf,
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09003255 .change_virtual_intf = change_virtual_intf,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003256
Chaehyun Lima13168d2015-09-14 12:24:12 +09003257 .start_ap = start_ap,
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09003258 .change_beacon = change_beacon,
Chaehyun Limc8cddd72015-09-14 12:24:14 +09003259 .stop_ap = stop_ap,
Chaehyun Limed269552015-09-14 12:24:15 +09003260 .add_station = add_station,
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003261 .del_station = del_station,
Chaehyun Lim14b42082015-09-14 12:24:17 +09003262 .change_station = change_station,
Chaehyun Limf06f5622015-09-14 12:24:18 +09003263 .get_station = get_station,
Chaehyun Limbdb63382015-09-14 12:24:19 +09003264 .dump_station = dump_station,
Chaehyun Lima5f7db62015-09-14 12:24:20 +09003265 .change_bss = change_bss,
Chaehyun Lima76b63e2015-09-14 12:24:21 +09003266 .set_wiphy_params = set_wiphy_params,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003267
Chaehyun Lim4d466572015-09-14 12:24:22 +09003268 .set_pmksa = set_pmksa,
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09003269 .del_pmksa = del_pmksa,
Chaehyun Limb33c39b2015-09-14 12:24:24 +09003270 .flush_pmksa = flush_pmksa,
Chaehyun Lim6d19d692015-09-14 12:24:25 +09003271 .remain_on_channel = remain_on_channel,
Chaehyun Lim1dd54402015-09-14 12:24:26 +09003272 .cancel_remain_on_channel = cancel_remain_on_channel,
Chaehyun Lim4a2f9b32015-09-14 12:24:27 +09003273 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
Chaehyun Lim12a26a32015-09-14 12:24:28 +09003274 .mgmt_tx = mgmt_tx,
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09003275 .mgmt_frame_register = wilc_mgmt_frame_register,
Chaehyun Lim46530672015-09-22 18:34:46 +09003276 .set_power_mgmt = set_power_mgmt,
Chaehyun Lima8047e22015-09-22 18:34:48 +09003277 .set_cqm_rssi_config = set_cqm_rssi_config,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003278
3279};
3280
3281
3282
3283
3284
3285/**
3286 * @brief WILC_WFI_update_stats
3287 * @details Modify parameters for a given BSS.
3288 * @param[in]
3289 * @return int : Return 0 on Success.
3290 * @author mdaftedar
3291 * @date 01 MAR 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09003292 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003293 */
3294int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
3295{
3296
Chaehyun Lim27268872015-09-15 14:06:13 +09003297 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003298
3299 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003300 switch (changed) {
3301
3302 case WILC_WFI_RX_PKT:
3303 {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003304 priv->netstats.rx_packets++;
3305 priv->netstats.rx_bytes += pktlen;
3306 priv->netstats.rx_time = get_jiffies_64();
3307 }
3308 break;
3309
3310 case WILC_WFI_TX_PKT:
3311 {
3312 priv->netstats.tx_packets++;
3313 priv->netstats.tx_bytes += pktlen;
3314 priv->netstats.tx_time = get_jiffies_64();
3315
3316 }
3317 break;
3318
3319 default:
3320 break;
3321 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003322 return 0;
3323}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003324
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003325/**
3326 * @brief WILC_WFI_CfgAlloc
3327 * @details Allocation of the wireless device structure and assigning it
3328 * to the cfg80211 operations structure.
3329 * @param[in] NONE
3330 * @return wireless_dev : Returns pointer to wireless_dev structure.
3331 * @author mdaftedar
3332 * @date 01 MAR 2012
3333 * @version 1.0
3334 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01003335static struct wireless_dev *WILC_WFI_CfgAlloc(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003336{
3337
3338 struct wireless_dev *wdev;
3339
3340
3341 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
3342 /*Allocating the wireless device structure*/
3343 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
3344 if (!wdev) {
3345 PRINT_ER("Cannot allocate wireless device\n");
3346 goto _fail_;
3347 }
3348
3349 /*Creating a new wiphy, linking wireless structure with the wiphy structure*/
Chaehyun Lim27268872015-09-15 14:06:13 +09003350 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003351 if (!wdev->wiphy) {
3352 PRINT_ER("Cannot allocate wiphy\n");
3353 goto _fail_mem_;
3354
3355 }
3356
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003357 /* enable 802.11n HT */
3358 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
3359 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
3360 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3361 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
3362 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003363
3364 /*wiphy bands*/
3365 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
3366
3367 return wdev;
3368
3369_fail_mem_:
3370 kfree(wdev);
3371_fail_:
3372 return NULL;
3373
3374}
3375/**
Chaehyun Lim8459fd52015-09-20 15:51:09 +09003376 * @brief wilc_create_wiphy
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003377 * @details Registering of the wiphy structure and interface modes
3378 * @param[in] NONE
3379 * @return NONE
3380 * @author mdaftedar
3381 * @date 01 MAR 2012
3382 * @version 1.0
3383 */
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01003384struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003385{
Chaehyun Lim27268872015-09-15 14:06:13 +09003386 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003387 struct wireless_dev *wdev;
Leo Kime6e12662015-09-16 18:36:03 +09003388 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003389
3390 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
3391
3392 wdev = WILC_WFI_CfgAlloc();
3393 if (wdev == NULL) {
3394 PRINT_ER("CfgAlloc Failed\n");
3395 return NULL;
3396 }
3397
3398
3399 /*Return hardware description structure (wiphy)'s priv*/
3400 priv = wdev_priv(wdev);
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003401 sema_init(&(priv->SemHandleUpdateStats), 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003402
3403 /*Link the wiphy with wireless structure*/
3404 priv->wdev = wdev;
3405
3406 /*Maximum number of probed ssid to be added by user for the scan request*/
3407 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003408 /*Maximum number of pmkids to be cashed*/
3409 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
3410 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003411
3412 wdev->wiphy->max_scan_ie_len = 1000;
3413
3414 /*signal strength in mBm (100*dBm) */
3415 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3416
3417 /*Set the availaible cipher suites*/
3418 wdev->wiphy->cipher_suites = cipher_suites;
3419 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003420 /*Setting default managment types: for register action frame: */
3421 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003422
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003423 wdev->wiphy->max_remain_on_channel_duration = 500;
3424 /*Setting the wiphy interfcae mode and type before registering the wiphy*/
3425 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
3426 BIT(NL80211_IFTYPE_P2P_CLIENT);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003427 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003428 wdev->iftype = NL80211_IFTYPE_STATION;
3429
3430
3431
3432 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
3433 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
3434 wdev->wiphy->interface_modes, wdev->iftype);
3435
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01003436 set_wiphy_dev(wdev->wiphy, dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003437
3438 /*Register wiphy structure*/
3439 s32Error = wiphy_register(wdev->wiphy);
3440 if (s32Error) {
3441 PRINT_ER("Cannot register wiphy device\n");
3442 /*should define what action to be taken in such failure*/
3443 } else {
3444 PRINT_D(CFG80211_DBG, "Successful Registering\n");
3445 }
3446
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003447 priv->dev = net;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003448 return wdev;
3449
3450
3451}
3452/**
3453 * @brief WILC_WFI_WiphyFree
3454 * @details Freeing allocation of the wireless device structure
3455 * @param[in] NONE
3456 * @return NONE
3457 * @author mdaftedar
3458 * @date 01 MAR 2012
3459 * @version 1.0
3460 */
Chaehyun Limdd4b6a82015-09-20 15:51:25 +09003461int wilc_init_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003462{
3463
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003464 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003465
Chaehyun Lim27268872015-09-15 14:06:13 +09003466 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003467
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003468 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
3469 priv = wdev_priv(net->ieee80211_ptr);
3470 if (op_ifcs == 0) {
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -07003471 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003472 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003473 }
3474 op_ifcs++;
3475 if (s32Error < 0) {
3476 PRINT_ER("Failed to creat refresh Timer\n");
3477 return s32Error;
3478 }
3479
Dean Lee72ed4dc2015-06-12 14:11:44 +09003480 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003481
Dean Lee72ed4dc2015-06-12 14:11:44 +09003482 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003483
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003484 sema_init(&(priv->hSemScanReq), 1);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003485 s32Error = wilc_init(net, &priv->hWILCWFIDrv);
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003486 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003487 PRINT_ER("Error while initializing hostinterface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003488
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003489 return s32Error;
3490}
3491
3492/**
3493 * @brief WILC_WFI_WiphyFree
3494 * @details Freeing allocation of the wireless device structure
3495 * @param[in] NONE
3496 * @return NONE
3497 * @author mdaftedar
3498 * @date 01 MAR 2012
3499 * @version 1.0
3500 */
Chaehyun Lima9a16822015-09-20 15:51:24 +09003501int wilc_deinit_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003502{
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003503 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003504
Chaehyun Lim27268872015-09-15 14:06:13 +09003505 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003506
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003507 priv = wdev_priv(net->ieee80211_ptr);
3508
Dean Lee72ed4dc2015-06-12 14:11:44 +09003509 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003510
Dean Lee72ed4dc2015-06-12 14:11:44 +09003511 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003512
3513 op_ifcs--;
3514
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003515 s32Error = wilc_deinit(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003516
3517 /* Clear the Shadow scan */
Leo Kimd14991a2015-11-19 15:56:22 +09003518 clear_shadow_scan();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003519 if (op_ifcs == 0) {
3520 PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003521 del_timer_sync(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003522 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003523
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003524 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003525 PRINT_ER("Error while deintializing host interface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003526
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003527 return s32Error;
3528}
3529
3530
3531/**
3532 * @brief WILC_WFI_WiphyFree
3533 * @details Freeing allocation of the wireless device structure
3534 * @param[in] NONE
3535 * @return NONE
3536 * @author mdaftedar
3537 * @date 01 MAR 2012
3538 * @version 1.0
3539 */
Chaehyun Lim96da20a2015-09-20 15:51:08 +09003540void wilc_free_wiphy(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003541{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003542 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
3543
Chaehyun Lim619837a2015-09-20 15:51:10 +09003544 if (!net) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003545 PRINT_D(INIT_DBG, "net_device is NULL\n");
3546 return;
3547 }
3548
Chaehyun Lim619837a2015-09-20 15:51:10 +09003549 if (!net->ieee80211_ptr) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003550 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
3551 return;
3552 }
3553
Chaehyun Lim619837a2015-09-20 15:51:10 +09003554 if (!net->ieee80211_ptr->wiphy) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003555 PRINT_D(INIT_DBG, "wiphy is NULL\n");
3556 return;
3557 }
3558
3559 wiphy_unregister(net->ieee80211_ptr->wiphy);
3560
3561 PRINT_D(INIT_DBG, "Freeing wiphy\n");
3562 wiphy_free(net->ieee80211_ptr->wiphy);
3563 kfree(net->ieee80211_ptr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003564}