blob: 56005f6e517453dc7f56c8d56fd69f5ab272e57a [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
Arnd Bergmann1608c402015-11-16 15:04:53 +0100333static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900334{
Chaehyun Lima74cc6b2015-10-02 16:41:17 +0900335 int state = -1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900336 int i;
337
Leo Kim771fbae2015-11-19 15:56:10 +0900338 if (last_scanned_cnt == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900339 PRINT_D(CFG80211_DBG, "Starting Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700340 hAgingTimer.data = (unsigned long)pUserVoid;
341 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900342 state = -1;
343 } else {
344 /* Linear search for now */
Leo Kim771fbae2015-11-19 15:56:10 +0900345 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900346 if (memcmp(last_scanned_shadow[i].au8bssid,
347 pstrNetworkInfo->au8bssid, 6) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900348 state = i;
349 break;
350 }
351 }
352 }
353 return state;
354}
355
Arnd Bergmann1608c402015-11-16 15:04:53 +0100356static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900357{
Chaehyun Lima74cc6b2015-10-02 16:41:17 +0900358 int ap_found = is_network_in_shadow(pstrNetworkInfo, pUserVoid);
Chaehyun Limfbc2fe12015-09-15 14:06:16 +0900359 u32 ap_index = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900360 u8 rssi_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900361
Leo Kim771fbae2015-11-19 15:56:10 +0900362 if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900363 PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
364 return;
365 }
366 if (ap_found == -1) {
Leo Kim771fbae2015-11-19 15:56:10 +0900367 ap_index = last_scanned_cnt;
368 last_scanned_cnt++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900369
370 } else {
371 ap_index = ap_found;
372 }
Leo Kimf1ab1172015-11-19 15:56:11 +0900373 rssi_index = last_scanned_shadow[ap_index].strRssi.u8Index;
374 last_scanned_shadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900375 if (rssi_index == NUM_RSSI) {
376 rssi_index = 0;
Leo Kimf1ab1172015-11-19 15:56:11 +0900377 last_scanned_shadow[ap_index].strRssi.u8Full = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900378 }
Leo Kimf1ab1172015-11-19 15:56:11 +0900379 last_scanned_shadow[ap_index].strRssi.u8Index = rssi_index;
380 last_scanned_shadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
381 last_scanned_shadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
382 last_scanned_shadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
383 memcpy(last_scanned_shadow[ap_index].au8ssid,
384 pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
385 memcpy(last_scanned_shadow[ap_index].au8bssid,
386 pstrNetworkInfo->au8bssid, ETH_ALEN);
387 last_scanned_shadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
388 last_scanned_shadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
389 last_scanned_shadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
390 last_scanned_shadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
391 last_scanned_shadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900392 if (ap_found != -1)
Leo Kimf1ab1172015-11-19 15:56:11 +0900393 kfree(last_scanned_shadow[ap_index].pu8IEs);
394 last_scanned_shadow[ap_index].pu8IEs =
Glen Leef3052582015-09-10 12:03:04 +0900395 kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL); /* will be deallocated by the WILC_WFI_CfgScan() function */
Leo Kimf1ab1172015-11-19 15:56:11 +0900396 memcpy(last_scanned_shadow[ap_index].pu8IEs,
397 pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
398 last_scanned_shadow[ap_index].u32TimeRcvdInScan = jiffies;
399 last_scanned_shadow[ap_index].u32TimeRcvdInScanCached = jiffies;
400 last_scanned_shadow[ap_index].u8Found = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900401 if (ap_found != -1)
Leo Kimf1ab1172015-11-19 15:56:11 +0900402 wilc_free_join_params(last_scanned_shadow[ap_index].pJoinParams);
403 last_scanned_shadow[ap_index].pJoinParams = pJoinParams;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900404}
405
406
407/**
408 * @brief CfgScanResult
409 * @details Callback function which returns the scan results found
410 *
411 * @param[in] tenuScanEvent enuScanEvent: enum, indicating the scan event triggered, whether that is
412 * SCAN_EVENT_NETWORK_FOUND or SCAN_EVENT_DONE
413 * tstrNetworkInfo* pstrNetworkInfo: structure holding the scan results information
414 * void* pUserVoid: Private structure associated with the wireless interface
415 * @return NONE
416 * @author mabubakr
417 * @date
418 * @version 1.0
419 */
Leo Kim1ec38152015-10-12 16:55:59 +0900420static void CfgScanResult(enum scan_event enuScanEvent, tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900421{
Chaehyun Lim27268872015-09-15 14:06:13 +0900422 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900423 struct wiphy *wiphy;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900424 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900425 struct ieee80211_channel *channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900426 struct cfg80211_bss *bss = NULL;
427
Chaehyun Lim27268872015-09-15 14:06:13 +0900428 priv = (struct wilc_priv *)pUserVoid;
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100429 if (priv->bCfgScanning) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900430 if (enuScanEvent == SCAN_EVENT_NETWORK_FOUND) {
431 wiphy = priv->dev->ieee80211_ptr->wiphy;
Leo Kim7ae43362015-09-16 18:35:59 +0900432
433 if (!wiphy)
434 return;
435
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900436 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC
437 &&
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900438 ((((s32)pstrNetworkInfo->s8rssi) * 100) < 0
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900439 ||
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900440 (((s32)pstrNetworkInfo->s8rssi) * 100) > 100)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900441 ) {
Leo Kim24db7132015-09-16 18:36:01 +0900442 PRINT_ER("wiphy signal type fial\n");
443 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900444 }
445
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900446 if (pstrNetworkInfo != NULL) {
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900447 s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900448 channel = ieee80211_get_channel(wiphy, s32Freq);
449
Leo Kim7ae43362015-09-16 18:35:59 +0900450 if (!channel)
451 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900452
453 PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530454 "BeaconPeriod: %d\n", channel->center_freq, (((s32)pstrNetworkInfo->s8rssi) * 100),
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900455 pstrNetworkInfo->u16CapInfo, pstrNetworkInfo->u16BeaconPeriod);
456
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100457 if (pstrNetworkInfo->bNewNetwork) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900458 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
459 /* max_scan_ssids */
460 PRINT_D(CFG80211_DBG, "Network %s found\n", pstrNetworkInfo->au8ssid);
461
462
463 priv->u32RcvdChCount++;
464
465
466
467 if (pJoinParams == NULL) {
468 PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n");
469 }
470 add_network_to_shadow(pstrNetworkInfo, priv, pJoinParams);
471
472 /*P2P peers are sent to WPA supplicant and added to shadow table*/
473
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900474 if (!(memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900475 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
476 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900477 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)pstrNetworkInfo->s8rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900478 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900479 }
480
481
482 } else {
483 PRINT_ER("Discovered networks exceeded the max limit\n");
484 }
485 } else {
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900486 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900487 /* So this network is discovered before, we'll just update its RSSI */
488 for (i = 0; i < priv->u32RcvdChCount; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900489 if (memcmp(last_scanned_shadow[i].au8bssid, pstrNetworkInfo->au8bssid, 6) == 0) {
490 PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", last_scanned_shadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900491
Leo Kimf1ab1172015-11-19 15:56:11 +0900492 last_scanned_shadow[i].s8rssi = pstrNetworkInfo->s8rssi;
493 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900494 break;
495 }
496 }
497 }
498 }
499 } else if (enuScanEvent == SCAN_EVENT_DONE) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530500 PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev);
501 PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n");
Dean Lee72ed4dc2015-06-12 14:11:44 +0900502 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900503
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530504 if (priv->u32RcvdChCount > 0)
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530505 PRINT_D(CFG80211_DBG, "%d Network(s) found\n", priv->u32RcvdChCount);
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530506 else
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530507 PRINT_D(CFG80211_DBG, "No networks found\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900508
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200509 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900510
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900511 if (priv->pstrScanReq != NULL) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900512 cfg80211_scan_done(priv->pstrScanReq, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900513 priv->u32RcvdChCount = 0;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900514 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900515 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900516 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200517 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900518
519 }
520 /*Aborting any scan operation during mac close*/
521 else if (enuScanEvent == SCAN_EVENT_ABORTED) {
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200522 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900523
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530524 PRINT_D(CFG80211_DBG, "Scan Aborted\n");
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900525 if (priv->pstrScanReq != NULL) {
Leo Kim5e51d8b2015-11-19 15:56:28 +0900526 update_scan_time();
Dean Lee72ed4dc2015-06-12 14:11:44 +0900527 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900528
Dean Lee72ed4dc2015-06-12 14:11:44 +0900529 cfg80211_scan_done(priv->pstrScanReq, false);
530 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900531 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900532 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200533 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900534 }
535 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900536}
537
538
539/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900540 * @brief CfgConnectResult
541 * @details
542 * @param[in] tenuConnDisconnEvent enuConnDisconnEvent: Type of connection response either
543 * connection response or disconnection notification.
544 * tstrConnectInfo* pstrConnectInfo: COnnection information.
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900545 * u8 u8MacStatus: Mac Status from firmware
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900546 * tstrDisconnectNotifInfo* pstrDisconnectNotifInfo: Disconnection Notification
547 * void* pUserVoid: Private data associated with wireless interface
548 * @return NONE
549 * @author mabubakr
550 * @date 01 MAR 2012
551 * @version 1.0
552 */
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100553int wilc_connecting;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900554
Leo Kimed3f0372015-10-12 16:56:01 +0900555static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900556 tstrConnectInfo *pstrConnectInfo,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900557 u8 u8MacStatus,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900558 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
559 void *pUserVoid)
560{
Chaehyun Lim27268872015-09-15 14:06:13 +0900561 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900562 struct net_device *dev;
Leo Kim441dc602015-10-12 16:55:35 +0900563 struct host_if_drv *pstrWFIDrv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900564 u8 NullBssid[ETH_ALEN] = {0};
Glen Leec1ec2c12015-10-20 17:13:58 +0900565 struct wilc *wl;
566 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900567
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100568 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900569
Chaehyun Lim27268872015-09-15 14:06:13 +0900570 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900571 dev = priv->dev;
Glen Leec1ec2c12015-10-20 17:13:58 +0900572 nic = netdev_priv(dev);
573 wl = nic->wilc;
Leo Kim441dc602015-10-12 16:55:35 +0900574 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900575
576 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
577 /*Initialization*/
Amitoj Kaur Chawlababa7c72015-10-15 13:48:29 +0530578 u16 u16ConnectStatus;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900579
580 u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
581
582 PRINT_D(CFG80211_DBG, " Connection response received = %d\n", u8MacStatus);
583
584 if ((u8MacStatus == MAC_DISCONNECTED) &&
585 (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
586 /* The case here is that our station was waiting for association response frame and has just received it containing status code
587 * = SUCCESSFUL_STATUSCODE, while mac status is MAC_DISCONNECTED (which means something wrong happened) */
588 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100589 wilc_wlan_set_bssid(priv->dev, NullBssid);
Leo Kime554a302015-11-19 15:56:21 +0900590 eth_zero_addr(wilc_connected_ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900591
Leo Kimab16ec02015-10-29 12:05:40 +0900592 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900593 wlan_channel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900594
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530595 PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d\n", u16ConnectStatus, u8MacStatus);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900596 }
597
598 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900599 bool bNeedScanRefresh = false;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900600 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900601
602 PRINT_INFO(CFG80211_DBG, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo->au8bssid[0],
603 pstrConnectInfo->au8bssid[1], pstrConnectInfo->au8bssid[2], pstrConnectInfo->au8bssid[3], pstrConnectInfo->au8bssid[4], pstrConnectInfo->au8bssid[5]);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900604 memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900605
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900606
Leo Kim771fbae2015-11-19 15:56:10 +0900607 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900608 if (memcmp(last_scanned_shadow[i].au8bssid,
609 pstrConnectInfo->au8bssid, ETH_ALEN) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900610 unsigned long now = jiffies;
611
612 if (time_after(now,
Leo Kimf1ab1172015-11-19 15:56:11 +0900613 last_scanned_shadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900614 bNeedScanRefresh = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900615 }
616
617 break;
618 }
619 }
620
Abdul Hussain5a66bf22015-06-16 09:44:06 +0000621 if (bNeedScanRefresh) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900622 /*Also, refrsh DIRECT- results if */
Dean Lee72ed4dc2015-06-12 14:11:44 +0900623 refresh_scan(priv, 1, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900624
625 }
626
627 }
628
629
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530630 PRINT_D(CFG80211_DBG, "Association request info elements length = %zu\n", pstrConnectInfo->ReqIEsLen);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900631
632 PRINT_D(CFG80211_DBG, "Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen);
633
634 cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
635 pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
636 pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
637 u16ConnectStatus, GFP_KERNEL); /* TODO: mostafa: u16ConnectStatus to */
638 /* be replaced by pstrConnectInfo->u16ConnectStatus */
639 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100640 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900641 PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n",
642 pstrDisconnectNotifInfo->u16reason, priv->dev);
Leo Kim583d9722015-11-19 15:56:16 +0900643 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +0900644 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +0900645 wilc_ie = false;
Shraddha Barkebcf02652015-10-05 17:00:32 +0530646 eth_zero_addr(priv->au8AssociatedBss);
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100647 wilc_wlan_set_bssid(priv->dev, NullBssid);
Leo Kime554a302015-11-19 15:56:21 +0900648 eth_zero_addr(wilc_connected_ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900649
Leo Kimab16ec02015-10-29 12:05:40 +0900650 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900651 wlan_channel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900652 /*Incase "P2P CLIENT Connected" send deauthentication reason by 3 to force the WPA_SUPPLICANT to directly change
653 * virtual interface to station*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900654 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900655 pstrDisconnectNotifInfo->u16reason = 3;
656 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900657 /*Incase "P2P CLIENT during connection(not connected)" send deauthentication reason by 1 to force the WPA_SUPPLICANT
658 * to scan again and retry the connection*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900659 else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900660 pstrDisconnectNotifInfo->u16reason = 1;
661 }
662 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
Sudip Mukherjeee26bb712015-06-30 13:51:51 +0530663 pstrDisconnectNotifInfo->ie_len, false,
664 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900665
666 }
667
668}
669
670
671/**
Chaehyun Lim80785a92015-09-14 12:24:01 +0900672 * @brief set_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900673 * @details Set channel for a given wireless interface. Some devices
674 * may support multi-channel operation (by channel hopping) so cfg80211
675 * doesn't verify much. Note, however, that the passed netdev may be
676 * %NULL as well if the user requested changing the channel for the
677 * device itself, or for a monitor interface.
678 * @param[in]
679 * @return int : Return 0 on Success
680 * @author mdaftedar
681 * @date 01 MAR 2012
682 * @version 1.0
683 */
Chaehyun Lim80785a92015-09-14 12:24:01 +0900684static int set_channel(struct wiphy *wiphy,
685 struct cfg80211_chan_def *chandef)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900686{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900687 u32 channelnum = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +0900688 struct wilc_priv *priv;
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900689 int result = 0;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900690
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900691 priv = wiphy_priv(wiphy);
692
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900693 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
694 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900695
Chaehyun Lim866a2c22015-10-02 16:41:21 +0900696 curr_channel = channelnum;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100697 result = wilc_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900698
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900699 if (result != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900700 PRINT_ER("Error in setting channel %d\n", channelnum);
701
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900702 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900703}
704
705/**
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900706 * @brief scan
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900707 * @details Request to do a scan. If returning zero, the scan request is given
708 * the driver, and will be valid until passed to cfg80211_scan_done().
709 * For scan results, call cfg80211_inform_bss(); you can call this outside
710 * the scan/scan_done bracket too.
711 * @param[in]
712 * @return int : Return 0 on Success
713 * @author mabubakr
714 * @date 01 MAR 2012
715 * @version 1.0
716 */
717
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900718static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900719{
Chaehyun Lim27268872015-09-15 14:06:13 +0900720 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900721 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +0900722 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900723 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
Leo Kim607db442015-10-05 15:25:37 +0900724 struct hidden_network strHiddenNetwork;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900725
726 priv = wiphy_priv(wiphy);
727
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900728 priv->pstrScanReq = request;
729
730 priv->u32RcvdChCount = 0;
731
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100732 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Leo Kim12b01382015-11-19 15:56:27 +0900733 reset_shadow_found();
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900734
Dean Lee72ed4dc2015-06-12 14:11:44 +0900735 priv->bCfgScanning = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900736 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
737 /* max_scan_ssids */
738 for (i = 0; i < request->n_channels; i++) {
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900739 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900740 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
741 }
742
743 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530744 PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900745
746 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
747
748 if (request->n_ssids >= 1) {
749
750
Leo Kim607db442015-10-05 15:25:37 +0900751 strHiddenNetwork.pstrHiddenNetworkInfo = kmalloc(request->n_ssids * sizeof(struct hidden_network), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900752 strHiddenNetwork.u8ssidnum = request->n_ssids;
753
754
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900755 for (i = 0; i < request->n_ssids; i++) {
756
757 if (request->ssids[i].ssid != NULL && request->ssids[i].ssid_len != 0) {
Glen Leef3052582015-09-10 12:03:04 +0900758 strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900759 memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900760 strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len;
761 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530762 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900763 strHiddenNetwork.u8ssidnum -= 1;
764 }
765 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530766 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100767 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900768 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900769 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900770 CfgScanResult, (void *)priv, &strHiddenNetwork);
771 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530772 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100773 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900774 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900775 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900776 CfgScanResult, (void *)priv, NULL);
777 }
778
779 } else {
780 PRINT_ER("Requested num of scanned channels is greater than the max, supported"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530781 " channels\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900782 }
783
Leo Kime6e12662015-09-16 18:36:03 +0900784 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900785 s32Error = -EBUSY;
786 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
787 }
788
789 return s32Error;
790}
791
792/**
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900793 * @brief connect
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900794 * @details Connect to the ESS with the specified parameters. When connected,
795 * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
796 * If the connection fails for some reason, call cfg80211_connect_result()
797 * with the status from the AP.
798 * @param[in]
799 * @return int : Return 0 on Success
800 * @author mabubakr
801 * @date 01 MAR 2012
802 * @version 1.0
803 */
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900804static int connect(struct wiphy *wiphy, struct net_device *dev,
805 struct cfg80211_connect_params *sme)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900806{
Leo Kime6e12662015-09-16 18:36:03 +0900807 s32 s32Error = 0;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900808 u32 i;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900809 u8 u8security = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +0900810 enum AUTHTYPE tenuAuth_type = ANY;
Dean Lee576917a2015-06-15 11:58:57 +0900811 char *pcgroup_encrypt_val = NULL;
812 char *pccipher_group = NULL;
813 char *pcwpa_version = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900814
Chaehyun Lim27268872015-09-15 14:06:13 +0900815 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +0900816 struct host_if_drv *pstrWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900817 tstrNetworkInfo *pstrNetworkInfo = NULL;
818
819
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100820 wilc_connecting = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900821 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +0900822 pstrWFIDrv = (struct host_if_drv *)(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900823
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100824 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900825
Johnny Kim8a143302015-06-10 17:06:46 +0900826 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 +0900827 if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900828 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
Leo Kimab16ec02015-10-29 12:05:40 +0900829 pstrWFIDrv->p2p_connect = 1;
830 } else {
831 pstrWFIDrv->p2p_connect = 0;
832 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530833 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900834
Leo Kim771fbae2015-11-19 15:56:10 +0900835 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900836 if ((sme->ssid_len == last_scanned_shadow[i].u8SsidLen) &&
837 memcmp(last_scanned_shadow[i].au8ssid,
838 sme->ssid,
839 sme->ssid_len) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900840 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
841 if (sme->bssid == NULL) {
842 /* BSSID is not passed from the user, so decision of matching
843 * is done by SSID only */
844 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
845 break;
846 } else {
847 /* BSSID is also passed from the user, so decision of matching
848 * should consider also this passed BSSID */
Leo Kimf1ab1172015-11-19 15:56:11 +0900849 if (memcmp(last_scanned_shadow[i].au8bssid,
850 sme->bssid,
851 ETH_ALEN) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900852 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
853 break;
854 }
855 }
856 }
857 }
858
Leo Kim771fbae2015-11-19 15:56:10 +0900859 if (i < last_scanned_cnt) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900860 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
861
Leo Kimf1ab1172015-11-19 15:56:11 +0900862 pstrNetworkInfo = &last_scanned_shadow[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900863
864 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
865 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
866 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
867 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
868 } else {
869 s32Error = -ENOENT;
Leo Kim771fbae2015-11-19 15:56:10 +0900870 if (last_scanned_cnt == 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900871 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
872 else
873 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
874
875 goto done;
876 }
877
878 priv->WILC_WFI_wep_default = 0;
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900879 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
880 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900881
882 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
883 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
884
885 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
886
887 if (INFO) {
888 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
889 PRINT_D(CORECONFIG_DBG, "sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]);
890 }
891
892 if (sme->crypto.cipher_group != NO_ENCRYPT) {
893 /* To determine the u8security value, first we check the group cipher suite then {in case of WPA or WPA2}
894 * we will add to it the pairwise cipher suite(s) */
895 pcwpa_version = "Default";
896 PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900897 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900898 u8security = ENCRYPT_ENABLED | WEP;
899 pcgroup_encrypt_val = "WEP40";
900 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
901 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
902
903 if (INFO) {
904 for (i = 0; i < sme->key_len; i++)
905 PRINT_D(CORECONFIG_DBG, "WEP Key Value[%d] = %d\n", i, sme->key[i]);
906 }
907 priv->WILC_WFI_wep_default = sme->key_idx;
908 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900909 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900910
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900911 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900912 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900913 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
914 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900915 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900916
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100917 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
918 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900919 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900920 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
921 pcgroup_encrypt_val = "WEP104";
922 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
923
924 priv->WILC_WFI_wep_default = sme->key_idx;
925 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900926 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900927
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900928 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900929 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900930 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
931 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900932 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900933
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100934 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
935 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900936 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900937 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900938 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
939 pcgroup_encrypt_val = "WPA2_TKIP";
940 pccipher_group = "TKIP";
941 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
942 /* tenuSecurity_t = WPA2_AES; */
943 u8security = ENCRYPT_ENABLED | WPA2 | AES;
944 pcgroup_encrypt_val = "WPA2_AES";
945 pccipher_group = "AES";
946 }
947 pcwpa_version = "WPA_VERSION_2";
948 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
949 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900950 u8security = ENCRYPT_ENABLED | WPA | TKIP;
951 pcgroup_encrypt_val = "WPA_TKIP";
952 pccipher_group = "TKIP";
953 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
954 /* tenuSecurity_t = WPA_AES; */
955 u8security = ENCRYPT_ENABLED | WPA | AES;
956 pcgroup_encrypt_val = "WPA_AES";
957 pccipher_group = "AES";
958
959 }
960 pcwpa_version = "WPA_VERSION_1";
961
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900962 } else {
963 s32Error = -ENOTSUPP;
964 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
965
966 goto done;
967 }
968
969 }
970
971 /* After we set the u8security value from checking the group cipher suite, {in case of WPA or WPA2} we will
972 * add to it the pairwise cipher suite(s) */
973 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
974 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
975 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
976 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
977 u8security = u8security | TKIP;
978 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
979 u8security = u8security | AES;
980 }
981 }
982 }
983
984 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
985
986 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
987 switch (sme->auth_type) {
988 case NL80211_AUTHTYPE_OPEN_SYSTEM:
989 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
990 tenuAuth_type = OPEN_SYSTEM;
991 break;
992
993 case NL80211_AUTHTYPE_SHARED_KEY:
994 tenuAuth_type = SHARED_KEY;
995 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
996 break;
997
998 default:
999 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
1000 }
1001
1002
1003 /* ai: key_mgmt: enterprise case */
1004 if (sme->crypto.n_akm_suites) {
1005 switch (sme->crypto.akm_suites[0]) {
1006 case WLAN_AKM_SUITE_8021X:
1007 tenuAuth_type = IEEE8021;
1008 break;
1009
1010 default:
1011 break;
1012 }
1013 }
1014
1015
1016 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
1017
1018 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
1019 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
1020
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001021 curr_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001022
Leo Kimab16ec02015-10-29 12:05:40 +09001023 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +09001024 wlan_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001025
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001026 wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001027
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001028 s32Error = wilc_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001029 sme->ssid_len, sme->ie, sme->ie_len,
1030 CfgConnectResult, (void *)priv, u8security,
1031 tenuAuth_type, pstrNetworkInfo->u8channel,
1032 pstrNetworkInfo->pJoinParams);
Leo Kime6e12662015-09-16 18:36:03 +09001033 if (s32Error != 0) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001034 PRINT_ER("wilc_set_join_req(): Error(%d)\n", s32Error);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001035 s32Error = -ENOENT;
1036 goto done;
1037 }
1038
1039done:
1040
1041 return s32Error;
1042}
1043
1044
1045/**
Chaehyun Limb027cde2015-09-14 12:24:04 +09001046 * @brief disconnect
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001047 * @details Disconnect from the BSS/ESS.
1048 * @param[in]
1049 * @return int : Return 0 on Success
1050 * @author mdaftedar
1051 * @date 01 MAR 2012
1052 * @version 1.0
1053 */
Chaehyun Limb027cde2015-09-14 12:24:04 +09001054static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001055{
Leo Kime6e12662015-09-16 18:36:03 +09001056 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09001057 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09001058 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim51e825f2015-09-15 14:06:14 +09001059 u8 NullBssid[ETH_ALEN] = {0};
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001060
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001061 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001062 priv = wiphy_priv(wiphy);
1063
Leo Kim441dc602015-10-12 16:55:35 +09001064 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Leo Kimab16ec02015-10-29 12:05:40 +09001065 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +09001066 wlan_channel = INVALID_CHANNEL;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001067 wilc_wlan_set_bssid(priv->dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001068
1069 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
1070
Leo Kim583d9722015-11-19 15:56:16 +09001071 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +09001072 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +09001073 wilc_ie = false;
Leo Kim1229b1a2015-10-29 12:05:39 +09001074 pstrWFIDrv->p2p_timeout = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001075
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001076 s32Error = wilc_disconnect(priv->hWILCWFIDrv, reason_code);
Leo Kime6e12662015-09-16 18:36:03 +09001077 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001078 PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
1079 s32Error = -EINVAL;
1080 }
1081
1082 return s32Error;
1083}
1084
1085/**
Chaehyun Lim953d4172015-09-14 12:24:05 +09001086 * @brief add_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001087 * @details Add a key with the given parameters. @mac_addr will be %NULL
1088 * when adding a group key.
1089 * @param[in] key : key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, 8-byte Rx Mic Key
1090 * @return int : Return 0 on Success
1091 * @author mdaftedar
1092 * @date 01 MAR 2012
1093 * @version 1.0
1094 */
Chaehyun Lim953d4172015-09-14 12:24:05 +09001095static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1096 bool pairwise,
1097 const u8 *mac_addr, struct key_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001098
1099{
Leo Kime6e12662015-09-16 18:36:03 +09001100 s32 s32Error = 0, KeyLen = params->key_len;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001101 u32 i;
Chaehyun Lim27268872015-09-15 14:06:13 +09001102 struct wilc_priv *priv;
Arnd Bergmann057d1e92015-06-01 21:06:44 +02001103 const u8 *pu8RxMic = NULL;
1104 const u8 *pu8TxMic = NULL;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001105 u8 u8mode = NO_ENCRYPT;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001106 u8 u8gmode = NO_ENCRYPT;
1107 u8 u8pmode = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +09001108 enum AUTHTYPE tenuAuth_type = ANY;
Glen Lee76469202015-10-20 17:13:59 +09001109 struct wilc *wl;
1110 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001111
1112 priv = wiphy_priv(wiphy);
Glen Lee76469202015-10-20 17:13:59 +09001113 nic = netdev_priv(netdev);
1114 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001115
1116 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
1117
Johnny Kim8a143302015-06-10 17:06:46 +09001118 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001119
1120 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
1121 params->key[1],
1122 params->key[2]);
1123
1124
1125 switch (params->cipher) {
1126 case WLAN_CIPHER_SUITE_WEP40:
1127 case WLAN_CIPHER_SUITE_WEP104:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001128 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
1129
1130 priv->WILC_WFI_wep_default = key_index;
1131 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001132 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001133
1134 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
1135 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
1136
1137 for (i = 0; i < params->key_len; i++)
1138 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
1139
1140 tenuAuth_type = OPEN_SYSTEM;
1141
1142 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
1143 u8mode = ENCRYPT_ENABLED | WEP;
1144 else
1145 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
1146
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001147 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 +09001148 break;
1149 }
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001150 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001151 priv->WILC_WFI_wep_default = key_index;
1152 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001153 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001154
1155 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
1156 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
1157 if (INFO) {
1158 for (i = 0; i < params->key_len; i++)
1159 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
1160 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001161 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001162 }
1163
1164 break;
1165
1166 case WLAN_CIPHER_SUITE_TKIP:
1167 case WLAN_CIPHER_SUITE_CCMP:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001168 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
1169
1170 if (priv->wilc_gtk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001171 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001172 priv->wilc_gtk[key_index]->key = NULL;
1173 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001174
1175 }
1176 if (priv->wilc_ptk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001177 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001178 priv->wilc_ptk[key_index]->key = NULL;
1179 priv->wilc_ptk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001180 }
1181
1182
1183
Daniel Machon19132212015-08-05 08:18:31 +02001184 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001185 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1186 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1187 else
1188 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1189
1190 priv->wilc_groupkey = u8gmode;
1191
1192 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1193
1194 pu8TxMic = params->key + 24;
1195 pu8RxMic = params->key + 16;
1196 KeyLen = params->key_len - 16;
1197 }
1198 /* 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 +05301199 kfree(priv->wilc_gtk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001200
Glen Leef3052582015-09-10 12:03:04 +09001201 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001202 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001203
1204 /* 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 +05301205 kfree(priv->wilc_gtk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001206
1207 if ((params->seq_len) > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001208 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001209 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001210 }
1211
1212 priv->wilc_gtk[key_index]->cipher = params->cipher;
1213 priv->wilc_gtk[key_index]->key_len = params->key_len;
1214 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1215
1216 if (INFO) {
1217 for (i = 0; i < params->key_len; i++)
1218 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1219 for (i = 0; i < params->seq_len; i++)
1220 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1221 }
1222
1223
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001224 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001225 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode);
1226
1227 } else {
1228 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]);
1229
1230 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1231 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1232 else
1233 u8pmode = priv->wilc_groupkey | AES;
1234
1235
1236 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1237
1238 pu8TxMic = params->key + 24;
1239 pu8RxMic = params->key + 16;
1240 KeyLen = params->key_len - 16;
1241 }
1242
Shraddha Barkecccfc392015-10-12 20:49:19 +05301243 kfree(priv->wilc_ptk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001244
Glen Leef3052582015-09-10 12:03:04 +09001245 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001246
Shraddha Barkecccfc392015-10-12 20:49:19 +05301247 kfree(priv->wilc_ptk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001248
1249 if ((params->seq_len) > 0)
Glen Leef3052582015-09-10 12:03:04 +09001250 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001251
1252 if (INFO) {
1253 for (i = 0; i < params->key_len; i++)
1254 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1255
1256 for (i = 0; i < params->seq_len; i++)
1257 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1258 }
1259
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001260 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001261
1262 if ((params->seq_len) > 0)
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001263 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001264
1265 priv->wilc_ptk[key_index]->cipher = params->cipher;
1266 priv->wilc_ptk[key_index]->key_len = params->key_len;
1267 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1268
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001269 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001270 pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index);
1271 }
1272 break;
1273 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001274
1275 {
1276 u8mode = 0;
Daniel Machon19132212015-08-05 08:18:31 +02001277 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001278 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1279 /* swap the tx mic by rx mic */
1280 pu8RxMic = params->key + 24;
1281 pu8TxMic = params->key + 16;
1282 KeyLen = params->key_len - 16;
1283 }
1284
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001285 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001286 if (!g_gtk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001287 g_add_gtk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001288 g_add_gtk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001289 if (!mac_addr) {
1290 g_add_gtk_key_params.mac_addr = NULL;
1291 } else {
Glen Leef3052582015-09-10 12:03:04 +09001292 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001293 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1294 }
1295 g_key_gtk_params.key_len = params->key_len;
1296 g_key_gtk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001297 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001298 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1299 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001300 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001301 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1302 }
1303 g_key_gtk_params.cipher = params->cipher;
1304
1305 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1306 g_key_gtk_params.key[1],
1307 g_key_gtk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001308 g_gtk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001309 }
1310
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001311 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001312 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001313 } else {
1314 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1315 /* swap the tx mic by rx mic */
1316 pu8RxMic = params->key + 24;
1317 pu8TxMic = params->key + 16;
1318 KeyLen = params->key_len - 16;
1319 }
1320
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001321 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001322 if (!g_ptk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001323 g_add_ptk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001324 g_add_ptk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001325 if (!mac_addr) {
1326 g_add_ptk_key_params.mac_addr = NULL;
1327 } else {
Glen Leef3052582015-09-10 12:03:04 +09001328 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001329 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1330 }
1331 g_key_ptk_params.key_len = params->key_len;
1332 g_key_ptk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001333 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001334 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1335 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001336 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001337 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1338 }
1339 g_key_ptk_params.cipher = params->cipher;
1340
1341 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1342 g_key_ptk_params.key[1],
1343 g_key_ptk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001344 g_ptk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001345 }
1346
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001347 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001348 pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index);
1349 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1350 if (INFO) {
1351 for (i = 0; i < params->key_len; i++)
1352 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1353 }
1354 }
1355 }
1356 break;
1357
1358 default:
1359 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
1360 s32Error = -ENOTSUPP;
1361
1362 }
1363
1364 return s32Error;
1365}
1366
1367/**
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001368 * @brief del_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001369 * @details Remove a key given the @mac_addr (%NULL for a group key)
1370 * and @key_index, return -ENOENT if the key doesn't exist.
1371 * @param[in]
1372 * @return int : Return 0 on Success
1373 * @author mdaftedar
1374 * @date 01 MAR 2012
1375 * @version 1.0
1376 */
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001377static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1378 u8 key_index,
1379 bool pairwise,
1380 const u8 *mac_addr)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001381{
Chaehyun Lim27268872015-09-15 14:06:13 +09001382 struct wilc_priv *priv;
Glen Lee692e2ac2015-10-20 17:14:00 +09001383 struct wilc *wl;
1384 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001385
1386 priv = wiphy_priv(wiphy);
Glen Lee692e2ac2015-10-20 17:14:00 +09001387 nic = netdev_priv(netdev);
1388 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001389
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001390 /*delete saved keys, if any*/
Glen Lee692e2ac2015-10-20 17:14:00 +09001391 if (netdev == wl->vif[0].ndev) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09001392 g_ptk_keys_saved = false;
1393 g_gtk_keys_saved = false;
1394 g_wep_keys_saved = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001395
1396 /*Delete saved WEP keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301397 kfree(g_key_wep_params.key);
1398 g_key_wep_params.key = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001399
1400 /*freeing memory allocated by "wilc_gtk" and "wilc_ptk" in "WILC_WIFI_ADD_KEY"*/
1401
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001402 if ((priv->wilc_gtk[key_index]) != NULL) {
1403
Shraddha Barkecccfc392015-10-12 20:49:19 +05301404 kfree(priv->wilc_gtk[key_index]->key);
1405 priv->wilc_gtk[key_index]->key = NULL;
1406 kfree(priv->wilc_gtk[key_index]->seq);
1407 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001408
Chaehyun Lim49188af2015-08-11 10:32:41 +09001409 kfree(priv->wilc_gtk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001410 priv->wilc_gtk[key_index] = NULL;
1411
1412 }
1413
1414 if ((priv->wilc_ptk[key_index]) != NULL) {
1415
Shraddha Barkecccfc392015-10-12 20:49:19 +05301416 kfree(priv->wilc_ptk[key_index]->key);
1417 priv->wilc_ptk[key_index]->key = NULL;
1418 kfree(priv->wilc_ptk[key_index]->seq);
1419 priv->wilc_ptk[key_index]->seq = NULL;
Chaehyun Lim49188af2015-08-11 10:32:41 +09001420 kfree(priv->wilc_ptk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001421 priv->wilc_ptk[key_index] = NULL;
1422 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001423
1424 /*Delete saved PTK and GTK keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301425 kfree(g_key_ptk_params.key);
1426 g_key_ptk_params.key = NULL;
1427 kfree(g_key_ptk_params.seq);
1428 g_key_ptk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001429
Shraddha Barkecccfc392015-10-12 20:49:19 +05301430 kfree(g_key_gtk_params.key);
1431 g_key_gtk_params.key = NULL;
1432 kfree(g_key_gtk_params.seq);
1433 g_key_gtk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001434
1435 /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001436 wilc_set_machw_change_vir_if(netdev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001437 }
1438
1439 if (key_index >= 0 && key_index <= 3) {
Chaehyun Lim2cc46832015-08-07 09:02:01 +09001440 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001441 priv->WILC_WFI_wep_key_len[key_index] = 0;
1442
1443 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001444 wilc_remove_wep_key(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001445 } else {
1446 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001447 wilc_remove_key(priv->hWILCWFIDrv, mac_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001448 }
1449
Leo Kimaaed3292015-10-12 16:55:38 +09001450 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001451}
1452
1453/**
Chaehyun Limf4893df2015-09-14 12:24:07 +09001454 * @brief get_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001455 * @details Get information about the key with the given parameters.
1456 * @mac_addr will be %NULL when requesting information for a group
1457 * key. All pointers given to the @callback function need not be valid
1458 * after it returns. This function should return an error if it is
1459 * not possible to retrieve the key, -ENOENT if it doesn't exist.
1460 * @param[in]
1461 * @return int : Return 0 on Success
1462 * @author mdaftedar
1463 * @date 01 MAR 2012
1464 * @version 1.0
1465 */
Chaehyun Limf4893df2015-09-14 12:24:07 +09001466static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1467 bool pairwise,
1468 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001469{
Chaehyun Lim27268872015-09-15 14:06:13 +09001470 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001471 struct key_params key_params;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001472 u32 i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001473
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001474 priv = wiphy_priv(wiphy);
1475
1476
Alison Schofield3604af52015-10-12 13:22:44 -07001477 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001478 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1479
1480 key_params.key = priv->wilc_gtk[key_index]->key;
1481 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1482 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1483 key_params.seq = priv->wilc_gtk[key_index]->seq;
1484 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1485 if (INFO) {
1486 for (i = 0; i < key_params.key_len; i++)
1487 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1488 }
1489 } else {
1490 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1491
1492 key_params.key = priv->wilc_ptk[key_index]->key;
1493 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1494 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1495 key_params.seq = priv->wilc_ptk[key_index]->seq;
1496 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1497 }
1498
1499 callback(cookie, &key_params);
1500
Leo Kimaaed3292015-10-12 16:55:38 +09001501 return 0; /* priv->wilc_gtk->key_len ?0 : -ENOENT; */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001502}
1503
1504/**
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001505 * @brief set_default_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001506 * @details Set the default management frame key on an interface
1507 * @param[in]
1508 * @return int : Return 0 on Success.
1509 * @author mdaftedar
1510 * @date 01 MAR 2012
1511 * @version 1.0
1512 */
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001513static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1514 bool unicast, bool multicast)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001515{
Chaehyun Lim27268872015-09-15 14:06:13 +09001516 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001517
1518
1519 priv = wiphy_priv(wiphy);
1520
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301521 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001522
1523 if (key_index != priv->WILC_WFI_wep_default) {
1524
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001525 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001526 }
1527
Leo Kimaaed3292015-10-12 16:55:38 +09001528 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001529}
1530
1531/**
Chaehyun Limf06f5622015-09-14 12:24:18 +09001532 * @brief get_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001533 * @details Get station information for the station identified by @mac
1534 * @param[in] NONE
1535 * @return int : Return 0 on Success.
1536 * @author mdaftedar
1537 * @date 01 MAR 2012
1538 * @version 1.0
1539 */
1540
Chaehyun Limf06f5622015-09-14 12:24:18 +09001541static int get_station(struct wiphy *wiphy, struct net_device *dev,
1542 const u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001543{
Chaehyun Lim27268872015-09-15 14:06:13 +09001544 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001545 perInterface_wlan_t *nic;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001546 u32 i = 0;
1547 u32 associatedsta = 0;
1548 u32 inactive_time = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001549 priv = wiphy_priv(wiphy);
1550 nic = netdev_priv(dev);
1551
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001552 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
1553 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1554
1555 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1556
1557 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1558
1559 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1560 associatedsta = i;
1561 break;
1562 }
1563
1564 }
1565
1566 if (associatedsta == -1) {
Leo Kimaaed3292015-10-12 16:55:38 +09001567 PRINT_ER("Station required is not associated\n");
1568 return -ENOENT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001569 }
1570
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001571 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001572
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001573 wilc_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001574 sinfo->inactive_time = 1000 * inactive_time;
1575 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
1576
1577 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001578
1579 if (nic->iftype == STATION_MODE) {
Leo Kim03e7b9c2015-10-12 16:55:58 +09001580 struct rf_info strStatistics;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001581
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001582 wilc_get_statistics(priv->hWILCWFIDrv, &strStatistics);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001583
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001584 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
Chandra S Gorentla62129902015-08-05 22:11:57 +05301585 BIT(NL80211_STA_INFO_RX_PACKETS) |
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001586 BIT(NL80211_STA_INFO_TX_PACKETS) |
1587 BIT(NL80211_STA_INFO_TX_FAILED) |
1588 BIT(NL80211_STA_INFO_TX_BITRATE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001589
Leo Kim00c8dfc2015-10-29 12:05:30 +09001590 sinfo->signal = strStatistics.rssi;
Leo Kim9b992742015-10-29 12:05:32 +09001591 sinfo->rx_packets = strStatistics.rx_cnt;
Leo Kim54160372015-10-29 12:05:33 +09001592 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1593 sinfo->tx_failed = strStatistics.tx_fail_cnt;
Leo Kim5babeec2015-10-29 12:05:29 +09001594 sinfo->txrate.legacy = strStatistics.link_speed * 10;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001595
Leo Kim5babeec2015-10-29 12:05:29 +09001596 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1597 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001598 wilc_enable_tcp_ack_filter(true);
Leo Kim5babeec2015-10-29 12:05:29 +09001599 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001600 wilc_enable_tcp_ack_filter(false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001601
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001602 PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
1603 sinfo->tx_failed, sinfo->txrate.legacy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001604 }
Leo Kimaaed3292015-10-12 16:55:38 +09001605 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001606}
1607
1608
1609/**
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001610 * @brief change_bss
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001611 * @details Modify parameters for a given BSS.
1612 * @param[in]
1613 * -use_cts_prot: Whether to use CTS protection
1614 * (0 = no, 1 = yes, -1 = do not change)
1615 * -use_short_preamble: Whether the use of short preambles is allowed
1616 * (0 = no, 1 = yes, -1 = do not change)
1617 * -use_short_slot_time: Whether the use of short slot time is allowed
1618 * (0 = no, 1 = yes, -1 = do not change)
1619 * -basic_rates: basic rates in IEEE 802.11 format
1620 * (or NULL for no change)
1621 * -basic_rates_len: number of basic rates
1622 * -ap_isolate: do not forward packets between connected stations
1623 * -ht_opmode: HT Operation mode
1624 * (u16 = opmode, -1 = do not change)
1625 * @return int : Return 0 on Success.
1626 * @author mdaftedar
1627 * @date 01 MAR 2012
1628 * @version 1.0
1629 */
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001630static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1631 struct bss_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001632{
1633 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1634 return 0;
1635}
1636
1637/**
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001638 * @brief set_wiphy_params
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001639 * @details Notify that wiphy parameters have changed;
1640 * @param[in] Changed bitfield (see &enum wiphy_params_flags) describes which values
1641 * have changed.
1642 * @return int : Return 0 on Success
1643 * @author mdaftedar
1644 * @date 01 MAR 2012
1645 * @version 1.0
1646 */
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001647static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001648{
Leo Kime6e12662015-09-16 18:36:03 +09001649 s32 s32Error = 0;
Leo Kim95296502015-10-05 15:25:46 +09001650 struct cfg_param_val pstrCfgParamVal;
Chaehyun Lim27268872015-09-15 14:06:13 +09001651 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001652
1653 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001654
Tony Cho87c05b22015-10-12 16:56:07 +09001655 pstrCfgParamVal.flag = 0;
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301656 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001657
1658 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1659 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1660 priv->dev->ieee80211_ptr->wiphy->retry_short);
Tony Cho87c05b22015-10-12 16:56:07 +09001661 pstrCfgParamVal.flag |= RETRY_SHORT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001662 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1663 }
1664 if (changed & WIPHY_PARAM_RETRY_LONG) {
1665
1666 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 +09001667 pstrCfgParamVal.flag |= RETRY_LONG;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001668 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1669
1670 }
1671 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1672 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 +09001673 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001674 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1675
1676 }
1677
1678 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1679 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1680
Tony Cho87c05b22015-10-12 16:56:07 +09001681 pstrCfgParamVal.flag |= RTS_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001682 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1683
1684 }
1685
1686 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001687 s32Error = wilc_hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001688 if (s32Error)
1689 PRINT_ER("Error in setting WIPHY PARAMS\n");
1690
1691
1692 return s32Error;
1693}
Arnd Bergmanne5af0562015-05-29 22:52:12 +02001694
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001695/**
Chaehyun Lim4d466572015-09-14 12:24:22 +09001696 * @brief set_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001697 * @details Cache a PMKID for a BSSID. This is mostly useful for fullmac
1698 * devices running firmwares capable of generating the (re) association
1699 * RSN IE. It allows for faster roaming between WPA2 BSSIDs.
1700 * @param[in]
1701 * @return int : Return 0 on Success
1702 * @author mdaftedar
1703 * @date 01 MAR 2012
1704 * @version 1.0
1705 */
Chaehyun Lim4d466572015-09-14 12:24:22 +09001706static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1707 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001708{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001709 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001710 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001711 u8 flag = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001712
Chaehyun Lim27268872015-09-15 14:06:13 +09001713 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001714
1715 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1716
1717
1718 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001719 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001720 ETH_ALEN)) {
1721 /*If bssid already exists and pmkid value needs to reset*/
1722 flag = PMKID_FOUND;
1723 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1724 break;
1725 }
1726 }
1727 if (i < WILC_MAX_NUM_PMKIDS) {
1728 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001729 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001730 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001731 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001732 PMKID_LEN);
1733 if (!(flag == PMKID_FOUND))
1734 priv->pmkid_list.numpmkid++;
1735 } else {
1736 PRINT_ER("Invalid PMKID index\n");
1737 s32Error = -EINVAL;
1738 }
1739
1740 if (!s32Error) {
1741 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001742 s32Error = wilc_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001743 }
1744 return s32Error;
1745}
1746
1747/**
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001748 * @brief del_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001749 * @details Delete a cached PMKID.
1750 * @param[in]
1751 * @return int : Return 0 on Success
1752 * @author mdaftedar
1753 * @date 01 MAR 2012
1754 * @version 1.0
1755 */
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001756static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1757 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001758{
1759
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001760 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001761 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001762
Chaehyun Lim27268872015-09-15 14:06:13 +09001763 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001764
1765 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1766
1767 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001768 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001769 ETH_ALEN)) {
1770 /*If bssid is found, reset the values*/
1771 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
Leo Kimcd1e6cb2015-10-05 15:25:45 +09001772 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001773 break;
1774 }
1775 }
1776
1777 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1778 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001779 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001780 priv->pmkid_list.pmkidlist[i + 1].bssid,
1781 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001782 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001783 priv->pmkid_list.pmkidlist[i].pmkid,
1784 PMKID_LEN);
1785 }
1786 priv->pmkid_list.numpmkid--;
1787 } else {
1788 s32Error = -EINVAL;
1789 }
1790
1791 return s32Error;
1792}
1793
1794/**
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001795 * @brief flush_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001796 * @details Flush all cached PMKIDs.
1797 * @param[in]
1798 * @return int : Return 0 on Success
1799 * @author mdaftedar
1800 * @date 01 MAR 2012
1801 * @version 1.0
1802 */
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001803static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001804{
Chaehyun Lim27268872015-09-15 14:06:13 +09001805 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001806
1807 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
1808
1809 /*Get cashed Pmkids and set all with zeros*/
Leo Kima949f902015-10-05 15:25:44 +09001810 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001811
1812 return 0;
1813}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001814
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001815
1816/**
1817 * @brief WILC_WFI_CfgParseRxAction
1818 * @details Function parses the received frames and modifies the following attributes:
1819 * -GO Intent
1820 * -Channel list
1821 * -Operating Channel
1822 *
1823 * @param[in] u8* Buffer, u32 length
1824 * @return NONE.
1825 * @author mdaftedar
1826 * @date 12 DEC 2012
1827 * @version
1828 */
1829
Arnd Bergmann1608c402015-11-16 15:04:53 +01001830static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001831{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001832 u32 index = 0;
1833 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001834
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001835 u8 op_channel_attr_index = 0;
1836 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001837
1838 while (index < len) {
1839 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001840 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001841 }
1842
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301843 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001844 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301845 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001846 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001847 index += buf[index + 1] + 3; /* ID,Length byte */
1848 }
Leo Kim0bd82742015-11-19 15:56:14 +09001849 if (wlan_channel != INVALID_CHANNEL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001850 /*Modify channel list attribute*/
1851 if (channel_list_attr_index) {
1852 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1853 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1854 if (buf[i] == 0x51) {
1855 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
Leo Kim0bd82742015-11-19 15:56:14 +09001856 buf[j] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001857 }
1858 break;
1859 }
1860 }
1861 }
1862 /*Modify operating channel attribute*/
1863 if (op_channel_attr_index) {
1864 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1865 buf[op_channel_attr_index + 6] = 0x51;
Leo Kim0bd82742015-11-19 15:56:14 +09001866 buf[op_channel_attr_index + 7] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001867 }
1868 }
1869}
1870
1871/**
1872 * @brief WILC_WFI_CfgParseTxAction
1873 * @details Function parses the transmitted action frames and modifies the
1874 * GO Intent attribute
1875 * @param[in] u8* Buffer, u32 length, bool bOperChan, u8 iftype
1876 * @return NONE.
1877 * @author mdaftedar
1878 * @date 12 DEC 2012
1879 * @version
1880 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01001881static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001882{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001883 u32 index = 0;
1884 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001885
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001886 u8 op_channel_attr_index = 0;
1887 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001888
1889 while (index < len) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001890 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001891 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001892
1893 break;
1894 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001895
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301896 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001897 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301898 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001899 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001900 index += buf[index + 1] + 3; /* ID,Length byte */
1901 }
Leo Kim0bd82742015-11-19 15:56:14 +09001902 if (wlan_channel != INVALID_CHANNEL && bOperChan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001903 /*Modify channel list attribute*/
1904 if (channel_list_attr_index) {
1905 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1906 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1907 if (buf[i] == 0x51) {
1908 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
Leo Kim0bd82742015-11-19 15:56:14 +09001909 buf[j] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001910 }
1911 break;
1912 }
1913 }
1914 }
1915 /*Modify operating channel attribute*/
1916 if (op_channel_attr_index) {
1917 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1918 buf[op_channel_attr_index + 6] = 0x51;
Leo Kim0bd82742015-11-19 15:56:14 +09001919 buf[op_channel_attr_index + 7] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001920 }
1921 }
1922}
1923
1924/* @brief WILC_WFI_p2p_rx
1925 * @details
1926 * @param[in]
1927 *
1928 * @return None
1929 * @author Mai Daftedar
1930 * @date 2 JUN 2013
1931 * @version 1.0
1932 */
1933
Chaehyun Limfbc2fe12015-09-15 14:06:16 +09001934void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001935{
1936
Chaehyun Lim27268872015-09-15 14:06:13 +09001937 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001938 u32 header, pkt_offset;
Leo Kim441dc602015-10-12 16:55:35 +09001939 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001940 u32 i = 0;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001941 s32 s32Freq;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001942
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001943 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001944 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001945
1946 /* Get WILC header */
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001947 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001948
1949 /* The packet offset field conain info about what type of managment frame */
1950 /* we are dealing with and ack status */
1951 pkt_offset = GET_PKT_OFFSET(header);
1952
1953 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1954 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1955 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001956 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001957 return;
1958 } else {
1959 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
1960 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],
1961 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001962 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001963 } else {
1964 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],
1965 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001966 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001967 }
1968 return;
1969 }
1970 } else {
1971
1972 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
1973
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001974 /*Upper layer is informed that the frame is received on this freq*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001975 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001976
1977 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1978 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
1979
Leo Kim1229b1a2015-10-29 12:05:39 +09001980 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001981 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
1982 return;
1983 }
1984 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1985
1986 switch (buff[ACTION_SUBTYPE_ID]) {
1987 case GAS_INTIAL_REQ:
1988 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
1989 break;
1990
1991 case GAS_INTIAL_RSP:
1992 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
1993 break;
1994
1995 case PUBLIC_ACT_VENDORSPEC:
Leo Kim881eb5d2015-11-19 15:56:15 +09001996 if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001997 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
Leo Kima25d5182015-11-19 15:56:19 +09001998 if (!wilc_ie) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001999 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
Leo Kim86685942015-11-19 15:56:18 +09002000 if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002001 p2p_recv_random = buff[i + 6];
Leo Kima25d5182015-11-19 15:56:19 +09002002 wilc_ie = true;
Leo Kimb84a3ac2015-11-19 15:56:17 +09002003 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", p2p_recv_random);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002004 break;
2005 }
2006 }
2007 }
2008 }
Leo Kimb84a3ac2015-11-19 15:56:17 +09002009 if (p2p_local_random > p2p_recv_random) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002010 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2011 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2012 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
Leo Kim881eb5d2015-11-19 15:56:15 +09002013 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002014 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
2015 break;
2016 }
2017 }
2018 }
Leo Kim583d9722015-11-19 15:56:16 +09002019 } else {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002020 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 +09002021 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002022 }
2023
2024
Leo Kima25d5182015-11-19 15:56:19 +09002025 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 +09002026 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
2027 /* extra attribute for sig_dbm: signal strength in mBm, or 0 if unknown */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002028 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002029 return;
2030 }
2031 break;
2032
2033 default:
2034 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
2035 break;
2036 }
2037 }
2038 }
2039
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002040 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002041 }
2042}
2043
2044/**
2045 * @brief WILC_WFI_mgmt_tx_complete
2046 * @details Returns result of writing mgmt frame to VMM (Tx buffers are freed here)
2047 * @param[in] priv
2048 * transmitting status
2049 * @return None
2050 * @author Amr Abdelmoghny
2051 * @date 20 MAY 2013
2052 * @version 1.0
2053 */
2054static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
2055{
2056 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
2057
2058
2059 kfree(pv_data->buff);
2060 kfree(pv_data);
2061}
2062
2063/**
2064 * @brief WILC_WFI_RemainOnChannelReady
2065 * @details Callback function, called from handle_remain_on_channel on being ready on channel
2066 * @param
2067 * @return none
2068 * @author Amr abdelmoghny
2069 * @date 9 JUNE 2013
2070 * @version
2071 */
2072
2073static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
2074{
Chaehyun Lim27268872015-09-15 14:06:13 +09002075 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002076
Chaehyun Lim27268872015-09-15 14:06:13 +09002077 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002078
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302079 PRINT_D(HOSTINF_DBG, "Remain on channel ready\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002080
Dean Lee72ed4dc2015-06-12 14:11:44 +09002081 priv->bInP2PlistenState = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002082
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002083 cfg80211_ready_on_channel(priv->wdev,
2084 priv->strRemainOnChanParams.u64ListenCookie,
2085 priv->strRemainOnChanParams.pstrListenChan,
2086 priv->strRemainOnChanParams.u32ListenDuration,
2087 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002088}
2089
2090/**
2091 * @brief WILC_WFI_RemainOnChannelExpired
2092 * @details Callback function, called on expiration of remain-on-channel duration
2093 * @param
2094 * @return none
2095 * @author Amr abdelmoghny
2096 * @date 15 MAY 2013
2097 * @version
2098 */
2099
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002100static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002101{
Chaehyun Lim27268872015-09-15 14:06:13 +09002102 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002103
Chaehyun Lim27268872015-09-15 14:06:13 +09002104 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002105
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002106 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302107 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002108
Dean Lee72ed4dc2015-06-12 14:11:44 +09002109 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002110
2111 /*Inform wpas of remain-on-channel expiration*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002112 cfg80211_remain_on_channel_expired(priv->wdev,
2113 priv->strRemainOnChanParams.u64ListenCookie,
2114 priv->strRemainOnChanParams.pstrListenChan,
2115 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002116 } else {
2117 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
2118 , priv->strRemainOnChanParams.u32ListenSessionID);
2119 }
2120}
2121
2122
2123/**
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002124 * @brief remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002125 * @details Request the driver to remain awake on the specified
2126 * channel for the specified duration to complete an off-channel
2127 * operation (e.g., public action frame exchange). When the driver is
2128 * ready on the requested channel, it must indicate this with an event
2129 * notification by calling cfg80211_ready_on_channel().
2130 * @param[in]
2131 * @return int : Return 0 on Success
2132 * @author mdaftedar
2133 * @date 01 MAR 2012
2134 * @version 1.0
2135 */
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002136static int remain_on_channel(struct wiphy *wiphy,
2137 struct wireless_dev *wdev,
2138 struct ieee80211_channel *chan,
2139 unsigned int duration, u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002140{
Leo Kime6e12662015-09-16 18:36:03 +09002141 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002142 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002143
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002144 priv = wiphy_priv(wiphy);
2145
2146 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
2147
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002148
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002149 if (wdev->iftype == NL80211_IFTYPE_AP) {
2150 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
2151 return s32Error;
2152 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002153
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002154 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002155
2156 /*Setting params needed by WILC_WFI_RemainOnChannelExpired()*/
2157 priv->strRemainOnChanParams.pstrListenChan = chan;
2158 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002159 priv->strRemainOnChanParams.u32ListenDuration = duration;
2160 priv->strRemainOnChanParams.u32ListenSessionID++;
2161
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002162 s32Error = wilc_remain_on_channel(priv->hWILCWFIDrv
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002163 , priv->strRemainOnChanParams.u32ListenSessionID
2164 , duration
2165 , chan->hw_value
2166 , WILC_WFI_RemainOnChannelExpired
2167 , WILC_WFI_RemainOnChannelReady
2168 , (void *)priv);
2169
2170 return s32Error;
2171}
2172
2173/**
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002174 * @brief cancel_remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002175 * @details Cancel an on-going remain-on-channel operation.
2176 * This allows the operation to be terminated prior to timeout based on
2177 * the duration value.
2178 * @param[in] struct wiphy *wiphy,
2179 * @param[in] struct net_device *dev
2180 * @param[in] u64 cookie,
2181 * @return int : Return 0 on Success
2182 * @author mdaftedar
2183 * @date 01 MAR 2012
2184 * @version 1.0
2185 */
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002186static int cancel_remain_on_channel(struct wiphy *wiphy,
2187 struct wireless_dev *wdev,
2188 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002189{
Leo Kime6e12662015-09-16 18:36:03 +09002190 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002191 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002192
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002193 priv = wiphy_priv(wiphy);
2194
2195 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
2196
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002197 s32Error = wilc_listen_state_expired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002198 return s32Error;
2199}
2200/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002201 * @brief WILC_WFI_mgmt_tx_frame
2202 * @details
2203 *
2204 * @param[in]
2205 * @return NONE.
2206 * @author mdaftedar
2207 * @date 01 JUL 2012
2208 * @version
2209 */
Chaehyun Limc1560322015-09-22 18:34:51 +09002210static int mgmt_tx(struct wiphy *wiphy,
2211 struct wireless_dev *wdev,
2212 struct cfg80211_mgmt_tx_params *params,
2213 u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002214{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002215 struct ieee80211_channel *chan = params->chan;
2216 unsigned int wait = params->wait;
2217 const u8 *buf = params->buf;
2218 size_t len = params->len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002219 const struct ieee80211_mgmt *mgmt;
2220 struct p2p_mgmt_data *mgmt_tx;
Chaehyun Lim27268872015-09-15 14:06:13 +09002221 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002222 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002223 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002224 perInterface_wlan_t *nic;
Leo Kim86685942015-11-19 15:56:18 +09002225 u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002226
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002227 nic = netdev_priv(wdev->netdev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002228 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002229 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002230
2231 *cookie = (unsigned long)buf;
2232 priv->u64tx_cookie = *cookie;
2233 mgmt = (const struct ieee80211_mgmt *) buf;
2234
2235 if (ieee80211_is_mgmt(mgmt->frame_control)) {
2236
2237 /*mgmt frame allocation*/
Glen Leef3052582015-09-10 12:03:04 +09002238 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002239 if (mgmt_tx == NULL) {
2240 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
Leo Kime6e12662015-09-16 18:36:03 +09002241 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002242 }
Glen Leef3052582015-09-10 12:03:04 +09002243 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002244 if (mgmt_tx->buff == NULL) {
2245 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
Tony Chof638dd32015-09-07 19:09:31 +09002246 kfree(mgmt_tx);
Leo Kime6e12662015-09-16 18:36:03 +09002247 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002248 }
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09002249 memcpy(mgmt_tx->buff, buf, len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002250 mgmt_tx->size = len;
2251
2252
2253 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
2254 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
2255 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002256 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002257 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002258 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002259 } else if (ieee80211_is_action(mgmt->frame_control)) {
Chaehyun Limd85f5322015-06-11 14:35:54 +09002260 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002261
2262
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002263 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002264 /*Only set the channel, if not a negotiation confirmation frame
2265 * (If Negotiation confirmation frame, force it
2266 * to be transmitted on the same negotiation channel)*/
2267
2268 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
2269 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
2270 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002271 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002272 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002273 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002274 }
2275 switch (buf[ACTION_SUBTYPE_ID]) {
2276 case GAS_INTIAL_REQ:
2277 {
2278 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
2279 break;
2280 }
2281
2282 case GAS_INTIAL_RSP:
2283 {
2284 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
2285 break;
2286 }
2287
2288 case PUBLIC_ACT_VENDORSPEC:
2289 {
Leo Kim881eb5d2015-11-19 15:56:15 +09002290 if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002291 /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/
2292 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002293 if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
Leo Kim583d9722015-11-19 15:56:16 +09002294 get_random_bytes(&p2p_local_random, 1);
2295 p2p_local_random++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002296 }
2297 }
2298
2299 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2300 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002301 if (p2p_local_random > p2p_recv_random) {
2302 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 +09002303
2304 /*Search for the p2p information information element , after the Public action subtype theres a byte for teh dialog token, skip that*/
2305 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
Leo Kim881eb5d2015-11-19 15:56:15 +09002306 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002307 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
Dean Lee72ed4dc2015-06-12 14:11:44 +09002308 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002309
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002310 /*If using supplicant go intent, no need at all*/
2311 /*to parse transmitted negotiation frames*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002312 else
Dean Lee72ed4dc2015-06-12 14:11:44 +09002313 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002314 break;
2315 }
2316 }
2317
2318 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
Shivani Bhardwajd8060fc2015-10-29 00:30:01 +05302319 /*
2320 * Adding WILC information element to allow two WILC devices to
2321 * identify each other and connect
2322 */
Leo Kim86685942015-11-19 15:56:18 +09002323 memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
2324 mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002325 mgmt_tx->size = buf_len;
2326 }
Leo Kim583d9722015-11-19 15:56:16 +09002327 } else {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002328 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 +09002329 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002330 }
2331
2332 } else {
2333 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
2334 }
2335
2336 break;
2337 }
2338
2339 default:
2340 {
2341 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
2342 break;
2343 }
2344 }
2345
2346 }
2347
2348 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 +09002349 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002350
Leo Kim1229b1a2015-10-29 12:05:39 +09002351 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n",
2352 jiffies, pstrWFIDrv->p2p_timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002353 }
2354
Glen Lee829c4772015-10-29 12:18:44 +09002355 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
2356 mgmt_tx->buff, mgmt_tx->size,
Glen Leec9d48342015-10-01 16:03:43 +09002357 WILC_WFI_mgmt_tx_complete);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002358 } else {
2359 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
2360 }
Leo Kimaaed3292015-10-12 16:55:38 +09002361 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002362}
2363
Chaehyun Lim85c587a2015-09-22 18:34:50 +09002364static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
2365 struct wireless_dev *wdev,
2366 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002367{
Chaehyun Lim27268872015-09-15 14:06:13 +09002368 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002369 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002370
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002371 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002372 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002373
2374
2375 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
Leo Kim1229b1a2015-10-29 12:05:39 +09002376 pstrWFIDrv->p2p_timeout = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002377
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +01002378 if (!priv->bInP2PlistenState) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002379 cfg80211_remain_on_channel_expired(priv->wdev,
2380 priv->strRemainOnChanParams.u64ListenCookie,
2381 priv->strRemainOnChanParams.pstrListenChan,
2382 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002383 }
2384
2385 return 0;
2386}
2387
2388/**
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002389 * @brief wilc_mgmt_frame_register
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002390 * @details Notify driver that a management frame type was
2391 * registered. Note that this callback may not sleep, and cannot run
2392 * concurrently with itself.
2393 * @param[in]
2394 * @return NONE.
2395 * @author mdaftedar
2396 * @date 01 JUL 2012
2397 * @version
2398 */
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002399void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
2400 u16 frame_type, bool reg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002401{
2402
Chaehyun Lim27268872015-09-15 14:06:13 +09002403 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002404 perInterface_wlan_t *nic;
Glen Lee1b869352015-10-20 17:14:01 +09002405 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002406
2407 priv = wiphy_priv(wiphy);
2408 nic = netdev_priv(priv->wdev->netdev);
Glen Lee1b869352015-10-20 17:14:01 +09002409 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002410
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002411 if (!frame_type)
2412 return;
2413
2414 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
2415 switch (frame_type) {
2416 case PROBE_REQ:
2417 {
2418 nic->g_struct_frame_reg[0].frame_type = frame_type;
2419 nic->g_struct_frame_reg[0].reg = reg;
2420 }
2421 break;
2422
2423 case ACTION:
2424 {
2425 nic->g_struct_frame_reg[1].frame_type = frame_type;
2426 nic->g_struct_frame_reg[1].reg = reg;
2427 }
2428 break;
2429
2430 default:
2431 {
2432 break;
2433 }
2434
2435 }
2436 /*If mac is closed, then return*/
Glen Lee1b869352015-10-20 17:14:01 +09002437 if (!wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002438 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
2439 return;
2440 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002441 wilc_frame_register(priv->hWILCWFIDrv, frame_type, reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002442
2443
2444}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002445
2446/**
Chaehyun Lima8047e22015-09-22 18:34:48 +09002447 * @brief set_cqm_rssi_config
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002448 * @details Configure connection quality monitor RSSI threshold.
2449 * @param[in] struct wiphy *wiphy:
2450 * @param[in] struct net_device *dev:
2451 * @param[in] s32 rssi_thold:
2452 * @param[in] u32 rssi_hyst:
2453 * @return int : Return 0 on Success
2454 * @author mdaftedar
2455 * @date 01 MAR 2012
2456 * @version 1.0
2457 */
Chaehyun Lima8047e22015-09-22 18:34:48 +09002458static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
2459 s32 rssi_thold, u32 rssi_hyst)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002460{
2461 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2462 return 0;
2463
2464}
2465/**
Chaehyun Limbdb63382015-09-14 12:24:19 +09002466 * @brief dump_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002467 * @details Configure connection quality monitor RSSI threshold.
2468 * @param[in] struct wiphy *wiphy:
2469 * @param[in] struct net_device *dev
2470 * @param[in] int idx
2471 * @param[in] u8 *mac
2472 * @param[in] struct station_info *sinfo
2473 * @return int : Return 0 on Success
2474 * @author mdaftedar
2475 * @date 01 MAR 2012
2476 * @version 1.0
2477 */
Chaehyun Limbdb63382015-09-14 12:24:19 +09002478static int dump_station(struct wiphy *wiphy, struct net_device *dev,
2479 int idx, u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002480{
Chaehyun Lim27268872015-09-15 14:06:13 +09002481 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002482
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002483 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2484
2485 if (idx != 0)
2486 return -ENOENT;
2487
2488 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002489
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002490 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002491
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002492 wilc_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002493
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002494 return 0;
2495
2496}
2497
2498
2499/**
Chaehyun Lim46530672015-09-22 18:34:46 +09002500 * @brief set_power_mgmt
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002501 * @details
2502 * @param[in]
2503 * @return int : Return 0 on Success.
2504 * @author mdaftedar
2505 * @date 01 JUL 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09002506 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002507 */
Chaehyun Lim46530672015-09-22 18:34:46 +09002508static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2509 bool enabled, int timeout)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002510{
Chaehyun Lim27268872015-09-15 14:06:13 +09002511 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002512
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002513 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2514
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002515 if (wiphy == NULL)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002516 return -ENOENT;
2517
2518 priv = wiphy_priv(wiphy);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002519 if (priv->hWILCWFIDrv == NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002520 PRINT_ER("Driver is NULL\n");
2521 return -EIO;
2522 }
2523
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002524 if (wilc_enable_ps)
2525 wilc_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002526
2527
Leo Kime6e12662015-09-16 18:36:03 +09002528 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002529
2530}
Glen Lee108b3432015-09-16 18:53:20 +09002531
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002532/**
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002533 * @brief change_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002534 * @details Change type/configuration of virtual interface,
2535 * keep the struct wireless_dev's iftype updated.
2536 * @param[in] NONE
2537 * @return int : Return 0 on Success.
2538 * @author mdaftedar
2539 * @date 01 MAR 2012
2540 * @version 1.0
2541 */
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002542static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2543 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002544{
Chaehyun Lim27268872015-09-15 14:06:13 +09002545 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002546 perInterface_wlan_t *nic;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002547 u8 interface_type;
Chaehyun Limd85f5322015-06-11 14:35:54 +09002548 u16 TID = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002549 u8 i;
Glen Lee299382c2015-10-20 17:13:56 +09002550 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002551
2552 nic = netdev_priv(dev);
2553 priv = wiphy_priv(wiphy);
Glen Lee299382c2015-10-20 17:13:56 +09002554 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002555
2556 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2557 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
Leo Kim583d9722015-11-19 15:56:16 +09002558 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +09002559 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +09002560 wilc_ie = false;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002561 wilc_optaining_ip = false;
2562 del_timer(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002563 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002564 /*Set WILC_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/
2565 if (g_ptk_keys_saved && g_gtk_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002566 wilc_set_machw_change_vir_if(dev, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002567 }
2568
2569 switch (type) {
2570 case NL80211_IFTYPE_STATION:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002571 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002572 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002573
2574 /* send delba over wlan interface */
2575
2576
2577 dev->ieee80211_ptr->iftype = type;
2578 priv->wdev->iftype = type;
2579 nic->monitor_flag = 0;
2580 nic->iftype = STATION_MODE;
2581
2582 /*Remove the enteries of the previously connected clients*/
2583 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002584 interface_type = nic->iftype;
2585 nic->iftype = STATION_MODE;
2586
Glen Lee299382c2015-10-20 17:13:56 +09002587 if (wl->initialized) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002588 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2589 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002590 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002591 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002592
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002593 /*Eliminate host interface blocking state*/
Glen Lee299382c2015-10-20 17:13:56 +09002594 up(&wl->cfg_event);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002595
Glen Lee53dc0cf2015-10-20 17:13:57 +09002596 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002597 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002598 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002599 nic->iftype = interface_type;
2600
2601 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002602 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2603 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002604 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002605 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002606
2607 /*Add saved WEP keys, if any*/
2608 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002609 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002610 g_key_wep_params.key_idx);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002611 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002612 g_key_wep_params.key,
2613 g_key_wep_params.key_len,
2614 g_key_wep_params.key_idx);
2615 }
2616
2617 /*No matter the driver handler passed here, it will be overwriiten*/
2618 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002619 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002620
2621 /*Add saved PTK and GTK keys, if any*/
2622 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2623 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2624 g_key_ptk_params.key[1],
2625 g_key_ptk_params.key[2]);
2626 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2627 g_key_gtk_params.key[1],
2628 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002629 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2630 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002631 g_add_ptk_key_params.key_idx,
2632 g_add_ptk_key_params.pairwise,
2633 g_add_ptk_key_params.mac_addr,
2634 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002635
Glen Lee299382c2015-10-20 17:13:56 +09002636 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2637 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002638 g_add_gtk_key_params.key_idx,
2639 g_add_gtk_key_params.pairwise,
2640 g_add_gtk_key_params.mac_addr,
2641 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002642 }
2643
Glen Lee299382c2015-10-20 17:13:56 +09002644 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002645 for (i = 0; i < num_reg_frame; i++) {
2646 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2647 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002648 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002649 nic->g_struct_frame_reg[i].frame_type,
2650 nic->g_struct_frame_reg[i].reg);
2651 }
2652 }
2653
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002654 wilc_enable_ps = true;
2655 wilc_set_power_mgmt(priv->hWILCWFIDrv, 1, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002656 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002657 break;
2658
2659 case NL80211_IFTYPE_P2P_CLIENT:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002660 wilc_enable_ps = false;
2661 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
2662 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002663 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002664
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002665 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2666 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002667
2668 dev->ieee80211_ptr->iftype = type;
2669 priv->wdev->iftype = type;
2670 nic->monitor_flag = 0;
2671
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002672 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2673 nic->iftype = CLIENT_MODE;
2674
2675
Glen Lee299382c2015-10-20 17:13:56 +09002676 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002677 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002678 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002679
Glen Lee53dc0cf2015-10-20 17:13:57 +09002680 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002681 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002682 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002683
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002684 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2685 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002686 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002687 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002688
2689 /*Add saved WEP keys, if any*/
2690 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002691 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2692 g_key_wep_params.key_idx);
2693 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
2694 g_key_wep_params.key,
2695 g_key_wep_params.key_len,
2696 g_key_wep_params.key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002697 }
2698
2699 /*No matter the driver handler passed here, it will be overwriiten*/
2700 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002701 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002702
2703 /*Add saved PTK and GTK keys, if any*/
2704 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2705 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2706 g_key_ptk_params.key[1],
2707 g_key_ptk_params.key[2]);
2708 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2709 g_key_gtk_params.key[1],
2710 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002711 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2712 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002713 g_add_ptk_key_params.key_idx,
2714 g_add_ptk_key_params.pairwise,
2715 g_add_ptk_key_params.mac_addr,
2716 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002717
Glen Lee299382c2015-10-20 17:13:56 +09002718 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2719 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002720 g_add_gtk_key_params.key_idx,
2721 g_add_gtk_key_params.pairwise,
2722 g_add_gtk_key_params.mac_addr,
2723 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002724 }
2725
2726 /*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 +09002727 refresh_scan(priv, 1, true);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002728 wilc_set_machw_change_vir_if(dev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002729
Glen Lee299382c2015-10-20 17:13:56 +09002730 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002731 for (i = 0; i < num_reg_frame; i++) {
2732 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2733 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002734 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002735 nic->g_struct_frame_reg[i].frame_type,
2736 nic->g_struct_frame_reg[i].reg);
2737 }
2738 }
2739 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002740 break;
2741
2742 case NL80211_IFTYPE_AP:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002743 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002744 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002745 dev->ieee80211_ptr->iftype = type;
2746 priv->wdev->iftype = type;
2747 nic->iftype = AP_MODE;
Johnny Kim8a143302015-06-10 17:06:46 +09002748 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002749
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002750 PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002751 wilc_wlan_get_firmware(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002752 /*If wilc is running, then close-open to actually get new firmware running (serves P2P)*/
Glen Lee299382c2015-10-20 17:13:56 +09002753 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002754 nic->iftype = AP_MODE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002755 wilc_mac_close(dev);
2756 wilc_mac_open(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002757
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002758 for (i = 0; i < num_reg_frame; i++) {
2759 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2760 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002761 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002762 nic->g_struct_frame_reg[i].frame_type,
2763 nic->g_struct_frame_reg[i].reg);
2764 }
2765 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002766 break;
2767
2768 case NL80211_IFTYPE_P2P_GO:
2769 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
2770
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002771 wilc_optaining_ip = true;
Leo Kim7e872df2015-11-19 15:56:20 +09002772 mod_timer(&wilc_during_ip_timer,
2773 jiffies + msecs_to_jiffies(during_ip_time));
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002774 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002775 /*Delete block ack has to be the latest config packet*/
2776 /*sent before downloading new FW. This is because it blocks on*/
2777 /*hWaitResponse semaphore, which allows previous config*/
2778 /*packets to actually take action on old FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002779 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2780 wl->vif[0].bssid, TID);
2781 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002782 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002783 dev->ieee80211_ptr->iftype = type;
2784 priv->wdev->iftype = type;
2785
Johnny Kim8a143302015-06-10 17:06:46 +09002786 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002787
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002788 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2789
2790
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002791 nic->iftype = GO_MODE;
2792
2793 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002794 wilc_wait_msg_queue_idle();
Glen Lee53dc0cf2015-10-20 17:13:57 +09002795 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002796 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002797 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002798
2799
2800 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002801 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2802 wilc_set_mac_address(wl->vif[0].hif_drv,
2803 wl->vif[0].src_addr);
2804 wilc_set_operation_mode(priv->hWILCWFIDrv, AP_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002805
2806 /*Add saved WEP keys, if any*/
2807 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002808 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2809 g_key_wep_params.key_idx);
2810 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002811 g_key_wep_params.key,
2812 g_key_wep_params.key_len,
2813 g_key_wep_params.key_idx);
2814 }
2815
2816 /*No matter the driver handler passed here, it will be overwriiten*/
2817 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002818 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002819
2820 /*Add saved PTK and GTK keys, if any*/
2821 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2822 PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0],
2823 g_key_ptk_params.key[1],
2824 g_key_ptk_params.key[2],
2825 g_key_ptk_params.cipher);
2826 PRINT_D(CFG80211_DBG, "gtk %x %x %x cipher %x\n", g_key_gtk_params.key[0],
2827 g_key_gtk_params.key[1],
2828 g_key_gtk_params.key[2],
2829 g_key_gtk_params.cipher);
Glen Lee299382c2015-10-20 17:13:56 +09002830 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2831 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002832 g_add_ptk_key_params.key_idx,
2833 g_add_ptk_key_params.pairwise,
2834 g_add_ptk_key_params.mac_addr,
2835 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002836
Glen Lee299382c2015-10-20 17:13:56 +09002837 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2838 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002839 g_add_gtk_key_params.key_idx,
2840 g_add_gtk_key_params.pairwise,
2841 g_add_gtk_key_params.mac_addr,
2842 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002843 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002844
Glen Lee299382c2015-10-20 17:13:56 +09002845 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002846 for (i = 0; i < num_reg_frame; i++) {
2847 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2848 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002849 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002850 nic->g_struct_frame_reg[i].frame_type,
2851 nic->g_struct_frame_reg[i].reg);
2852 }
2853 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002854 break;
2855
2856 default:
2857 PRINT_ER("Unknown interface type= %d\n", type);
Leo Kimaaed3292015-10-12 16:55:38 +09002858 return -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002859 }
2860
Leo Kimaaed3292015-10-12 16:55:38 +09002861 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002862}
2863
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002864/* (austin.2013-07-23)
2865 *
2866 * To support revised cfg80211_ops
2867 *
2868 * add_beacon --> start_ap
2869 * set_beacon --> change_beacon
2870 * del_beacon --> stop_ap
2871 *
2872 * beacon_parameters --> cfg80211_ap_settings
2873 * cfg80211_beacon_data
2874 *
2875 * applicable for linux kernel 3.4+
2876 */
2877
2878/**
Chaehyun Lima13168d2015-09-14 12:24:12 +09002879 * @brief start_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002880 * @details Add a beacon with given parameters, @head, @interval
2881 * and @dtim_period will be valid, @tail is optional.
2882 * @param[in] wiphy
2883 * @param[in] dev The net device structure
2884 * @param[in] settings cfg80211_ap_settings parameters for the beacon to be added
2885 * @return int : Return 0 on Success.
2886 * @author austin
2887 * @date 23 JUL 2013
2888 * @version 1.0
2889 */
Chaehyun Lima13168d2015-09-14 12:24:12 +09002890static int start_ap(struct wiphy *wiphy, struct net_device *dev,
2891 struct cfg80211_ap_settings *settings)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002892{
2893 struct cfg80211_beacon_data *beacon = &(settings->beacon);
Chaehyun Lim27268872015-09-15 14:06:13 +09002894 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002895 s32 s32Error = 0;
Glen Lee684dc182015-10-20 17:14:02 +09002896 struct wilc *wl;
2897 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002898
2899 priv = wiphy_priv(wiphy);
Glen Lee684dc182015-10-20 17:14:02 +09002900 nic = netdev_priv(dev);
2901 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002902 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
2903
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302904 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 +09002905 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
2906
Chaehyun Lim80785a92015-09-14 12:24:01 +09002907 s32Error = set_channel(wiphy, &settings->chandef);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002908
Leo Kime6e12662015-09-16 18:36:03 +09002909 if (s32Error != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002910 PRINT_ER("Error in setting channel\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002911
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002912 wilc_wlan_set_bssid(dev, wl->vif[0].src_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002913
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002914 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002915 settings->beacon_interval,
2916 settings->dtim_period,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002917 beacon->head_len, (u8 *)beacon->head,
2918 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002919
2920 return s32Error;
2921}
2922
2923/**
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002924 * @brief change_beacon
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002925 * @details Add a beacon with given parameters, @head, @interval
2926 * and @dtim_period will be valid, @tail is optional.
2927 * @param[in] wiphy
2928 * @param[in] dev The net device structure
2929 * @param[in] beacon cfg80211_beacon_data for the beacon to be changed
2930 * @return int : Return 0 on Success.
2931 * @author austin
2932 * @date 23 JUL 2013
2933 * @version 1.0
2934 */
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002935static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
2936 struct cfg80211_beacon_data *beacon)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002937{
Chaehyun Lim27268872015-09-15 14:06:13 +09002938 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002939 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002940
2941 priv = wiphy_priv(wiphy);
2942 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
2943
2944
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002945 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002946 0,
2947 0,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002948 beacon->head_len, (u8 *)beacon->head,
2949 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002950
2951 return s32Error;
2952}
2953
2954/**
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002955 * @brief stop_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002956 * @details Remove beacon configuration and stop sending the beacon.
2957 * @param[in]
2958 * @return int : Return 0 on Success.
2959 * @author austin
2960 * @date 23 JUL 2013
2961 * @version 1.0
2962 */
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002963static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002964{
Leo Kime6e12662015-09-16 18:36:03 +09002965 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002966 struct wilc_priv *priv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002967 u8 NullBssid[ETH_ALEN] = {0};
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002968
Leo Kim7ae43362015-09-16 18:35:59 +09002969 if (!wiphy)
2970 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002971
2972 priv = wiphy_priv(wiphy);
2973
2974 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
2975
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002976 wilc_wlan_set_bssid(dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002977
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002978 s32Error = wilc_del_beacon(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002979
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002980 if (s32Error)
2981 PRINT_ER("Host delete beacon fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002982
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002983 return s32Error;
2984}
2985
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002986/**
Chaehyun Limed269552015-09-14 12:24:15 +09002987 * @brief add_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002988 * @details Add a new station.
2989 * @param[in]
2990 * @return int : Return 0 on Success.
2991 * @author mdaftedar
2992 * @date 01 MAR 2012
2993 * @version 1.0
2994 */
Chaehyun Limed269552015-09-14 12:24:15 +09002995static int add_station(struct wiphy *wiphy, struct net_device *dev,
2996 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002997{
Leo Kime6e12662015-09-16 18:36:03 +09002998 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002999 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09003000 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003001 perInterface_wlan_t *nic;
3002
Leo Kim7ae43362015-09-16 18:35:59 +09003003 if (!wiphy)
3004 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003005
3006 priv = wiphy_priv(wiphy);
3007 nic = netdev_priv(dev);
3008
3009 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003010 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09003011 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003012 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003013 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003014 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003015
3016 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
3017
3018 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],
3019 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003020 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003021 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3022 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003023
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003024 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003025 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003026 } else {
Leo Kim22520122015-10-29 12:05:45 +09003027 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003028 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003029 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003030 memcpy(strStaParams.ht_supp_mcs_set,
3031 &params->ht_capa->mcs,
3032 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003033 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003034 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003035 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003036 }
3037
Leo Kimf676e172015-10-29 12:05:52 +09003038 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003039 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003040
Leo Kim22520122015-10-29 12:05:45 +09003041 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3042 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003043 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3044 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003045 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3046 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003047 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3048 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003049 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3050 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003051 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3052 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003053 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3054 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003055 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3056 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003057
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003058 s32Error = wilc_add_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003059 if (s32Error)
3060 PRINT_ER("Host add station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003061 }
3062
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003063 return s32Error;
3064}
3065
3066/**
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003067 * @brief del_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003068 * @details Remove a station; @mac may be NULL to remove all stations.
3069 * @param[in]
3070 * @return int : Return 0 on Success.
3071 * @author mdaftedar
3072 * @date 01 MAR 2012
3073 * @version 1.0
3074 */
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003075static int del_station(struct wiphy *wiphy, struct net_device *dev,
3076 struct station_del_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003077{
Arnd Bergmann057d1e92015-06-01 21:06:44 +02003078 const u8 *mac = params->mac;
Leo Kime6e12662015-09-16 18:36:03 +09003079 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003080 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003081 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003082
Leo Kim7ae43362015-09-16 18:35:59 +09003083 if (!wiphy)
3084 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003085
3086 priv = wiphy_priv(wiphy);
3087 nic = netdev_priv(dev);
3088
3089 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
3090 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
3091
3092
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003093 if (mac == NULL) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05303094 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003095 s32Error = wilc_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003096 } else {
3097 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]);
3098 }
3099
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003100 s32Error = wilc_del_station(priv->hWILCWFIDrv, mac);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003101
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003102 if (s32Error)
3103 PRINT_ER("Host delete station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003104 }
3105 return s32Error;
3106}
3107
3108/**
Chaehyun Lim14b42082015-09-14 12:24:17 +09003109 * @brief change_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003110 * @details Modify a given station.
3111 * @param[in]
3112 * @return int : Return 0 on Success.
3113 * @author mdaftedar
3114 * @date 01 MAR 2012
3115 * @version 1.0
3116 */
Chaehyun Lim14b42082015-09-14 12:24:17 +09003117static int change_station(struct wiphy *wiphy, struct net_device *dev,
3118 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003119{
Leo Kime6e12662015-09-16 18:36:03 +09003120 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003121 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09003122 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003123 perInterface_wlan_t *nic;
3124
3125
3126 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
3127
Leo Kim7ae43362015-09-16 18:35:59 +09003128 if (!wiphy)
3129 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003130
3131 priv = wiphy_priv(wiphy);
3132 nic = netdev_priv(dev);
3133
3134 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003135 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003136 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003137 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003138 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003139
Leo Kim2353c382015-10-29 12:05:41 +09003140 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n",
3141 strStaParams.bssid[0], strStaParams.bssid[1],
3142 strStaParams.bssid[2], strStaParams.bssid[3],
3143 strStaParams.bssid[4], strStaParams.bssid[5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003144 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003145 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3146 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003147
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003148 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003149 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003150 } else {
Leo Kim22520122015-10-29 12:05:45 +09003151 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003152 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003153 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003154 memcpy(strStaParams.ht_supp_mcs_set,
3155 &params->ht_capa->mcs,
3156 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003157 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003158 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003159 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003160 }
3161
Leo Kimf676e172015-10-29 12:05:52 +09003162 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003163 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003164
Leo Kim22520122015-10-29 12:05:45 +09003165 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3166 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003167 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3168 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003169 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3170 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003171 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3172 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003173 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3174 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003175 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3176 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003177 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3178 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003179 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3180 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003181
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003182 s32Error = wilc_edit_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003183 if (s32Error)
3184 PRINT_ER("Host edit station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003185 }
3186 return s32Error;
3187}
3188
3189
3190/**
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003191 * @brief add_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003192 * @details
3193 * @param[in]
3194 * @return int : Return 0 on Success.
3195 * @author mdaftedar
3196 * @date 01 JUL 2012
3197 * @version 1.0
3198 */
Chaehyun Lim37316e82015-09-22 18:34:52 +09003199static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
3200 const char *name,
3201 unsigned char name_assign_type,
3202 enum nl80211_iftype type,
3203 u32 *flags,
3204 struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003205{
3206 perInterface_wlan_t *nic;
Chaehyun Lim27268872015-09-15 14:06:13 +09003207 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003208 struct net_device *new_ifc = NULL;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003209
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003210 priv = wiphy_priv(wiphy);
3211
3212
3213
3214 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
3215
3216 nic = netdev_priv(priv->wdev->netdev);
3217
3218
3219 if (type == NL80211_IFTYPE_MONITOR) {
3220 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
3221 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", nic->wilc_netdev);
3222 new_ifc = WILC_WFI_init_mon_interface(name, nic->wilc_netdev);
3223 if (new_ifc != NULL) {
3224 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003225 nic = netdev_priv(priv->wdev->netdev);
3226 nic->monitor_flag = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003227 } else
3228 PRINT_ER("Error in initializing monitor interface\n ");
3229 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003230 return priv->wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003231}
3232
3233/**
Chaehyun Limb4a73352015-09-14 12:24:10 +09003234 * @brief del_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003235 * @details
3236 * @param[in]
3237 * @return int : Return 0 on Success.
3238 * @author mdaftedar
3239 * @date 01 JUL 2012
3240 * @version 1.0
3241 */
Chaehyun Lim956d7212015-09-22 18:34:49 +09003242static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003243{
3244 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
Leo Kime6e12662015-09-16 18:36:03 +09003245 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003246}
3247
Chaehyun Lim08241922015-09-15 14:06:12 +09003248static struct cfg80211_ops wilc_cfg80211_ops = {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003249
Chaehyun Lim80785a92015-09-14 12:24:01 +09003250 .set_monitor_channel = set_channel,
Chaehyun Lim0e30d062015-09-14 12:24:02 +09003251 .scan = scan,
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +09003252 .connect = connect,
Chaehyun Limb027cde2015-09-14 12:24:04 +09003253 .disconnect = disconnect,
Chaehyun Lim953d4172015-09-14 12:24:05 +09003254 .add_key = add_key,
Chaehyun Lim3044ba72015-09-14 12:24:06 +09003255 .del_key = del_key,
Chaehyun Limf4893df2015-09-14 12:24:07 +09003256 .get_key = get_key,
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09003257 .set_default_key = set_default_key,
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003258 .add_virtual_intf = add_virtual_intf,
Chaehyun Limb4a73352015-09-14 12:24:10 +09003259 .del_virtual_intf = del_virtual_intf,
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09003260 .change_virtual_intf = change_virtual_intf,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003261
Chaehyun Lima13168d2015-09-14 12:24:12 +09003262 .start_ap = start_ap,
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09003263 .change_beacon = change_beacon,
Chaehyun Limc8cddd72015-09-14 12:24:14 +09003264 .stop_ap = stop_ap,
Chaehyun Limed269552015-09-14 12:24:15 +09003265 .add_station = add_station,
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003266 .del_station = del_station,
Chaehyun Lim14b42082015-09-14 12:24:17 +09003267 .change_station = change_station,
Chaehyun Limf06f5622015-09-14 12:24:18 +09003268 .get_station = get_station,
Chaehyun Limbdb63382015-09-14 12:24:19 +09003269 .dump_station = dump_station,
Chaehyun Lima5f7db62015-09-14 12:24:20 +09003270 .change_bss = change_bss,
Chaehyun Lima76b63e2015-09-14 12:24:21 +09003271 .set_wiphy_params = set_wiphy_params,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003272
Chaehyun Lim4d466572015-09-14 12:24:22 +09003273 .set_pmksa = set_pmksa,
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09003274 .del_pmksa = del_pmksa,
Chaehyun Limb33c39b2015-09-14 12:24:24 +09003275 .flush_pmksa = flush_pmksa,
Chaehyun Lim6d19d692015-09-14 12:24:25 +09003276 .remain_on_channel = remain_on_channel,
Chaehyun Lim1dd54402015-09-14 12:24:26 +09003277 .cancel_remain_on_channel = cancel_remain_on_channel,
Chaehyun Lim4a2f9b32015-09-14 12:24:27 +09003278 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
Chaehyun Lim12a26a32015-09-14 12:24:28 +09003279 .mgmt_tx = mgmt_tx,
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09003280 .mgmt_frame_register = wilc_mgmt_frame_register,
Chaehyun Lim46530672015-09-22 18:34:46 +09003281 .set_power_mgmt = set_power_mgmt,
Chaehyun Lima8047e22015-09-22 18:34:48 +09003282 .set_cqm_rssi_config = set_cqm_rssi_config,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003283
3284};
3285
3286
3287
3288
3289
3290/**
3291 * @brief WILC_WFI_update_stats
3292 * @details Modify parameters for a given BSS.
3293 * @param[in]
3294 * @return int : Return 0 on Success.
3295 * @author mdaftedar
3296 * @date 01 MAR 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09003297 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003298 */
3299int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
3300{
3301
Chaehyun Lim27268872015-09-15 14:06:13 +09003302 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003303
3304 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003305 switch (changed) {
3306
3307 case WILC_WFI_RX_PKT:
3308 {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003309 priv->netstats.rx_packets++;
3310 priv->netstats.rx_bytes += pktlen;
3311 priv->netstats.rx_time = get_jiffies_64();
3312 }
3313 break;
3314
3315 case WILC_WFI_TX_PKT:
3316 {
3317 priv->netstats.tx_packets++;
3318 priv->netstats.tx_bytes += pktlen;
3319 priv->netstats.tx_time = get_jiffies_64();
3320
3321 }
3322 break;
3323
3324 default:
3325 break;
3326 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003327 return 0;
3328}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003329
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003330/**
3331 * @brief WILC_WFI_CfgAlloc
3332 * @details Allocation of the wireless device structure and assigning it
3333 * to the cfg80211 operations structure.
3334 * @param[in] NONE
3335 * @return wireless_dev : Returns pointer to wireless_dev structure.
3336 * @author mdaftedar
3337 * @date 01 MAR 2012
3338 * @version 1.0
3339 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01003340static struct wireless_dev *WILC_WFI_CfgAlloc(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003341{
3342
3343 struct wireless_dev *wdev;
3344
3345
3346 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
3347 /*Allocating the wireless device structure*/
3348 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
3349 if (!wdev) {
3350 PRINT_ER("Cannot allocate wireless device\n");
3351 goto _fail_;
3352 }
3353
3354 /*Creating a new wiphy, linking wireless structure with the wiphy structure*/
Chaehyun Lim27268872015-09-15 14:06:13 +09003355 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003356 if (!wdev->wiphy) {
3357 PRINT_ER("Cannot allocate wiphy\n");
3358 goto _fail_mem_;
3359
3360 }
3361
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003362 /* enable 802.11n HT */
3363 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
3364 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
3365 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3366 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
3367 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003368
3369 /*wiphy bands*/
3370 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
3371
3372 return wdev;
3373
3374_fail_mem_:
3375 kfree(wdev);
3376_fail_:
3377 return NULL;
3378
3379}
3380/**
Chaehyun Lim8459fd52015-09-20 15:51:09 +09003381 * @brief wilc_create_wiphy
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003382 * @details Registering of the wiphy structure and interface modes
3383 * @param[in] NONE
3384 * @return NONE
3385 * @author mdaftedar
3386 * @date 01 MAR 2012
3387 * @version 1.0
3388 */
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01003389struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003390{
Chaehyun Lim27268872015-09-15 14:06:13 +09003391 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003392 struct wireless_dev *wdev;
Leo Kime6e12662015-09-16 18:36:03 +09003393 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003394
3395 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
3396
3397 wdev = WILC_WFI_CfgAlloc();
3398 if (wdev == NULL) {
3399 PRINT_ER("CfgAlloc Failed\n");
3400 return NULL;
3401 }
3402
3403
3404 /*Return hardware description structure (wiphy)'s priv*/
3405 priv = wdev_priv(wdev);
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003406 sema_init(&(priv->SemHandleUpdateStats), 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003407
3408 /*Link the wiphy with wireless structure*/
3409 priv->wdev = wdev;
3410
3411 /*Maximum number of probed ssid to be added by user for the scan request*/
3412 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003413 /*Maximum number of pmkids to be cashed*/
3414 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
3415 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003416
3417 wdev->wiphy->max_scan_ie_len = 1000;
3418
3419 /*signal strength in mBm (100*dBm) */
3420 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3421
3422 /*Set the availaible cipher suites*/
3423 wdev->wiphy->cipher_suites = cipher_suites;
3424 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003425 /*Setting default managment types: for register action frame: */
3426 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003427
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003428 wdev->wiphy->max_remain_on_channel_duration = 500;
3429 /*Setting the wiphy interfcae mode and type before registering the wiphy*/
3430 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
3431 BIT(NL80211_IFTYPE_P2P_CLIENT);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003432 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003433 wdev->iftype = NL80211_IFTYPE_STATION;
3434
3435
3436
3437 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
3438 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
3439 wdev->wiphy->interface_modes, wdev->iftype);
3440
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01003441 set_wiphy_dev(wdev->wiphy, dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003442
3443 /*Register wiphy structure*/
3444 s32Error = wiphy_register(wdev->wiphy);
3445 if (s32Error) {
3446 PRINT_ER("Cannot register wiphy device\n");
3447 /*should define what action to be taken in such failure*/
3448 } else {
3449 PRINT_D(CFG80211_DBG, "Successful Registering\n");
3450 }
3451
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003452 priv->dev = net;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003453 return wdev;
3454
3455
3456}
3457/**
3458 * @brief WILC_WFI_WiphyFree
3459 * @details Freeing allocation of the wireless device structure
3460 * @param[in] NONE
3461 * @return NONE
3462 * @author mdaftedar
3463 * @date 01 MAR 2012
3464 * @version 1.0
3465 */
Chaehyun Limdd4b6a82015-09-20 15:51:25 +09003466int wilc_init_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003467{
3468
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003469 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003470
Chaehyun Lim27268872015-09-15 14:06:13 +09003471 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003472
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003473 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
3474 priv = wdev_priv(net->ieee80211_ptr);
3475 if (op_ifcs == 0) {
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -07003476 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003477 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003478 }
3479 op_ifcs++;
3480 if (s32Error < 0) {
3481 PRINT_ER("Failed to creat refresh Timer\n");
3482 return s32Error;
3483 }
3484
Dean Lee72ed4dc2015-06-12 14:11:44 +09003485 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003486
Dean Lee72ed4dc2015-06-12 14:11:44 +09003487 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003488
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003489 sema_init(&(priv->hSemScanReq), 1);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003490 s32Error = wilc_init(net, &priv->hWILCWFIDrv);
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003491 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003492 PRINT_ER("Error while initializing hostinterface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003493
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003494 return s32Error;
3495}
3496
3497/**
3498 * @brief WILC_WFI_WiphyFree
3499 * @details Freeing allocation of the wireless device structure
3500 * @param[in] NONE
3501 * @return NONE
3502 * @author mdaftedar
3503 * @date 01 MAR 2012
3504 * @version 1.0
3505 */
Chaehyun Lima9a16822015-09-20 15:51:24 +09003506int wilc_deinit_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003507{
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003508 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003509
Chaehyun Lim27268872015-09-15 14:06:13 +09003510 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003511
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003512 priv = wdev_priv(net->ieee80211_ptr);
3513
Dean Lee72ed4dc2015-06-12 14:11:44 +09003514 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003515
Dean Lee72ed4dc2015-06-12 14:11:44 +09003516 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003517
3518 op_ifcs--;
3519
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003520 s32Error = wilc_deinit(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003521
3522 /* Clear the Shadow scan */
Leo Kimd14991a2015-11-19 15:56:22 +09003523 clear_shadow_scan();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003524 if (op_ifcs == 0) {
3525 PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003526 del_timer_sync(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003527 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003528
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003529 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003530 PRINT_ER("Error while deintializing host interface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003531
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003532 return s32Error;
3533}
3534
3535
3536/**
3537 * @brief WILC_WFI_WiphyFree
3538 * @details Freeing allocation of the wireless device structure
3539 * @param[in] NONE
3540 * @return NONE
3541 * @author mdaftedar
3542 * @date 01 MAR 2012
3543 * @version 1.0
3544 */
Chaehyun Lim96da20a2015-09-20 15:51:08 +09003545void wilc_free_wiphy(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003546{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003547 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
3548
Chaehyun Lim619837a2015-09-20 15:51:10 +09003549 if (!net) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003550 PRINT_D(INIT_DBG, "net_device is NULL\n");
3551 return;
3552 }
3553
Chaehyun Lim619837a2015-09-20 15:51:10 +09003554 if (!net->ieee80211_ptr) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003555 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
3556 return;
3557 }
3558
Chaehyun Lim619837a2015-09-20 15:51:10 +09003559 if (!net->ieee80211_ptr->wiphy) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003560 PRINT_D(INIT_DBG, "wiphy is NULL\n");
3561 return;
3562 }
3563
3564 wiphy_unregister(net->ieee80211_ptr->wiphy);
3565
3566 PRINT_D(INIT_DBG, "Freeing wiphy\n");
3567 wiphy_free(net->ieee80211_ptr->wiphy);
3568 kfree(net->ieee80211_ptr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003569}