blob: 5a9d0e23dffcfc02a21584c5938ebcb1dfce5bd4 [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
Arnd Bergmann1608c402015-11-16 15:04:53 +0100357static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900358{
Chaehyun Lima74cc6b2015-10-02 16:41:17 +0900359 int ap_found = is_network_in_shadow(pstrNetworkInfo, pUserVoid);
Chaehyun Limfbc2fe12015-09-15 14:06:16 +0900360 u32 ap_index = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900361 u8 rssi_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900362
Leo Kim771fbae2015-11-19 15:56:10 +0900363 if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900364 PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
365 return;
366 }
367 if (ap_found == -1) {
Leo Kim771fbae2015-11-19 15:56:10 +0900368 ap_index = last_scanned_cnt;
369 last_scanned_cnt++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900370
371 } else {
372 ap_index = ap_found;
373 }
Leo Kimf1ab1172015-11-19 15:56:11 +0900374 rssi_index = last_scanned_shadow[ap_index].strRssi.u8Index;
375 last_scanned_shadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900376 if (rssi_index == NUM_RSSI) {
377 rssi_index = 0;
Leo Kimf1ab1172015-11-19 15:56:11 +0900378 last_scanned_shadow[ap_index].strRssi.u8Full = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900379 }
Leo Kimf1ab1172015-11-19 15:56:11 +0900380 last_scanned_shadow[ap_index].strRssi.u8Index = rssi_index;
381 last_scanned_shadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
382 last_scanned_shadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
383 last_scanned_shadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
384 memcpy(last_scanned_shadow[ap_index].au8ssid,
385 pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
386 memcpy(last_scanned_shadow[ap_index].au8bssid,
387 pstrNetworkInfo->au8bssid, ETH_ALEN);
388 last_scanned_shadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
389 last_scanned_shadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
390 last_scanned_shadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
391 last_scanned_shadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
392 last_scanned_shadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900393 if (ap_found != -1)
Leo Kimf1ab1172015-11-19 15:56:11 +0900394 kfree(last_scanned_shadow[ap_index].pu8IEs);
395 last_scanned_shadow[ap_index].pu8IEs =
Glen Leef3052582015-09-10 12:03:04 +0900396 kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL); /* will be deallocated by the WILC_WFI_CfgScan() function */
Leo Kimf1ab1172015-11-19 15:56:11 +0900397 memcpy(last_scanned_shadow[ap_index].pu8IEs,
398 pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
399 last_scanned_shadow[ap_index].u32TimeRcvdInScan = jiffies;
400 last_scanned_shadow[ap_index].u32TimeRcvdInScanCached = jiffies;
401 last_scanned_shadow[ap_index].u8Found = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900402 if (ap_found != -1)
Leo Kimf1ab1172015-11-19 15:56:11 +0900403 wilc_free_join_params(last_scanned_shadow[ap_index].pJoinParams);
404 last_scanned_shadow[ap_index].pJoinParams = pJoinParams;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900405}
406
407
408/**
409 * @brief CfgScanResult
410 * @details Callback function which returns the scan results found
411 *
412 * @param[in] tenuScanEvent enuScanEvent: enum, indicating the scan event triggered, whether that is
413 * SCAN_EVENT_NETWORK_FOUND or SCAN_EVENT_DONE
414 * tstrNetworkInfo* pstrNetworkInfo: structure holding the scan results information
415 * void* pUserVoid: Private structure associated with the wireless interface
416 * @return NONE
417 * @author mabubakr
418 * @date
419 * @version 1.0
420 */
Leo Kim1ec38152015-10-12 16:55:59 +0900421static void CfgScanResult(enum scan_event enuScanEvent, tstrNetworkInfo *pstrNetworkInfo, void *pUserVoid, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900422{
Chaehyun Lim27268872015-09-15 14:06:13 +0900423 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900424 struct wiphy *wiphy;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900425 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900426 struct ieee80211_channel *channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900427 struct cfg80211_bss *bss = NULL;
428
Chaehyun Lim27268872015-09-15 14:06:13 +0900429 priv = (struct wilc_priv *)pUserVoid;
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100430 if (priv->bCfgScanning) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900431 if (enuScanEvent == SCAN_EVENT_NETWORK_FOUND) {
432 wiphy = priv->dev->ieee80211_ptr->wiphy;
Leo Kim7ae43362015-09-16 18:35:59 +0900433
434 if (!wiphy)
435 return;
436
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900437 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC
438 &&
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900439 ((((s32)pstrNetworkInfo->s8rssi) * 100) < 0
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900440 ||
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900441 (((s32)pstrNetworkInfo->s8rssi) * 100) > 100)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900442 ) {
Leo Kim24db7132015-09-16 18:36:01 +0900443 PRINT_ER("wiphy signal type fial\n");
444 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900445 }
446
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900447 if (pstrNetworkInfo != NULL) {
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900448 s32Freq = ieee80211_channel_to_frequency((s32)pstrNetworkInfo->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900449 channel = ieee80211_get_channel(wiphy, s32Freq);
450
Leo Kim7ae43362015-09-16 18:35:59 +0900451 if (!channel)
452 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900453
454 PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530455 "BeaconPeriod: %d\n", channel->center_freq, (((s32)pstrNetworkInfo->s8rssi) * 100),
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900456 pstrNetworkInfo->u16CapInfo, pstrNetworkInfo->u16BeaconPeriod);
457
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100458 if (pstrNetworkInfo->bNewNetwork) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900459 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
460 /* max_scan_ssids */
461 PRINT_D(CFG80211_DBG, "Network %s found\n", pstrNetworkInfo->au8ssid);
462
463
464 priv->u32RcvdChCount++;
465
466
467
468 if (pJoinParams == NULL) {
469 PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n");
470 }
471 add_network_to_shadow(pstrNetworkInfo, priv, pJoinParams);
472
473 /*P2P peers are sent to WPA supplicant and added to shadow table*/
474
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900475 if (!(memcmp("DIRECT-", pstrNetworkInfo->au8ssid, 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900476 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, pstrNetworkInfo->au8bssid, pstrNetworkInfo->u64Tsf, pstrNetworkInfo->u16CapInfo,
477 pstrNetworkInfo->u16BeaconPeriod, (const u8 *)pstrNetworkInfo->pu8IEs,
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900478 (size_t)pstrNetworkInfo->u16IEsLen, (((s32)pstrNetworkInfo->s8rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900479 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900480 }
481
482
483 } else {
484 PRINT_ER("Discovered networks exceeded the max limit\n");
485 }
486 } else {
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900487 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900488 /* So this network is discovered before, we'll just update its RSSI */
489 for (i = 0; i < priv->u32RcvdChCount; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900490 if (memcmp(last_scanned_shadow[i].au8bssid, pstrNetworkInfo->au8bssid, 6) == 0) {
491 PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", last_scanned_shadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900492
Leo Kimf1ab1172015-11-19 15:56:11 +0900493 last_scanned_shadow[i].s8rssi = pstrNetworkInfo->s8rssi;
494 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900495 break;
496 }
497 }
498 }
499 }
500 } else if (enuScanEvent == SCAN_EVENT_DONE) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530501 PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev);
502 PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n");
Dean Lee72ed4dc2015-06-12 14:11:44 +0900503 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900504
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530505 if (priv->u32RcvdChCount > 0)
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530506 PRINT_D(CFG80211_DBG, "%d Network(s) found\n", priv->u32RcvdChCount);
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530507 else
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530508 PRINT_D(CFG80211_DBG, "No networks found\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900509
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200510 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900511
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900512 if (priv->pstrScanReq != NULL) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900513 cfg80211_scan_done(priv->pstrScanReq, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900514 priv->u32RcvdChCount = 0;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900515 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900516 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900517 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200518 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900519
520 }
521 /*Aborting any scan operation during mac close*/
522 else if (enuScanEvent == SCAN_EVENT_ABORTED) {
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200523 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900524
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530525 PRINT_D(CFG80211_DBG, "Scan Aborted\n");
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900526 if (priv->pstrScanReq != NULL) {
Leo Kim5e51d8b2015-11-19 15:56:28 +0900527 update_scan_time();
Dean Lee72ed4dc2015-06-12 14:11:44 +0900528 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900529
Dean Lee72ed4dc2015-06-12 14:11:44 +0900530 cfg80211_scan_done(priv->pstrScanReq, false);
531 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900532 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900533 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200534 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900535 }
536 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900537}
538
539
540/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900541 * @brief CfgConnectResult
542 * @details
543 * @param[in] tenuConnDisconnEvent enuConnDisconnEvent: Type of connection response either
544 * connection response or disconnection notification.
545 * tstrConnectInfo* pstrConnectInfo: COnnection information.
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900546 * u8 u8MacStatus: Mac Status from firmware
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900547 * tstrDisconnectNotifInfo* pstrDisconnectNotifInfo: Disconnection Notification
548 * void* pUserVoid: Private data associated with wireless interface
549 * @return NONE
550 * @author mabubakr
551 * @date 01 MAR 2012
552 * @version 1.0
553 */
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100554int wilc_connecting;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900555
Leo Kimed3f0372015-10-12 16:56:01 +0900556static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900557 tstrConnectInfo *pstrConnectInfo,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900558 u8 u8MacStatus,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900559 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
560 void *pUserVoid)
561{
Chaehyun Lim27268872015-09-15 14:06:13 +0900562 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900563 struct net_device *dev;
Leo Kim441dc602015-10-12 16:55:35 +0900564 struct host_if_drv *pstrWFIDrv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900565 u8 NullBssid[ETH_ALEN] = {0};
Glen Leec1ec2c12015-10-20 17:13:58 +0900566 struct wilc *wl;
567 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900568
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100569 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900570
Chaehyun Lim27268872015-09-15 14:06:13 +0900571 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900572 dev = priv->dev;
Glen Leec1ec2c12015-10-20 17:13:58 +0900573 nic = netdev_priv(dev);
574 wl = nic->wilc;
Leo Kim441dc602015-10-12 16:55:35 +0900575 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900576
577 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
578 /*Initialization*/
Amitoj Kaur Chawlababa7c72015-10-15 13:48:29 +0530579 u16 u16ConnectStatus;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900580
581 u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
582
583 PRINT_D(CFG80211_DBG, " Connection response received = %d\n", u8MacStatus);
584
585 if ((u8MacStatus == MAC_DISCONNECTED) &&
586 (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
587 /* The case here is that our station was waiting for association response frame and has just received it containing status code
588 * = SUCCESSFUL_STATUSCODE, while mac status is MAC_DISCONNECTED (which means something wrong happened) */
589 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100590 wilc_wlan_set_bssid(priv->dev, NullBssid);
Leo Kime554a302015-11-19 15:56:21 +0900591 eth_zero_addr(wilc_connected_ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900592
Leo Kimab16ec02015-10-29 12:05:40 +0900593 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900594 wlan_channel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900595
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530596 PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d\n", u16ConnectStatus, u8MacStatus);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900597 }
598
599 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900600 bool bNeedScanRefresh = false;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900601 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900602
603 PRINT_INFO(CFG80211_DBG, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo->au8bssid[0],
604 pstrConnectInfo->au8bssid[1], pstrConnectInfo->au8bssid[2], pstrConnectInfo->au8bssid[3], pstrConnectInfo->au8bssid[4], pstrConnectInfo->au8bssid[5]);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900605 memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900606
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900607
Leo Kim771fbae2015-11-19 15:56:10 +0900608 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900609 if (memcmp(last_scanned_shadow[i].au8bssid,
610 pstrConnectInfo->au8bssid, ETH_ALEN) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900611 unsigned long now = jiffies;
612
613 if (time_after(now,
Leo Kimf1ab1172015-11-19 15:56:11 +0900614 last_scanned_shadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900615 bNeedScanRefresh = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900616 }
617
618 break;
619 }
620 }
621
Abdul Hussain5a66bf22015-06-16 09:44:06 +0000622 if (bNeedScanRefresh) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900623 /*Also, refrsh DIRECT- results if */
Dean Lee72ed4dc2015-06-12 14:11:44 +0900624 refresh_scan(priv, 1, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900625
626 }
627
628 }
629
630
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530631 PRINT_D(CFG80211_DBG, "Association request info elements length = %zu\n", pstrConnectInfo->ReqIEsLen);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900632
633 PRINT_D(CFG80211_DBG, "Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen);
634
635 cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
636 pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
637 pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
638 u16ConnectStatus, GFP_KERNEL); /* TODO: mostafa: u16ConnectStatus to */
639 /* be replaced by pstrConnectInfo->u16ConnectStatus */
640 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100641 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900642 PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n",
643 pstrDisconnectNotifInfo->u16reason, priv->dev);
Leo Kim583d9722015-11-19 15:56:16 +0900644 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +0900645 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +0900646 wilc_ie = false;
Shraddha Barkebcf02652015-10-05 17:00:32 +0530647 eth_zero_addr(priv->au8AssociatedBss);
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100648 wilc_wlan_set_bssid(priv->dev, NullBssid);
Leo Kime554a302015-11-19 15:56:21 +0900649 eth_zero_addr(wilc_connected_ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900650
Leo Kimab16ec02015-10-29 12:05:40 +0900651 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900652 wlan_channel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900653 /*Incase "P2P CLIENT Connected" send deauthentication reason by 3 to force the WPA_SUPPLICANT to directly change
654 * virtual interface to station*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900655 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900656 pstrDisconnectNotifInfo->u16reason = 3;
657 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900658 /*Incase "P2P CLIENT during connection(not connected)" send deauthentication reason by 1 to force the WPA_SUPPLICANT
659 * to scan again and retry the connection*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900660 else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900661 pstrDisconnectNotifInfo->u16reason = 1;
662 }
663 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
Sudip Mukherjeee26bb712015-06-30 13:51:51 +0530664 pstrDisconnectNotifInfo->ie_len, false,
665 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900666
667 }
668
669}
670
671
672/**
Chaehyun Lim80785a92015-09-14 12:24:01 +0900673 * @brief set_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900674 * @details Set channel for a given wireless interface. Some devices
675 * may support multi-channel operation (by channel hopping) so cfg80211
676 * doesn't verify much. Note, however, that the passed netdev may be
677 * %NULL as well if the user requested changing the channel for the
678 * device itself, or for a monitor interface.
679 * @param[in]
680 * @return int : Return 0 on Success
681 * @author mdaftedar
682 * @date 01 MAR 2012
683 * @version 1.0
684 */
Chaehyun Lim80785a92015-09-14 12:24:01 +0900685static int set_channel(struct wiphy *wiphy,
686 struct cfg80211_chan_def *chandef)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900687{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900688 u32 channelnum = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +0900689 struct wilc_priv *priv;
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900690 int result = 0;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900691
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900692 priv = wiphy_priv(wiphy);
693
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900694 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
695 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900696
Chaehyun Lim866a2c22015-10-02 16:41:21 +0900697 curr_channel = channelnum;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100698 result = wilc_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900699
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900700 if (result != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900701 PRINT_ER("Error in setting channel %d\n", channelnum);
702
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900703 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900704}
705
706/**
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900707 * @brief scan
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900708 * @details Request to do a scan. If returning zero, the scan request is given
709 * the driver, and will be valid until passed to cfg80211_scan_done().
710 * For scan results, call cfg80211_inform_bss(); you can call this outside
711 * the scan/scan_done bracket too.
712 * @param[in]
713 * @return int : Return 0 on Success
714 * @author mabubakr
715 * @date 01 MAR 2012
716 * @version 1.0
717 */
718
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900719static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900720{
Chaehyun Lim27268872015-09-15 14:06:13 +0900721 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900722 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +0900723 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900724 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
Leo Kim607db442015-10-05 15:25:37 +0900725 struct hidden_network strHiddenNetwork;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900726
727 priv = wiphy_priv(wiphy);
728
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900729 priv->pstrScanReq = request;
730
731 priv->u32RcvdChCount = 0;
732
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100733 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Leo Kim12b01382015-11-19 15:56:27 +0900734 reset_shadow_found();
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900735
Dean Lee72ed4dc2015-06-12 14:11:44 +0900736 priv->bCfgScanning = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900737 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
738 /* max_scan_ssids */
739 for (i = 0; i < request->n_channels; i++) {
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900740 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900741 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
742 }
743
744 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530745 PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900746
747 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
748
749 if (request->n_ssids >= 1) {
750
751
Leo Kim607db442015-10-05 15:25:37 +0900752 strHiddenNetwork.pstrHiddenNetworkInfo = kmalloc(request->n_ssids * sizeof(struct hidden_network), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900753 strHiddenNetwork.u8ssidnum = request->n_ssids;
754
755
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900756 for (i = 0; i < request->n_ssids; i++) {
757
758 if (request->ssids[i].ssid != NULL && request->ssids[i].ssid_len != 0) {
Glen Leef3052582015-09-10 12:03:04 +0900759 strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900760 memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900761 strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len;
762 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530763 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900764 strHiddenNetwork.u8ssidnum -= 1;
765 }
766 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530767 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100768 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900769 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900770 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900771 CfgScanResult, (void *)priv, &strHiddenNetwork);
772 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530773 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100774 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900775 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900776 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900777 CfgScanResult, (void *)priv, NULL);
778 }
779
780 } else {
781 PRINT_ER("Requested num of scanned channels is greater than the max, supported"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530782 " channels\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900783 }
784
Leo Kime6e12662015-09-16 18:36:03 +0900785 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900786 s32Error = -EBUSY;
787 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
788 }
789
790 return s32Error;
791}
792
793/**
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900794 * @brief connect
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900795 * @details Connect to the ESS with the specified parameters. When connected,
796 * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
797 * If the connection fails for some reason, call cfg80211_connect_result()
798 * with the status from the AP.
799 * @param[in]
800 * @return int : Return 0 on Success
801 * @author mabubakr
802 * @date 01 MAR 2012
803 * @version 1.0
804 */
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900805static int connect(struct wiphy *wiphy, struct net_device *dev,
806 struct cfg80211_connect_params *sme)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900807{
Leo Kime6e12662015-09-16 18:36:03 +0900808 s32 s32Error = 0;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900809 u32 i;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900810 u8 u8security = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +0900811 enum AUTHTYPE tenuAuth_type = ANY;
Dean Lee576917a2015-06-15 11:58:57 +0900812 char *pcgroup_encrypt_val = NULL;
813 char *pccipher_group = NULL;
814 char *pcwpa_version = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900815
Chaehyun Lim27268872015-09-15 14:06:13 +0900816 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +0900817 struct host_if_drv *pstrWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900818 tstrNetworkInfo *pstrNetworkInfo = NULL;
819
820
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100821 wilc_connecting = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900822 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +0900823 pstrWFIDrv = (struct host_if_drv *)(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900824
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100825 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900826
Johnny Kim8a143302015-06-10 17:06:46 +0900827 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 +0900828 if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900829 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
Leo Kimab16ec02015-10-29 12:05:40 +0900830 pstrWFIDrv->p2p_connect = 1;
831 } else {
832 pstrWFIDrv->p2p_connect = 0;
833 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530834 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900835
Leo Kim771fbae2015-11-19 15:56:10 +0900836 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900837 if ((sme->ssid_len == last_scanned_shadow[i].u8SsidLen) &&
838 memcmp(last_scanned_shadow[i].au8ssid,
839 sme->ssid,
840 sme->ssid_len) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900841 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
842 if (sme->bssid == NULL) {
843 /* BSSID is not passed from the user, so decision of matching
844 * is done by SSID only */
845 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
846 break;
847 } else {
848 /* BSSID is also passed from the user, so decision of matching
849 * should consider also this passed BSSID */
Leo Kimf1ab1172015-11-19 15:56:11 +0900850 if (memcmp(last_scanned_shadow[i].au8bssid,
851 sme->bssid,
852 ETH_ALEN) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900853 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
854 break;
855 }
856 }
857 }
858 }
859
Leo Kim771fbae2015-11-19 15:56:10 +0900860 if (i < last_scanned_cnt) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900861 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
862
Leo Kimf1ab1172015-11-19 15:56:11 +0900863 pstrNetworkInfo = &last_scanned_shadow[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900864
865 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
866 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
867 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
868 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
869 } else {
870 s32Error = -ENOENT;
Leo Kim771fbae2015-11-19 15:56:10 +0900871 if (last_scanned_cnt == 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900872 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
873 else
874 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
875
876 goto done;
877 }
878
879 priv->WILC_WFI_wep_default = 0;
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900880 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
881 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900882
883 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
884 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
885
886 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
887
888 if (INFO) {
889 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
890 PRINT_D(CORECONFIG_DBG, "sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]);
891 }
892
893 if (sme->crypto.cipher_group != NO_ENCRYPT) {
894 /* To determine the u8security value, first we check the group cipher suite then {in case of WPA or WPA2}
895 * we will add to it the pairwise cipher suite(s) */
896 pcwpa_version = "Default";
897 PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900898 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900899 u8security = ENCRYPT_ENABLED | WEP;
900 pcgroup_encrypt_val = "WEP40";
901 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
902 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
903
904 if (INFO) {
905 for (i = 0; i < sme->key_len; i++)
906 PRINT_D(CORECONFIG_DBG, "WEP Key Value[%d] = %d\n", i, sme->key[i]);
907 }
908 priv->WILC_WFI_wep_default = sme->key_idx;
909 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900910 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900911
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900912 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900913 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900914 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
915 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900916 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900917
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100918 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
919 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900920 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900921 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
922 pcgroup_encrypt_val = "WEP104";
923 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
924
925 priv->WILC_WFI_wep_default = sme->key_idx;
926 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900927 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900928
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900929 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900930 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900931 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
932 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900933 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900934
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100935 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
936 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900937 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900938 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900939 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
940 pcgroup_encrypt_val = "WPA2_TKIP";
941 pccipher_group = "TKIP";
942 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
943 /* tenuSecurity_t = WPA2_AES; */
944 u8security = ENCRYPT_ENABLED | WPA2 | AES;
945 pcgroup_encrypt_val = "WPA2_AES";
946 pccipher_group = "AES";
947 }
948 pcwpa_version = "WPA_VERSION_2";
949 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
950 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900951 u8security = ENCRYPT_ENABLED | WPA | TKIP;
952 pcgroup_encrypt_val = "WPA_TKIP";
953 pccipher_group = "TKIP";
954 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
955 /* tenuSecurity_t = WPA_AES; */
956 u8security = ENCRYPT_ENABLED | WPA | AES;
957 pcgroup_encrypt_val = "WPA_AES";
958 pccipher_group = "AES";
959
960 }
961 pcwpa_version = "WPA_VERSION_1";
962
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900963 } else {
964 s32Error = -ENOTSUPP;
965 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
966
967 goto done;
968 }
969
970 }
971
972 /* After we set the u8security value from checking the group cipher suite, {in case of WPA or WPA2} we will
973 * add to it the pairwise cipher suite(s) */
974 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
975 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
976 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
977 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
978 u8security = u8security | TKIP;
979 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
980 u8security = u8security | AES;
981 }
982 }
983 }
984
985 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
986
987 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
988 switch (sme->auth_type) {
989 case NL80211_AUTHTYPE_OPEN_SYSTEM:
990 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
991 tenuAuth_type = OPEN_SYSTEM;
992 break;
993
994 case NL80211_AUTHTYPE_SHARED_KEY:
995 tenuAuth_type = SHARED_KEY;
996 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
997 break;
998
999 default:
1000 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
1001 }
1002
1003
1004 /* ai: key_mgmt: enterprise case */
1005 if (sme->crypto.n_akm_suites) {
1006 switch (sme->crypto.akm_suites[0]) {
1007 case WLAN_AKM_SUITE_8021X:
1008 tenuAuth_type = IEEE8021;
1009 break;
1010
1011 default:
1012 break;
1013 }
1014 }
1015
1016
1017 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
1018
1019 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
1020 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
1021
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001022 curr_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001023
Leo Kimab16ec02015-10-29 12:05:40 +09001024 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +09001025 wlan_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001026
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001027 wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001028
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001029 s32Error = wilc_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001030 sme->ssid_len, sme->ie, sme->ie_len,
1031 CfgConnectResult, (void *)priv, u8security,
1032 tenuAuth_type, pstrNetworkInfo->u8channel,
1033 pstrNetworkInfo->pJoinParams);
Leo Kime6e12662015-09-16 18:36:03 +09001034 if (s32Error != 0) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001035 PRINT_ER("wilc_set_join_req(): Error(%d)\n", s32Error);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001036 s32Error = -ENOENT;
1037 goto done;
1038 }
1039
1040done:
1041
1042 return s32Error;
1043}
1044
1045
1046/**
Chaehyun Limb027cde2015-09-14 12:24:04 +09001047 * @brief disconnect
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001048 * @details Disconnect from the BSS/ESS.
1049 * @param[in]
1050 * @return int : Return 0 on Success
1051 * @author mdaftedar
1052 * @date 01 MAR 2012
1053 * @version 1.0
1054 */
Chaehyun Limb027cde2015-09-14 12:24:04 +09001055static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001056{
Leo Kime6e12662015-09-16 18:36:03 +09001057 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09001058 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09001059 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim51e825f2015-09-15 14:06:14 +09001060 u8 NullBssid[ETH_ALEN] = {0};
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001061
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001062 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001063 priv = wiphy_priv(wiphy);
1064
Leo Kim441dc602015-10-12 16:55:35 +09001065 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Leo Kimab16ec02015-10-29 12:05:40 +09001066 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +09001067 wlan_channel = INVALID_CHANNEL;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001068 wilc_wlan_set_bssid(priv->dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001069
1070 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
1071
Leo Kim583d9722015-11-19 15:56:16 +09001072 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +09001073 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +09001074 wilc_ie = false;
Leo Kim1229b1a2015-10-29 12:05:39 +09001075 pstrWFIDrv->p2p_timeout = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001076
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001077 s32Error = wilc_disconnect(priv->hWILCWFIDrv, reason_code);
Leo Kime6e12662015-09-16 18:36:03 +09001078 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001079 PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
1080 s32Error = -EINVAL;
1081 }
1082
1083 return s32Error;
1084}
1085
1086/**
Chaehyun Lim953d4172015-09-14 12:24:05 +09001087 * @brief add_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001088 * @details Add a key with the given parameters. @mac_addr will be %NULL
1089 * when adding a group key.
1090 * @param[in] key : key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, 8-byte Rx Mic Key
1091 * @return int : Return 0 on Success
1092 * @author mdaftedar
1093 * @date 01 MAR 2012
1094 * @version 1.0
1095 */
Chaehyun Lim953d4172015-09-14 12:24:05 +09001096static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1097 bool pairwise,
1098 const u8 *mac_addr, struct key_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001099
1100{
Leo Kime6e12662015-09-16 18:36:03 +09001101 s32 s32Error = 0, KeyLen = params->key_len;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001102 u32 i;
Chaehyun Lim27268872015-09-15 14:06:13 +09001103 struct wilc_priv *priv;
Arnd Bergmann057d1e92015-06-01 21:06:44 +02001104 const u8 *pu8RxMic = NULL;
1105 const u8 *pu8TxMic = NULL;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001106 u8 u8mode = NO_ENCRYPT;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001107 u8 u8gmode = NO_ENCRYPT;
1108 u8 u8pmode = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +09001109 enum AUTHTYPE tenuAuth_type = ANY;
Glen Lee76469202015-10-20 17:13:59 +09001110 struct wilc *wl;
1111 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001112
1113 priv = wiphy_priv(wiphy);
Glen Lee76469202015-10-20 17:13:59 +09001114 nic = netdev_priv(netdev);
1115 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001116
1117 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
1118
Johnny Kim8a143302015-06-10 17:06:46 +09001119 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001120
1121 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
1122 params->key[1],
1123 params->key[2]);
1124
1125
1126 switch (params->cipher) {
1127 case WLAN_CIPHER_SUITE_WEP40:
1128 case WLAN_CIPHER_SUITE_WEP104:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001129 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
1130
1131 priv->WILC_WFI_wep_default = key_index;
1132 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001133 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001134
1135 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
1136 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
1137
1138 for (i = 0; i < params->key_len; i++)
1139 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
1140
1141 tenuAuth_type = OPEN_SYSTEM;
1142
1143 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
1144 u8mode = ENCRYPT_ENABLED | WEP;
1145 else
1146 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
1147
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001148 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 +09001149 break;
1150 }
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001151 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001152 priv->WILC_WFI_wep_default = key_index;
1153 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001154 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001155
1156 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
1157 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
1158 if (INFO) {
1159 for (i = 0; i < params->key_len; i++)
1160 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
1161 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001162 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001163 }
1164
1165 break;
1166
1167 case WLAN_CIPHER_SUITE_TKIP:
1168 case WLAN_CIPHER_SUITE_CCMP:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001169 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
1170
1171 if (priv->wilc_gtk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001172 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001173 priv->wilc_gtk[key_index]->key = NULL;
1174 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001175
1176 }
1177 if (priv->wilc_ptk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001178 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001179 priv->wilc_ptk[key_index]->key = NULL;
1180 priv->wilc_ptk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001181 }
1182
1183
1184
Daniel Machon19132212015-08-05 08:18:31 +02001185 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001186 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1187 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1188 else
1189 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1190
1191 priv->wilc_groupkey = u8gmode;
1192
1193 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1194
1195 pu8TxMic = params->key + 24;
1196 pu8RxMic = params->key + 16;
1197 KeyLen = params->key_len - 16;
1198 }
1199 /* 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 +05301200 kfree(priv->wilc_gtk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001201
Glen Leef3052582015-09-10 12:03:04 +09001202 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001203 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001204
1205 /* 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 +05301206 kfree(priv->wilc_gtk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001207
1208 if ((params->seq_len) > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001209 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001210 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001211 }
1212
1213 priv->wilc_gtk[key_index]->cipher = params->cipher;
1214 priv->wilc_gtk[key_index]->key_len = params->key_len;
1215 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1216
1217 if (INFO) {
1218 for (i = 0; i < params->key_len; i++)
1219 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1220 for (i = 0; i < params->seq_len; i++)
1221 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1222 }
1223
1224
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001225 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001226 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode);
1227
1228 } else {
1229 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]);
1230
1231 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1232 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1233 else
1234 u8pmode = priv->wilc_groupkey | AES;
1235
1236
1237 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1238
1239 pu8TxMic = params->key + 24;
1240 pu8RxMic = params->key + 16;
1241 KeyLen = params->key_len - 16;
1242 }
1243
Shraddha Barkecccfc392015-10-12 20:49:19 +05301244 kfree(priv->wilc_ptk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001245
Glen Leef3052582015-09-10 12:03:04 +09001246 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001247
Shraddha Barkecccfc392015-10-12 20:49:19 +05301248 kfree(priv->wilc_ptk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001249
1250 if ((params->seq_len) > 0)
Glen Leef3052582015-09-10 12:03:04 +09001251 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001252
1253 if (INFO) {
1254 for (i = 0; i < params->key_len; i++)
1255 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1256
1257 for (i = 0; i < params->seq_len; i++)
1258 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1259 }
1260
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001261 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001262
1263 if ((params->seq_len) > 0)
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001264 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001265
1266 priv->wilc_ptk[key_index]->cipher = params->cipher;
1267 priv->wilc_ptk[key_index]->key_len = params->key_len;
1268 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1269
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001270 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001271 pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index);
1272 }
1273 break;
1274 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001275
1276 {
1277 u8mode = 0;
Daniel Machon19132212015-08-05 08:18:31 +02001278 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001279 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1280 /* swap the tx mic by rx mic */
1281 pu8RxMic = params->key + 24;
1282 pu8TxMic = params->key + 16;
1283 KeyLen = params->key_len - 16;
1284 }
1285
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001286 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001287 if (!g_gtk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001288 g_add_gtk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001289 g_add_gtk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001290 if (!mac_addr) {
1291 g_add_gtk_key_params.mac_addr = NULL;
1292 } else {
Glen Leef3052582015-09-10 12:03:04 +09001293 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001294 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1295 }
1296 g_key_gtk_params.key_len = params->key_len;
1297 g_key_gtk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001298 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001299 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1300 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001301 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001302 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1303 }
1304 g_key_gtk_params.cipher = params->cipher;
1305
1306 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1307 g_key_gtk_params.key[1],
1308 g_key_gtk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001309 g_gtk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001310 }
1311
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001312 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001313 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001314 } else {
1315 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1316 /* swap the tx mic by rx mic */
1317 pu8RxMic = params->key + 24;
1318 pu8TxMic = params->key + 16;
1319 KeyLen = params->key_len - 16;
1320 }
1321
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001322 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001323 if (!g_ptk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001324 g_add_ptk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001325 g_add_ptk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001326 if (!mac_addr) {
1327 g_add_ptk_key_params.mac_addr = NULL;
1328 } else {
Glen Leef3052582015-09-10 12:03:04 +09001329 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001330 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1331 }
1332 g_key_ptk_params.key_len = params->key_len;
1333 g_key_ptk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001334 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001335 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1336 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001337 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001338 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1339 }
1340 g_key_ptk_params.cipher = params->cipher;
1341
1342 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1343 g_key_ptk_params.key[1],
1344 g_key_ptk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001345 g_ptk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001346 }
1347
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001348 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001349 pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index);
1350 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1351 if (INFO) {
1352 for (i = 0; i < params->key_len; i++)
1353 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1354 }
1355 }
1356 }
1357 break;
1358
1359 default:
1360 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
1361 s32Error = -ENOTSUPP;
1362
1363 }
1364
1365 return s32Error;
1366}
1367
1368/**
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001369 * @brief del_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001370 * @details Remove a key given the @mac_addr (%NULL for a group key)
1371 * and @key_index, return -ENOENT if the key doesn't exist.
1372 * @param[in]
1373 * @return int : Return 0 on Success
1374 * @author mdaftedar
1375 * @date 01 MAR 2012
1376 * @version 1.0
1377 */
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001378static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1379 u8 key_index,
1380 bool pairwise,
1381 const u8 *mac_addr)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001382{
Chaehyun Lim27268872015-09-15 14:06:13 +09001383 struct wilc_priv *priv;
Glen Lee692e2ac2015-10-20 17:14:00 +09001384 struct wilc *wl;
1385 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001386
1387 priv = wiphy_priv(wiphy);
Glen Lee692e2ac2015-10-20 17:14:00 +09001388 nic = netdev_priv(netdev);
1389 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001390
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001391 /*delete saved keys, if any*/
Glen Lee692e2ac2015-10-20 17:14:00 +09001392 if (netdev == wl->vif[0].ndev) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09001393 g_ptk_keys_saved = false;
1394 g_gtk_keys_saved = false;
1395 g_wep_keys_saved = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001396
1397 /*Delete saved WEP keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301398 kfree(g_key_wep_params.key);
1399 g_key_wep_params.key = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001400
1401 /*freeing memory allocated by "wilc_gtk" and "wilc_ptk" in "WILC_WIFI_ADD_KEY"*/
1402
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001403 if ((priv->wilc_gtk[key_index]) != NULL) {
1404
Shraddha Barkecccfc392015-10-12 20:49:19 +05301405 kfree(priv->wilc_gtk[key_index]->key);
1406 priv->wilc_gtk[key_index]->key = NULL;
1407 kfree(priv->wilc_gtk[key_index]->seq);
1408 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001409
Chaehyun Lim49188af2015-08-11 10:32:41 +09001410 kfree(priv->wilc_gtk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001411 priv->wilc_gtk[key_index] = NULL;
1412
1413 }
1414
1415 if ((priv->wilc_ptk[key_index]) != NULL) {
1416
Shraddha Barkecccfc392015-10-12 20:49:19 +05301417 kfree(priv->wilc_ptk[key_index]->key);
1418 priv->wilc_ptk[key_index]->key = NULL;
1419 kfree(priv->wilc_ptk[key_index]->seq);
1420 priv->wilc_ptk[key_index]->seq = NULL;
Chaehyun Lim49188af2015-08-11 10:32:41 +09001421 kfree(priv->wilc_ptk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001422 priv->wilc_ptk[key_index] = NULL;
1423 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001424
1425 /*Delete saved PTK and GTK keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301426 kfree(g_key_ptk_params.key);
1427 g_key_ptk_params.key = NULL;
1428 kfree(g_key_ptk_params.seq);
1429 g_key_ptk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001430
Shraddha Barkecccfc392015-10-12 20:49:19 +05301431 kfree(g_key_gtk_params.key);
1432 g_key_gtk_params.key = NULL;
1433 kfree(g_key_gtk_params.seq);
1434 g_key_gtk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001435
1436 /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001437 wilc_set_machw_change_vir_if(netdev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001438 }
1439
1440 if (key_index >= 0 && key_index <= 3) {
Chaehyun Lim2cc46832015-08-07 09:02:01 +09001441 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001442 priv->WILC_WFI_wep_key_len[key_index] = 0;
1443
1444 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001445 wilc_remove_wep_key(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001446 } else {
1447 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001448 wilc_remove_key(priv->hWILCWFIDrv, mac_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001449 }
1450
Leo Kimaaed3292015-10-12 16:55:38 +09001451 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001452}
1453
1454/**
Chaehyun Limf4893df2015-09-14 12:24:07 +09001455 * @brief get_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001456 * @details Get information about the key with the given parameters.
1457 * @mac_addr will be %NULL when requesting information for a group
1458 * key. All pointers given to the @callback function need not be valid
1459 * after it returns. This function should return an error if it is
1460 * not possible to retrieve the key, -ENOENT if it doesn't exist.
1461 * @param[in]
1462 * @return int : Return 0 on Success
1463 * @author mdaftedar
1464 * @date 01 MAR 2012
1465 * @version 1.0
1466 */
Chaehyun Limf4893df2015-09-14 12:24:07 +09001467static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1468 bool pairwise,
1469 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001470{
Chaehyun Lim27268872015-09-15 14:06:13 +09001471 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001472 struct key_params key_params;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001473 u32 i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001474
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001475 priv = wiphy_priv(wiphy);
1476
1477
Alison Schofield3604af52015-10-12 13:22:44 -07001478 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001479 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1480
1481 key_params.key = priv->wilc_gtk[key_index]->key;
1482 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1483 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1484 key_params.seq = priv->wilc_gtk[key_index]->seq;
1485 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1486 if (INFO) {
1487 for (i = 0; i < key_params.key_len; i++)
1488 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1489 }
1490 } else {
1491 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1492
1493 key_params.key = priv->wilc_ptk[key_index]->key;
1494 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1495 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1496 key_params.seq = priv->wilc_ptk[key_index]->seq;
1497 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1498 }
1499
1500 callback(cookie, &key_params);
1501
Leo Kimaaed3292015-10-12 16:55:38 +09001502 return 0; /* priv->wilc_gtk->key_len ?0 : -ENOENT; */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001503}
1504
1505/**
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001506 * @brief set_default_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001507 * @details Set the default management frame key on an interface
1508 * @param[in]
1509 * @return int : Return 0 on Success.
1510 * @author mdaftedar
1511 * @date 01 MAR 2012
1512 * @version 1.0
1513 */
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001514static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1515 bool unicast, bool multicast)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001516{
Chaehyun Lim27268872015-09-15 14:06:13 +09001517 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001518
1519
1520 priv = wiphy_priv(wiphy);
1521
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301522 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001523
1524 if (key_index != priv->WILC_WFI_wep_default) {
1525
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001526 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001527 }
1528
Leo Kimaaed3292015-10-12 16:55:38 +09001529 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001530}
1531
1532/**
Chaehyun Limf06f5622015-09-14 12:24:18 +09001533 * @brief get_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001534 * @details Get station information for the station identified by @mac
1535 * @param[in] NONE
1536 * @return int : Return 0 on Success.
1537 * @author mdaftedar
1538 * @date 01 MAR 2012
1539 * @version 1.0
1540 */
1541
Chaehyun Limf06f5622015-09-14 12:24:18 +09001542static int get_station(struct wiphy *wiphy, struct net_device *dev,
1543 const u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001544{
Chaehyun Lim27268872015-09-15 14:06:13 +09001545 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001546 perInterface_wlan_t *nic;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001547 u32 i = 0;
1548 u32 associatedsta = 0;
1549 u32 inactive_time = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001550 priv = wiphy_priv(wiphy);
1551 nic = netdev_priv(dev);
1552
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001553 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
1554 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1555
1556 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1557
1558 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1559
1560 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1561 associatedsta = i;
1562 break;
1563 }
1564
1565 }
1566
1567 if (associatedsta == -1) {
Leo Kimaaed3292015-10-12 16:55:38 +09001568 PRINT_ER("Station required is not associated\n");
1569 return -ENOENT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001570 }
1571
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001572 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001573
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001574 wilc_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001575 sinfo->inactive_time = 1000 * inactive_time;
1576 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
1577
1578 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001579
1580 if (nic->iftype == STATION_MODE) {
Leo Kim03e7b9c2015-10-12 16:55:58 +09001581 struct rf_info strStatistics;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001582
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001583 wilc_get_statistics(priv->hWILCWFIDrv, &strStatistics);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001584
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001585 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
Chandra S Gorentla62129902015-08-05 22:11:57 +05301586 BIT(NL80211_STA_INFO_RX_PACKETS) |
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001587 BIT(NL80211_STA_INFO_TX_PACKETS) |
1588 BIT(NL80211_STA_INFO_TX_FAILED) |
1589 BIT(NL80211_STA_INFO_TX_BITRATE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001590
Leo Kim00c8dfc2015-10-29 12:05:30 +09001591 sinfo->signal = strStatistics.rssi;
Leo Kim9b992742015-10-29 12:05:32 +09001592 sinfo->rx_packets = strStatistics.rx_cnt;
Leo Kim54160372015-10-29 12:05:33 +09001593 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1594 sinfo->tx_failed = strStatistics.tx_fail_cnt;
Leo Kim5babeec2015-10-29 12:05:29 +09001595 sinfo->txrate.legacy = strStatistics.link_speed * 10;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001596
Leo Kim5babeec2015-10-29 12:05:29 +09001597 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1598 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001599 wilc_enable_tcp_ack_filter(true);
Leo Kim5babeec2015-10-29 12:05:29 +09001600 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001601 wilc_enable_tcp_ack_filter(false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001602
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001603 PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
1604 sinfo->tx_failed, sinfo->txrate.legacy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001605 }
Leo Kimaaed3292015-10-12 16:55:38 +09001606 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001607}
1608
1609
1610/**
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001611 * @brief change_bss
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001612 * @details Modify parameters for a given BSS.
1613 * @param[in]
1614 * -use_cts_prot: Whether to use CTS protection
1615 * (0 = no, 1 = yes, -1 = do not change)
1616 * -use_short_preamble: Whether the use of short preambles is allowed
1617 * (0 = no, 1 = yes, -1 = do not change)
1618 * -use_short_slot_time: Whether the use of short slot time is allowed
1619 * (0 = no, 1 = yes, -1 = do not change)
1620 * -basic_rates: basic rates in IEEE 802.11 format
1621 * (or NULL for no change)
1622 * -basic_rates_len: number of basic rates
1623 * -ap_isolate: do not forward packets between connected stations
1624 * -ht_opmode: HT Operation mode
1625 * (u16 = opmode, -1 = do not change)
1626 * @return int : Return 0 on Success.
1627 * @author mdaftedar
1628 * @date 01 MAR 2012
1629 * @version 1.0
1630 */
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001631static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1632 struct bss_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001633{
1634 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1635 return 0;
1636}
1637
1638/**
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001639 * @brief set_wiphy_params
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001640 * @details Notify that wiphy parameters have changed;
1641 * @param[in] Changed bitfield (see &enum wiphy_params_flags) describes which values
1642 * have changed.
1643 * @return int : Return 0 on Success
1644 * @author mdaftedar
1645 * @date 01 MAR 2012
1646 * @version 1.0
1647 */
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001648static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001649{
Leo Kime6e12662015-09-16 18:36:03 +09001650 s32 s32Error = 0;
Leo Kim95296502015-10-05 15:25:46 +09001651 struct cfg_param_val pstrCfgParamVal;
Chaehyun Lim27268872015-09-15 14:06:13 +09001652 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001653
1654 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001655
Tony Cho87c05b22015-10-12 16:56:07 +09001656 pstrCfgParamVal.flag = 0;
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301657 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001658
1659 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1660 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1661 priv->dev->ieee80211_ptr->wiphy->retry_short);
Tony Cho87c05b22015-10-12 16:56:07 +09001662 pstrCfgParamVal.flag |= RETRY_SHORT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001663 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1664 }
1665 if (changed & WIPHY_PARAM_RETRY_LONG) {
1666
1667 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 +09001668 pstrCfgParamVal.flag |= RETRY_LONG;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001669 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1670
1671 }
1672 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1673 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 +09001674 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001675 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1676
1677 }
1678
1679 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1680 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1681
Tony Cho87c05b22015-10-12 16:56:07 +09001682 pstrCfgParamVal.flag |= RTS_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001683 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1684
1685 }
1686
1687 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001688 s32Error = wilc_hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001689 if (s32Error)
1690 PRINT_ER("Error in setting WIPHY PARAMS\n");
1691
1692
1693 return s32Error;
1694}
Arnd Bergmanne5af0562015-05-29 22:52:12 +02001695
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001696/**
Chaehyun Lim4d466572015-09-14 12:24:22 +09001697 * @brief set_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001698 * @details Cache a PMKID for a BSSID. This is mostly useful for fullmac
1699 * devices running firmwares capable of generating the (re) association
1700 * RSN IE. It allows for faster roaming between WPA2 BSSIDs.
1701 * @param[in]
1702 * @return int : Return 0 on Success
1703 * @author mdaftedar
1704 * @date 01 MAR 2012
1705 * @version 1.0
1706 */
Chaehyun Lim4d466572015-09-14 12:24:22 +09001707static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1708 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001709{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001710 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001711 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001712 u8 flag = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001713
Chaehyun Lim27268872015-09-15 14:06:13 +09001714 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001715
1716 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1717
1718
1719 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001720 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001721 ETH_ALEN)) {
1722 /*If bssid already exists and pmkid value needs to reset*/
1723 flag = PMKID_FOUND;
1724 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1725 break;
1726 }
1727 }
1728 if (i < WILC_MAX_NUM_PMKIDS) {
1729 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001730 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001731 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001732 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001733 PMKID_LEN);
1734 if (!(flag == PMKID_FOUND))
1735 priv->pmkid_list.numpmkid++;
1736 } else {
1737 PRINT_ER("Invalid PMKID index\n");
1738 s32Error = -EINVAL;
1739 }
1740
1741 if (!s32Error) {
1742 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001743 s32Error = wilc_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001744 }
1745 return s32Error;
1746}
1747
1748/**
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001749 * @brief del_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001750 * @details Delete a cached PMKID.
1751 * @param[in]
1752 * @return int : Return 0 on Success
1753 * @author mdaftedar
1754 * @date 01 MAR 2012
1755 * @version 1.0
1756 */
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001757static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1758 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001759{
1760
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001761 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001762 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001763
Chaehyun Lim27268872015-09-15 14:06:13 +09001764 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001765
1766 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1767
1768 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001769 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001770 ETH_ALEN)) {
1771 /*If bssid is found, reset the values*/
1772 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
Leo Kimcd1e6cb2015-10-05 15:25:45 +09001773 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001774 break;
1775 }
1776 }
1777
1778 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1779 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001780 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001781 priv->pmkid_list.pmkidlist[i + 1].bssid,
1782 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001783 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001784 priv->pmkid_list.pmkidlist[i].pmkid,
1785 PMKID_LEN);
1786 }
1787 priv->pmkid_list.numpmkid--;
1788 } else {
1789 s32Error = -EINVAL;
1790 }
1791
1792 return s32Error;
1793}
1794
1795/**
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001796 * @brief flush_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001797 * @details Flush all cached PMKIDs.
1798 * @param[in]
1799 * @return int : Return 0 on Success
1800 * @author mdaftedar
1801 * @date 01 MAR 2012
1802 * @version 1.0
1803 */
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001804static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001805{
Chaehyun Lim27268872015-09-15 14:06:13 +09001806 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001807
1808 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
1809
1810 /*Get cashed Pmkids and set all with zeros*/
Leo Kima949f902015-10-05 15:25:44 +09001811 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001812
1813 return 0;
1814}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001815
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001816
1817/**
1818 * @brief WILC_WFI_CfgParseRxAction
1819 * @details Function parses the received frames and modifies the following attributes:
1820 * -GO Intent
1821 * -Channel list
1822 * -Operating Channel
1823 *
1824 * @param[in] u8* Buffer, u32 length
1825 * @return NONE.
1826 * @author mdaftedar
1827 * @date 12 DEC 2012
1828 * @version
1829 */
1830
Arnd Bergmann1608c402015-11-16 15:04:53 +01001831static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001832{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001833 u32 index = 0;
1834 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001835
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001836 u8 op_channel_attr_index = 0;
1837 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001838
1839 while (index < len) {
1840 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001841 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001842 }
1843
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301844 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001845 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301846 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001847 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001848 index += buf[index + 1] + 3; /* ID,Length byte */
1849 }
Leo Kim0bd82742015-11-19 15:56:14 +09001850 if (wlan_channel != INVALID_CHANNEL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001851 /*Modify channel list attribute*/
1852 if (channel_list_attr_index) {
1853 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1854 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1855 if (buf[i] == 0x51) {
1856 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
Leo Kim0bd82742015-11-19 15:56:14 +09001857 buf[j] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001858 }
1859 break;
1860 }
1861 }
1862 }
1863 /*Modify operating channel attribute*/
1864 if (op_channel_attr_index) {
1865 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1866 buf[op_channel_attr_index + 6] = 0x51;
Leo Kim0bd82742015-11-19 15:56:14 +09001867 buf[op_channel_attr_index + 7] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001868 }
1869 }
1870}
1871
1872/**
1873 * @brief WILC_WFI_CfgParseTxAction
1874 * @details Function parses the transmitted action frames and modifies the
1875 * GO Intent attribute
1876 * @param[in] u8* Buffer, u32 length, bool bOperChan, u8 iftype
1877 * @return NONE.
1878 * @author mdaftedar
1879 * @date 12 DEC 2012
1880 * @version
1881 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01001882static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001883{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001884 u32 index = 0;
1885 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001886
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001887 u8 op_channel_attr_index = 0;
1888 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001889
1890 while (index < len) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001891 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001892 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001893
1894 break;
1895 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001896
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301897 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001898 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301899 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001900 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001901 index += buf[index + 1] + 3; /* ID,Length byte */
1902 }
Leo Kim0bd82742015-11-19 15:56:14 +09001903 if (wlan_channel != INVALID_CHANNEL && bOperChan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001904 /*Modify channel list attribute*/
1905 if (channel_list_attr_index) {
1906 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1907 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1908 if (buf[i] == 0x51) {
1909 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
Leo Kim0bd82742015-11-19 15:56:14 +09001910 buf[j] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001911 }
1912 break;
1913 }
1914 }
1915 }
1916 /*Modify operating channel attribute*/
1917 if (op_channel_attr_index) {
1918 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1919 buf[op_channel_attr_index + 6] = 0x51;
Leo Kim0bd82742015-11-19 15:56:14 +09001920 buf[op_channel_attr_index + 7] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001921 }
1922 }
1923}
1924
1925/* @brief WILC_WFI_p2p_rx
1926 * @details
1927 * @param[in]
1928 *
1929 * @return None
1930 * @author Mai Daftedar
1931 * @date 2 JUN 2013
1932 * @version 1.0
1933 */
1934
Chaehyun Limfbc2fe12015-09-15 14:06:16 +09001935void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001936{
1937
Chaehyun Lim27268872015-09-15 14:06:13 +09001938 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001939 u32 header, pkt_offset;
Leo Kim441dc602015-10-12 16:55:35 +09001940 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001941 u32 i = 0;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001942 s32 s32Freq;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001943
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001944 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001945 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001946
1947 /* Get WILC header */
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001948 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001949
1950 /* The packet offset field conain info about what type of managment frame */
1951 /* we are dealing with and ack status */
1952 pkt_offset = GET_PKT_OFFSET(header);
1953
1954 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1955 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1956 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001957 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001958 return;
1959 } else {
1960 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
1961 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],
1962 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001963 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001964 } else {
1965 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],
1966 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001967 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001968 }
1969 return;
1970 }
1971 } else {
1972
1973 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
1974
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001975 /*Upper layer is informed that the frame is received on this freq*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001976 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001977
1978 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1979 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
1980
Leo Kim1229b1a2015-10-29 12:05:39 +09001981 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001982 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
1983 return;
1984 }
1985 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1986
1987 switch (buff[ACTION_SUBTYPE_ID]) {
1988 case GAS_INTIAL_REQ:
1989 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
1990 break;
1991
1992 case GAS_INTIAL_RSP:
1993 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
1994 break;
1995
1996 case PUBLIC_ACT_VENDORSPEC:
Leo Kim881eb5d2015-11-19 15:56:15 +09001997 if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001998 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
Leo Kima25d5182015-11-19 15:56:19 +09001999 if (!wilc_ie) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002000 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
Leo Kim86685942015-11-19 15:56:18 +09002001 if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002002 p2p_recv_random = buff[i + 6];
Leo Kima25d5182015-11-19 15:56:19 +09002003 wilc_ie = true;
Leo Kimb84a3ac2015-11-19 15:56:17 +09002004 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", p2p_recv_random);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002005 break;
2006 }
2007 }
2008 }
2009 }
Leo Kimb84a3ac2015-11-19 15:56:17 +09002010 if (p2p_local_random > p2p_recv_random) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002011 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2012 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2013 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
Leo Kim881eb5d2015-11-19 15:56:15 +09002014 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002015 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
2016 break;
2017 }
2018 }
2019 }
Leo Kim583d9722015-11-19 15:56:16 +09002020 } else {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002021 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 +09002022 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002023 }
2024
2025
Leo Kima25d5182015-11-19 15:56:19 +09002026 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 +09002027 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
2028 /* extra attribute for sig_dbm: signal strength in mBm, or 0 if unknown */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002029 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002030 return;
2031 }
2032 break;
2033
2034 default:
2035 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
2036 break;
2037 }
2038 }
2039 }
2040
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002041 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002042 }
2043}
2044
2045/**
2046 * @brief WILC_WFI_mgmt_tx_complete
2047 * @details Returns result of writing mgmt frame to VMM (Tx buffers are freed here)
2048 * @param[in] priv
2049 * transmitting status
2050 * @return None
2051 * @author Amr Abdelmoghny
2052 * @date 20 MAY 2013
2053 * @version 1.0
2054 */
2055static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
2056{
2057 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
2058
2059
2060 kfree(pv_data->buff);
2061 kfree(pv_data);
2062}
2063
2064/**
2065 * @brief WILC_WFI_RemainOnChannelReady
2066 * @details Callback function, called from handle_remain_on_channel on being ready on channel
2067 * @param
2068 * @return none
2069 * @author Amr abdelmoghny
2070 * @date 9 JUNE 2013
2071 * @version
2072 */
2073
2074static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
2075{
Chaehyun Lim27268872015-09-15 14:06:13 +09002076 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002077
Chaehyun Lim27268872015-09-15 14:06:13 +09002078 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002079
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302080 PRINT_D(HOSTINF_DBG, "Remain on channel ready\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002081
Dean Lee72ed4dc2015-06-12 14:11:44 +09002082 priv->bInP2PlistenState = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002083
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002084 cfg80211_ready_on_channel(priv->wdev,
2085 priv->strRemainOnChanParams.u64ListenCookie,
2086 priv->strRemainOnChanParams.pstrListenChan,
2087 priv->strRemainOnChanParams.u32ListenDuration,
2088 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002089}
2090
2091/**
2092 * @brief WILC_WFI_RemainOnChannelExpired
2093 * @details Callback function, called on expiration of remain-on-channel duration
2094 * @param
2095 * @return none
2096 * @author Amr abdelmoghny
2097 * @date 15 MAY 2013
2098 * @version
2099 */
2100
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002101static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002102{
Chaehyun Lim27268872015-09-15 14:06:13 +09002103 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002104
Chaehyun Lim27268872015-09-15 14:06:13 +09002105 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002106
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002107 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302108 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002109
Dean Lee72ed4dc2015-06-12 14:11:44 +09002110 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002111
2112 /*Inform wpas of remain-on-channel expiration*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002113 cfg80211_remain_on_channel_expired(priv->wdev,
2114 priv->strRemainOnChanParams.u64ListenCookie,
2115 priv->strRemainOnChanParams.pstrListenChan,
2116 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002117 } else {
2118 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
2119 , priv->strRemainOnChanParams.u32ListenSessionID);
2120 }
2121}
2122
2123
2124/**
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002125 * @brief remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002126 * @details Request the driver to remain awake on the specified
2127 * channel for the specified duration to complete an off-channel
2128 * operation (e.g., public action frame exchange). When the driver is
2129 * ready on the requested channel, it must indicate this with an event
2130 * notification by calling cfg80211_ready_on_channel().
2131 * @param[in]
2132 * @return int : Return 0 on Success
2133 * @author mdaftedar
2134 * @date 01 MAR 2012
2135 * @version 1.0
2136 */
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002137static int remain_on_channel(struct wiphy *wiphy,
2138 struct wireless_dev *wdev,
2139 struct ieee80211_channel *chan,
2140 unsigned int duration, u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002141{
Leo Kime6e12662015-09-16 18:36:03 +09002142 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002143 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002144
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002145 priv = wiphy_priv(wiphy);
2146
2147 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
2148
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002149
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002150 if (wdev->iftype == NL80211_IFTYPE_AP) {
2151 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
2152 return s32Error;
2153 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002154
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002155 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002156
2157 /*Setting params needed by WILC_WFI_RemainOnChannelExpired()*/
2158 priv->strRemainOnChanParams.pstrListenChan = chan;
2159 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002160 priv->strRemainOnChanParams.u32ListenDuration = duration;
2161 priv->strRemainOnChanParams.u32ListenSessionID++;
2162
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002163 s32Error = wilc_remain_on_channel(priv->hWILCWFIDrv
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002164 , priv->strRemainOnChanParams.u32ListenSessionID
2165 , duration
2166 , chan->hw_value
2167 , WILC_WFI_RemainOnChannelExpired
2168 , WILC_WFI_RemainOnChannelReady
2169 , (void *)priv);
2170
2171 return s32Error;
2172}
2173
2174/**
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002175 * @brief cancel_remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002176 * @details Cancel an on-going remain-on-channel operation.
2177 * This allows the operation to be terminated prior to timeout based on
2178 * the duration value.
2179 * @param[in] struct wiphy *wiphy,
2180 * @param[in] struct net_device *dev
2181 * @param[in] u64 cookie,
2182 * @return int : Return 0 on Success
2183 * @author mdaftedar
2184 * @date 01 MAR 2012
2185 * @version 1.0
2186 */
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002187static int cancel_remain_on_channel(struct wiphy *wiphy,
2188 struct wireless_dev *wdev,
2189 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002190{
Leo Kime6e12662015-09-16 18:36:03 +09002191 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002192 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002193
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002194 priv = wiphy_priv(wiphy);
2195
2196 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
2197
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002198 s32Error = wilc_listen_state_expired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002199 return s32Error;
2200}
2201/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002202 * @brief WILC_WFI_mgmt_tx_frame
2203 * @details
2204 *
2205 * @param[in]
2206 * @return NONE.
2207 * @author mdaftedar
2208 * @date 01 JUL 2012
2209 * @version
2210 */
Chaehyun Limc1560322015-09-22 18:34:51 +09002211static int mgmt_tx(struct wiphy *wiphy,
2212 struct wireless_dev *wdev,
2213 struct cfg80211_mgmt_tx_params *params,
2214 u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002215{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002216 struct ieee80211_channel *chan = params->chan;
2217 unsigned int wait = params->wait;
2218 const u8 *buf = params->buf;
2219 size_t len = params->len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002220 const struct ieee80211_mgmt *mgmt;
2221 struct p2p_mgmt_data *mgmt_tx;
Chaehyun Lim27268872015-09-15 14:06:13 +09002222 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002223 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002224 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002225 perInterface_wlan_t *nic;
Leo Kim86685942015-11-19 15:56:18 +09002226 u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002227
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002228 nic = netdev_priv(wdev->netdev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002229 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002230 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002231
2232 *cookie = (unsigned long)buf;
2233 priv->u64tx_cookie = *cookie;
2234 mgmt = (const struct ieee80211_mgmt *) buf;
2235
2236 if (ieee80211_is_mgmt(mgmt->frame_control)) {
2237
2238 /*mgmt frame allocation*/
Glen Leef3052582015-09-10 12:03:04 +09002239 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002240 if (mgmt_tx == NULL) {
2241 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
Leo Kime6e12662015-09-16 18:36:03 +09002242 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002243 }
Glen Leef3052582015-09-10 12:03:04 +09002244 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002245 if (mgmt_tx->buff == NULL) {
2246 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
Tony Chof638dd32015-09-07 19:09:31 +09002247 kfree(mgmt_tx);
Leo Kime6e12662015-09-16 18:36:03 +09002248 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002249 }
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09002250 memcpy(mgmt_tx->buff, buf, len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002251 mgmt_tx->size = len;
2252
2253
2254 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
2255 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
2256 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002257 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002258 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002259 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002260 } else if (ieee80211_is_action(mgmt->frame_control)) {
Chaehyun Limd85f5322015-06-11 14:35:54 +09002261 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002262
2263
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002264 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002265 /*Only set the channel, if not a negotiation confirmation frame
2266 * (If Negotiation confirmation frame, force it
2267 * to be transmitted on the same negotiation channel)*/
2268
2269 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
2270 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
2271 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002272 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002273 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002274 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002275 }
2276 switch (buf[ACTION_SUBTYPE_ID]) {
2277 case GAS_INTIAL_REQ:
2278 {
2279 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
2280 break;
2281 }
2282
2283 case GAS_INTIAL_RSP:
2284 {
2285 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
2286 break;
2287 }
2288
2289 case PUBLIC_ACT_VENDORSPEC:
2290 {
Leo Kim881eb5d2015-11-19 15:56:15 +09002291 if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002292 /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/
2293 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002294 if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
Leo Kim583d9722015-11-19 15:56:16 +09002295 get_random_bytes(&p2p_local_random, 1);
2296 p2p_local_random++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002297 }
2298 }
2299
2300 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2301 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002302 if (p2p_local_random > p2p_recv_random) {
2303 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 +09002304
2305 /*Search for the p2p information information element , after the Public action subtype theres a byte for teh dialog token, skip that*/
2306 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
Leo Kim881eb5d2015-11-19 15:56:15 +09002307 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002308 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
Dean Lee72ed4dc2015-06-12 14:11:44 +09002309 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002310
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002311 /*If using supplicant go intent, no need at all*/
2312 /*to parse transmitted negotiation frames*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002313 else
Dean Lee72ed4dc2015-06-12 14:11:44 +09002314 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002315 break;
2316 }
2317 }
2318
2319 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
Shivani Bhardwajd8060fc2015-10-29 00:30:01 +05302320 /*
2321 * Adding WILC information element to allow two WILC devices to
2322 * identify each other and connect
2323 */
Leo Kim86685942015-11-19 15:56:18 +09002324 memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
2325 mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002326 mgmt_tx->size = buf_len;
2327 }
Leo Kim583d9722015-11-19 15:56:16 +09002328 } else {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002329 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 +09002330 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002331 }
2332
2333 } else {
2334 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
2335 }
2336
2337 break;
2338 }
2339
2340 default:
2341 {
2342 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
2343 break;
2344 }
2345 }
2346
2347 }
2348
2349 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 +09002350 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002351
Leo Kim1229b1a2015-10-29 12:05:39 +09002352 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n",
2353 jiffies, pstrWFIDrv->p2p_timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002354 }
2355
Glen Lee829c4772015-10-29 12:18:44 +09002356 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
2357 mgmt_tx->buff, mgmt_tx->size,
Glen Leec9d48342015-10-01 16:03:43 +09002358 WILC_WFI_mgmt_tx_complete);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002359 } else {
2360 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
2361 }
Leo Kimaaed3292015-10-12 16:55:38 +09002362 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002363}
2364
Chaehyun Lim85c587a2015-09-22 18:34:50 +09002365static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
2366 struct wireless_dev *wdev,
2367 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002368{
Chaehyun Lim27268872015-09-15 14:06:13 +09002369 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002370 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002371
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002372 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002373 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002374
2375
2376 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
Leo Kim1229b1a2015-10-29 12:05:39 +09002377 pstrWFIDrv->p2p_timeout = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002378
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +01002379 if (!priv->bInP2PlistenState) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002380 cfg80211_remain_on_channel_expired(priv->wdev,
2381 priv->strRemainOnChanParams.u64ListenCookie,
2382 priv->strRemainOnChanParams.pstrListenChan,
2383 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002384 }
2385
2386 return 0;
2387}
2388
2389/**
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002390 * @brief wilc_mgmt_frame_register
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002391 * @details Notify driver that a management frame type was
2392 * registered. Note that this callback may not sleep, and cannot run
2393 * concurrently with itself.
2394 * @param[in]
2395 * @return NONE.
2396 * @author mdaftedar
2397 * @date 01 JUL 2012
2398 * @version
2399 */
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002400void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
2401 u16 frame_type, bool reg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002402{
2403
Chaehyun Lim27268872015-09-15 14:06:13 +09002404 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002405 perInterface_wlan_t *nic;
Glen Lee1b869352015-10-20 17:14:01 +09002406 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002407
2408 priv = wiphy_priv(wiphy);
2409 nic = netdev_priv(priv->wdev->netdev);
Glen Lee1b869352015-10-20 17:14:01 +09002410 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002411
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002412 if (!frame_type)
2413 return;
2414
2415 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
2416 switch (frame_type) {
2417 case PROBE_REQ:
2418 {
2419 nic->g_struct_frame_reg[0].frame_type = frame_type;
2420 nic->g_struct_frame_reg[0].reg = reg;
2421 }
2422 break;
2423
2424 case ACTION:
2425 {
2426 nic->g_struct_frame_reg[1].frame_type = frame_type;
2427 nic->g_struct_frame_reg[1].reg = reg;
2428 }
2429 break;
2430
2431 default:
2432 {
2433 break;
2434 }
2435
2436 }
2437 /*If mac is closed, then return*/
Glen Lee1b869352015-10-20 17:14:01 +09002438 if (!wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002439 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
2440 return;
2441 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002442 wilc_frame_register(priv->hWILCWFIDrv, frame_type, reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002443
2444
2445}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002446
2447/**
Chaehyun Lima8047e22015-09-22 18:34:48 +09002448 * @brief set_cqm_rssi_config
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002449 * @details Configure connection quality monitor RSSI threshold.
2450 * @param[in] struct wiphy *wiphy:
2451 * @param[in] struct net_device *dev:
2452 * @param[in] s32 rssi_thold:
2453 * @param[in] u32 rssi_hyst:
2454 * @return int : Return 0 on Success
2455 * @author mdaftedar
2456 * @date 01 MAR 2012
2457 * @version 1.0
2458 */
Chaehyun Lima8047e22015-09-22 18:34:48 +09002459static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
2460 s32 rssi_thold, u32 rssi_hyst)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002461{
2462 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2463 return 0;
2464
2465}
2466/**
Chaehyun Limbdb63382015-09-14 12:24:19 +09002467 * @brief dump_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002468 * @details Configure connection quality monitor RSSI threshold.
2469 * @param[in] struct wiphy *wiphy:
2470 * @param[in] struct net_device *dev
2471 * @param[in] int idx
2472 * @param[in] u8 *mac
2473 * @param[in] struct station_info *sinfo
2474 * @return int : Return 0 on Success
2475 * @author mdaftedar
2476 * @date 01 MAR 2012
2477 * @version 1.0
2478 */
Chaehyun Limbdb63382015-09-14 12:24:19 +09002479static int dump_station(struct wiphy *wiphy, struct net_device *dev,
2480 int idx, u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002481{
Chaehyun Lim27268872015-09-15 14:06:13 +09002482 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002483
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002484 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2485
2486 if (idx != 0)
2487 return -ENOENT;
2488
2489 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002490
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002491 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002492
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002493 wilc_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002494
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002495 return 0;
2496
2497}
2498
2499
2500/**
Chaehyun Lim46530672015-09-22 18:34:46 +09002501 * @brief set_power_mgmt
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002502 * @details
2503 * @param[in]
2504 * @return int : Return 0 on Success.
2505 * @author mdaftedar
2506 * @date 01 JUL 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09002507 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002508 */
Chaehyun Lim46530672015-09-22 18:34:46 +09002509static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2510 bool enabled, int timeout)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002511{
Chaehyun Lim27268872015-09-15 14:06:13 +09002512 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002513
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002514 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2515
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002516 if (wiphy == NULL)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002517 return -ENOENT;
2518
2519 priv = wiphy_priv(wiphy);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002520 if (priv->hWILCWFIDrv == NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002521 PRINT_ER("Driver is NULL\n");
2522 return -EIO;
2523 }
2524
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002525 if (wilc_enable_ps)
2526 wilc_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002527
2528
Leo Kime6e12662015-09-16 18:36:03 +09002529 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002530
2531}
Glen Lee108b3432015-09-16 18:53:20 +09002532
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002533/**
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002534 * @brief change_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002535 * @details Change type/configuration of virtual interface,
2536 * keep the struct wireless_dev's iftype updated.
2537 * @param[in] NONE
2538 * @return int : Return 0 on Success.
2539 * @author mdaftedar
2540 * @date 01 MAR 2012
2541 * @version 1.0
2542 */
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002543static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2544 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002545{
Chaehyun Lim27268872015-09-15 14:06:13 +09002546 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002547 perInterface_wlan_t *nic;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002548 u8 interface_type;
Chaehyun Limd85f5322015-06-11 14:35:54 +09002549 u16 TID = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002550 u8 i;
Glen Lee299382c2015-10-20 17:13:56 +09002551 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002552
2553 nic = netdev_priv(dev);
2554 priv = wiphy_priv(wiphy);
Glen Lee299382c2015-10-20 17:13:56 +09002555 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002556
2557 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2558 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
Leo Kim583d9722015-11-19 15:56:16 +09002559 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +09002560 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +09002561 wilc_ie = false;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002562 wilc_optaining_ip = false;
2563 del_timer(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002564 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002565 /*Set WILC_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/
2566 if (g_ptk_keys_saved && g_gtk_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002567 wilc_set_machw_change_vir_if(dev, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002568 }
2569
2570 switch (type) {
2571 case NL80211_IFTYPE_STATION:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002572 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002573 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002574
2575 /* send delba over wlan interface */
2576
2577
2578 dev->ieee80211_ptr->iftype = type;
2579 priv->wdev->iftype = type;
2580 nic->monitor_flag = 0;
2581 nic->iftype = STATION_MODE;
2582
2583 /*Remove the enteries of the previously connected clients*/
2584 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002585 interface_type = nic->iftype;
2586 nic->iftype = STATION_MODE;
2587
Glen Lee299382c2015-10-20 17:13:56 +09002588 if (wl->initialized) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002589 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2590 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002591 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002592 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002593
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002594 /*Eliminate host interface blocking state*/
Glen Lee299382c2015-10-20 17:13:56 +09002595 up(&wl->cfg_event);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002596
Glen Lee53dc0cf2015-10-20 17:13:57 +09002597 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002598 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002599 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002600 nic->iftype = interface_type;
2601
2602 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002603 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2604 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002605 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002606 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002607
2608 /*Add saved WEP keys, if any*/
2609 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002610 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002611 g_key_wep_params.key_idx);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002612 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002613 g_key_wep_params.key,
2614 g_key_wep_params.key_len,
2615 g_key_wep_params.key_idx);
2616 }
2617
2618 /*No matter the driver handler passed here, it will be overwriiten*/
2619 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002620 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002621
2622 /*Add saved PTK and GTK keys, if any*/
2623 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2624 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2625 g_key_ptk_params.key[1],
2626 g_key_ptk_params.key[2]);
2627 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2628 g_key_gtk_params.key[1],
2629 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002630 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2631 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002632 g_add_ptk_key_params.key_idx,
2633 g_add_ptk_key_params.pairwise,
2634 g_add_ptk_key_params.mac_addr,
2635 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002636
Glen Lee299382c2015-10-20 17:13:56 +09002637 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2638 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002639 g_add_gtk_key_params.key_idx,
2640 g_add_gtk_key_params.pairwise,
2641 g_add_gtk_key_params.mac_addr,
2642 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002643 }
2644
Glen Lee299382c2015-10-20 17:13:56 +09002645 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002646 for (i = 0; i < num_reg_frame; i++) {
2647 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2648 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002649 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002650 nic->g_struct_frame_reg[i].frame_type,
2651 nic->g_struct_frame_reg[i].reg);
2652 }
2653 }
2654
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002655 wilc_enable_ps = true;
2656 wilc_set_power_mgmt(priv->hWILCWFIDrv, 1, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002657 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002658 break;
2659
2660 case NL80211_IFTYPE_P2P_CLIENT:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002661 wilc_enable_ps = false;
2662 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
2663 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002664 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002665
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002666 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2667 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002668
2669 dev->ieee80211_ptr->iftype = type;
2670 priv->wdev->iftype = type;
2671 nic->monitor_flag = 0;
2672
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002673 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2674 nic->iftype = CLIENT_MODE;
2675
2676
Glen Lee299382c2015-10-20 17:13:56 +09002677 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002678 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002679 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002680
Glen Lee53dc0cf2015-10-20 17:13:57 +09002681 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002682 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002683 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002684
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002685 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2686 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002687 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002688 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002689
2690 /*Add saved WEP keys, if any*/
2691 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002692 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2693 g_key_wep_params.key_idx);
2694 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
2695 g_key_wep_params.key,
2696 g_key_wep_params.key_len,
2697 g_key_wep_params.key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002698 }
2699
2700 /*No matter the driver handler passed here, it will be overwriiten*/
2701 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002702 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002703
2704 /*Add saved PTK and GTK keys, if any*/
2705 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2706 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2707 g_key_ptk_params.key[1],
2708 g_key_ptk_params.key[2]);
2709 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2710 g_key_gtk_params.key[1],
2711 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002712 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2713 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002714 g_add_ptk_key_params.key_idx,
2715 g_add_ptk_key_params.pairwise,
2716 g_add_ptk_key_params.mac_addr,
2717 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002718
Glen Lee299382c2015-10-20 17:13:56 +09002719 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2720 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002721 g_add_gtk_key_params.key_idx,
2722 g_add_gtk_key_params.pairwise,
2723 g_add_gtk_key_params.mac_addr,
2724 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002725 }
2726
2727 /*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 +09002728 refresh_scan(priv, 1, true);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002729 wilc_set_machw_change_vir_if(dev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002730
Glen Lee299382c2015-10-20 17:13:56 +09002731 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002732 for (i = 0; i < num_reg_frame; i++) {
2733 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2734 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002735 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002736 nic->g_struct_frame_reg[i].frame_type,
2737 nic->g_struct_frame_reg[i].reg);
2738 }
2739 }
2740 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002741 break;
2742
2743 case NL80211_IFTYPE_AP:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002744 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002745 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002746 dev->ieee80211_ptr->iftype = type;
2747 priv->wdev->iftype = type;
2748 nic->iftype = AP_MODE;
Johnny Kim8a143302015-06-10 17:06:46 +09002749 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002750
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002751 PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002752 wilc_wlan_get_firmware(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002753 /*If wilc is running, then close-open to actually get new firmware running (serves P2P)*/
Glen Lee299382c2015-10-20 17:13:56 +09002754 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002755 nic->iftype = AP_MODE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002756 wilc_mac_close(dev);
2757 wilc_mac_open(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002758
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002759 for (i = 0; i < num_reg_frame; i++) {
2760 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2761 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002762 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002763 nic->g_struct_frame_reg[i].frame_type,
2764 nic->g_struct_frame_reg[i].reg);
2765 }
2766 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002767 break;
2768
2769 case NL80211_IFTYPE_P2P_GO:
2770 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
2771
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002772 wilc_optaining_ip = true;
Leo Kim7e872df2015-11-19 15:56:20 +09002773 mod_timer(&wilc_during_ip_timer,
2774 jiffies + msecs_to_jiffies(during_ip_time));
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002775 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002776 /*Delete block ack has to be the latest config packet*/
2777 /*sent before downloading new FW. This is because it blocks on*/
2778 /*hWaitResponse semaphore, which allows previous config*/
2779 /*packets to actually take action on old FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002780 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2781 wl->vif[0].bssid, TID);
2782 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002783 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002784 dev->ieee80211_ptr->iftype = type;
2785 priv->wdev->iftype = type;
2786
Johnny Kim8a143302015-06-10 17:06:46 +09002787 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002788
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002789 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2790
2791
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002792 nic->iftype = GO_MODE;
2793
2794 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002795 wilc_wait_msg_queue_idle();
Glen Lee53dc0cf2015-10-20 17:13:57 +09002796 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002797 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002798 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002799
2800
2801 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002802 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2803 wilc_set_mac_address(wl->vif[0].hif_drv,
2804 wl->vif[0].src_addr);
2805 wilc_set_operation_mode(priv->hWILCWFIDrv, AP_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002806
2807 /*Add saved WEP keys, if any*/
2808 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002809 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2810 g_key_wep_params.key_idx);
2811 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002812 g_key_wep_params.key,
2813 g_key_wep_params.key_len,
2814 g_key_wep_params.key_idx);
2815 }
2816
2817 /*No matter the driver handler passed here, it will be overwriiten*/
2818 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002819 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002820
2821 /*Add saved PTK and GTK keys, if any*/
2822 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2823 PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0],
2824 g_key_ptk_params.key[1],
2825 g_key_ptk_params.key[2],
2826 g_key_ptk_params.cipher);
2827 PRINT_D(CFG80211_DBG, "gtk %x %x %x cipher %x\n", g_key_gtk_params.key[0],
2828 g_key_gtk_params.key[1],
2829 g_key_gtk_params.key[2],
2830 g_key_gtk_params.cipher);
Glen Lee299382c2015-10-20 17:13:56 +09002831 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2832 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002833 g_add_ptk_key_params.key_idx,
2834 g_add_ptk_key_params.pairwise,
2835 g_add_ptk_key_params.mac_addr,
2836 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002837
Glen Lee299382c2015-10-20 17:13:56 +09002838 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2839 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002840 g_add_gtk_key_params.key_idx,
2841 g_add_gtk_key_params.pairwise,
2842 g_add_gtk_key_params.mac_addr,
2843 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002844 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002845
Glen Lee299382c2015-10-20 17:13:56 +09002846 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002847 for (i = 0; i < num_reg_frame; i++) {
2848 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2849 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002850 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002851 nic->g_struct_frame_reg[i].frame_type,
2852 nic->g_struct_frame_reg[i].reg);
2853 }
2854 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002855 break;
2856
2857 default:
2858 PRINT_ER("Unknown interface type= %d\n", type);
Leo Kimaaed3292015-10-12 16:55:38 +09002859 return -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002860 }
2861
Leo Kimaaed3292015-10-12 16:55:38 +09002862 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002863}
2864
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002865/* (austin.2013-07-23)
2866 *
2867 * To support revised cfg80211_ops
2868 *
2869 * add_beacon --> start_ap
2870 * set_beacon --> change_beacon
2871 * del_beacon --> stop_ap
2872 *
2873 * beacon_parameters --> cfg80211_ap_settings
2874 * cfg80211_beacon_data
2875 *
2876 * applicable for linux kernel 3.4+
2877 */
2878
2879/**
Chaehyun Lima13168d2015-09-14 12:24:12 +09002880 * @brief start_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002881 * @details Add a beacon with given parameters, @head, @interval
2882 * and @dtim_period will be valid, @tail is optional.
2883 * @param[in] wiphy
2884 * @param[in] dev The net device structure
2885 * @param[in] settings cfg80211_ap_settings parameters for the beacon to be added
2886 * @return int : Return 0 on Success.
2887 * @author austin
2888 * @date 23 JUL 2013
2889 * @version 1.0
2890 */
Chaehyun Lima13168d2015-09-14 12:24:12 +09002891static int start_ap(struct wiphy *wiphy, struct net_device *dev,
2892 struct cfg80211_ap_settings *settings)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002893{
2894 struct cfg80211_beacon_data *beacon = &(settings->beacon);
Chaehyun Lim27268872015-09-15 14:06:13 +09002895 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002896 s32 s32Error = 0;
Glen Lee684dc182015-10-20 17:14:02 +09002897 struct wilc *wl;
2898 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002899
2900 priv = wiphy_priv(wiphy);
Glen Lee684dc182015-10-20 17:14:02 +09002901 nic = netdev_priv(dev);
2902 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002903 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
2904
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302905 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 +09002906 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
2907
Chaehyun Lim80785a92015-09-14 12:24:01 +09002908 s32Error = set_channel(wiphy, &settings->chandef);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002909
Leo Kime6e12662015-09-16 18:36:03 +09002910 if (s32Error != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002911 PRINT_ER("Error in setting channel\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002912
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002913 wilc_wlan_set_bssid(dev, wl->vif[0].src_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002914
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002915 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002916 settings->beacon_interval,
2917 settings->dtim_period,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002918 beacon->head_len, (u8 *)beacon->head,
2919 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002920
2921 return s32Error;
2922}
2923
2924/**
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002925 * @brief change_beacon
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002926 * @details Add a beacon with given parameters, @head, @interval
2927 * and @dtim_period will be valid, @tail is optional.
2928 * @param[in] wiphy
2929 * @param[in] dev The net device structure
2930 * @param[in] beacon cfg80211_beacon_data for the beacon to be changed
2931 * @return int : Return 0 on Success.
2932 * @author austin
2933 * @date 23 JUL 2013
2934 * @version 1.0
2935 */
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002936static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
2937 struct cfg80211_beacon_data *beacon)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002938{
Chaehyun Lim27268872015-09-15 14:06:13 +09002939 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002940 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002941
2942 priv = wiphy_priv(wiphy);
2943 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
2944
2945
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002946 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002947 0,
2948 0,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002949 beacon->head_len, (u8 *)beacon->head,
2950 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002951
2952 return s32Error;
2953}
2954
2955/**
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002956 * @brief stop_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002957 * @details Remove beacon configuration and stop sending the beacon.
2958 * @param[in]
2959 * @return int : Return 0 on Success.
2960 * @author austin
2961 * @date 23 JUL 2013
2962 * @version 1.0
2963 */
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002964static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002965{
Leo Kime6e12662015-09-16 18:36:03 +09002966 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002967 struct wilc_priv *priv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002968 u8 NullBssid[ETH_ALEN] = {0};
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002969
Leo Kim7ae43362015-09-16 18:35:59 +09002970 if (!wiphy)
2971 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002972
2973 priv = wiphy_priv(wiphy);
2974
2975 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
2976
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002977 wilc_wlan_set_bssid(dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002978
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002979 s32Error = wilc_del_beacon(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002980
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002981 if (s32Error)
2982 PRINT_ER("Host delete beacon fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002983
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002984 return s32Error;
2985}
2986
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002987/**
Chaehyun Limed269552015-09-14 12:24:15 +09002988 * @brief add_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002989 * @details Add a new station.
2990 * @param[in]
2991 * @return int : Return 0 on Success.
2992 * @author mdaftedar
2993 * @date 01 MAR 2012
2994 * @version 1.0
2995 */
Chaehyun Limed269552015-09-14 12:24:15 +09002996static int add_station(struct wiphy *wiphy, struct net_device *dev,
2997 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002998{
Leo Kime6e12662015-09-16 18:36:03 +09002999 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003000 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09003001 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003002 perInterface_wlan_t *nic;
3003
Leo Kim7ae43362015-09-16 18:35:59 +09003004 if (!wiphy)
3005 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003006
3007 priv = wiphy_priv(wiphy);
3008 nic = netdev_priv(dev);
3009
3010 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003011 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09003012 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003013 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003014 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003015 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003016
3017 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
3018
3019 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],
3020 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003021 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003022 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3023 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003024
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003025 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003026 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003027 } else {
Leo Kim22520122015-10-29 12:05:45 +09003028 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003029 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003030 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003031 memcpy(strStaParams.ht_supp_mcs_set,
3032 &params->ht_capa->mcs,
3033 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003034 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003035 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003036 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003037 }
3038
Leo Kimf676e172015-10-29 12:05:52 +09003039 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003040 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003041
Leo Kim22520122015-10-29 12:05:45 +09003042 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3043 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003044 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3045 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003046 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3047 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003048 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3049 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003050 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3051 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003052 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3053 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003054 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3055 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003056 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3057 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003058
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003059 s32Error = wilc_add_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003060 if (s32Error)
3061 PRINT_ER("Host add station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003062 }
3063
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003064 return s32Error;
3065}
3066
3067/**
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003068 * @brief del_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003069 * @details Remove a station; @mac may be NULL to remove all stations.
3070 * @param[in]
3071 * @return int : Return 0 on Success.
3072 * @author mdaftedar
3073 * @date 01 MAR 2012
3074 * @version 1.0
3075 */
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003076static int del_station(struct wiphy *wiphy, struct net_device *dev,
3077 struct station_del_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003078{
Arnd Bergmann057d1e92015-06-01 21:06:44 +02003079 const u8 *mac = params->mac;
Leo Kime6e12662015-09-16 18:36:03 +09003080 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003081 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003082 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003083
Leo Kim7ae43362015-09-16 18:35:59 +09003084 if (!wiphy)
3085 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003086
3087 priv = wiphy_priv(wiphy);
3088 nic = netdev_priv(dev);
3089
3090 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
3091 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
3092
3093
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003094 if (mac == NULL) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05303095 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003096 s32Error = wilc_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003097 } else {
3098 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]);
3099 }
3100
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003101 s32Error = wilc_del_station(priv->hWILCWFIDrv, mac);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003102
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003103 if (s32Error)
3104 PRINT_ER("Host delete station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003105 }
3106 return s32Error;
3107}
3108
3109/**
Chaehyun Lim14b42082015-09-14 12:24:17 +09003110 * @brief change_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003111 * @details Modify a given station.
3112 * @param[in]
3113 * @return int : Return 0 on Success.
3114 * @author mdaftedar
3115 * @date 01 MAR 2012
3116 * @version 1.0
3117 */
Chaehyun Lim14b42082015-09-14 12:24:17 +09003118static int change_station(struct wiphy *wiphy, struct net_device *dev,
3119 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003120{
Leo Kime6e12662015-09-16 18:36:03 +09003121 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003122 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09003123 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003124 perInterface_wlan_t *nic;
3125
3126
3127 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
3128
Leo Kim7ae43362015-09-16 18:35:59 +09003129 if (!wiphy)
3130 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003131
3132 priv = wiphy_priv(wiphy);
3133 nic = netdev_priv(dev);
3134
3135 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003136 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003137 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003138 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003139 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003140
Leo Kim2353c382015-10-29 12:05:41 +09003141 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n",
3142 strStaParams.bssid[0], strStaParams.bssid[1],
3143 strStaParams.bssid[2], strStaParams.bssid[3],
3144 strStaParams.bssid[4], strStaParams.bssid[5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003145 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003146 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3147 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003148
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003149 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003150 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003151 } else {
Leo Kim22520122015-10-29 12:05:45 +09003152 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003153 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003154 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003155 memcpy(strStaParams.ht_supp_mcs_set,
3156 &params->ht_capa->mcs,
3157 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003158 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003159 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003160 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003161 }
3162
Leo Kimf676e172015-10-29 12:05:52 +09003163 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003164 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003165
Leo Kim22520122015-10-29 12:05:45 +09003166 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3167 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003168 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3169 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003170 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3171 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003172 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3173 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003174 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3175 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003176 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3177 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003178 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3179 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003180 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3181 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003182
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003183 s32Error = wilc_edit_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003184 if (s32Error)
3185 PRINT_ER("Host edit station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003186 }
3187 return s32Error;
3188}
3189
3190
3191/**
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003192 * @brief add_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003193 * @details
3194 * @param[in]
3195 * @return int : Return 0 on Success.
3196 * @author mdaftedar
3197 * @date 01 JUL 2012
3198 * @version 1.0
3199 */
Chaehyun Lim37316e82015-09-22 18:34:52 +09003200static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
3201 const char *name,
3202 unsigned char name_assign_type,
3203 enum nl80211_iftype type,
3204 u32 *flags,
3205 struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003206{
3207 perInterface_wlan_t *nic;
Chaehyun Lim27268872015-09-15 14:06:13 +09003208 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003209 struct net_device *new_ifc = NULL;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003210
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003211 priv = wiphy_priv(wiphy);
3212
3213
3214
3215 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
3216
3217 nic = netdev_priv(priv->wdev->netdev);
3218
3219
3220 if (type == NL80211_IFTYPE_MONITOR) {
3221 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
3222 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", nic->wilc_netdev);
3223 new_ifc = WILC_WFI_init_mon_interface(name, nic->wilc_netdev);
3224 if (new_ifc != NULL) {
3225 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003226 nic = netdev_priv(priv->wdev->netdev);
3227 nic->monitor_flag = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003228 } else
3229 PRINT_ER("Error in initializing monitor interface\n ");
3230 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003231 return priv->wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003232}
3233
3234/**
Chaehyun Limb4a73352015-09-14 12:24:10 +09003235 * @brief del_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003236 * @details
3237 * @param[in]
3238 * @return int : Return 0 on Success.
3239 * @author mdaftedar
3240 * @date 01 JUL 2012
3241 * @version 1.0
3242 */
Chaehyun Lim956d7212015-09-22 18:34:49 +09003243static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003244{
3245 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
Leo Kime6e12662015-09-16 18:36:03 +09003246 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003247}
3248
Chaehyun Lim08241922015-09-15 14:06:12 +09003249static struct cfg80211_ops wilc_cfg80211_ops = {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003250
Chaehyun Lim80785a92015-09-14 12:24:01 +09003251 .set_monitor_channel = set_channel,
Chaehyun Lim0e30d062015-09-14 12:24:02 +09003252 .scan = scan,
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +09003253 .connect = connect,
Chaehyun Limb027cde2015-09-14 12:24:04 +09003254 .disconnect = disconnect,
Chaehyun Lim953d4172015-09-14 12:24:05 +09003255 .add_key = add_key,
Chaehyun Lim3044ba72015-09-14 12:24:06 +09003256 .del_key = del_key,
Chaehyun Limf4893df2015-09-14 12:24:07 +09003257 .get_key = get_key,
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09003258 .set_default_key = set_default_key,
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003259 .add_virtual_intf = add_virtual_intf,
Chaehyun Limb4a73352015-09-14 12:24:10 +09003260 .del_virtual_intf = del_virtual_intf,
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09003261 .change_virtual_intf = change_virtual_intf,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003262
Chaehyun Lima13168d2015-09-14 12:24:12 +09003263 .start_ap = start_ap,
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09003264 .change_beacon = change_beacon,
Chaehyun Limc8cddd72015-09-14 12:24:14 +09003265 .stop_ap = stop_ap,
Chaehyun Limed269552015-09-14 12:24:15 +09003266 .add_station = add_station,
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003267 .del_station = del_station,
Chaehyun Lim14b42082015-09-14 12:24:17 +09003268 .change_station = change_station,
Chaehyun Limf06f5622015-09-14 12:24:18 +09003269 .get_station = get_station,
Chaehyun Limbdb63382015-09-14 12:24:19 +09003270 .dump_station = dump_station,
Chaehyun Lima5f7db62015-09-14 12:24:20 +09003271 .change_bss = change_bss,
Chaehyun Lima76b63e2015-09-14 12:24:21 +09003272 .set_wiphy_params = set_wiphy_params,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003273
Chaehyun Lim4d466572015-09-14 12:24:22 +09003274 .set_pmksa = set_pmksa,
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09003275 .del_pmksa = del_pmksa,
Chaehyun Limb33c39b2015-09-14 12:24:24 +09003276 .flush_pmksa = flush_pmksa,
Chaehyun Lim6d19d692015-09-14 12:24:25 +09003277 .remain_on_channel = remain_on_channel,
Chaehyun Lim1dd54402015-09-14 12:24:26 +09003278 .cancel_remain_on_channel = cancel_remain_on_channel,
Chaehyun Lim4a2f9b32015-09-14 12:24:27 +09003279 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
Chaehyun Lim12a26a32015-09-14 12:24:28 +09003280 .mgmt_tx = mgmt_tx,
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09003281 .mgmt_frame_register = wilc_mgmt_frame_register,
Chaehyun Lim46530672015-09-22 18:34:46 +09003282 .set_power_mgmt = set_power_mgmt,
Chaehyun Lima8047e22015-09-22 18:34:48 +09003283 .set_cqm_rssi_config = set_cqm_rssi_config,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003284
3285};
3286
3287
3288
3289
3290
3291/**
3292 * @brief WILC_WFI_update_stats
3293 * @details Modify parameters for a given BSS.
3294 * @param[in]
3295 * @return int : Return 0 on Success.
3296 * @author mdaftedar
3297 * @date 01 MAR 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09003298 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003299 */
3300int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
3301{
3302
Chaehyun Lim27268872015-09-15 14:06:13 +09003303 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003304
3305 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003306 switch (changed) {
3307
3308 case WILC_WFI_RX_PKT:
3309 {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003310 priv->netstats.rx_packets++;
3311 priv->netstats.rx_bytes += pktlen;
3312 priv->netstats.rx_time = get_jiffies_64();
3313 }
3314 break;
3315
3316 case WILC_WFI_TX_PKT:
3317 {
3318 priv->netstats.tx_packets++;
3319 priv->netstats.tx_bytes += pktlen;
3320 priv->netstats.tx_time = get_jiffies_64();
3321
3322 }
3323 break;
3324
3325 default:
3326 break;
3327 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003328 return 0;
3329}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003330
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003331/**
3332 * @brief WILC_WFI_CfgAlloc
3333 * @details Allocation of the wireless device structure and assigning it
3334 * to the cfg80211 operations structure.
3335 * @param[in] NONE
3336 * @return wireless_dev : Returns pointer to wireless_dev structure.
3337 * @author mdaftedar
3338 * @date 01 MAR 2012
3339 * @version 1.0
3340 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01003341static struct wireless_dev *WILC_WFI_CfgAlloc(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003342{
3343
3344 struct wireless_dev *wdev;
3345
3346
3347 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
3348 /*Allocating the wireless device structure*/
3349 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
3350 if (!wdev) {
3351 PRINT_ER("Cannot allocate wireless device\n");
3352 goto _fail_;
3353 }
3354
3355 /*Creating a new wiphy, linking wireless structure with the wiphy structure*/
Chaehyun Lim27268872015-09-15 14:06:13 +09003356 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003357 if (!wdev->wiphy) {
3358 PRINT_ER("Cannot allocate wiphy\n");
3359 goto _fail_mem_;
3360
3361 }
3362
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003363 /* enable 802.11n HT */
3364 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
3365 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
3366 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3367 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
3368 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003369
3370 /*wiphy bands*/
3371 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
3372
3373 return wdev;
3374
3375_fail_mem_:
3376 kfree(wdev);
3377_fail_:
3378 return NULL;
3379
3380}
3381/**
Chaehyun Lim8459fd52015-09-20 15:51:09 +09003382 * @brief wilc_create_wiphy
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003383 * @details Registering of the wiphy structure and interface modes
3384 * @param[in] NONE
3385 * @return NONE
3386 * @author mdaftedar
3387 * @date 01 MAR 2012
3388 * @version 1.0
3389 */
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01003390struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003391{
Chaehyun Lim27268872015-09-15 14:06:13 +09003392 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003393 struct wireless_dev *wdev;
Leo Kime6e12662015-09-16 18:36:03 +09003394 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003395
3396 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
3397
3398 wdev = WILC_WFI_CfgAlloc();
3399 if (wdev == NULL) {
3400 PRINT_ER("CfgAlloc Failed\n");
3401 return NULL;
3402 }
3403
3404
3405 /*Return hardware description structure (wiphy)'s priv*/
3406 priv = wdev_priv(wdev);
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003407 sema_init(&(priv->SemHandleUpdateStats), 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003408
3409 /*Link the wiphy with wireless structure*/
3410 priv->wdev = wdev;
3411
3412 /*Maximum number of probed ssid to be added by user for the scan request*/
3413 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003414 /*Maximum number of pmkids to be cashed*/
3415 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
3416 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003417
3418 wdev->wiphy->max_scan_ie_len = 1000;
3419
3420 /*signal strength in mBm (100*dBm) */
3421 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3422
3423 /*Set the availaible cipher suites*/
3424 wdev->wiphy->cipher_suites = cipher_suites;
3425 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003426 /*Setting default managment types: for register action frame: */
3427 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003428
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003429 wdev->wiphy->max_remain_on_channel_duration = 500;
3430 /*Setting the wiphy interfcae mode and type before registering the wiphy*/
3431 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
3432 BIT(NL80211_IFTYPE_P2P_CLIENT);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003433 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003434 wdev->iftype = NL80211_IFTYPE_STATION;
3435
3436
3437
3438 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
3439 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
3440 wdev->wiphy->interface_modes, wdev->iftype);
3441
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01003442 set_wiphy_dev(wdev->wiphy, dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003443
3444 /*Register wiphy structure*/
3445 s32Error = wiphy_register(wdev->wiphy);
3446 if (s32Error) {
3447 PRINT_ER("Cannot register wiphy device\n");
3448 /*should define what action to be taken in such failure*/
3449 } else {
3450 PRINT_D(CFG80211_DBG, "Successful Registering\n");
3451 }
3452
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003453 priv->dev = net;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003454 return wdev;
3455
3456
3457}
3458/**
3459 * @brief WILC_WFI_WiphyFree
3460 * @details Freeing allocation of the wireless device structure
3461 * @param[in] NONE
3462 * @return NONE
3463 * @author mdaftedar
3464 * @date 01 MAR 2012
3465 * @version 1.0
3466 */
Chaehyun Limdd4b6a82015-09-20 15:51:25 +09003467int wilc_init_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003468{
3469
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003470 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003471
Chaehyun Lim27268872015-09-15 14:06:13 +09003472 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003473
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003474 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
3475 priv = wdev_priv(net->ieee80211_ptr);
3476 if (op_ifcs == 0) {
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -07003477 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003478 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003479 }
3480 op_ifcs++;
3481 if (s32Error < 0) {
3482 PRINT_ER("Failed to creat refresh Timer\n");
3483 return s32Error;
3484 }
3485
Dean Lee72ed4dc2015-06-12 14:11:44 +09003486 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003487
Dean Lee72ed4dc2015-06-12 14:11:44 +09003488 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003489
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003490 sema_init(&(priv->hSemScanReq), 1);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003491 s32Error = wilc_init(net, &priv->hWILCWFIDrv);
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003492 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003493 PRINT_ER("Error while initializing hostinterface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003494
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003495 return s32Error;
3496}
3497
3498/**
3499 * @brief WILC_WFI_WiphyFree
3500 * @details Freeing allocation of the wireless device structure
3501 * @param[in] NONE
3502 * @return NONE
3503 * @author mdaftedar
3504 * @date 01 MAR 2012
3505 * @version 1.0
3506 */
Chaehyun Lima9a16822015-09-20 15:51:24 +09003507int wilc_deinit_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003508{
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003509 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003510
Chaehyun Lim27268872015-09-15 14:06:13 +09003511 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003512
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003513 priv = wdev_priv(net->ieee80211_ptr);
3514
Dean Lee72ed4dc2015-06-12 14:11:44 +09003515 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003516
Dean Lee72ed4dc2015-06-12 14:11:44 +09003517 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003518
3519 op_ifcs--;
3520
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003521 s32Error = wilc_deinit(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003522
3523 /* Clear the Shadow scan */
Leo Kimd14991a2015-11-19 15:56:22 +09003524 clear_shadow_scan();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003525 if (op_ifcs == 0) {
3526 PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003527 del_timer_sync(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003528 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003529
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003530 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003531 PRINT_ER("Error while deintializing host interface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003532
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003533 return s32Error;
3534}
3535
3536
3537/**
3538 * @brief WILC_WFI_WiphyFree
3539 * @details Freeing allocation of the wireless device structure
3540 * @param[in] NONE
3541 * @return NONE
3542 * @author mdaftedar
3543 * @date 01 MAR 2012
3544 * @version 1.0
3545 */
Chaehyun Lim96da20a2015-09-20 15:51:08 +09003546void wilc_free_wiphy(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003547{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003548 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
3549
Chaehyun Lim619837a2015-09-20 15:51:10 +09003550 if (!net) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003551 PRINT_D(INIT_DBG, "net_device is NULL\n");
3552 return;
3553 }
3554
Chaehyun Lim619837a2015-09-20 15:51:10 +09003555 if (!net->ieee80211_ptr) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003556 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
3557 return;
3558 }
3559
Chaehyun Lim619837a2015-09-20 15:51:10 +09003560 if (!net->ieee80211_ptr->wiphy) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003561 PRINT_D(INIT_DBG, "wiphy is NULL\n");
3562 return;
3563 }
3564
3565 wiphy_unregister(net->ieee80211_ptr->wiphy);
3566
3567 PRINT_D(INIT_DBG, "Freeing wiphy\n");
3568 wiphy_free(net->ieee80211_ptr->wiphy);
3569 kfree(net->ieee80211_ptr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003570}