blob: 646beff5d73fab669ebb75961e523b9b06bb14d5 [file] [log] [blame]
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001/*!
2 * @file wilc_wfi_cfgopertaions.c
3 * @brief CFG80211 Function Implementation functionality
4 * @author aabouzaeid
5 * mabubakr
6 * mdaftedar
7 * zsalah
8 * @sa wilc_wfi_cfgopertaions.h top level OS wrapper file
9 * @date 31 Aug 2010
10 * @version 1.0
11 */
12
13#include "wilc_wfi_cfgoperations.h"
Arnd Bergmann491880e2015-11-16 15:04:55 +010014#include "host_interface.h"
Leo Kim7ae43362015-09-16 18:35:59 +090015#include <linux/errno.h>
Johnny Kimc5c77ba2015-05-11 14:30:56 +090016
Arnd Bergmann15162fb2015-11-16 15:04:57 +010017/* The following macros describe the bitfield map used by the firmware to determine its 11i mode */
18#define NO_ENCRYPT 0
19#define ENCRYPT_ENABLED BIT(0)
20#define WEP BIT(1)
21#define WEP_EXTENDED BIT(2)
22#define WPA BIT(3)
23#define WPA2 BIT(4)
24#define AES BIT(5)
25#define TKIP BIT(6)
26
27/*Public action frame index IDs*/
28#define FRAME_TYPE_ID 0
29#define ACTION_CAT_ID 24
30#define ACTION_SUBTYPE_ID 25
31#define P2P_PUB_ACTION_SUBTYPE 30
32
33/*Public action frame Attribute IDs*/
34#define ACTION_FRAME 0xd0
35#define GO_INTENT_ATTR_ID 0x04
36#define CHANLIST_ATTR_ID 0x0b
37#define OPERCHAN_ATTR_ID 0x11
38#define PUB_ACTION_ATTR_ID 0x04
39#define P2PELEM_ATTR_ID 0xdd
40
41/*Public action subtype values*/
42#define GO_NEG_REQ 0x00
43#define GO_NEG_RSP 0x01
44#define GO_NEG_CONF 0x02
45#define P2P_INV_REQ 0x03
46#define P2P_INV_RSP 0x04
47#define PUBLIC_ACT_VENDORSPEC 0x09
48#define GAS_INTIAL_REQ 0x0a
49#define GAS_INTIAL_RSP 0x0b
50
51#define INVALID_CHANNEL 0
52
53#define nl80211_SCAN_RESULT_EXPIRE (3 * HZ)
54#define SCAN_RESULT_EXPIRE (40 * HZ)
55
56static const u32 cipher_suites[] = {
57 WLAN_CIPHER_SUITE_WEP40,
58 WLAN_CIPHER_SUITE_WEP104,
59 WLAN_CIPHER_SUITE_TKIP,
60 WLAN_CIPHER_SUITE_CCMP,
61 WLAN_CIPHER_SUITE_AES_CMAC,
62};
63
64static const struct ieee80211_txrx_stypes
65 wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = {
66 [NL80211_IFTYPE_STATION] = {
67 .tx = 0xffff,
68 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
69 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
70 },
71 [NL80211_IFTYPE_AP] = {
72 .tx = 0xffff,
73 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
74 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
75 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
76 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
77 BIT(IEEE80211_STYPE_AUTH >> 4) |
78 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
79 BIT(IEEE80211_STYPE_ACTION >> 4)
80 },
81 [NL80211_IFTYPE_P2P_CLIENT] = {
82 .tx = 0xffff,
83 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
84 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
85 BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
86 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
87 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
88 BIT(IEEE80211_STYPE_AUTH >> 4) |
89 BIT(IEEE80211_STYPE_DEAUTH >> 4)
90 }
91};
92
93/* Time to stay on the channel */
94#define WILC_WFI_DWELL_PASSIVE 100
95#define WILC_WFI_DWELL_ACTIVE 40
96
97#define TCP_ACK_FILTER_LINK_SPEED_THRESH 54
98#define DEFAULT_LINK_SPEED 72
99
100
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900101#define IS_MANAGMEMENT 0x100
102#define IS_MANAGMEMENT_CALLBACK 0x080
103#define IS_MGMT_STATUS_SUCCES 0x040
104#define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff)
105
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100106extern int wilc_mac_open(struct net_device *ndev);
107extern int wilc_mac_close(struct net_device *ndev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900108
Leo Kimf1ab1172015-11-19 15:56:11 +0900109static tstrNetworkInfo last_scanned_shadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
Leo Kim771fbae2015-11-19 15:56:10 +0900110static u32 last_scanned_cnt;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100111struct timer_list wilc_during_ip_timer;
Arnd Bergmann1608c402015-11-16 15:04:53 +0100112static struct timer_list hAgingTimer;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900113static u8 op_ifcs;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900114
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100115u8 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900116
117#define CHAN2G(_channel, _freq, _flags) { \
118 .band = IEEE80211_BAND_2GHZ, \
119 .center_freq = (_freq), \
120 .hw_value = (_channel), \
121 .flags = (_flags), \
122 .max_antenna_gain = 0, \
123 .max_power = 30, \
124}
125
126/*Frequency range for channels*/
Leo Kim2736f472015-11-19 15:56:12 +0900127static struct ieee80211_channel ieee80211_2ghz_channels[] = {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900128 CHAN2G(1, 2412, 0),
129 CHAN2G(2, 2417, 0),
130 CHAN2G(3, 2422, 0),
131 CHAN2G(4, 2427, 0),
132 CHAN2G(5, 2432, 0),
133 CHAN2G(6, 2437, 0),
134 CHAN2G(7, 2442, 0),
135 CHAN2G(8, 2447, 0),
136 CHAN2G(9, 2452, 0),
137 CHAN2G(10, 2457, 0),
138 CHAN2G(11, 2462, 0),
139 CHAN2G(12, 2467, 0),
140 CHAN2G(13, 2472, 0),
141 CHAN2G(14, 2484, 0),
142};
143
144#define RATETAB_ENT(_rate, _hw_value, _flags) { \
145 .bitrate = (_rate), \
146 .hw_value = (_hw_value), \
147 .flags = (_flags), \
148}
149
150
151/* Table 6 in section 3.2.1.1 */
Leo Kim8d48b5b2015-11-19 15:56:13 +0900152static struct ieee80211_rate ieee80211_bitrates[] = {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900153 RATETAB_ENT(10, 0, 0),
154 RATETAB_ENT(20, 1, 0),
155 RATETAB_ENT(55, 2, 0),
156 RATETAB_ENT(110, 3, 0),
157 RATETAB_ENT(60, 9, 0),
158 RATETAB_ENT(90, 6, 0),
159 RATETAB_ENT(120, 7, 0),
160 RATETAB_ENT(180, 8, 0),
161 RATETAB_ENT(240, 9, 0),
162 RATETAB_ENT(360, 10, 0),
163 RATETAB_ENT(480, 11, 0),
164 RATETAB_ENT(540, 12, 0),
165};
166
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900167struct p2p_mgmt_data {
168 int size;
169 u8 *buff;
170};
171
Leo Kim0bd82742015-11-19 15:56:14 +0900172static u8 wlan_channel = INVALID_CHANNEL;
Arnd Bergmann1608c402015-11-16 15:04:53 +0100173static u8 curr_channel;
Leo Kim881eb5d2015-11-19 15:56:15 +0900174static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09};
Leo Kim583d9722015-11-19 15:56:16 +0900175static u8 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +0900176static u8 p2p_recv_random = 0x00;
Leo Kim86685942015-11-19 15:56:18 +0900177static u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
Leo Kima25d5182015-11-19 15:56:19 +0900178static bool wilc_ie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900179
180static struct ieee80211_supported_band WILC_WFI_band_2ghz = {
Leo Kim2736f472015-11-19 15:56:12 +0900181 .channels = ieee80211_2ghz_channels,
182 .n_channels = ARRAY_SIZE(ieee80211_2ghz_channels),
Leo Kim8d48b5b2015-11-19 15:56:13 +0900183 .bitrates = ieee80211_bitrates,
184 .n_bitrates = ARRAY_SIZE(ieee80211_bitrates),
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900185};
186
187
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900188struct add_key_params {
189 u8 key_idx;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900190 bool pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900191 u8 *mac_addr;
192};
Arnd Bergmann1608c402015-11-16 15:04:53 +0100193static struct add_key_params g_add_gtk_key_params;
194static struct wilc_wfi_key g_key_gtk_params;
195static struct add_key_params g_add_ptk_key_params;
196static struct wilc_wfi_key g_key_ptk_params;
197static struct wilc_wfi_wep_key g_key_wep_params;
198static bool g_ptk_keys_saved;
199static bool g_gtk_keys_saved;
200static bool g_wep_keys_saved;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900201
202#define AGING_TIME (9 * 1000)
Leo Kim7e872df2015-11-19 15:56:20 +0900203#define during_ip_time 15000
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900204
Leo Kimd14991a2015-11-19 15:56:22 +0900205static void clear_shadow_scan(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900206{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900207 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900208
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900209 if (op_ifcs == 0) {
Greg Kroah-Hartman4183e972015-08-14 20:11:16 -0700210 del_timer_sync(&hAgingTimer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900211 PRINT_INFO(CORECONFIG_DBG, "destroy aging timer\n");
212
Leo Kim771fbae2015-11-19 15:56:10 +0900213 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900214 if (last_scanned_shadow[last_scanned_cnt].pu8IEs) {
215 kfree(last_scanned_shadow[i].pu8IEs);
216 last_scanned_shadow[last_scanned_cnt].pu8IEs = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900217 }
218
Leo Kimf1ab1172015-11-19 15:56:11 +0900219 wilc_free_join_params(last_scanned_shadow[i].pJoinParams);
220 last_scanned_shadow[i].pJoinParams = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900221 }
Leo Kim771fbae2015-11-19 15:56:10 +0900222 last_scanned_cnt = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900223 }
224
225}
226
Arnd Bergmann1608c402015-11-16 15:04:53 +0100227static u32 get_rssi_avg(tstrNetworkInfo *pstrNetworkInfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900228{
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900229 u8 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900230 int rssi_v = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900231 u8 num_rssi = (pstrNetworkInfo->strRssi.u8Full) ? NUM_RSSI : (pstrNetworkInfo->strRssi.u8Index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900232
233 for (i = 0; i < num_rssi; i++)
234 rssi_v += pstrNetworkInfo->strRssi.as8RSSI[i];
235
236 rssi_v /= num_rssi;
237 return rssi_v;
238}
239
Leo Kim48ee7ba2015-11-19 15:56:24 +0900240static void refresh_scan(void *user_void, u8 all, bool direct_scan)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900241{
Chaehyun Lim27268872015-09-15 14:06:13 +0900242 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900243 struct wiphy *wiphy;
244 struct cfg80211_bss *bss = NULL;
245 int i;
246 int rssi = 0;
247
Leo Kim84df0e62015-11-19 15:56:23 +0900248 priv = (struct wilc_priv *)user_void;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900249 wiphy = priv->dev->ieee80211_ptr->wiphy;
250
Leo Kim771fbae2015-11-19 15:56:10 +0900251 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimce3b1b52015-11-19 15:56:25 +0900252 tstrNetworkInfo *network_info;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900253
Leo Kimce3b1b52015-11-19 15:56:25 +0900254 network_info = &last_scanned_shadow[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900255
Leo Kimce3b1b52015-11-19 15:56:25 +0900256 if (!network_info->u8Found || all) {
Leo Kimc6f5e3a2015-11-19 15:56:26 +0900257 s32 freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900258 struct ieee80211_channel *channel;
259
Leo Kimce3b1b52015-11-19 15:56:25 +0900260 if (network_info) {
Leo Kimc6f5e3a2015-11-19 15:56:26 +0900261 freq = ieee80211_channel_to_frequency((s32)network_info->u8channel, IEEE80211_BAND_2GHZ);
262 channel = ieee80211_get_channel(wiphy, freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900263
Leo Kimce3b1b52015-11-19 15:56:25 +0900264 rssi = get_rssi_avg(network_info);
265 if (memcmp("DIRECT-", network_info->au8ssid, 7) ||
Leo Kim48ee7ba2015-11-19 15:56:24 +0900266 direct_scan) {
Leo Kimce3b1b52015-11-19 15:56:25 +0900267 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, network_info->au8bssid, network_info->u64Tsf, network_info->u16CapInfo,
268 network_info->u16BeaconPeriod, (const u8 *)network_info->pu8IEs,
269 (size_t)network_info->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900270 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900271 }
272 }
273
274 }
275 }
276
277}
278
Leo Kim12b01382015-11-19 15:56:27 +0900279static void reset_shadow_found(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900280{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900281 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900282
Leo Kim771fbae2015-11-19 15:56:10 +0900283 for (i = 0; i < last_scanned_cnt; i++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900284 last_scanned_shadow[i].u8Found = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900285}
286
Leo Kim5e51d8b2015-11-19 15:56:28 +0900287static void update_scan_time(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900288{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900289 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900290
Leo Kim771fbae2015-11-19 15:56:10 +0900291 for (i = 0; i < last_scanned_cnt; i++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900292 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900293}
294
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700295static void remove_network_from_shadow(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900296{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900297 unsigned long now = jiffies;
298 int i, j;
299
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900300
Leo Kim771fbae2015-11-19 15:56:10 +0900301 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900302 if (time_after(now, last_scanned_shadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) {
303 PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", last_scanned_shadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900304
Leo Kimf1ab1172015-11-19 15:56:11 +0900305 kfree(last_scanned_shadow[i].pu8IEs);
306 last_scanned_shadow[i].pu8IEs = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900307
Leo Kimf1ab1172015-11-19 15:56:11 +0900308 wilc_free_join_params(last_scanned_shadow[i].pJoinParams);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900309
Leo Kim771fbae2015-11-19 15:56:10 +0900310 for (j = i; (j < last_scanned_cnt - 1); j++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900311 last_scanned_shadow[j] = last_scanned_shadow[j + 1];
Leo Kim771fbae2015-11-19 15:56:10 +0900312
313 last_scanned_cnt--;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900314 }
315 }
316
Leo Kim771fbae2015-11-19 15:56:10 +0900317 PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n",
318 last_scanned_cnt);
319 if (last_scanned_cnt != 0) {
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700320 hAgingTimer.data = arg;
321 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
322 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900323 PRINT_D(CFG80211_DBG, "No need to restart Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700324 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900325}
326
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700327static void clear_duringIP(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900328{
329 PRINT_D(GENERIC_DBG, "GO:IP Obtained , enable scan\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100330 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900331}
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900332
Leo Kim157814f2015-11-19 15:56:29 +0900333static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo,
334 void *user_void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900335{
Chaehyun Lima74cc6b2015-10-02 16:41:17 +0900336 int state = -1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900337 int i;
338
Leo Kim771fbae2015-11-19 15:56:10 +0900339 if (last_scanned_cnt == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900340 PRINT_D(CFG80211_DBG, "Starting Aging timer\n");
Leo Kim157814f2015-11-19 15:56:29 +0900341 hAgingTimer.data = (unsigned long)user_void;
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700342 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900343 state = -1;
344 } else {
345 /* Linear search for now */
Leo Kim771fbae2015-11-19 15:56:10 +0900346 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900347 if (memcmp(last_scanned_shadow[i].au8bssid,
348 pstrNetworkInfo->au8bssid, 6) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900349 state = i;
350 break;
351 }
352 }
353 }
354 return state;
355}
356
Leo Kim5c4cf0d2015-11-19 15:56:30 +0900357static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo,
358 void *user_void, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900359{
Leo Kim5c4cf0d2015-11-19 15:56:30 +0900360 int ap_found = is_network_in_shadow(pstrNetworkInfo, user_void);
Chaehyun Limfbc2fe12015-09-15 14:06:16 +0900361 u32 ap_index = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900362 u8 rssi_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900363
Leo Kim771fbae2015-11-19 15:56:10 +0900364 if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900365 PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
366 return;
367 }
368 if (ap_found == -1) {
Leo Kim771fbae2015-11-19 15:56:10 +0900369 ap_index = last_scanned_cnt;
370 last_scanned_cnt++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900371
372 } else {
373 ap_index = ap_found;
374 }
Leo Kimf1ab1172015-11-19 15:56:11 +0900375 rssi_index = last_scanned_shadow[ap_index].strRssi.u8Index;
376 last_scanned_shadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900377 if (rssi_index == NUM_RSSI) {
378 rssi_index = 0;
Leo Kimf1ab1172015-11-19 15:56:11 +0900379 last_scanned_shadow[ap_index].strRssi.u8Full = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900380 }
Leo Kimf1ab1172015-11-19 15:56:11 +0900381 last_scanned_shadow[ap_index].strRssi.u8Index = rssi_index;
382 last_scanned_shadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
383 last_scanned_shadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
384 last_scanned_shadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
385 memcpy(last_scanned_shadow[ap_index].au8ssid,
386 pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
387 memcpy(last_scanned_shadow[ap_index].au8bssid,
388 pstrNetworkInfo->au8bssid, ETH_ALEN);
389 last_scanned_shadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
390 last_scanned_shadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
391 last_scanned_shadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
392 last_scanned_shadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
393 last_scanned_shadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900394 if (ap_found != -1)
Leo Kimf1ab1172015-11-19 15:56:11 +0900395 kfree(last_scanned_shadow[ap_index].pu8IEs);
396 last_scanned_shadow[ap_index].pu8IEs =
Glen Leef3052582015-09-10 12:03:04 +0900397 kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL); /* will be deallocated by the WILC_WFI_CfgScan() function */
Leo Kimf1ab1172015-11-19 15:56:11 +0900398 memcpy(last_scanned_shadow[ap_index].pu8IEs,
399 pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
400 last_scanned_shadow[ap_index].u32TimeRcvdInScan = jiffies;
401 last_scanned_shadow[ap_index].u32TimeRcvdInScanCached = jiffies;
402 last_scanned_shadow[ap_index].u8Found = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900403 if (ap_found != -1)
Leo Kimf1ab1172015-11-19 15:56:11 +0900404 wilc_free_join_params(last_scanned_shadow[ap_index].pJoinParams);
405 last_scanned_shadow[ap_index].pJoinParams = pJoinParams;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900406}
407
408
409/**
410 * @brief CfgScanResult
411 * @details Callback function which returns the scan results found
412 *
413 * @param[in] tenuScanEvent enuScanEvent: enum, indicating the scan event triggered, whether that is
414 * SCAN_EVENT_NETWORK_FOUND or SCAN_EVENT_DONE
415 * tstrNetworkInfo* pstrNetworkInfo: structure holding the scan results information
416 * void* pUserVoid: Private structure associated with the wireless interface
417 * @return NONE
418 * @author mabubakr
419 * @date
420 * @version 1.0
421 */
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900422static void CfgScanResult(enum scan_event scan_event,
423 tstrNetworkInfo *pstrNetworkInfo,
424 void *pUserVoid,
425 void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900426{
Chaehyun Lim27268872015-09-15 14:06:13 +0900427 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900428 struct wiphy *wiphy;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900429 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900430 struct ieee80211_channel *channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900431 struct cfg80211_bss *bss = NULL;
432
Chaehyun Lim27268872015-09-15 14:06:13 +0900433 priv = (struct wilc_priv *)pUserVoid;
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100434 if (priv->bCfgScanning) {
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900435 if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900436 wiphy = priv->dev->ieee80211_ptr->wiphy;
Leo Kim7ae43362015-09-16 18:35:59 +0900437
438 if (!wiphy)
439 return;
440
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900441 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC
442 &&
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900443 ((((s32)pstrNetworkInfo->s8rssi) * 100) < 0
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900444 ||
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900445 (((s32)pstrNetworkInfo->s8rssi) * 100) > 100)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900446 ) {
Leo Kim24db7132015-09-16 18:36:01 +0900447 PRINT_ER("wiphy signal type fial\n");
448 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900449 }
450
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900451 if (pstrNetworkInfo != NULL) {
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900452 s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900453 channel = ieee80211_get_channel(wiphy, s32Freq);
454
Leo Kim7ae43362015-09-16 18:35:59 +0900455 if (!channel)
456 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900457
458 PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530459 "BeaconPeriod: %d\n", channel->center_freq, (((s32)pstrNetworkInfo->s8rssi) * 100),
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900460 pstrNetworkInfo->u16CapInfo, pstrNetworkInfo->u16BeaconPeriod);
461
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100462 if (pstrNetworkInfo->bNewNetwork) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900463 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
464 /* max_scan_ssids */
465 PRINT_D(CFG80211_DBG, "Network %s found\n", pstrNetworkInfo->au8ssid);
466
467
468 priv->u32RcvdChCount++;
469
470
471
472 if (pJoinParams == NULL) {
473 PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n");
474 }
475 add_network_to_shadow(pstrNetworkInfo, priv, pJoinParams);
476
477 /*P2P peers are sent to WPA supplicant and added to shadow table*/
478
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900479 if (!(memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900480 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
481 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900482 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)pstrNetworkInfo->s8rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900483 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900484 }
485
486
487 } else {
488 PRINT_ER("Discovered networks exceeded the max limit\n");
489 }
490 } else {
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900491 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900492 /* So this network is discovered before, we'll just update its RSSI */
493 for (i = 0; i < priv->u32RcvdChCount; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900494 if (memcmp(last_scanned_shadow[i].au8bssid, pstrNetworkInfo->au8bssid, 6) == 0) {
495 PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", last_scanned_shadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900496
Leo Kimf1ab1172015-11-19 15:56:11 +0900497 last_scanned_shadow[i].s8rssi = pstrNetworkInfo->s8rssi;
498 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900499 break;
500 }
501 }
502 }
503 }
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900504 } else if (scan_event == SCAN_EVENT_DONE) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530505 PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev);
506 PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n");
Dean Lee72ed4dc2015-06-12 14:11:44 +0900507 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900508
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530509 if (priv->u32RcvdChCount > 0)
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530510 PRINT_D(CFG80211_DBG, "%d Network(s) found\n", priv->u32RcvdChCount);
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530511 else
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530512 PRINT_D(CFG80211_DBG, "No networks found\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900513
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200514 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900515
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900516 if (priv->pstrScanReq != NULL) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900517 cfg80211_scan_done(priv->pstrScanReq, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900518 priv->u32RcvdChCount = 0;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900519 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900520 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900521 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200522 up(&(priv->hSemScanReq));
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900523 } else if (scan_event == SCAN_EVENT_ABORTED) {
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200524 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900525
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530526 PRINT_D(CFG80211_DBG, "Scan Aborted\n");
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900527 if (priv->pstrScanReq != NULL) {
Leo Kim5e51d8b2015-11-19 15:56:28 +0900528 update_scan_time();
Dean Lee72ed4dc2015-06-12 14:11:44 +0900529 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900530
Dean Lee72ed4dc2015-06-12 14:11:44 +0900531 cfg80211_scan_done(priv->pstrScanReq, false);
532 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900533 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900534 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200535 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900536 }
537 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900538}
539
540
541/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900542 * @brief CfgConnectResult
543 * @details
544 * @param[in] tenuConnDisconnEvent enuConnDisconnEvent: Type of connection response either
545 * connection response or disconnection notification.
546 * tstrConnectInfo* pstrConnectInfo: COnnection information.
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900547 * u8 u8MacStatus: Mac Status from firmware
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900548 * tstrDisconnectNotifInfo* pstrDisconnectNotifInfo: Disconnection Notification
549 * void* pUserVoid: Private data associated with wireless interface
550 * @return NONE
551 * @author mabubakr
552 * @date 01 MAR 2012
553 * @version 1.0
554 */
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100555int wilc_connecting;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900556
Leo Kimed3f0372015-10-12 16:56:01 +0900557static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900558 tstrConnectInfo *pstrConnectInfo,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900559 u8 u8MacStatus,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900560 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
561 void *pUserVoid)
562{
Chaehyun Lim27268872015-09-15 14:06:13 +0900563 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900564 struct net_device *dev;
Leo Kim441dc602015-10-12 16:55:35 +0900565 struct host_if_drv *pstrWFIDrv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900566 u8 NullBssid[ETH_ALEN] = {0};
Glen Leec1ec2c12015-10-20 17:13:58 +0900567 struct wilc *wl;
568 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900569
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100570 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900571
Chaehyun Lim27268872015-09-15 14:06:13 +0900572 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900573 dev = priv->dev;
Glen Leec1ec2c12015-10-20 17:13:58 +0900574 nic = netdev_priv(dev);
575 wl = nic->wilc;
Leo Kim441dc602015-10-12 16:55:35 +0900576 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900577
578 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
579 /*Initialization*/
Amitoj Kaur Chawlababa7c72015-10-15 13:48:29 +0530580 u16 u16ConnectStatus;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900581
582 u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
583
584 PRINT_D(CFG80211_DBG, " Connection response received = %d\n", u8MacStatus);
585
586 if ((u8MacStatus == MAC_DISCONNECTED) &&
587 (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
588 /* The case here is that our station was waiting for association response frame and has just received it containing status code
589 * = SUCCESSFUL_STATUSCODE, while mac status is MAC_DISCONNECTED (which means something wrong happened) */
590 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100591 wilc_wlan_set_bssid(priv->dev, NullBssid);
Leo Kime554a302015-11-19 15:56:21 +0900592 eth_zero_addr(wilc_connected_ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900593
Leo Kimab16ec02015-10-29 12:05:40 +0900594 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900595 wlan_channel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900596
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530597 PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d\n", u16ConnectStatus, u8MacStatus);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900598 }
599
600 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900601 bool bNeedScanRefresh = false;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900602 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900603
604 PRINT_INFO(CFG80211_DBG, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo->au8bssid[0],
605 pstrConnectInfo->au8bssid[1], pstrConnectInfo->au8bssid[2], pstrConnectInfo->au8bssid[3], pstrConnectInfo->au8bssid[4], pstrConnectInfo->au8bssid[5]);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900606 memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900607
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900608
Leo Kim771fbae2015-11-19 15:56:10 +0900609 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900610 if (memcmp(last_scanned_shadow[i].au8bssid,
611 pstrConnectInfo->au8bssid, ETH_ALEN) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900612 unsigned long now = jiffies;
613
614 if (time_after(now,
Leo Kimf1ab1172015-11-19 15:56:11 +0900615 last_scanned_shadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900616 bNeedScanRefresh = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900617 }
618
619 break;
620 }
621 }
622
Abdul Hussain5a66bf22015-06-16 09:44:06 +0000623 if (bNeedScanRefresh) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900624 /*Also, refrsh DIRECT- results if */
Dean Lee72ed4dc2015-06-12 14:11:44 +0900625 refresh_scan(priv, 1, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900626
627 }
628
629 }
630
631
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530632 PRINT_D(CFG80211_DBG, "Association request info elements length = %zu\n", pstrConnectInfo->ReqIEsLen);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900633
634 PRINT_D(CFG80211_DBG, "Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen);
635
636 cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
637 pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
638 pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
639 u16ConnectStatus, GFP_KERNEL); /* TODO: mostafa: u16ConnectStatus to */
640 /* be replaced by pstrConnectInfo->u16ConnectStatus */
641 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100642 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900643 PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n",
644 pstrDisconnectNotifInfo->u16reason, priv->dev);
Leo Kim583d9722015-11-19 15:56:16 +0900645 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +0900646 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +0900647 wilc_ie = false;
Shraddha Barkebcf02652015-10-05 17:00:32 +0530648 eth_zero_addr(priv->au8AssociatedBss);
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100649 wilc_wlan_set_bssid(priv->dev, NullBssid);
Leo Kime554a302015-11-19 15:56:21 +0900650 eth_zero_addr(wilc_connected_ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900651
Leo Kimab16ec02015-10-29 12:05:40 +0900652 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900653 wlan_channel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900654 /*Incase "P2P CLIENT Connected" send deauthentication reason by 3 to force the WPA_SUPPLICANT to directly change
655 * virtual interface to station*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900656 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900657 pstrDisconnectNotifInfo->u16reason = 3;
658 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900659 /*Incase "P2P CLIENT during connection(not connected)" send deauthentication reason by 1 to force the WPA_SUPPLICANT
660 * to scan again and retry the connection*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900661 else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900662 pstrDisconnectNotifInfo->u16reason = 1;
663 }
664 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
Sudip Mukherjeee26bb712015-06-30 13:51:51 +0530665 pstrDisconnectNotifInfo->ie_len, false,
666 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900667
668 }
669
670}
671
672
673/**
Chaehyun Lim80785a92015-09-14 12:24:01 +0900674 * @brief set_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900675 * @details Set channel for a given wireless interface. Some devices
676 * may support multi-channel operation (by channel hopping) so cfg80211
677 * doesn't verify much. Note, however, that the passed netdev may be
678 * %NULL as well if the user requested changing the channel for the
679 * device itself, or for a monitor interface.
680 * @param[in]
681 * @return int : Return 0 on Success
682 * @author mdaftedar
683 * @date 01 MAR 2012
684 * @version 1.0
685 */
Chaehyun Lim80785a92015-09-14 12:24:01 +0900686static int set_channel(struct wiphy *wiphy,
687 struct cfg80211_chan_def *chandef)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900688{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900689 u32 channelnum = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +0900690 struct wilc_priv *priv;
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900691 int result = 0;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900692
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900693 priv = wiphy_priv(wiphy);
694
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900695 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
696 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900697
Chaehyun Lim866a2c22015-10-02 16:41:21 +0900698 curr_channel = channelnum;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100699 result = wilc_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900700
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900701 if (result != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900702 PRINT_ER("Error in setting channel %d\n", channelnum);
703
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900704 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900705}
706
707/**
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900708 * @brief scan
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900709 * @details Request to do a scan. If returning zero, the scan request is given
710 * the driver, and will be valid until passed to cfg80211_scan_done().
711 * For scan results, call cfg80211_inform_bss(); you can call this outside
712 * the scan/scan_done bracket too.
713 * @param[in]
714 * @return int : Return 0 on Success
715 * @author mabubakr
716 * @date 01 MAR 2012
717 * @version 1.0
718 */
719
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900720static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900721{
Chaehyun Lim27268872015-09-15 14:06:13 +0900722 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900723 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +0900724 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900725 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
Leo Kim607db442015-10-05 15:25:37 +0900726 struct hidden_network strHiddenNetwork;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900727
728 priv = wiphy_priv(wiphy);
729
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900730 priv->pstrScanReq = request;
731
732 priv->u32RcvdChCount = 0;
733
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100734 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Leo Kim12b01382015-11-19 15:56:27 +0900735 reset_shadow_found();
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900736
Dean Lee72ed4dc2015-06-12 14:11:44 +0900737 priv->bCfgScanning = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900738 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
739 /* max_scan_ssids */
740 for (i = 0; i < request->n_channels; i++) {
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900741 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900742 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
743 }
744
745 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530746 PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900747
748 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
749
750 if (request->n_ssids >= 1) {
751
752
Leo Kim607db442015-10-05 15:25:37 +0900753 strHiddenNetwork.pstrHiddenNetworkInfo = kmalloc(request->n_ssids * sizeof(struct hidden_network), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900754 strHiddenNetwork.u8ssidnum = request->n_ssids;
755
756
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900757 for (i = 0; i < request->n_ssids; i++) {
758
759 if (request->ssids[i].ssid != NULL && request->ssids[i].ssid_len != 0) {
Glen Leef3052582015-09-10 12:03:04 +0900760 strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900761 memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900762 strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len;
763 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530764 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900765 strHiddenNetwork.u8ssidnum -= 1;
766 }
767 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530768 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100769 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900770 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900771 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900772 CfgScanResult, (void *)priv, &strHiddenNetwork);
773 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530774 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100775 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900776 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900777 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900778 CfgScanResult, (void *)priv, NULL);
779 }
780
781 } else {
782 PRINT_ER("Requested num of scanned channels is greater than the max, supported"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530783 " channels\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900784 }
785
Leo Kime6e12662015-09-16 18:36:03 +0900786 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900787 s32Error = -EBUSY;
788 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
789 }
790
791 return s32Error;
792}
793
794/**
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900795 * @brief connect
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900796 * @details Connect to the ESS with the specified parameters. When connected,
797 * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
798 * If the connection fails for some reason, call cfg80211_connect_result()
799 * with the status from the AP.
800 * @param[in]
801 * @return int : Return 0 on Success
802 * @author mabubakr
803 * @date 01 MAR 2012
804 * @version 1.0
805 */
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900806static int connect(struct wiphy *wiphy, struct net_device *dev,
807 struct cfg80211_connect_params *sme)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900808{
Leo Kime6e12662015-09-16 18:36:03 +0900809 s32 s32Error = 0;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900810 u32 i;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900811 u8 u8security = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +0900812 enum AUTHTYPE tenuAuth_type = ANY;
Dean Lee576917a2015-06-15 11:58:57 +0900813 char *pcgroup_encrypt_val = NULL;
814 char *pccipher_group = NULL;
815 char *pcwpa_version = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900816
Chaehyun Lim27268872015-09-15 14:06:13 +0900817 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +0900818 struct host_if_drv *pstrWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900819 tstrNetworkInfo *pstrNetworkInfo = NULL;
820
821
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100822 wilc_connecting = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900823 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +0900824 pstrWFIDrv = (struct host_if_drv *)(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900825
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100826 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900827
Johnny Kim8a143302015-06-10 17:06:46 +0900828 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 +0900829 if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900830 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
Leo Kimab16ec02015-10-29 12:05:40 +0900831 pstrWFIDrv->p2p_connect = 1;
832 } else {
833 pstrWFIDrv->p2p_connect = 0;
834 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530835 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900836
Leo Kim771fbae2015-11-19 15:56:10 +0900837 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900838 if ((sme->ssid_len == last_scanned_shadow[i].u8SsidLen) &&
839 memcmp(last_scanned_shadow[i].au8ssid,
840 sme->ssid,
841 sme->ssid_len) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900842 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
843 if (sme->bssid == NULL) {
844 /* BSSID is not passed from the user, so decision of matching
845 * is done by SSID only */
846 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
847 break;
848 } else {
849 /* BSSID is also passed from the user, so decision of matching
850 * should consider also this passed BSSID */
Leo Kimf1ab1172015-11-19 15:56:11 +0900851 if (memcmp(last_scanned_shadow[i].au8bssid,
852 sme->bssid,
853 ETH_ALEN) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900854 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
855 break;
856 }
857 }
858 }
859 }
860
Leo Kim771fbae2015-11-19 15:56:10 +0900861 if (i < last_scanned_cnt) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900862 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
863
Leo Kimf1ab1172015-11-19 15:56:11 +0900864 pstrNetworkInfo = &last_scanned_shadow[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900865
866 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
867 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
868 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
869 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
870 } else {
871 s32Error = -ENOENT;
Leo Kim771fbae2015-11-19 15:56:10 +0900872 if (last_scanned_cnt == 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900873 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
874 else
875 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
876
877 goto done;
878 }
879
880 priv->WILC_WFI_wep_default = 0;
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900881 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
882 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900883
884 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
885 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
886
887 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
888
889 if (INFO) {
890 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
891 PRINT_D(CORECONFIG_DBG, "sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]);
892 }
893
894 if (sme->crypto.cipher_group != NO_ENCRYPT) {
895 /* To determine the u8security value, first we check the group cipher suite then {in case of WPA or WPA2}
896 * we will add to it the pairwise cipher suite(s) */
897 pcwpa_version = "Default";
898 PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900899 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900900 u8security = ENCRYPT_ENABLED | WEP;
901 pcgroup_encrypt_val = "WEP40";
902 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
903 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
904
905 if (INFO) {
906 for (i = 0; i < sme->key_len; i++)
907 PRINT_D(CORECONFIG_DBG, "WEP Key Value[%d] = %d\n", i, sme->key[i]);
908 }
909 priv->WILC_WFI_wep_default = sme->key_idx;
910 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900911 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900912
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900913 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900914 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900915 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
916 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900917 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900918
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100919 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
920 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900921 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900922 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
923 pcgroup_encrypt_val = "WEP104";
924 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
925
926 priv->WILC_WFI_wep_default = sme->key_idx;
927 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900928 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900929
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900930 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900931 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900932 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
933 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900934 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900935
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100936 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
937 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900938 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900939 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900940 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
941 pcgroup_encrypt_val = "WPA2_TKIP";
942 pccipher_group = "TKIP";
943 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
944 /* tenuSecurity_t = WPA2_AES; */
945 u8security = ENCRYPT_ENABLED | WPA2 | AES;
946 pcgroup_encrypt_val = "WPA2_AES";
947 pccipher_group = "AES";
948 }
949 pcwpa_version = "WPA_VERSION_2";
950 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
951 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900952 u8security = ENCRYPT_ENABLED | WPA | TKIP;
953 pcgroup_encrypt_val = "WPA_TKIP";
954 pccipher_group = "TKIP";
955 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
956 /* tenuSecurity_t = WPA_AES; */
957 u8security = ENCRYPT_ENABLED | WPA | AES;
958 pcgroup_encrypt_val = "WPA_AES";
959 pccipher_group = "AES";
960
961 }
962 pcwpa_version = "WPA_VERSION_1";
963
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900964 } else {
965 s32Error = -ENOTSUPP;
966 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
967
968 goto done;
969 }
970
971 }
972
973 /* After we set the u8security value from checking the group cipher suite, {in case of WPA or WPA2} we will
974 * add to it the pairwise cipher suite(s) */
975 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
976 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
977 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
978 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
979 u8security = u8security | TKIP;
980 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
981 u8security = u8security | AES;
982 }
983 }
984 }
985
986 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
987
988 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
989 switch (sme->auth_type) {
990 case NL80211_AUTHTYPE_OPEN_SYSTEM:
991 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
992 tenuAuth_type = OPEN_SYSTEM;
993 break;
994
995 case NL80211_AUTHTYPE_SHARED_KEY:
996 tenuAuth_type = SHARED_KEY;
997 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
998 break;
999
1000 default:
1001 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
1002 }
1003
1004
1005 /* ai: key_mgmt: enterprise case */
1006 if (sme->crypto.n_akm_suites) {
1007 switch (sme->crypto.akm_suites[0]) {
1008 case WLAN_AKM_SUITE_8021X:
1009 tenuAuth_type = IEEE8021;
1010 break;
1011
1012 default:
1013 break;
1014 }
1015 }
1016
1017
1018 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
1019
1020 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
1021 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
1022
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001023 curr_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001024
Leo Kimab16ec02015-10-29 12:05:40 +09001025 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +09001026 wlan_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001027
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001028 wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001029
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001030 s32Error = wilc_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001031 sme->ssid_len, sme->ie, sme->ie_len,
1032 CfgConnectResult, (void *)priv, u8security,
1033 tenuAuth_type, pstrNetworkInfo->u8channel,
1034 pstrNetworkInfo->pJoinParams);
Leo Kime6e12662015-09-16 18:36:03 +09001035 if (s32Error != 0) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001036 PRINT_ER("wilc_set_join_req(): Error(%d)\n", s32Error);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001037 s32Error = -ENOENT;
1038 goto done;
1039 }
1040
1041done:
1042
1043 return s32Error;
1044}
1045
1046
1047/**
Chaehyun Limb027cde2015-09-14 12:24:04 +09001048 * @brief disconnect
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001049 * @details Disconnect from the BSS/ESS.
1050 * @param[in]
1051 * @return int : Return 0 on Success
1052 * @author mdaftedar
1053 * @date 01 MAR 2012
1054 * @version 1.0
1055 */
Chaehyun Limb027cde2015-09-14 12:24:04 +09001056static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001057{
Leo Kime6e12662015-09-16 18:36:03 +09001058 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09001059 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09001060 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim51e825f2015-09-15 14:06:14 +09001061 u8 NullBssid[ETH_ALEN] = {0};
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001062
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001063 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001064 priv = wiphy_priv(wiphy);
1065
Leo Kim441dc602015-10-12 16:55:35 +09001066 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Leo Kimab16ec02015-10-29 12:05:40 +09001067 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +09001068 wlan_channel = INVALID_CHANNEL;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001069 wilc_wlan_set_bssid(priv->dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001070
1071 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
1072
Leo Kim583d9722015-11-19 15:56:16 +09001073 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +09001074 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +09001075 wilc_ie = false;
Leo Kim1229b1a2015-10-29 12:05:39 +09001076 pstrWFIDrv->p2p_timeout = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001077
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001078 s32Error = wilc_disconnect(priv->hWILCWFIDrv, reason_code);
Leo Kime6e12662015-09-16 18:36:03 +09001079 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001080 PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
1081 s32Error = -EINVAL;
1082 }
1083
1084 return s32Error;
1085}
1086
1087/**
Chaehyun Lim953d4172015-09-14 12:24:05 +09001088 * @brief add_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001089 * @details Add a key with the given parameters. @mac_addr will be %NULL
1090 * when adding a group key.
1091 * @param[in] key : key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, 8-byte Rx Mic Key
1092 * @return int : Return 0 on Success
1093 * @author mdaftedar
1094 * @date 01 MAR 2012
1095 * @version 1.0
1096 */
Chaehyun Lim953d4172015-09-14 12:24:05 +09001097static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1098 bool pairwise,
1099 const u8 *mac_addr, struct key_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001100
1101{
Leo Kime6e12662015-09-16 18:36:03 +09001102 s32 s32Error = 0, KeyLen = params->key_len;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001103 u32 i;
Chaehyun Lim27268872015-09-15 14:06:13 +09001104 struct wilc_priv *priv;
Arnd Bergmann057d1e92015-06-01 21:06:44 +02001105 const u8 *pu8RxMic = NULL;
1106 const u8 *pu8TxMic = NULL;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001107 u8 u8mode = NO_ENCRYPT;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001108 u8 u8gmode = NO_ENCRYPT;
1109 u8 u8pmode = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +09001110 enum AUTHTYPE tenuAuth_type = ANY;
Glen Lee76469202015-10-20 17:13:59 +09001111 struct wilc *wl;
1112 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001113
1114 priv = wiphy_priv(wiphy);
Glen Lee76469202015-10-20 17:13:59 +09001115 nic = netdev_priv(netdev);
1116 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001117
1118 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
1119
Johnny Kim8a143302015-06-10 17:06:46 +09001120 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001121
1122 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
1123 params->key[1],
1124 params->key[2]);
1125
1126
1127 switch (params->cipher) {
1128 case WLAN_CIPHER_SUITE_WEP40:
1129 case WLAN_CIPHER_SUITE_WEP104:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001130 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
1131
1132 priv->WILC_WFI_wep_default = key_index;
1133 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001134 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001135
1136 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
1137 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
1138
1139 for (i = 0; i < params->key_len; i++)
1140 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
1141
1142 tenuAuth_type = OPEN_SYSTEM;
1143
1144 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
1145 u8mode = ENCRYPT_ENABLED | WEP;
1146 else
1147 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
1148
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001149 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 +09001150 break;
1151 }
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001152 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001153 priv->WILC_WFI_wep_default = key_index;
1154 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001155 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001156
1157 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
1158 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
1159 if (INFO) {
1160 for (i = 0; i < params->key_len; i++)
1161 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
1162 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001163 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001164 }
1165
1166 break;
1167
1168 case WLAN_CIPHER_SUITE_TKIP:
1169 case WLAN_CIPHER_SUITE_CCMP:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001170 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
1171
1172 if (priv->wilc_gtk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001173 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001174 priv->wilc_gtk[key_index]->key = NULL;
1175 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001176
1177 }
1178 if (priv->wilc_ptk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001179 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001180 priv->wilc_ptk[key_index]->key = NULL;
1181 priv->wilc_ptk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001182 }
1183
1184
1185
Daniel Machon19132212015-08-05 08:18:31 +02001186 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001187 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1188 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1189 else
1190 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1191
1192 priv->wilc_groupkey = u8gmode;
1193
1194 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1195
1196 pu8TxMic = params->key + 24;
1197 pu8RxMic = params->key + 16;
1198 KeyLen = params->key_len - 16;
1199 }
1200 /* 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 +05301201 kfree(priv->wilc_gtk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001202
Glen Leef3052582015-09-10 12:03:04 +09001203 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001204 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001205
1206 /* 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 +05301207 kfree(priv->wilc_gtk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001208
1209 if ((params->seq_len) > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001210 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001211 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001212 }
1213
1214 priv->wilc_gtk[key_index]->cipher = params->cipher;
1215 priv->wilc_gtk[key_index]->key_len = params->key_len;
1216 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1217
1218 if (INFO) {
1219 for (i = 0; i < params->key_len; i++)
1220 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1221 for (i = 0; i < params->seq_len; i++)
1222 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1223 }
1224
1225
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001226 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001227 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode);
1228
1229 } else {
1230 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]);
1231
1232 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1233 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1234 else
1235 u8pmode = priv->wilc_groupkey | AES;
1236
1237
1238 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1239
1240 pu8TxMic = params->key + 24;
1241 pu8RxMic = params->key + 16;
1242 KeyLen = params->key_len - 16;
1243 }
1244
Shraddha Barkecccfc392015-10-12 20:49:19 +05301245 kfree(priv->wilc_ptk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001246
Glen Leef3052582015-09-10 12:03:04 +09001247 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001248
Shraddha Barkecccfc392015-10-12 20:49:19 +05301249 kfree(priv->wilc_ptk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001250
1251 if ((params->seq_len) > 0)
Glen Leef3052582015-09-10 12:03:04 +09001252 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001253
1254 if (INFO) {
1255 for (i = 0; i < params->key_len; i++)
1256 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1257
1258 for (i = 0; i < params->seq_len; i++)
1259 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1260 }
1261
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001262 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001263
1264 if ((params->seq_len) > 0)
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001265 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001266
1267 priv->wilc_ptk[key_index]->cipher = params->cipher;
1268 priv->wilc_ptk[key_index]->key_len = params->key_len;
1269 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1270
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001271 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001272 pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index);
1273 }
1274 break;
1275 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001276
1277 {
1278 u8mode = 0;
Daniel Machon19132212015-08-05 08:18:31 +02001279 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001280 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1281 /* swap the tx mic by rx mic */
1282 pu8RxMic = params->key + 24;
1283 pu8TxMic = params->key + 16;
1284 KeyLen = params->key_len - 16;
1285 }
1286
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001287 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001288 if (!g_gtk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001289 g_add_gtk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001290 g_add_gtk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001291 if (!mac_addr) {
1292 g_add_gtk_key_params.mac_addr = NULL;
1293 } else {
Glen Leef3052582015-09-10 12:03:04 +09001294 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001295 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1296 }
1297 g_key_gtk_params.key_len = params->key_len;
1298 g_key_gtk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001299 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001300 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1301 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001302 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001303 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1304 }
1305 g_key_gtk_params.cipher = params->cipher;
1306
1307 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1308 g_key_gtk_params.key[1],
1309 g_key_gtk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001310 g_gtk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001311 }
1312
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001313 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001314 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001315 } else {
1316 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1317 /* swap the tx mic by rx mic */
1318 pu8RxMic = params->key + 24;
1319 pu8TxMic = params->key + 16;
1320 KeyLen = params->key_len - 16;
1321 }
1322
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001323 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001324 if (!g_ptk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001325 g_add_ptk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001326 g_add_ptk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001327 if (!mac_addr) {
1328 g_add_ptk_key_params.mac_addr = NULL;
1329 } else {
Glen Leef3052582015-09-10 12:03:04 +09001330 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001331 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1332 }
1333 g_key_ptk_params.key_len = params->key_len;
1334 g_key_ptk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001335 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001336 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1337 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001338 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001339 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1340 }
1341 g_key_ptk_params.cipher = params->cipher;
1342
1343 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1344 g_key_ptk_params.key[1],
1345 g_key_ptk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001346 g_ptk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001347 }
1348
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001349 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001350 pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index);
1351 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1352 if (INFO) {
1353 for (i = 0; i < params->key_len; i++)
1354 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1355 }
1356 }
1357 }
1358 break;
1359
1360 default:
1361 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
1362 s32Error = -ENOTSUPP;
1363
1364 }
1365
1366 return s32Error;
1367}
1368
1369/**
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001370 * @brief del_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001371 * @details Remove a key given the @mac_addr (%NULL for a group key)
1372 * and @key_index, return -ENOENT if the key doesn't exist.
1373 * @param[in]
1374 * @return int : Return 0 on Success
1375 * @author mdaftedar
1376 * @date 01 MAR 2012
1377 * @version 1.0
1378 */
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001379static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1380 u8 key_index,
1381 bool pairwise,
1382 const u8 *mac_addr)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001383{
Chaehyun Lim27268872015-09-15 14:06:13 +09001384 struct wilc_priv *priv;
Glen Lee692e2ac2015-10-20 17:14:00 +09001385 struct wilc *wl;
1386 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001387
1388 priv = wiphy_priv(wiphy);
Glen Lee692e2ac2015-10-20 17:14:00 +09001389 nic = netdev_priv(netdev);
1390 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001391
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001392 /*delete saved keys, if any*/
Glen Lee692e2ac2015-10-20 17:14:00 +09001393 if (netdev == wl->vif[0].ndev) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09001394 g_ptk_keys_saved = false;
1395 g_gtk_keys_saved = false;
1396 g_wep_keys_saved = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001397
1398 /*Delete saved WEP keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301399 kfree(g_key_wep_params.key);
1400 g_key_wep_params.key = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001401
1402 /*freeing memory allocated by "wilc_gtk" and "wilc_ptk" in "WILC_WIFI_ADD_KEY"*/
1403
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001404 if ((priv->wilc_gtk[key_index]) != NULL) {
1405
Shraddha Barkecccfc392015-10-12 20:49:19 +05301406 kfree(priv->wilc_gtk[key_index]->key);
1407 priv->wilc_gtk[key_index]->key = NULL;
1408 kfree(priv->wilc_gtk[key_index]->seq);
1409 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001410
Chaehyun Lim49188af2015-08-11 10:32:41 +09001411 kfree(priv->wilc_gtk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001412 priv->wilc_gtk[key_index] = NULL;
1413
1414 }
1415
1416 if ((priv->wilc_ptk[key_index]) != NULL) {
1417
Shraddha Barkecccfc392015-10-12 20:49:19 +05301418 kfree(priv->wilc_ptk[key_index]->key);
1419 priv->wilc_ptk[key_index]->key = NULL;
1420 kfree(priv->wilc_ptk[key_index]->seq);
1421 priv->wilc_ptk[key_index]->seq = NULL;
Chaehyun Lim49188af2015-08-11 10:32:41 +09001422 kfree(priv->wilc_ptk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001423 priv->wilc_ptk[key_index] = NULL;
1424 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001425
1426 /*Delete saved PTK and GTK keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301427 kfree(g_key_ptk_params.key);
1428 g_key_ptk_params.key = NULL;
1429 kfree(g_key_ptk_params.seq);
1430 g_key_ptk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001431
Shraddha Barkecccfc392015-10-12 20:49:19 +05301432 kfree(g_key_gtk_params.key);
1433 g_key_gtk_params.key = NULL;
1434 kfree(g_key_gtk_params.seq);
1435 g_key_gtk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001436
1437 /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001438 wilc_set_machw_change_vir_if(netdev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001439 }
1440
1441 if (key_index >= 0 && key_index <= 3) {
Chaehyun Lim2cc46832015-08-07 09:02:01 +09001442 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001443 priv->WILC_WFI_wep_key_len[key_index] = 0;
1444
1445 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001446 wilc_remove_wep_key(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001447 } else {
1448 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001449 wilc_remove_key(priv->hWILCWFIDrv, mac_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001450 }
1451
Leo Kimaaed3292015-10-12 16:55:38 +09001452 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001453}
1454
1455/**
Chaehyun Limf4893df2015-09-14 12:24:07 +09001456 * @brief get_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001457 * @details Get information about the key with the given parameters.
1458 * @mac_addr will be %NULL when requesting information for a group
1459 * key. All pointers given to the @callback function need not be valid
1460 * after it returns. This function should return an error if it is
1461 * not possible to retrieve the key, -ENOENT if it doesn't exist.
1462 * @param[in]
1463 * @return int : Return 0 on Success
1464 * @author mdaftedar
1465 * @date 01 MAR 2012
1466 * @version 1.0
1467 */
Chaehyun Limf4893df2015-09-14 12:24:07 +09001468static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1469 bool pairwise,
1470 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001471{
Chaehyun Lim27268872015-09-15 14:06:13 +09001472 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001473 struct key_params key_params;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001474 u32 i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001475
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001476 priv = wiphy_priv(wiphy);
1477
1478
Alison Schofield3604af52015-10-12 13:22:44 -07001479 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001480 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1481
1482 key_params.key = priv->wilc_gtk[key_index]->key;
1483 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1484 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1485 key_params.seq = priv->wilc_gtk[key_index]->seq;
1486 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1487 if (INFO) {
1488 for (i = 0; i < key_params.key_len; i++)
1489 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1490 }
1491 } else {
1492 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1493
1494 key_params.key = priv->wilc_ptk[key_index]->key;
1495 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1496 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1497 key_params.seq = priv->wilc_ptk[key_index]->seq;
1498 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1499 }
1500
1501 callback(cookie, &key_params);
1502
Leo Kimaaed3292015-10-12 16:55:38 +09001503 return 0; /* priv->wilc_gtk->key_len ?0 : -ENOENT; */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001504}
1505
1506/**
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001507 * @brief set_default_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001508 * @details Set the default management frame key on an interface
1509 * @param[in]
1510 * @return int : Return 0 on Success.
1511 * @author mdaftedar
1512 * @date 01 MAR 2012
1513 * @version 1.0
1514 */
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001515static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1516 bool unicast, bool multicast)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001517{
Chaehyun Lim27268872015-09-15 14:06:13 +09001518 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001519
1520
1521 priv = wiphy_priv(wiphy);
1522
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301523 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001524
1525 if (key_index != priv->WILC_WFI_wep_default) {
1526
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001527 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001528 }
1529
Leo Kimaaed3292015-10-12 16:55:38 +09001530 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001531}
1532
1533/**
Chaehyun Limf06f5622015-09-14 12:24:18 +09001534 * @brief get_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001535 * @details Get station information for the station identified by @mac
1536 * @param[in] NONE
1537 * @return int : Return 0 on Success.
1538 * @author mdaftedar
1539 * @date 01 MAR 2012
1540 * @version 1.0
1541 */
1542
Chaehyun Limf06f5622015-09-14 12:24:18 +09001543static int get_station(struct wiphy *wiphy, struct net_device *dev,
1544 const u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001545{
Chaehyun Lim27268872015-09-15 14:06:13 +09001546 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001547 perInterface_wlan_t *nic;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001548 u32 i = 0;
1549 u32 associatedsta = 0;
1550 u32 inactive_time = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001551 priv = wiphy_priv(wiphy);
1552 nic = netdev_priv(dev);
1553
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001554 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
1555 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1556
1557 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1558
1559 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1560
1561 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1562 associatedsta = i;
1563 break;
1564 }
1565
1566 }
1567
1568 if (associatedsta == -1) {
Leo Kimaaed3292015-10-12 16:55:38 +09001569 PRINT_ER("Station required is not associated\n");
1570 return -ENOENT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001571 }
1572
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001573 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001574
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001575 wilc_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001576 sinfo->inactive_time = 1000 * inactive_time;
1577 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
1578
1579 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001580
1581 if (nic->iftype == STATION_MODE) {
Leo Kim03e7b9c2015-10-12 16:55:58 +09001582 struct rf_info strStatistics;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001583
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001584 wilc_get_statistics(priv->hWILCWFIDrv, &strStatistics);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001585
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001586 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
Chandra S Gorentla62129902015-08-05 22:11:57 +05301587 BIT(NL80211_STA_INFO_RX_PACKETS) |
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001588 BIT(NL80211_STA_INFO_TX_PACKETS) |
1589 BIT(NL80211_STA_INFO_TX_FAILED) |
1590 BIT(NL80211_STA_INFO_TX_BITRATE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001591
Leo Kim00c8dfc2015-10-29 12:05:30 +09001592 sinfo->signal = strStatistics.rssi;
Leo Kim9b992742015-10-29 12:05:32 +09001593 sinfo->rx_packets = strStatistics.rx_cnt;
Leo Kim54160372015-10-29 12:05:33 +09001594 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1595 sinfo->tx_failed = strStatistics.tx_fail_cnt;
Leo Kim5babeec2015-10-29 12:05:29 +09001596 sinfo->txrate.legacy = strStatistics.link_speed * 10;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001597
Leo Kim5babeec2015-10-29 12:05:29 +09001598 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1599 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001600 wilc_enable_tcp_ack_filter(true);
Leo Kim5babeec2015-10-29 12:05:29 +09001601 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001602 wilc_enable_tcp_ack_filter(false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001603
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001604 PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
1605 sinfo->tx_failed, sinfo->txrate.legacy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001606 }
Leo Kimaaed3292015-10-12 16:55:38 +09001607 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001608}
1609
1610
1611/**
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001612 * @brief change_bss
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001613 * @details Modify parameters for a given BSS.
1614 * @param[in]
1615 * -use_cts_prot: Whether to use CTS protection
1616 * (0 = no, 1 = yes, -1 = do not change)
1617 * -use_short_preamble: Whether the use of short preambles is allowed
1618 * (0 = no, 1 = yes, -1 = do not change)
1619 * -use_short_slot_time: Whether the use of short slot time is allowed
1620 * (0 = no, 1 = yes, -1 = do not change)
1621 * -basic_rates: basic rates in IEEE 802.11 format
1622 * (or NULL for no change)
1623 * -basic_rates_len: number of basic rates
1624 * -ap_isolate: do not forward packets between connected stations
1625 * -ht_opmode: HT Operation mode
1626 * (u16 = opmode, -1 = do not change)
1627 * @return int : Return 0 on Success.
1628 * @author mdaftedar
1629 * @date 01 MAR 2012
1630 * @version 1.0
1631 */
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001632static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1633 struct bss_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001634{
1635 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1636 return 0;
1637}
1638
1639/**
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001640 * @brief set_wiphy_params
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001641 * @details Notify that wiphy parameters have changed;
1642 * @param[in] Changed bitfield (see &enum wiphy_params_flags) describes which values
1643 * have changed.
1644 * @return int : Return 0 on Success
1645 * @author mdaftedar
1646 * @date 01 MAR 2012
1647 * @version 1.0
1648 */
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001649static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001650{
Leo Kime6e12662015-09-16 18:36:03 +09001651 s32 s32Error = 0;
Leo Kim95296502015-10-05 15:25:46 +09001652 struct cfg_param_val pstrCfgParamVal;
Chaehyun Lim27268872015-09-15 14:06:13 +09001653 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001654
1655 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001656
Tony Cho87c05b22015-10-12 16:56:07 +09001657 pstrCfgParamVal.flag = 0;
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301658 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001659
1660 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1661 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1662 priv->dev->ieee80211_ptr->wiphy->retry_short);
Tony Cho87c05b22015-10-12 16:56:07 +09001663 pstrCfgParamVal.flag |= RETRY_SHORT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001664 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1665 }
1666 if (changed & WIPHY_PARAM_RETRY_LONG) {
1667
1668 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 +09001669 pstrCfgParamVal.flag |= RETRY_LONG;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001670 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1671
1672 }
1673 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1674 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 +09001675 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001676 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1677
1678 }
1679
1680 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1681 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1682
Tony Cho87c05b22015-10-12 16:56:07 +09001683 pstrCfgParamVal.flag |= RTS_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001684 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1685
1686 }
1687
1688 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001689 s32Error = wilc_hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001690 if (s32Error)
1691 PRINT_ER("Error in setting WIPHY PARAMS\n");
1692
1693
1694 return s32Error;
1695}
Arnd Bergmanne5af0562015-05-29 22:52:12 +02001696
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001697/**
Chaehyun Lim4d466572015-09-14 12:24:22 +09001698 * @brief set_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001699 * @details Cache a PMKID for a BSSID. This is mostly useful for fullmac
1700 * devices running firmwares capable of generating the (re) association
1701 * RSN IE. It allows for faster roaming between WPA2 BSSIDs.
1702 * @param[in]
1703 * @return int : Return 0 on Success
1704 * @author mdaftedar
1705 * @date 01 MAR 2012
1706 * @version 1.0
1707 */
Chaehyun Lim4d466572015-09-14 12:24:22 +09001708static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1709 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001710{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001711 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001712 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001713 u8 flag = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001714
Chaehyun Lim27268872015-09-15 14:06:13 +09001715 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001716
1717 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1718
1719
1720 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001721 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001722 ETH_ALEN)) {
1723 /*If bssid already exists and pmkid value needs to reset*/
1724 flag = PMKID_FOUND;
1725 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1726 break;
1727 }
1728 }
1729 if (i < WILC_MAX_NUM_PMKIDS) {
1730 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001731 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001732 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001733 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001734 PMKID_LEN);
1735 if (!(flag == PMKID_FOUND))
1736 priv->pmkid_list.numpmkid++;
1737 } else {
1738 PRINT_ER("Invalid PMKID index\n");
1739 s32Error = -EINVAL;
1740 }
1741
1742 if (!s32Error) {
1743 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001744 s32Error = wilc_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001745 }
1746 return s32Error;
1747}
1748
1749/**
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001750 * @brief del_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001751 * @details Delete a cached PMKID.
1752 * @param[in]
1753 * @return int : Return 0 on Success
1754 * @author mdaftedar
1755 * @date 01 MAR 2012
1756 * @version 1.0
1757 */
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001758static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1759 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001760{
1761
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001762 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001763 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001764
Chaehyun Lim27268872015-09-15 14:06:13 +09001765 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001766
1767 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1768
1769 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001770 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001771 ETH_ALEN)) {
1772 /*If bssid is found, reset the values*/
1773 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
Leo Kimcd1e6cb2015-10-05 15:25:45 +09001774 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001775 break;
1776 }
1777 }
1778
1779 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1780 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001781 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001782 priv->pmkid_list.pmkidlist[i + 1].bssid,
1783 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001784 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001785 priv->pmkid_list.pmkidlist[i].pmkid,
1786 PMKID_LEN);
1787 }
1788 priv->pmkid_list.numpmkid--;
1789 } else {
1790 s32Error = -EINVAL;
1791 }
1792
1793 return s32Error;
1794}
1795
1796/**
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001797 * @brief flush_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001798 * @details Flush all cached PMKIDs.
1799 * @param[in]
1800 * @return int : Return 0 on Success
1801 * @author mdaftedar
1802 * @date 01 MAR 2012
1803 * @version 1.0
1804 */
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001805static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001806{
Chaehyun Lim27268872015-09-15 14:06:13 +09001807 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001808
1809 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
1810
1811 /*Get cashed Pmkids and set all with zeros*/
Leo Kima949f902015-10-05 15:25:44 +09001812 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001813
1814 return 0;
1815}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001816
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001817
1818/**
1819 * @brief WILC_WFI_CfgParseRxAction
1820 * @details Function parses the received frames and modifies the following attributes:
1821 * -GO Intent
1822 * -Channel list
1823 * -Operating Channel
1824 *
1825 * @param[in] u8* Buffer, u32 length
1826 * @return NONE.
1827 * @author mdaftedar
1828 * @date 12 DEC 2012
1829 * @version
1830 */
1831
Arnd Bergmann1608c402015-11-16 15:04:53 +01001832static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001833{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001834 u32 index = 0;
1835 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001836
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001837 u8 op_channel_attr_index = 0;
1838 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001839
1840 while (index < len) {
1841 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001842 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001843 }
1844
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301845 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001846 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301847 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001848 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001849 index += buf[index + 1] + 3; /* ID,Length byte */
1850 }
Leo Kim0bd82742015-11-19 15:56:14 +09001851 if (wlan_channel != INVALID_CHANNEL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001852 /*Modify channel list attribute*/
1853 if (channel_list_attr_index) {
1854 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1855 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1856 if (buf[i] == 0x51) {
1857 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
Leo Kim0bd82742015-11-19 15:56:14 +09001858 buf[j] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001859 }
1860 break;
1861 }
1862 }
1863 }
1864 /*Modify operating channel attribute*/
1865 if (op_channel_attr_index) {
1866 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1867 buf[op_channel_attr_index + 6] = 0x51;
Leo Kim0bd82742015-11-19 15:56:14 +09001868 buf[op_channel_attr_index + 7] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001869 }
1870 }
1871}
1872
1873/**
1874 * @brief WILC_WFI_CfgParseTxAction
1875 * @details Function parses the transmitted action frames and modifies the
1876 * GO Intent attribute
1877 * @param[in] u8* Buffer, u32 length, bool bOperChan, u8 iftype
1878 * @return NONE.
1879 * @author mdaftedar
1880 * @date 12 DEC 2012
1881 * @version
1882 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01001883static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001884{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001885 u32 index = 0;
1886 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001887
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001888 u8 op_channel_attr_index = 0;
1889 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001890
1891 while (index < len) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001892 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001893 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001894
1895 break;
1896 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001897
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301898 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001899 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301900 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001901 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001902 index += buf[index + 1] + 3; /* ID,Length byte */
1903 }
Leo Kim0bd82742015-11-19 15:56:14 +09001904 if (wlan_channel != INVALID_CHANNEL && bOperChan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001905 /*Modify channel list attribute*/
1906 if (channel_list_attr_index) {
1907 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1908 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1909 if (buf[i] == 0x51) {
1910 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
Leo Kim0bd82742015-11-19 15:56:14 +09001911 buf[j] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001912 }
1913 break;
1914 }
1915 }
1916 }
1917 /*Modify operating channel attribute*/
1918 if (op_channel_attr_index) {
1919 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1920 buf[op_channel_attr_index + 6] = 0x51;
Leo Kim0bd82742015-11-19 15:56:14 +09001921 buf[op_channel_attr_index + 7] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001922 }
1923 }
1924}
1925
1926/* @brief WILC_WFI_p2p_rx
1927 * @details
1928 * @param[in]
1929 *
1930 * @return None
1931 * @author Mai Daftedar
1932 * @date 2 JUN 2013
1933 * @version 1.0
1934 */
1935
Chaehyun Limfbc2fe12015-09-15 14:06:16 +09001936void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001937{
1938
Chaehyun Lim27268872015-09-15 14:06:13 +09001939 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001940 u32 header, pkt_offset;
Leo Kim441dc602015-10-12 16:55:35 +09001941 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001942 u32 i = 0;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001943 s32 s32Freq;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001944
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001945 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001946 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001947
1948 /* Get WILC header */
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001949 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001950
1951 /* The packet offset field conain info about what type of managment frame */
1952 /* we are dealing with and ack status */
1953 pkt_offset = GET_PKT_OFFSET(header);
1954
1955 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1956 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1957 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001958 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001959 return;
1960 } else {
1961 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
1962 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],
1963 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001964 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001965 } else {
1966 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],
1967 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001968 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001969 }
1970 return;
1971 }
1972 } else {
1973
1974 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
1975
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001976 /*Upper layer is informed that the frame is received on this freq*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001977 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001978
1979 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1980 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
1981
Leo Kim1229b1a2015-10-29 12:05:39 +09001982 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001983 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
1984 return;
1985 }
1986 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1987
1988 switch (buff[ACTION_SUBTYPE_ID]) {
1989 case GAS_INTIAL_REQ:
1990 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
1991 break;
1992
1993 case GAS_INTIAL_RSP:
1994 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
1995 break;
1996
1997 case PUBLIC_ACT_VENDORSPEC:
Leo Kim881eb5d2015-11-19 15:56:15 +09001998 if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001999 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
Leo Kima25d5182015-11-19 15:56:19 +09002000 if (!wilc_ie) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002001 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
Leo Kim86685942015-11-19 15:56:18 +09002002 if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002003 p2p_recv_random = buff[i + 6];
Leo Kima25d5182015-11-19 15:56:19 +09002004 wilc_ie = true;
Leo Kimb84a3ac2015-11-19 15:56:17 +09002005 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", p2p_recv_random);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002006 break;
2007 }
2008 }
2009 }
2010 }
Leo Kimb84a3ac2015-11-19 15:56:17 +09002011 if (p2p_local_random > p2p_recv_random) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002012 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2013 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2014 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
Leo Kim881eb5d2015-11-19 15:56:15 +09002015 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002016 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
2017 break;
2018 }
2019 }
2020 }
Leo Kim583d9722015-11-19 15:56:16 +09002021 } else {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002022 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 +09002023 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002024 }
2025
2026
Leo Kima25d5182015-11-19 15:56:19 +09002027 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 +09002028 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
2029 /* extra attribute for sig_dbm: signal strength in mBm, or 0 if unknown */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002030 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002031 return;
2032 }
2033 break;
2034
2035 default:
2036 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
2037 break;
2038 }
2039 }
2040 }
2041
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002042 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002043 }
2044}
2045
2046/**
2047 * @brief WILC_WFI_mgmt_tx_complete
2048 * @details Returns result of writing mgmt frame to VMM (Tx buffers are freed here)
2049 * @param[in] priv
2050 * transmitting status
2051 * @return None
2052 * @author Amr Abdelmoghny
2053 * @date 20 MAY 2013
2054 * @version 1.0
2055 */
2056static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
2057{
2058 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
2059
2060
2061 kfree(pv_data->buff);
2062 kfree(pv_data);
2063}
2064
2065/**
2066 * @brief WILC_WFI_RemainOnChannelReady
2067 * @details Callback function, called from handle_remain_on_channel on being ready on channel
2068 * @param
2069 * @return none
2070 * @author Amr abdelmoghny
2071 * @date 9 JUNE 2013
2072 * @version
2073 */
2074
2075static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
2076{
Chaehyun Lim27268872015-09-15 14:06:13 +09002077 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002078
Chaehyun Lim27268872015-09-15 14:06:13 +09002079 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002080
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302081 PRINT_D(HOSTINF_DBG, "Remain on channel ready\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002082
Dean Lee72ed4dc2015-06-12 14:11:44 +09002083 priv->bInP2PlistenState = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002084
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002085 cfg80211_ready_on_channel(priv->wdev,
2086 priv->strRemainOnChanParams.u64ListenCookie,
2087 priv->strRemainOnChanParams.pstrListenChan,
2088 priv->strRemainOnChanParams.u32ListenDuration,
2089 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002090}
2091
2092/**
2093 * @brief WILC_WFI_RemainOnChannelExpired
2094 * @details Callback function, called on expiration of remain-on-channel duration
2095 * @param
2096 * @return none
2097 * @author Amr abdelmoghny
2098 * @date 15 MAY 2013
2099 * @version
2100 */
2101
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002102static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002103{
Chaehyun Lim27268872015-09-15 14:06:13 +09002104 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002105
Chaehyun Lim27268872015-09-15 14:06:13 +09002106 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002107
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002108 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302109 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002110
Dean Lee72ed4dc2015-06-12 14:11:44 +09002111 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002112
2113 /*Inform wpas of remain-on-channel expiration*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002114 cfg80211_remain_on_channel_expired(priv->wdev,
2115 priv->strRemainOnChanParams.u64ListenCookie,
2116 priv->strRemainOnChanParams.pstrListenChan,
2117 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002118 } else {
2119 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
2120 , priv->strRemainOnChanParams.u32ListenSessionID);
2121 }
2122}
2123
2124
2125/**
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002126 * @brief remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002127 * @details Request the driver to remain awake on the specified
2128 * channel for the specified duration to complete an off-channel
2129 * operation (e.g., public action frame exchange). When the driver is
2130 * ready on the requested channel, it must indicate this with an event
2131 * notification by calling cfg80211_ready_on_channel().
2132 * @param[in]
2133 * @return int : Return 0 on Success
2134 * @author mdaftedar
2135 * @date 01 MAR 2012
2136 * @version 1.0
2137 */
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002138static int remain_on_channel(struct wiphy *wiphy,
2139 struct wireless_dev *wdev,
2140 struct ieee80211_channel *chan,
2141 unsigned int duration, u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002142{
Leo Kime6e12662015-09-16 18:36:03 +09002143 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002144 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002145
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002146 priv = wiphy_priv(wiphy);
2147
2148 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
2149
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002150
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002151 if (wdev->iftype == NL80211_IFTYPE_AP) {
2152 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
2153 return s32Error;
2154 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002155
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002156 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002157
2158 /*Setting params needed by WILC_WFI_RemainOnChannelExpired()*/
2159 priv->strRemainOnChanParams.pstrListenChan = chan;
2160 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002161 priv->strRemainOnChanParams.u32ListenDuration = duration;
2162 priv->strRemainOnChanParams.u32ListenSessionID++;
2163
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002164 s32Error = wilc_remain_on_channel(priv->hWILCWFIDrv
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002165 , priv->strRemainOnChanParams.u32ListenSessionID
2166 , duration
2167 , chan->hw_value
2168 , WILC_WFI_RemainOnChannelExpired
2169 , WILC_WFI_RemainOnChannelReady
2170 , (void *)priv);
2171
2172 return s32Error;
2173}
2174
2175/**
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002176 * @brief cancel_remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002177 * @details Cancel an on-going remain-on-channel operation.
2178 * This allows the operation to be terminated prior to timeout based on
2179 * the duration value.
2180 * @param[in] struct wiphy *wiphy,
2181 * @param[in] struct net_device *dev
2182 * @param[in] u64 cookie,
2183 * @return int : Return 0 on Success
2184 * @author mdaftedar
2185 * @date 01 MAR 2012
2186 * @version 1.0
2187 */
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002188static int cancel_remain_on_channel(struct wiphy *wiphy,
2189 struct wireless_dev *wdev,
2190 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002191{
Leo Kime6e12662015-09-16 18:36:03 +09002192 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002193 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002194
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002195 priv = wiphy_priv(wiphy);
2196
2197 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
2198
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002199 s32Error = wilc_listen_state_expired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002200 return s32Error;
2201}
2202/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002203 * @brief WILC_WFI_mgmt_tx_frame
2204 * @details
2205 *
2206 * @param[in]
2207 * @return NONE.
2208 * @author mdaftedar
2209 * @date 01 JUL 2012
2210 * @version
2211 */
Chaehyun Limc1560322015-09-22 18:34:51 +09002212static int mgmt_tx(struct wiphy *wiphy,
2213 struct wireless_dev *wdev,
2214 struct cfg80211_mgmt_tx_params *params,
2215 u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002216{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002217 struct ieee80211_channel *chan = params->chan;
2218 unsigned int wait = params->wait;
2219 const u8 *buf = params->buf;
2220 size_t len = params->len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002221 const struct ieee80211_mgmt *mgmt;
2222 struct p2p_mgmt_data *mgmt_tx;
Chaehyun Lim27268872015-09-15 14:06:13 +09002223 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002224 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002225 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002226 perInterface_wlan_t *nic;
Leo Kim86685942015-11-19 15:56:18 +09002227 u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002228
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002229 nic = netdev_priv(wdev->netdev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002230 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002231 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002232
2233 *cookie = (unsigned long)buf;
2234 priv->u64tx_cookie = *cookie;
2235 mgmt = (const struct ieee80211_mgmt *) buf;
2236
2237 if (ieee80211_is_mgmt(mgmt->frame_control)) {
2238
2239 /*mgmt frame allocation*/
Glen Leef3052582015-09-10 12:03:04 +09002240 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002241 if (mgmt_tx == NULL) {
2242 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
Leo Kime6e12662015-09-16 18:36:03 +09002243 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002244 }
Glen Leef3052582015-09-10 12:03:04 +09002245 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002246 if (mgmt_tx->buff == NULL) {
2247 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
Tony Chof638dd32015-09-07 19:09:31 +09002248 kfree(mgmt_tx);
Leo Kime6e12662015-09-16 18:36:03 +09002249 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002250 }
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09002251 memcpy(mgmt_tx->buff, buf, len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002252 mgmt_tx->size = len;
2253
2254
2255 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
2256 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
2257 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002258 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002259 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002260 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002261 } else if (ieee80211_is_action(mgmt->frame_control)) {
Chaehyun Limd85f5322015-06-11 14:35:54 +09002262 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002263
2264
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002265 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002266 /*Only set the channel, if not a negotiation confirmation frame
2267 * (If Negotiation confirmation frame, force it
2268 * to be transmitted on the same negotiation channel)*/
2269
2270 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
2271 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
2272 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002273 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002274 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002275 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002276 }
2277 switch (buf[ACTION_SUBTYPE_ID]) {
2278 case GAS_INTIAL_REQ:
2279 {
2280 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
2281 break;
2282 }
2283
2284 case GAS_INTIAL_RSP:
2285 {
2286 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
2287 break;
2288 }
2289
2290 case PUBLIC_ACT_VENDORSPEC:
2291 {
Leo Kim881eb5d2015-11-19 15:56:15 +09002292 if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002293 /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/
2294 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002295 if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
Leo Kim583d9722015-11-19 15:56:16 +09002296 get_random_bytes(&p2p_local_random, 1);
2297 p2p_local_random++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002298 }
2299 }
2300
2301 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2302 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002303 if (p2p_local_random > p2p_recv_random) {
2304 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 +09002305
2306 /*Search for the p2p information information element , after the Public action subtype theres a byte for teh dialog token, skip that*/
2307 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
Leo Kim881eb5d2015-11-19 15:56:15 +09002308 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002309 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
Dean Lee72ed4dc2015-06-12 14:11:44 +09002310 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002311
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002312 /*If using supplicant go intent, no need at all*/
2313 /*to parse transmitted negotiation frames*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002314 else
Dean Lee72ed4dc2015-06-12 14:11:44 +09002315 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002316 break;
2317 }
2318 }
2319
2320 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
Shivani Bhardwajd8060fc2015-10-29 00:30:01 +05302321 /*
2322 * Adding WILC information element to allow two WILC devices to
2323 * identify each other and connect
2324 */
Leo Kim86685942015-11-19 15:56:18 +09002325 memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
2326 mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002327 mgmt_tx->size = buf_len;
2328 }
Leo Kim583d9722015-11-19 15:56:16 +09002329 } else {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002330 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 +09002331 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002332 }
2333
2334 } else {
2335 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
2336 }
2337
2338 break;
2339 }
2340
2341 default:
2342 {
2343 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
2344 break;
2345 }
2346 }
2347
2348 }
2349
2350 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 +09002351 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002352
Leo Kim1229b1a2015-10-29 12:05:39 +09002353 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n",
2354 jiffies, pstrWFIDrv->p2p_timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002355 }
2356
Glen Lee829c4772015-10-29 12:18:44 +09002357 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
2358 mgmt_tx->buff, mgmt_tx->size,
Glen Leec9d48342015-10-01 16:03:43 +09002359 WILC_WFI_mgmt_tx_complete);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002360 } else {
2361 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
2362 }
Leo Kimaaed3292015-10-12 16:55:38 +09002363 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002364}
2365
Chaehyun Lim85c587a2015-09-22 18:34:50 +09002366static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
2367 struct wireless_dev *wdev,
2368 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002369{
Chaehyun Lim27268872015-09-15 14:06:13 +09002370 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002371 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002372
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002373 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002374 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002375
2376
2377 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
Leo Kim1229b1a2015-10-29 12:05:39 +09002378 pstrWFIDrv->p2p_timeout = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002379
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +01002380 if (!priv->bInP2PlistenState) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002381 cfg80211_remain_on_channel_expired(priv->wdev,
2382 priv->strRemainOnChanParams.u64ListenCookie,
2383 priv->strRemainOnChanParams.pstrListenChan,
2384 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002385 }
2386
2387 return 0;
2388}
2389
2390/**
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002391 * @brief wilc_mgmt_frame_register
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002392 * @details Notify driver that a management frame type was
2393 * registered. Note that this callback may not sleep, and cannot run
2394 * concurrently with itself.
2395 * @param[in]
2396 * @return NONE.
2397 * @author mdaftedar
2398 * @date 01 JUL 2012
2399 * @version
2400 */
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002401void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
2402 u16 frame_type, bool reg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002403{
2404
Chaehyun Lim27268872015-09-15 14:06:13 +09002405 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002406 perInterface_wlan_t *nic;
Glen Lee1b869352015-10-20 17:14:01 +09002407 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002408
2409 priv = wiphy_priv(wiphy);
2410 nic = netdev_priv(priv->wdev->netdev);
Glen Lee1b869352015-10-20 17:14:01 +09002411 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002412
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002413 if (!frame_type)
2414 return;
2415
2416 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
2417 switch (frame_type) {
2418 case PROBE_REQ:
2419 {
2420 nic->g_struct_frame_reg[0].frame_type = frame_type;
2421 nic->g_struct_frame_reg[0].reg = reg;
2422 }
2423 break;
2424
2425 case ACTION:
2426 {
2427 nic->g_struct_frame_reg[1].frame_type = frame_type;
2428 nic->g_struct_frame_reg[1].reg = reg;
2429 }
2430 break;
2431
2432 default:
2433 {
2434 break;
2435 }
2436
2437 }
2438 /*If mac is closed, then return*/
Glen Lee1b869352015-10-20 17:14:01 +09002439 if (!wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002440 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
2441 return;
2442 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002443 wilc_frame_register(priv->hWILCWFIDrv, frame_type, reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002444
2445
2446}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002447
2448/**
Chaehyun Lima8047e22015-09-22 18:34:48 +09002449 * @brief set_cqm_rssi_config
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002450 * @details Configure connection quality monitor RSSI threshold.
2451 * @param[in] struct wiphy *wiphy:
2452 * @param[in] struct net_device *dev:
2453 * @param[in] s32 rssi_thold:
2454 * @param[in] u32 rssi_hyst:
2455 * @return int : Return 0 on Success
2456 * @author mdaftedar
2457 * @date 01 MAR 2012
2458 * @version 1.0
2459 */
Chaehyun Lima8047e22015-09-22 18:34:48 +09002460static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
2461 s32 rssi_thold, u32 rssi_hyst)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002462{
2463 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2464 return 0;
2465
2466}
2467/**
Chaehyun Limbdb63382015-09-14 12:24:19 +09002468 * @brief dump_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002469 * @details Configure connection quality monitor RSSI threshold.
2470 * @param[in] struct wiphy *wiphy:
2471 * @param[in] struct net_device *dev
2472 * @param[in] int idx
2473 * @param[in] u8 *mac
2474 * @param[in] struct station_info *sinfo
2475 * @return int : Return 0 on Success
2476 * @author mdaftedar
2477 * @date 01 MAR 2012
2478 * @version 1.0
2479 */
Chaehyun Limbdb63382015-09-14 12:24:19 +09002480static int dump_station(struct wiphy *wiphy, struct net_device *dev,
2481 int idx, u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002482{
Chaehyun Lim27268872015-09-15 14:06:13 +09002483 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002484
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002485 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2486
2487 if (idx != 0)
2488 return -ENOENT;
2489
2490 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002491
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002492 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002493
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002494 wilc_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002495
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002496 return 0;
2497
2498}
2499
2500
2501/**
Chaehyun Lim46530672015-09-22 18:34:46 +09002502 * @brief set_power_mgmt
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002503 * @details
2504 * @param[in]
2505 * @return int : Return 0 on Success.
2506 * @author mdaftedar
2507 * @date 01 JUL 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09002508 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002509 */
Chaehyun Lim46530672015-09-22 18:34:46 +09002510static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2511 bool enabled, int timeout)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002512{
Chaehyun Lim27268872015-09-15 14:06:13 +09002513 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002514
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002515 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2516
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002517 if (wiphy == NULL)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002518 return -ENOENT;
2519
2520 priv = wiphy_priv(wiphy);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002521 if (priv->hWILCWFIDrv == NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002522 PRINT_ER("Driver is NULL\n");
2523 return -EIO;
2524 }
2525
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002526 if (wilc_enable_ps)
2527 wilc_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002528
2529
Leo Kime6e12662015-09-16 18:36:03 +09002530 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002531
2532}
Glen Lee108b3432015-09-16 18:53:20 +09002533
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002534/**
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002535 * @brief change_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002536 * @details Change type/configuration of virtual interface,
2537 * keep the struct wireless_dev's iftype updated.
2538 * @param[in] NONE
2539 * @return int : Return 0 on Success.
2540 * @author mdaftedar
2541 * @date 01 MAR 2012
2542 * @version 1.0
2543 */
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002544static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2545 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002546{
Chaehyun Lim27268872015-09-15 14:06:13 +09002547 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002548 perInterface_wlan_t *nic;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002549 u8 interface_type;
Chaehyun Limd85f5322015-06-11 14:35:54 +09002550 u16 TID = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002551 u8 i;
Glen Lee299382c2015-10-20 17:13:56 +09002552 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002553
2554 nic = netdev_priv(dev);
2555 priv = wiphy_priv(wiphy);
Glen Lee299382c2015-10-20 17:13:56 +09002556 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002557
2558 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2559 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
Leo Kim583d9722015-11-19 15:56:16 +09002560 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +09002561 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +09002562 wilc_ie = false;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002563 wilc_optaining_ip = false;
2564 del_timer(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002565 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002566 /*Set WILC_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/
2567 if (g_ptk_keys_saved && g_gtk_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002568 wilc_set_machw_change_vir_if(dev, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002569 }
2570
2571 switch (type) {
2572 case NL80211_IFTYPE_STATION:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002573 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002574 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002575
2576 /* send delba over wlan interface */
2577
2578
2579 dev->ieee80211_ptr->iftype = type;
2580 priv->wdev->iftype = type;
2581 nic->monitor_flag = 0;
2582 nic->iftype = STATION_MODE;
2583
2584 /*Remove the enteries of the previously connected clients*/
2585 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002586 interface_type = nic->iftype;
2587 nic->iftype = STATION_MODE;
2588
Glen Lee299382c2015-10-20 17:13:56 +09002589 if (wl->initialized) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002590 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2591 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002592 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002593 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002594
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002595 /*Eliminate host interface blocking state*/
Glen Lee299382c2015-10-20 17:13:56 +09002596 up(&wl->cfg_event);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002597
Glen Lee53dc0cf2015-10-20 17:13:57 +09002598 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002599 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002600 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002601 nic->iftype = interface_type;
2602
2603 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002604 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2605 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002606 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002607 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002608
2609 /*Add saved WEP keys, if any*/
2610 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002611 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002612 g_key_wep_params.key_idx);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002613 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002614 g_key_wep_params.key,
2615 g_key_wep_params.key_len,
2616 g_key_wep_params.key_idx);
2617 }
2618
2619 /*No matter the driver handler passed here, it will be overwriiten*/
2620 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002621 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002622
2623 /*Add saved PTK and GTK keys, if any*/
2624 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2625 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2626 g_key_ptk_params.key[1],
2627 g_key_ptk_params.key[2]);
2628 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2629 g_key_gtk_params.key[1],
2630 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002631 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2632 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002633 g_add_ptk_key_params.key_idx,
2634 g_add_ptk_key_params.pairwise,
2635 g_add_ptk_key_params.mac_addr,
2636 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002637
Glen Lee299382c2015-10-20 17:13:56 +09002638 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2639 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002640 g_add_gtk_key_params.key_idx,
2641 g_add_gtk_key_params.pairwise,
2642 g_add_gtk_key_params.mac_addr,
2643 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002644 }
2645
Glen Lee299382c2015-10-20 17:13:56 +09002646 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002647 for (i = 0; i < num_reg_frame; i++) {
2648 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2649 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002650 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002651 nic->g_struct_frame_reg[i].frame_type,
2652 nic->g_struct_frame_reg[i].reg);
2653 }
2654 }
2655
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002656 wilc_enable_ps = true;
2657 wilc_set_power_mgmt(priv->hWILCWFIDrv, 1, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002658 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002659 break;
2660
2661 case NL80211_IFTYPE_P2P_CLIENT:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002662 wilc_enable_ps = false;
2663 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
2664 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002665 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002666
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002667 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2668 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002669
2670 dev->ieee80211_ptr->iftype = type;
2671 priv->wdev->iftype = type;
2672 nic->monitor_flag = 0;
2673
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002674 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2675 nic->iftype = CLIENT_MODE;
2676
2677
Glen Lee299382c2015-10-20 17:13:56 +09002678 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002679 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002680 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002681
Glen Lee53dc0cf2015-10-20 17:13:57 +09002682 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002683 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002684 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002685
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002686 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2687 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002688 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002689 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002690
2691 /*Add saved WEP keys, if any*/
2692 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002693 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2694 g_key_wep_params.key_idx);
2695 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
2696 g_key_wep_params.key,
2697 g_key_wep_params.key_len,
2698 g_key_wep_params.key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002699 }
2700
2701 /*No matter the driver handler passed here, it will be overwriiten*/
2702 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002703 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002704
2705 /*Add saved PTK and GTK keys, if any*/
2706 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2707 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2708 g_key_ptk_params.key[1],
2709 g_key_ptk_params.key[2]);
2710 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2711 g_key_gtk_params.key[1],
2712 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002713 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2714 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002715 g_add_ptk_key_params.key_idx,
2716 g_add_ptk_key_params.pairwise,
2717 g_add_ptk_key_params.mac_addr,
2718 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002719
Glen Lee299382c2015-10-20 17:13:56 +09002720 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2721 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002722 g_add_gtk_key_params.key_idx,
2723 g_add_gtk_key_params.pairwise,
2724 g_add_gtk_key_params.mac_addr,
2725 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002726 }
2727
2728 /*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 +09002729 refresh_scan(priv, 1, true);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002730 wilc_set_machw_change_vir_if(dev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002731
Glen Lee299382c2015-10-20 17:13:56 +09002732 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002733 for (i = 0; i < num_reg_frame; i++) {
2734 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2735 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002736 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002737 nic->g_struct_frame_reg[i].frame_type,
2738 nic->g_struct_frame_reg[i].reg);
2739 }
2740 }
2741 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002742 break;
2743
2744 case NL80211_IFTYPE_AP:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002745 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002746 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002747 dev->ieee80211_ptr->iftype = type;
2748 priv->wdev->iftype = type;
2749 nic->iftype = AP_MODE;
Johnny Kim8a143302015-06-10 17:06:46 +09002750 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002751
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002752 PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002753 wilc_wlan_get_firmware(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002754 /*If wilc is running, then close-open to actually get new firmware running (serves P2P)*/
Glen Lee299382c2015-10-20 17:13:56 +09002755 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002756 nic->iftype = AP_MODE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002757 wilc_mac_close(dev);
2758 wilc_mac_open(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002759
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002760 for (i = 0; i < num_reg_frame; i++) {
2761 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2762 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002763 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002764 nic->g_struct_frame_reg[i].frame_type,
2765 nic->g_struct_frame_reg[i].reg);
2766 }
2767 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002768 break;
2769
2770 case NL80211_IFTYPE_P2P_GO:
2771 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
2772
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002773 wilc_optaining_ip = true;
Leo Kim7e872df2015-11-19 15:56:20 +09002774 mod_timer(&wilc_during_ip_timer,
2775 jiffies + msecs_to_jiffies(during_ip_time));
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002776 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002777 /*Delete block ack has to be the latest config packet*/
2778 /*sent before downloading new FW. This is because it blocks on*/
2779 /*hWaitResponse semaphore, which allows previous config*/
2780 /*packets to actually take action on old FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002781 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2782 wl->vif[0].bssid, TID);
2783 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002784 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002785 dev->ieee80211_ptr->iftype = type;
2786 priv->wdev->iftype = type;
2787
Johnny Kim8a143302015-06-10 17:06:46 +09002788 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002789
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002790 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2791
2792
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002793 nic->iftype = GO_MODE;
2794
2795 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002796 wilc_wait_msg_queue_idle();
Glen Lee53dc0cf2015-10-20 17:13:57 +09002797 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002798 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002799 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002800
2801
2802 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002803 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2804 wilc_set_mac_address(wl->vif[0].hif_drv,
2805 wl->vif[0].src_addr);
2806 wilc_set_operation_mode(priv->hWILCWFIDrv, AP_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002807
2808 /*Add saved WEP keys, if any*/
2809 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002810 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2811 g_key_wep_params.key_idx);
2812 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002813 g_key_wep_params.key,
2814 g_key_wep_params.key_len,
2815 g_key_wep_params.key_idx);
2816 }
2817
2818 /*No matter the driver handler passed here, it will be overwriiten*/
2819 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002820 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002821
2822 /*Add saved PTK and GTK keys, if any*/
2823 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2824 PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0],
2825 g_key_ptk_params.key[1],
2826 g_key_ptk_params.key[2],
2827 g_key_ptk_params.cipher);
2828 PRINT_D(CFG80211_DBG, "gtk %x %x %x cipher %x\n", g_key_gtk_params.key[0],
2829 g_key_gtk_params.key[1],
2830 g_key_gtk_params.key[2],
2831 g_key_gtk_params.cipher);
Glen Lee299382c2015-10-20 17:13:56 +09002832 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2833 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002834 g_add_ptk_key_params.key_idx,
2835 g_add_ptk_key_params.pairwise,
2836 g_add_ptk_key_params.mac_addr,
2837 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002838
Glen Lee299382c2015-10-20 17:13:56 +09002839 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2840 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002841 g_add_gtk_key_params.key_idx,
2842 g_add_gtk_key_params.pairwise,
2843 g_add_gtk_key_params.mac_addr,
2844 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002845 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002846
Glen Lee299382c2015-10-20 17:13:56 +09002847 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002848 for (i = 0; i < num_reg_frame; i++) {
2849 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2850 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002851 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002852 nic->g_struct_frame_reg[i].frame_type,
2853 nic->g_struct_frame_reg[i].reg);
2854 }
2855 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002856 break;
2857
2858 default:
2859 PRINT_ER("Unknown interface type= %d\n", type);
Leo Kimaaed3292015-10-12 16:55:38 +09002860 return -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002861 }
2862
Leo Kimaaed3292015-10-12 16:55:38 +09002863 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002864}
2865
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002866/* (austin.2013-07-23)
2867 *
2868 * To support revised cfg80211_ops
2869 *
2870 * add_beacon --> start_ap
2871 * set_beacon --> change_beacon
2872 * del_beacon --> stop_ap
2873 *
2874 * beacon_parameters --> cfg80211_ap_settings
2875 * cfg80211_beacon_data
2876 *
2877 * applicable for linux kernel 3.4+
2878 */
2879
2880/**
Chaehyun Lima13168d2015-09-14 12:24:12 +09002881 * @brief start_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002882 * @details Add a beacon with given parameters, @head, @interval
2883 * and @dtim_period will be valid, @tail is optional.
2884 * @param[in] wiphy
2885 * @param[in] dev The net device structure
2886 * @param[in] settings cfg80211_ap_settings parameters for the beacon to be added
2887 * @return int : Return 0 on Success.
2888 * @author austin
2889 * @date 23 JUL 2013
2890 * @version 1.0
2891 */
Chaehyun Lima13168d2015-09-14 12:24:12 +09002892static int start_ap(struct wiphy *wiphy, struct net_device *dev,
2893 struct cfg80211_ap_settings *settings)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002894{
2895 struct cfg80211_beacon_data *beacon = &(settings->beacon);
Chaehyun Lim27268872015-09-15 14:06:13 +09002896 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002897 s32 s32Error = 0;
Glen Lee684dc182015-10-20 17:14:02 +09002898 struct wilc *wl;
2899 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002900
2901 priv = wiphy_priv(wiphy);
Glen Lee684dc182015-10-20 17:14:02 +09002902 nic = netdev_priv(dev);
2903 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002904 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
2905
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302906 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 +09002907 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
2908
Chaehyun Lim80785a92015-09-14 12:24:01 +09002909 s32Error = set_channel(wiphy, &settings->chandef);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002910
Leo Kime6e12662015-09-16 18:36:03 +09002911 if (s32Error != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002912 PRINT_ER("Error in setting channel\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002913
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002914 wilc_wlan_set_bssid(dev, wl->vif[0].src_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002915
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002916 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002917 settings->beacon_interval,
2918 settings->dtim_period,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002919 beacon->head_len, (u8 *)beacon->head,
2920 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002921
2922 return s32Error;
2923}
2924
2925/**
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002926 * @brief change_beacon
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002927 * @details Add a beacon with given parameters, @head, @interval
2928 * and @dtim_period will be valid, @tail is optional.
2929 * @param[in] wiphy
2930 * @param[in] dev The net device structure
2931 * @param[in] beacon cfg80211_beacon_data for the beacon to be changed
2932 * @return int : Return 0 on Success.
2933 * @author austin
2934 * @date 23 JUL 2013
2935 * @version 1.0
2936 */
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002937static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
2938 struct cfg80211_beacon_data *beacon)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002939{
Chaehyun Lim27268872015-09-15 14:06:13 +09002940 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002941 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002942
2943 priv = wiphy_priv(wiphy);
2944 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
2945
2946
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002947 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002948 0,
2949 0,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002950 beacon->head_len, (u8 *)beacon->head,
2951 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002952
2953 return s32Error;
2954}
2955
2956/**
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002957 * @brief stop_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002958 * @details Remove beacon configuration and stop sending the beacon.
2959 * @param[in]
2960 * @return int : Return 0 on Success.
2961 * @author austin
2962 * @date 23 JUL 2013
2963 * @version 1.0
2964 */
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002965static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002966{
Leo Kime6e12662015-09-16 18:36:03 +09002967 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002968 struct wilc_priv *priv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002969 u8 NullBssid[ETH_ALEN] = {0};
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002970
Leo Kim7ae43362015-09-16 18:35:59 +09002971 if (!wiphy)
2972 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002973
2974 priv = wiphy_priv(wiphy);
2975
2976 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
2977
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002978 wilc_wlan_set_bssid(dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002979
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002980 s32Error = wilc_del_beacon(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002981
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002982 if (s32Error)
2983 PRINT_ER("Host delete beacon fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002984
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002985 return s32Error;
2986}
2987
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002988/**
Chaehyun Limed269552015-09-14 12:24:15 +09002989 * @brief add_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002990 * @details Add a new station.
2991 * @param[in]
2992 * @return int : Return 0 on Success.
2993 * @author mdaftedar
2994 * @date 01 MAR 2012
2995 * @version 1.0
2996 */
Chaehyun Limed269552015-09-14 12:24:15 +09002997static int add_station(struct wiphy *wiphy, struct net_device *dev,
2998 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002999{
Leo Kime6e12662015-09-16 18:36:03 +09003000 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003001 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09003002 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003003 perInterface_wlan_t *nic;
3004
Leo Kim7ae43362015-09-16 18:35:59 +09003005 if (!wiphy)
3006 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003007
3008 priv = wiphy_priv(wiphy);
3009 nic = netdev_priv(dev);
3010
3011 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003012 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09003013 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003014 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003015 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003016 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003017
3018 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
3019
3020 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],
3021 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003022 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003023 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3024 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003025
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003026 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003027 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003028 } else {
Leo Kim22520122015-10-29 12:05:45 +09003029 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003030 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003031 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003032 memcpy(strStaParams.ht_supp_mcs_set,
3033 &params->ht_capa->mcs,
3034 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003035 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003036 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003037 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003038 }
3039
Leo Kimf676e172015-10-29 12:05:52 +09003040 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003041 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003042
Leo Kim22520122015-10-29 12:05:45 +09003043 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3044 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003045 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3046 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003047 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3048 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003049 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3050 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003051 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3052 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003053 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3054 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003055 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3056 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003057 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3058 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003059
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003060 s32Error = wilc_add_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003061 if (s32Error)
3062 PRINT_ER("Host add station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003063 }
3064
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003065 return s32Error;
3066}
3067
3068/**
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003069 * @brief del_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003070 * @details Remove a station; @mac may be NULL to remove all stations.
3071 * @param[in]
3072 * @return int : Return 0 on Success.
3073 * @author mdaftedar
3074 * @date 01 MAR 2012
3075 * @version 1.0
3076 */
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003077static int del_station(struct wiphy *wiphy, struct net_device *dev,
3078 struct station_del_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003079{
Arnd Bergmann057d1e92015-06-01 21:06:44 +02003080 const u8 *mac = params->mac;
Leo Kime6e12662015-09-16 18:36:03 +09003081 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003082 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003083 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003084
Leo Kim7ae43362015-09-16 18:35:59 +09003085 if (!wiphy)
3086 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003087
3088 priv = wiphy_priv(wiphy);
3089 nic = netdev_priv(dev);
3090
3091 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
3092 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
3093
3094
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003095 if (mac == NULL) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05303096 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003097 s32Error = wilc_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003098 } else {
3099 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]);
3100 }
3101
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003102 s32Error = wilc_del_station(priv->hWILCWFIDrv, mac);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003103
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003104 if (s32Error)
3105 PRINT_ER("Host delete station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003106 }
3107 return s32Error;
3108}
3109
3110/**
Chaehyun Lim14b42082015-09-14 12:24:17 +09003111 * @brief change_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003112 * @details Modify a given station.
3113 * @param[in]
3114 * @return int : Return 0 on Success.
3115 * @author mdaftedar
3116 * @date 01 MAR 2012
3117 * @version 1.0
3118 */
Chaehyun Lim14b42082015-09-14 12:24:17 +09003119static int change_station(struct wiphy *wiphy, struct net_device *dev,
3120 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003121{
Leo Kime6e12662015-09-16 18:36:03 +09003122 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003123 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09003124 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003125 perInterface_wlan_t *nic;
3126
3127
3128 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
3129
Leo Kim7ae43362015-09-16 18:35:59 +09003130 if (!wiphy)
3131 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003132
3133 priv = wiphy_priv(wiphy);
3134 nic = netdev_priv(dev);
3135
3136 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003137 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003138 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003139 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003140 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003141
Leo Kim2353c382015-10-29 12:05:41 +09003142 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n",
3143 strStaParams.bssid[0], strStaParams.bssid[1],
3144 strStaParams.bssid[2], strStaParams.bssid[3],
3145 strStaParams.bssid[4], strStaParams.bssid[5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003146 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003147 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3148 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003149
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003150 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003151 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003152 } else {
Leo Kim22520122015-10-29 12:05:45 +09003153 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003154 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003155 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003156 memcpy(strStaParams.ht_supp_mcs_set,
3157 &params->ht_capa->mcs,
3158 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003159 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003160 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003161 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003162 }
3163
Leo Kimf676e172015-10-29 12:05:52 +09003164 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003165 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003166
Leo Kim22520122015-10-29 12:05:45 +09003167 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3168 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003169 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3170 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003171 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3172 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003173 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3174 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003175 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3176 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003177 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3178 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003179 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3180 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003181 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3182 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003183
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003184 s32Error = wilc_edit_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003185 if (s32Error)
3186 PRINT_ER("Host edit station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003187 }
3188 return s32Error;
3189}
3190
3191
3192/**
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003193 * @brief add_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003194 * @details
3195 * @param[in]
3196 * @return int : Return 0 on Success.
3197 * @author mdaftedar
3198 * @date 01 JUL 2012
3199 * @version 1.0
3200 */
Chaehyun Lim37316e82015-09-22 18:34:52 +09003201static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
3202 const char *name,
3203 unsigned char name_assign_type,
3204 enum nl80211_iftype type,
3205 u32 *flags,
3206 struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003207{
3208 perInterface_wlan_t *nic;
Chaehyun Lim27268872015-09-15 14:06:13 +09003209 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003210 struct net_device *new_ifc = NULL;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003211
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003212 priv = wiphy_priv(wiphy);
3213
3214
3215
3216 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
3217
3218 nic = netdev_priv(priv->wdev->netdev);
3219
3220
3221 if (type == NL80211_IFTYPE_MONITOR) {
3222 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
3223 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", nic->wilc_netdev);
3224 new_ifc = WILC_WFI_init_mon_interface(name, nic->wilc_netdev);
3225 if (new_ifc != NULL) {
3226 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003227 nic = netdev_priv(priv->wdev->netdev);
3228 nic->monitor_flag = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003229 } else
3230 PRINT_ER("Error in initializing monitor interface\n ");
3231 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003232 return priv->wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003233}
3234
3235/**
Chaehyun Limb4a73352015-09-14 12:24:10 +09003236 * @brief del_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003237 * @details
3238 * @param[in]
3239 * @return int : Return 0 on Success.
3240 * @author mdaftedar
3241 * @date 01 JUL 2012
3242 * @version 1.0
3243 */
Chaehyun Lim956d7212015-09-22 18:34:49 +09003244static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003245{
3246 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
Leo Kime6e12662015-09-16 18:36:03 +09003247 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003248}
3249
Chaehyun Lim08241922015-09-15 14:06:12 +09003250static struct cfg80211_ops wilc_cfg80211_ops = {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003251
Chaehyun Lim80785a92015-09-14 12:24:01 +09003252 .set_monitor_channel = set_channel,
Chaehyun Lim0e30d062015-09-14 12:24:02 +09003253 .scan = scan,
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +09003254 .connect = connect,
Chaehyun Limb027cde2015-09-14 12:24:04 +09003255 .disconnect = disconnect,
Chaehyun Lim953d4172015-09-14 12:24:05 +09003256 .add_key = add_key,
Chaehyun Lim3044ba72015-09-14 12:24:06 +09003257 .del_key = del_key,
Chaehyun Limf4893df2015-09-14 12:24:07 +09003258 .get_key = get_key,
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09003259 .set_default_key = set_default_key,
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003260 .add_virtual_intf = add_virtual_intf,
Chaehyun Limb4a73352015-09-14 12:24:10 +09003261 .del_virtual_intf = del_virtual_intf,
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09003262 .change_virtual_intf = change_virtual_intf,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003263
Chaehyun Lima13168d2015-09-14 12:24:12 +09003264 .start_ap = start_ap,
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09003265 .change_beacon = change_beacon,
Chaehyun Limc8cddd72015-09-14 12:24:14 +09003266 .stop_ap = stop_ap,
Chaehyun Limed269552015-09-14 12:24:15 +09003267 .add_station = add_station,
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003268 .del_station = del_station,
Chaehyun Lim14b42082015-09-14 12:24:17 +09003269 .change_station = change_station,
Chaehyun Limf06f5622015-09-14 12:24:18 +09003270 .get_station = get_station,
Chaehyun Limbdb63382015-09-14 12:24:19 +09003271 .dump_station = dump_station,
Chaehyun Lima5f7db62015-09-14 12:24:20 +09003272 .change_bss = change_bss,
Chaehyun Lima76b63e2015-09-14 12:24:21 +09003273 .set_wiphy_params = set_wiphy_params,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003274
Chaehyun Lim4d466572015-09-14 12:24:22 +09003275 .set_pmksa = set_pmksa,
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09003276 .del_pmksa = del_pmksa,
Chaehyun Limb33c39b2015-09-14 12:24:24 +09003277 .flush_pmksa = flush_pmksa,
Chaehyun Lim6d19d692015-09-14 12:24:25 +09003278 .remain_on_channel = remain_on_channel,
Chaehyun Lim1dd54402015-09-14 12:24:26 +09003279 .cancel_remain_on_channel = cancel_remain_on_channel,
Chaehyun Lim4a2f9b32015-09-14 12:24:27 +09003280 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
Chaehyun Lim12a26a32015-09-14 12:24:28 +09003281 .mgmt_tx = mgmt_tx,
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09003282 .mgmt_frame_register = wilc_mgmt_frame_register,
Chaehyun Lim46530672015-09-22 18:34:46 +09003283 .set_power_mgmt = set_power_mgmt,
Chaehyun Lima8047e22015-09-22 18:34:48 +09003284 .set_cqm_rssi_config = set_cqm_rssi_config,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003285
3286};
3287
3288
3289
3290
3291
3292/**
3293 * @brief WILC_WFI_update_stats
3294 * @details Modify parameters for a given BSS.
3295 * @param[in]
3296 * @return int : Return 0 on Success.
3297 * @author mdaftedar
3298 * @date 01 MAR 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09003299 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003300 */
3301int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
3302{
3303
Chaehyun Lim27268872015-09-15 14:06:13 +09003304 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003305
3306 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003307 switch (changed) {
3308
3309 case WILC_WFI_RX_PKT:
3310 {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003311 priv->netstats.rx_packets++;
3312 priv->netstats.rx_bytes += pktlen;
3313 priv->netstats.rx_time = get_jiffies_64();
3314 }
3315 break;
3316
3317 case WILC_WFI_TX_PKT:
3318 {
3319 priv->netstats.tx_packets++;
3320 priv->netstats.tx_bytes += pktlen;
3321 priv->netstats.tx_time = get_jiffies_64();
3322
3323 }
3324 break;
3325
3326 default:
3327 break;
3328 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003329 return 0;
3330}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003331
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003332/**
3333 * @brief WILC_WFI_CfgAlloc
3334 * @details Allocation of the wireless device structure and assigning it
3335 * to the cfg80211 operations structure.
3336 * @param[in] NONE
3337 * @return wireless_dev : Returns pointer to wireless_dev structure.
3338 * @author mdaftedar
3339 * @date 01 MAR 2012
3340 * @version 1.0
3341 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01003342static struct wireless_dev *WILC_WFI_CfgAlloc(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003343{
3344
3345 struct wireless_dev *wdev;
3346
3347
3348 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
3349 /*Allocating the wireless device structure*/
3350 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
3351 if (!wdev) {
3352 PRINT_ER("Cannot allocate wireless device\n");
3353 goto _fail_;
3354 }
3355
3356 /*Creating a new wiphy, linking wireless structure with the wiphy structure*/
Chaehyun Lim27268872015-09-15 14:06:13 +09003357 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003358 if (!wdev->wiphy) {
3359 PRINT_ER("Cannot allocate wiphy\n");
3360 goto _fail_mem_;
3361
3362 }
3363
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003364 /* enable 802.11n HT */
3365 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
3366 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
3367 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3368 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
3369 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003370
3371 /*wiphy bands*/
3372 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
3373
3374 return wdev;
3375
3376_fail_mem_:
3377 kfree(wdev);
3378_fail_:
3379 return NULL;
3380
3381}
3382/**
Chaehyun Lim8459fd52015-09-20 15:51:09 +09003383 * @brief wilc_create_wiphy
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003384 * @details Registering of the wiphy structure and interface modes
3385 * @param[in] NONE
3386 * @return NONE
3387 * @author mdaftedar
3388 * @date 01 MAR 2012
3389 * @version 1.0
3390 */
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01003391struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003392{
Chaehyun Lim27268872015-09-15 14:06:13 +09003393 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003394 struct wireless_dev *wdev;
Leo Kime6e12662015-09-16 18:36:03 +09003395 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003396
3397 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
3398
3399 wdev = WILC_WFI_CfgAlloc();
3400 if (wdev == NULL) {
3401 PRINT_ER("CfgAlloc Failed\n");
3402 return NULL;
3403 }
3404
3405
3406 /*Return hardware description structure (wiphy)'s priv*/
3407 priv = wdev_priv(wdev);
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003408 sema_init(&(priv->SemHandleUpdateStats), 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003409
3410 /*Link the wiphy with wireless structure*/
3411 priv->wdev = wdev;
3412
3413 /*Maximum number of probed ssid to be added by user for the scan request*/
3414 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003415 /*Maximum number of pmkids to be cashed*/
3416 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
3417 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003418
3419 wdev->wiphy->max_scan_ie_len = 1000;
3420
3421 /*signal strength in mBm (100*dBm) */
3422 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3423
3424 /*Set the availaible cipher suites*/
3425 wdev->wiphy->cipher_suites = cipher_suites;
3426 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003427 /*Setting default managment types: for register action frame: */
3428 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003429
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003430 wdev->wiphy->max_remain_on_channel_duration = 500;
3431 /*Setting the wiphy interfcae mode and type before registering the wiphy*/
3432 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
3433 BIT(NL80211_IFTYPE_P2P_CLIENT);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003434 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003435 wdev->iftype = NL80211_IFTYPE_STATION;
3436
3437
3438
3439 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
3440 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
3441 wdev->wiphy->interface_modes, wdev->iftype);
3442
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01003443 set_wiphy_dev(wdev->wiphy, dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003444
3445 /*Register wiphy structure*/
3446 s32Error = wiphy_register(wdev->wiphy);
3447 if (s32Error) {
3448 PRINT_ER("Cannot register wiphy device\n");
3449 /*should define what action to be taken in such failure*/
3450 } else {
3451 PRINT_D(CFG80211_DBG, "Successful Registering\n");
3452 }
3453
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003454 priv->dev = net;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003455 return wdev;
3456
3457
3458}
3459/**
3460 * @brief WILC_WFI_WiphyFree
3461 * @details Freeing allocation of the wireless device structure
3462 * @param[in] NONE
3463 * @return NONE
3464 * @author mdaftedar
3465 * @date 01 MAR 2012
3466 * @version 1.0
3467 */
Chaehyun Limdd4b6a82015-09-20 15:51:25 +09003468int wilc_init_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003469{
3470
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003471 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003472
Chaehyun Lim27268872015-09-15 14:06:13 +09003473 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003474
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003475 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
3476 priv = wdev_priv(net->ieee80211_ptr);
3477 if (op_ifcs == 0) {
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -07003478 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003479 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003480 }
3481 op_ifcs++;
3482 if (s32Error < 0) {
3483 PRINT_ER("Failed to creat refresh Timer\n");
3484 return s32Error;
3485 }
3486
Dean Lee72ed4dc2015-06-12 14:11:44 +09003487 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003488
Dean Lee72ed4dc2015-06-12 14:11:44 +09003489 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003490
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003491 sema_init(&(priv->hSemScanReq), 1);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003492 s32Error = wilc_init(net, &priv->hWILCWFIDrv);
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003493 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003494 PRINT_ER("Error while initializing hostinterface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003495
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003496 return s32Error;
3497}
3498
3499/**
3500 * @brief WILC_WFI_WiphyFree
3501 * @details Freeing allocation of the wireless device structure
3502 * @param[in] NONE
3503 * @return NONE
3504 * @author mdaftedar
3505 * @date 01 MAR 2012
3506 * @version 1.0
3507 */
Chaehyun Lima9a16822015-09-20 15:51:24 +09003508int wilc_deinit_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003509{
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003510 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003511
Chaehyun Lim27268872015-09-15 14:06:13 +09003512 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003513
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003514 priv = wdev_priv(net->ieee80211_ptr);
3515
Dean Lee72ed4dc2015-06-12 14:11:44 +09003516 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003517
Dean Lee72ed4dc2015-06-12 14:11:44 +09003518 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003519
3520 op_ifcs--;
3521
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003522 s32Error = wilc_deinit(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003523
3524 /* Clear the Shadow scan */
Leo Kimd14991a2015-11-19 15:56:22 +09003525 clear_shadow_scan();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003526 if (op_ifcs == 0) {
3527 PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003528 del_timer_sync(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003529 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003530
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003531 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003532 PRINT_ER("Error while deintializing host interface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003533
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003534 return s32Error;
3535}
3536
3537
3538/**
3539 * @brief WILC_WFI_WiphyFree
3540 * @details Freeing allocation of the wireless device structure
3541 * @param[in] NONE
3542 * @return NONE
3543 * @author mdaftedar
3544 * @date 01 MAR 2012
3545 * @version 1.0
3546 */
Chaehyun Lim96da20a2015-09-20 15:51:08 +09003547void wilc_free_wiphy(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003548{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003549 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
3550
Chaehyun Lim619837a2015-09-20 15:51:10 +09003551 if (!net) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003552 PRINT_D(INIT_DBG, "net_device is NULL\n");
3553 return;
3554 }
3555
Chaehyun Lim619837a2015-09-20 15:51:10 +09003556 if (!net->ieee80211_ptr) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003557 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
3558 return;
3559 }
3560
Chaehyun Lim619837a2015-09-20 15:51:10 +09003561 if (!net->ieee80211_ptr->wiphy) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003562 PRINT_D(INIT_DBG, "wiphy is NULL\n");
3563 return;
3564 }
3565
3566 wiphy_unregister(net->ieee80211_ptr->wiphy);
3567
3568 PRINT_D(INIT_DBG, "Freeing wiphy\n");
3569 wiphy_free(net->ieee80211_ptr->wiphy);
3570 kfree(net->ieee80211_ptr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003571}