blob: bcfddbfe7e9b856b71534e1211301d3f6eec4ba9 [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
Leo Kim0b8bea12015-11-19 15:56:35 +0900227static u32 get_rssi_avg(tstrNetworkInfo *network_info)
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;
Leo Kim0b8bea12015-11-19 15:56:35 +0900231 u8 num_rssi = (network_info->strRssi.u8Full) ? NUM_RSSI : (network_info->strRssi.u8Index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900232
233 for (i = 0; i < num_rssi; i++)
Leo Kim0b8bea12015-11-19 15:56:35 +0900234 rssi_v += network_info->strRssi.as8RSSI[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900235
236 rssi_v /= num_rssi;
237 return rssi_v;
238}
239
Leo Kim48ee7ba2015-11-19 15:56:24 +0900240static void refresh_scan(void *user_void, u8 all, bool direct_scan)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900241{
Chaehyun Lim27268872015-09-15 14:06:13 +0900242 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900243 struct wiphy *wiphy;
244 struct cfg80211_bss *bss = NULL;
245 int i;
246 int rssi = 0;
247
Leo Kim84df0e62015-11-19 15:56:23 +0900248 priv = (struct wilc_priv *)user_void;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900249 wiphy = priv->dev->ieee80211_ptr->wiphy;
250
Leo Kim771fbae2015-11-19 15:56:10 +0900251 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimce3b1b52015-11-19 15:56:25 +0900252 tstrNetworkInfo *network_info;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900253
Leo Kimce3b1b52015-11-19 15:56:25 +0900254 network_info = &last_scanned_shadow[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900255
Leo Kimce3b1b52015-11-19 15:56:25 +0900256 if (!network_info->u8Found || all) {
Leo Kimc6f5e3a2015-11-19 15:56:26 +0900257 s32 freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900258 struct ieee80211_channel *channel;
259
Leo Kimce3b1b52015-11-19 15:56:25 +0900260 if (network_info) {
Leo Kimc6f5e3a2015-11-19 15:56:26 +0900261 freq = ieee80211_channel_to_frequency((s32)network_info->u8channel, IEEE80211_BAND_2GHZ);
262 channel = ieee80211_get_channel(wiphy, freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900263
Leo Kimce3b1b52015-11-19 15:56:25 +0900264 rssi = get_rssi_avg(network_info);
265 if (memcmp("DIRECT-", network_info->au8ssid, 7) ||
Leo Kim48ee7ba2015-11-19 15:56:24 +0900266 direct_scan) {
Leo Kimce3b1b52015-11-19 15:56:25 +0900267 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, network_info->au8bssid, network_info->u64Tsf, network_info->u16CapInfo,
268 network_info->u16BeaconPeriod, (const u8 *)network_info->pu8IEs,
269 (size_t)network_info->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900270 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900271 }
272 }
273
274 }
275 }
276
277}
278
Leo Kim12b01382015-11-19 15:56:27 +0900279static void reset_shadow_found(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900280{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900281 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900282
Leo Kim771fbae2015-11-19 15:56:10 +0900283 for (i = 0; i < last_scanned_cnt; i++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900284 last_scanned_shadow[i].u8Found = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900285}
286
Leo Kim5e51d8b2015-11-19 15:56:28 +0900287static void update_scan_time(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900288{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900289 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900290
Leo Kim771fbae2015-11-19 15:56:10 +0900291 for (i = 0; i < last_scanned_cnt; i++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900292 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900293}
294
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700295static void remove_network_from_shadow(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900296{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900297 unsigned long now = jiffies;
298 int i, j;
299
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900300
Leo Kim771fbae2015-11-19 15:56:10 +0900301 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900302 if (time_after(now, last_scanned_shadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) {
303 PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", last_scanned_shadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900304
Leo Kimf1ab1172015-11-19 15:56:11 +0900305 kfree(last_scanned_shadow[i].pu8IEs);
306 last_scanned_shadow[i].pu8IEs = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900307
Leo Kimf1ab1172015-11-19 15:56:11 +0900308 wilc_free_join_params(last_scanned_shadow[i].pJoinParams);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900309
Leo Kim771fbae2015-11-19 15:56:10 +0900310 for (j = i; (j < last_scanned_cnt - 1); j++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900311 last_scanned_shadow[j] = last_scanned_shadow[j + 1];
Leo Kim771fbae2015-11-19 15:56:10 +0900312
313 last_scanned_cnt--;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900314 }
315 }
316
Leo Kim771fbae2015-11-19 15:56:10 +0900317 PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n",
318 last_scanned_cnt);
319 if (last_scanned_cnt != 0) {
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700320 hAgingTimer.data = arg;
321 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
322 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900323 PRINT_D(CFG80211_DBG, "No need to restart Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700324 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900325}
326
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700327static void clear_duringIP(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900328{
329 PRINT_D(GENERIC_DBG, "GO:IP Obtained , enable scan\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100330 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900331}
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900332
Leo Kim157814f2015-11-19 15:56:29 +0900333static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo,
334 void *user_void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900335{
Chaehyun Lima74cc6b2015-10-02 16:41:17 +0900336 int state = -1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900337 int i;
338
Leo Kim771fbae2015-11-19 15:56:10 +0900339 if (last_scanned_cnt == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900340 PRINT_D(CFG80211_DBG, "Starting Aging timer\n");
Leo Kim157814f2015-11-19 15:56:29 +0900341 hAgingTimer.data = (unsigned long)user_void;
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700342 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900343 state = -1;
344 } else {
345 /* Linear search for now */
Leo Kim771fbae2015-11-19 15:56:10 +0900346 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900347 if (memcmp(last_scanned_shadow[i].au8bssid,
348 pstrNetworkInfo->au8bssid, 6) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900349 state = i;
350 break;
351 }
352 }
353 }
354 return state;
355}
356
Leo Kim5c4cf0d2015-11-19 15:56:30 +0900357static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo,
358 void *user_void, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900359{
Leo Kim5c4cf0d2015-11-19 15:56:30 +0900360 int ap_found = is_network_in_shadow(pstrNetworkInfo, user_void);
Chaehyun Limfbc2fe12015-09-15 14:06:16 +0900361 u32 ap_index = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900362 u8 rssi_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900363
Leo Kim771fbae2015-11-19 15:56:10 +0900364 if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900365 PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
366 return;
367 }
368 if (ap_found == -1) {
Leo Kim771fbae2015-11-19 15:56:10 +0900369 ap_index = last_scanned_cnt;
370 last_scanned_cnt++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900371
372 } else {
373 ap_index = ap_found;
374 }
Leo Kimf1ab1172015-11-19 15:56:11 +0900375 rssi_index = last_scanned_shadow[ap_index].strRssi.u8Index;
376 last_scanned_shadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900377 if (rssi_index == NUM_RSSI) {
378 rssi_index = 0;
Leo Kimf1ab1172015-11-19 15:56:11 +0900379 last_scanned_shadow[ap_index].strRssi.u8Full = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900380 }
Leo Kimf1ab1172015-11-19 15:56:11 +0900381 last_scanned_shadow[ap_index].strRssi.u8Index = rssi_index;
382 last_scanned_shadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
383 last_scanned_shadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
384 last_scanned_shadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
385 memcpy(last_scanned_shadow[ap_index].au8ssid,
386 pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
387 memcpy(last_scanned_shadow[ap_index].au8bssid,
388 pstrNetworkInfo->au8bssid, ETH_ALEN);
389 last_scanned_shadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
390 last_scanned_shadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
391 last_scanned_shadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
392 last_scanned_shadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
393 last_scanned_shadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900394 if (ap_found != -1)
Leo Kimf1ab1172015-11-19 15:56:11 +0900395 kfree(last_scanned_shadow[ap_index].pu8IEs);
396 last_scanned_shadow[ap_index].pu8IEs =
Glen Leef3052582015-09-10 12:03:04 +0900397 kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL); /* will be deallocated by the WILC_WFI_CfgScan() function */
Leo Kimf1ab1172015-11-19 15:56:11 +0900398 memcpy(last_scanned_shadow[ap_index].pu8IEs,
399 pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
400 last_scanned_shadow[ap_index].u32TimeRcvdInScan = jiffies;
401 last_scanned_shadow[ap_index].u32TimeRcvdInScanCached = jiffies;
402 last_scanned_shadow[ap_index].u8Found = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900403 if (ap_found != -1)
Leo Kimf1ab1172015-11-19 15:56:11 +0900404 wilc_free_join_params(last_scanned_shadow[ap_index].pJoinParams);
405 last_scanned_shadow[ap_index].pJoinParams = pJoinParams;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900406}
407
408
409/**
410 * @brief CfgScanResult
411 * @details Callback function which returns the scan results found
412 *
413 * @param[in] tenuScanEvent enuScanEvent: enum, indicating the scan event triggered, whether that is
414 * SCAN_EVENT_NETWORK_FOUND or SCAN_EVENT_DONE
415 * tstrNetworkInfo* pstrNetworkInfo: structure holding the scan results information
416 * void* pUserVoid: Private structure associated with the wireless interface
417 * @return NONE
418 * @author mabubakr
419 * @date
420 * @version 1.0
421 */
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900422static void CfgScanResult(enum scan_event scan_event,
Leo Kim0551a722015-11-19 15:56:32 +0900423 tstrNetworkInfo *network_info,
Leo Kim30cd10c2015-11-19 15:56:33 +0900424 void *user_void,
Leo Kimbdd34602015-11-19 15:56:34 +0900425 void *join_params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900426{
Chaehyun Lim27268872015-09-15 14:06:13 +0900427 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900428 struct wiphy *wiphy;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900429 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900430 struct ieee80211_channel *channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900431 struct cfg80211_bss *bss = NULL;
432
Leo Kim30cd10c2015-11-19 15:56:33 +0900433 priv = (struct wilc_priv *)user_void;
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100434 if (priv->bCfgScanning) {
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900435 if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900436 wiphy = priv->dev->ieee80211_ptr->wiphy;
Leo Kim7ae43362015-09-16 18:35:59 +0900437
438 if (!wiphy)
439 return;
440
Leo Kim0551a722015-11-19 15:56:32 +0900441 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
442 (((s32)network_info->s8rssi * 100) < 0 ||
443 ((s32)network_info->s8rssi * 100) > 100)) {
Leo Kim24db7132015-09-16 18:36:01 +0900444 PRINT_ER("wiphy signal type fial\n");
445 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900446 }
447
Leo Kim0551a722015-11-19 15:56:32 +0900448 if (network_info) {
449 s32Freq = ieee80211_channel_to_frequency((s32)network_info->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900450 channel = ieee80211_get_channel(wiphy, s32Freq);
451
Leo Kim7ae43362015-09-16 18:35:59 +0900452 if (!channel)
453 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900454
455 PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
Leo Kim0551a722015-11-19 15:56:32 +0900456 "BeaconPeriod: %d\n", channel->center_freq, (((s32)network_info->s8rssi) * 100),
457 network_info->u16CapInfo, network_info->u16BeaconPeriod);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900458
Leo Kim0551a722015-11-19 15:56:32 +0900459 if (network_info->bNewNetwork) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900460 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
Leo Kim0551a722015-11-19 15:56:32 +0900461 PRINT_D(CFG80211_DBG, "Network %s found\n", network_info->au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900462 priv->u32RcvdChCount++;
463
Leo Kimbdd34602015-11-19 15:56:34 +0900464 if (!join_params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900465 PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n");
Leo Kimbdd34602015-11-19 15:56:34 +0900466 add_network_to_shadow(network_info, priv, join_params);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900467
468 /*P2P peers are sent to WPA supplicant and added to shadow table*/
Leo Kim0551a722015-11-19 15:56:32 +0900469 if (!(memcmp("DIRECT-", network_info->au8ssid, 7))) {
470 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, network_info->au8bssid, network_info->u64Tsf, network_info->u16CapInfo,
471 network_info->u16BeaconPeriod, (const u8 *)network_info->pu8IEs,
472 (size_t)network_info->u16IEsLen, (((s32)network_info->s8rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900473 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900474 }
475
476
477 } else {
478 PRINT_ER("Discovered networks exceeded the max limit\n");
479 }
480 } else {
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900481 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900482 /* So this network is discovered before, we'll just update its RSSI */
483 for (i = 0; i < priv->u32RcvdChCount; i++) {
Leo Kim0551a722015-11-19 15:56:32 +0900484 if (memcmp(last_scanned_shadow[i].au8bssid, network_info->au8bssid, 6) == 0) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900485 PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", last_scanned_shadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900486
Leo Kim0551a722015-11-19 15:56:32 +0900487 last_scanned_shadow[i].s8rssi = network_info->s8rssi;
Leo Kimf1ab1172015-11-19 15:56:11 +0900488 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900489 break;
490 }
491 }
492 }
493 }
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900494 } else if (scan_event == SCAN_EVENT_DONE) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530495 PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev);
496 PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n");
Dean Lee72ed4dc2015-06-12 14:11:44 +0900497 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900498
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530499 if (priv->u32RcvdChCount > 0)
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530500 PRINT_D(CFG80211_DBG, "%d Network(s) found\n", priv->u32RcvdChCount);
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530501 else
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530502 PRINT_D(CFG80211_DBG, "No networks found\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900503
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200504 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900505
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900506 if (priv->pstrScanReq != NULL) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900507 cfg80211_scan_done(priv->pstrScanReq, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900508 priv->u32RcvdChCount = 0;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900509 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900510 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900511 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200512 up(&(priv->hSemScanReq));
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900513 } else if (scan_event == SCAN_EVENT_ABORTED) {
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200514 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900515
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530516 PRINT_D(CFG80211_DBG, "Scan Aborted\n");
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900517 if (priv->pstrScanReq != NULL) {
Leo Kim5e51d8b2015-11-19 15:56:28 +0900518 update_scan_time();
Dean Lee72ed4dc2015-06-12 14:11:44 +0900519 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900520
Dean Lee72ed4dc2015-06-12 14:11:44 +0900521 cfg80211_scan_done(priv->pstrScanReq, false);
522 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900523 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900524 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200525 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900526 }
527 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900528}
529
530
531/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900532 * @brief CfgConnectResult
533 * @details
534 * @param[in] tenuConnDisconnEvent enuConnDisconnEvent: Type of connection response either
535 * connection response or disconnection notification.
536 * tstrConnectInfo* pstrConnectInfo: COnnection information.
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900537 * u8 u8MacStatus: Mac Status from firmware
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900538 * tstrDisconnectNotifInfo* pstrDisconnectNotifInfo: Disconnection Notification
539 * void* pUserVoid: Private data associated with wireless interface
540 * @return NONE
541 * @author mabubakr
542 * @date 01 MAR 2012
543 * @version 1.0
544 */
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100545int wilc_connecting;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900546
Leo Kimed3f0372015-10-12 16:56:01 +0900547static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900548 tstrConnectInfo *pstrConnectInfo,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900549 u8 u8MacStatus,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900550 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
551 void *pUserVoid)
552{
Chaehyun Lim27268872015-09-15 14:06:13 +0900553 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900554 struct net_device *dev;
Leo Kim441dc602015-10-12 16:55:35 +0900555 struct host_if_drv *pstrWFIDrv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900556 u8 NullBssid[ETH_ALEN] = {0};
Glen Leec1ec2c12015-10-20 17:13:58 +0900557 struct wilc *wl;
558 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900559
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100560 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900561
Chaehyun Lim27268872015-09-15 14:06:13 +0900562 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900563 dev = priv->dev;
Glen Leec1ec2c12015-10-20 17:13:58 +0900564 nic = netdev_priv(dev);
565 wl = nic->wilc;
Leo Kim441dc602015-10-12 16:55:35 +0900566 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900567
568 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
569 /*Initialization*/
Amitoj Kaur Chawlababa7c72015-10-15 13:48:29 +0530570 u16 u16ConnectStatus;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900571
572 u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
573
574 PRINT_D(CFG80211_DBG, " Connection response received = %d\n", u8MacStatus);
575
576 if ((u8MacStatus == MAC_DISCONNECTED) &&
577 (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
578 /* The case here is that our station was waiting for association response frame and has just received it containing status code
579 * = SUCCESSFUL_STATUSCODE, while mac status is MAC_DISCONNECTED (which means something wrong happened) */
580 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100581 wilc_wlan_set_bssid(priv->dev, NullBssid);
Leo Kime554a302015-11-19 15:56:21 +0900582 eth_zero_addr(wilc_connected_ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900583
Leo Kimab16ec02015-10-29 12:05:40 +0900584 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900585 wlan_channel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900586
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530587 PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d\n", u16ConnectStatus, u8MacStatus);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900588 }
589
590 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900591 bool bNeedScanRefresh = false;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900592 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900593
594 PRINT_INFO(CFG80211_DBG, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo->au8bssid[0],
595 pstrConnectInfo->au8bssid[1], pstrConnectInfo->au8bssid[2], pstrConnectInfo->au8bssid[3], pstrConnectInfo->au8bssid[4], pstrConnectInfo->au8bssid[5]);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900596 memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900597
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900598
Leo Kim771fbae2015-11-19 15:56:10 +0900599 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900600 if (memcmp(last_scanned_shadow[i].au8bssid,
601 pstrConnectInfo->au8bssid, ETH_ALEN) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900602 unsigned long now = jiffies;
603
604 if (time_after(now,
Leo Kimf1ab1172015-11-19 15:56:11 +0900605 last_scanned_shadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900606 bNeedScanRefresh = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900607 }
608
609 break;
610 }
611 }
612
Abdul Hussain5a66bf22015-06-16 09:44:06 +0000613 if (bNeedScanRefresh) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900614 /*Also, refrsh DIRECT- results if */
Dean Lee72ed4dc2015-06-12 14:11:44 +0900615 refresh_scan(priv, 1, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900616
617 }
618
619 }
620
621
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530622 PRINT_D(CFG80211_DBG, "Association request info elements length = %zu\n", pstrConnectInfo->ReqIEsLen);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900623
624 PRINT_D(CFG80211_DBG, "Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen);
625
626 cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
627 pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
628 pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
629 u16ConnectStatus, GFP_KERNEL); /* TODO: mostafa: u16ConnectStatus to */
630 /* be replaced by pstrConnectInfo->u16ConnectStatus */
631 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100632 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900633 PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n",
634 pstrDisconnectNotifInfo->u16reason, priv->dev);
Leo Kim583d9722015-11-19 15:56:16 +0900635 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +0900636 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +0900637 wilc_ie = false;
Shraddha Barkebcf02652015-10-05 17:00:32 +0530638 eth_zero_addr(priv->au8AssociatedBss);
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100639 wilc_wlan_set_bssid(priv->dev, NullBssid);
Leo Kime554a302015-11-19 15:56:21 +0900640 eth_zero_addr(wilc_connected_ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900641
Leo Kimab16ec02015-10-29 12:05:40 +0900642 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900643 wlan_channel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900644 /*Incase "P2P CLIENT Connected" send deauthentication reason by 3 to force the WPA_SUPPLICANT to directly change
645 * virtual interface to station*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900646 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900647 pstrDisconnectNotifInfo->u16reason = 3;
648 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900649 /*Incase "P2P CLIENT during connection(not connected)" send deauthentication reason by 1 to force the WPA_SUPPLICANT
650 * to scan again and retry the connection*/
Glen Leec1ec2c12015-10-20 17:13:58 +0900651 else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900652 pstrDisconnectNotifInfo->u16reason = 1;
653 }
654 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
Sudip Mukherjeee26bb712015-06-30 13:51:51 +0530655 pstrDisconnectNotifInfo->ie_len, false,
656 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900657
658 }
659
660}
661
662
663/**
Chaehyun Lim80785a92015-09-14 12:24:01 +0900664 * @brief set_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900665 * @details Set channel for a given wireless interface. Some devices
666 * may support multi-channel operation (by channel hopping) so cfg80211
667 * doesn't verify much. Note, however, that the passed netdev may be
668 * %NULL as well if the user requested changing the channel for the
669 * device itself, or for a monitor interface.
670 * @param[in]
671 * @return int : Return 0 on Success
672 * @author mdaftedar
673 * @date 01 MAR 2012
674 * @version 1.0
675 */
Chaehyun Lim80785a92015-09-14 12:24:01 +0900676static int set_channel(struct wiphy *wiphy,
677 struct cfg80211_chan_def *chandef)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900678{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900679 u32 channelnum = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +0900680 struct wilc_priv *priv;
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900681 int result = 0;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900682
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900683 priv = wiphy_priv(wiphy);
684
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900685 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
686 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900687
Chaehyun Lim866a2c22015-10-02 16:41:21 +0900688 curr_channel = channelnum;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100689 result = wilc_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900690
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900691 if (result != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900692 PRINT_ER("Error in setting channel %d\n", channelnum);
693
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900694 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900695}
696
697/**
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900698 * @brief scan
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900699 * @details Request to do a scan. If returning zero, the scan request is given
700 * the driver, and will be valid until passed to cfg80211_scan_done().
701 * For scan results, call cfg80211_inform_bss(); you can call this outside
702 * the scan/scan_done bracket too.
703 * @param[in]
704 * @return int : Return 0 on Success
705 * @author mabubakr
706 * @date 01 MAR 2012
707 * @version 1.0
708 */
709
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900710static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900711{
Chaehyun Lim27268872015-09-15 14:06:13 +0900712 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900713 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +0900714 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900715 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
Leo Kim607db442015-10-05 15:25:37 +0900716 struct hidden_network strHiddenNetwork;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900717
718 priv = wiphy_priv(wiphy);
719
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900720 priv->pstrScanReq = request;
721
722 priv->u32RcvdChCount = 0;
723
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100724 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Leo Kim12b01382015-11-19 15:56:27 +0900725 reset_shadow_found();
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900726
Dean Lee72ed4dc2015-06-12 14:11:44 +0900727 priv->bCfgScanning = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900728 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) { /* TODO: mostafa: to be replaced by */
729 /* max_scan_ssids */
730 for (i = 0; i < request->n_channels; i++) {
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900731 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900732 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
733 }
734
735 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530736 PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900737
738 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
739
740 if (request->n_ssids >= 1) {
741
742
Leo Kim607db442015-10-05 15:25:37 +0900743 strHiddenNetwork.pstrHiddenNetworkInfo = kmalloc(request->n_ssids * sizeof(struct hidden_network), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900744 strHiddenNetwork.u8ssidnum = request->n_ssids;
745
746
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900747 for (i = 0; i < request->n_ssids; i++) {
748
749 if (request->ssids[i].ssid != NULL && request->ssids[i].ssid_len != 0) {
Glen Leef3052582015-09-10 12:03:04 +0900750 strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900751 memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900752 strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len;
753 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530754 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900755 strHiddenNetwork.u8ssidnum -= 1;
756 }
757 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530758 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100759 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900760 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900761 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900762 CfgScanResult, (void *)priv, &strHiddenNetwork);
763 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530764 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100765 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900766 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900767 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900768 CfgScanResult, (void *)priv, NULL);
769 }
770
771 } else {
772 PRINT_ER("Requested num of scanned channels is greater than the max, supported"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530773 " channels\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900774 }
775
Leo Kime6e12662015-09-16 18:36:03 +0900776 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900777 s32Error = -EBUSY;
778 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
779 }
780
781 return s32Error;
782}
783
784/**
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900785 * @brief connect
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900786 * @details Connect to the ESS with the specified parameters. When connected,
787 * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS.
788 * If the connection fails for some reason, call cfg80211_connect_result()
789 * with the status from the AP.
790 * @param[in]
791 * @return int : Return 0 on Success
792 * @author mabubakr
793 * @date 01 MAR 2012
794 * @version 1.0
795 */
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900796static int connect(struct wiphy *wiphy, struct net_device *dev,
797 struct cfg80211_connect_params *sme)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900798{
Leo Kime6e12662015-09-16 18:36:03 +0900799 s32 s32Error = 0;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900800 u32 i;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900801 u8 u8security = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +0900802 enum AUTHTYPE tenuAuth_type = ANY;
Dean Lee576917a2015-06-15 11:58:57 +0900803 char *pcgroup_encrypt_val = NULL;
804 char *pccipher_group = NULL;
805 char *pcwpa_version = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900806
Chaehyun Lim27268872015-09-15 14:06:13 +0900807 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +0900808 struct host_if_drv *pstrWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900809 tstrNetworkInfo *pstrNetworkInfo = NULL;
810
811
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100812 wilc_connecting = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900813 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +0900814 pstrWFIDrv = (struct host_if_drv *)(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900815
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100816 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900817
Johnny Kim8a143302015-06-10 17:06:46 +0900818 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 +0900819 if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900820 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
Leo Kimab16ec02015-10-29 12:05:40 +0900821 pstrWFIDrv->p2p_connect = 1;
822 } else {
823 pstrWFIDrv->p2p_connect = 0;
824 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530825 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900826
Leo Kim771fbae2015-11-19 15:56:10 +0900827 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900828 if ((sme->ssid_len == last_scanned_shadow[i].u8SsidLen) &&
829 memcmp(last_scanned_shadow[i].au8ssid,
830 sme->ssid,
831 sme->ssid_len) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900832 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
833 if (sme->bssid == NULL) {
834 /* BSSID is not passed from the user, so decision of matching
835 * is done by SSID only */
836 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
837 break;
838 } else {
839 /* BSSID is also passed from the user, so decision of matching
840 * should consider also this passed BSSID */
Leo Kimf1ab1172015-11-19 15:56:11 +0900841 if (memcmp(last_scanned_shadow[i].au8bssid,
842 sme->bssid,
843 ETH_ALEN) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900844 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
845 break;
846 }
847 }
848 }
849 }
850
Leo Kim771fbae2015-11-19 15:56:10 +0900851 if (i < last_scanned_cnt) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900852 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
853
Leo Kimf1ab1172015-11-19 15:56:11 +0900854 pstrNetworkInfo = &last_scanned_shadow[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900855
856 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
857 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
858 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
859 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
860 } else {
861 s32Error = -ENOENT;
Leo Kim771fbae2015-11-19 15:56:10 +0900862 if (last_scanned_cnt == 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900863 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
864 else
865 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
866
867 goto done;
868 }
869
870 priv->WILC_WFI_wep_default = 0;
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900871 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
872 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900873
874 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
875 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
876
877 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
878
879 if (INFO) {
880 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
881 PRINT_D(CORECONFIG_DBG, "sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]);
882 }
883
884 if (sme->crypto.cipher_group != NO_ENCRYPT) {
885 /* To determine the u8security value, first we check the group cipher suite then {in case of WPA or WPA2}
886 * we will add to it the pairwise cipher suite(s) */
887 pcwpa_version = "Default";
888 PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900889 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900890 u8security = ENCRYPT_ENABLED | WEP;
891 pcgroup_encrypt_val = "WEP40";
892 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
893 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
894
895 if (INFO) {
896 for (i = 0; i < sme->key_len; i++)
897 PRINT_D(CORECONFIG_DBG, "WEP Key Value[%d] = %d\n", i, sme->key[i]);
898 }
899 priv->WILC_WFI_wep_default = sme->key_idx;
900 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900901 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900902
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900903 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900904 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900905 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
906 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900907 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900908
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100909 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
910 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900911 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900912 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
913 pcgroup_encrypt_val = "WEP104";
914 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
915
916 priv->WILC_WFI_wep_default = sme->key_idx;
917 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900918 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900919
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900920 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900921 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900922 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
923 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900924 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900925
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100926 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
927 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900928 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900929 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900930 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
931 pcgroup_encrypt_val = "WPA2_TKIP";
932 pccipher_group = "TKIP";
933 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
934 /* tenuSecurity_t = WPA2_AES; */
935 u8security = ENCRYPT_ENABLED | WPA2 | AES;
936 pcgroup_encrypt_val = "WPA2_AES";
937 pccipher_group = "AES";
938 }
939 pcwpa_version = "WPA_VERSION_2";
940 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
941 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900942 u8security = ENCRYPT_ENABLED | WPA | TKIP;
943 pcgroup_encrypt_val = "WPA_TKIP";
944 pccipher_group = "TKIP";
945 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
946 /* tenuSecurity_t = WPA_AES; */
947 u8security = ENCRYPT_ENABLED | WPA | AES;
948 pcgroup_encrypt_val = "WPA_AES";
949 pccipher_group = "AES";
950
951 }
952 pcwpa_version = "WPA_VERSION_1";
953
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900954 } else {
955 s32Error = -ENOTSUPP;
956 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
957
958 goto done;
959 }
960
961 }
962
963 /* After we set the u8security value from checking the group cipher suite, {in case of WPA or WPA2} we will
964 * add to it the pairwise cipher suite(s) */
965 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
966 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
967 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
968 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
969 u8security = u8security | TKIP;
970 } else { /* TODO: mostafa: here we assume that any other encryption type is AES */
971 u8security = u8security | AES;
972 }
973 }
974 }
975
976 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
977
978 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
979 switch (sme->auth_type) {
980 case NL80211_AUTHTYPE_OPEN_SYSTEM:
981 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
982 tenuAuth_type = OPEN_SYSTEM;
983 break;
984
985 case NL80211_AUTHTYPE_SHARED_KEY:
986 tenuAuth_type = SHARED_KEY;
987 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
988 break;
989
990 default:
991 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
992 }
993
994
995 /* ai: key_mgmt: enterprise case */
996 if (sme->crypto.n_akm_suites) {
997 switch (sme->crypto.akm_suites[0]) {
998 case WLAN_AKM_SUITE_8021X:
999 tenuAuth_type = IEEE8021;
1000 break;
1001
1002 default:
1003 break;
1004 }
1005 }
1006
1007
1008 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
1009
1010 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
1011 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
1012
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001013 curr_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001014
Leo Kimab16ec02015-10-29 12:05:40 +09001015 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +09001016 wlan_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001017
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001018 wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001019
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001020 s32Error = wilc_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001021 sme->ssid_len, sme->ie, sme->ie_len,
1022 CfgConnectResult, (void *)priv, u8security,
1023 tenuAuth_type, pstrNetworkInfo->u8channel,
1024 pstrNetworkInfo->pJoinParams);
Leo Kime6e12662015-09-16 18:36:03 +09001025 if (s32Error != 0) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001026 PRINT_ER("wilc_set_join_req(): Error(%d)\n", s32Error);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001027 s32Error = -ENOENT;
1028 goto done;
1029 }
1030
1031done:
1032
1033 return s32Error;
1034}
1035
1036
1037/**
Chaehyun Limb027cde2015-09-14 12:24:04 +09001038 * @brief disconnect
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001039 * @details Disconnect from the BSS/ESS.
1040 * @param[in]
1041 * @return int : Return 0 on Success
1042 * @author mdaftedar
1043 * @date 01 MAR 2012
1044 * @version 1.0
1045 */
Chaehyun Limb027cde2015-09-14 12:24:04 +09001046static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001047{
Leo Kime6e12662015-09-16 18:36:03 +09001048 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09001049 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09001050 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim51e825f2015-09-15 14:06:14 +09001051 u8 NullBssid[ETH_ALEN] = {0};
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001052
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001053 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001054 priv = wiphy_priv(wiphy);
1055
Leo Kim441dc602015-10-12 16:55:35 +09001056 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Leo Kimab16ec02015-10-29 12:05:40 +09001057 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +09001058 wlan_channel = INVALID_CHANNEL;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001059 wilc_wlan_set_bssid(priv->dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001060
1061 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
1062
Leo Kim583d9722015-11-19 15:56:16 +09001063 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +09001064 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +09001065 wilc_ie = false;
Leo Kim1229b1a2015-10-29 12:05:39 +09001066 pstrWFIDrv->p2p_timeout = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001067
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001068 s32Error = wilc_disconnect(priv->hWILCWFIDrv, reason_code);
Leo Kime6e12662015-09-16 18:36:03 +09001069 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001070 PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
1071 s32Error = -EINVAL;
1072 }
1073
1074 return s32Error;
1075}
1076
1077/**
Chaehyun Lim953d4172015-09-14 12:24:05 +09001078 * @brief add_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001079 * @details Add a key with the given parameters. @mac_addr will be %NULL
1080 * when adding a group key.
1081 * @param[in] key : key buffer; TKIP: 16-byte temporal key, 8-byte Tx Mic key, 8-byte Rx Mic Key
1082 * @return int : Return 0 on Success
1083 * @author mdaftedar
1084 * @date 01 MAR 2012
1085 * @version 1.0
1086 */
Chaehyun Lim953d4172015-09-14 12:24:05 +09001087static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1088 bool pairwise,
1089 const u8 *mac_addr, struct key_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001090
1091{
Leo Kime6e12662015-09-16 18:36:03 +09001092 s32 s32Error = 0, KeyLen = params->key_len;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001093 u32 i;
Chaehyun Lim27268872015-09-15 14:06:13 +09001094 struct wilc_priv *priv;
Arnd Bergmann057d1e92015-06-01 21:06:44 +02001095 const u8 *pu8RxMic = NULL;
1096 const u8 *pu8TxMic = NULL;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001097 u8 u8mode = NO_ENCRYPT;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001098 u8 u8gmode = NO_ENCRYPT;
1099 u8 u8pmode = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +09001100 enum AUTHTYPE tenuAuth_type = ANY;
Glen Lee76469202015-10-20 17:13:59 +09001101 struct wilc *wl;
1102 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001103
1104 priv = wiphy_priv(wiphy);
Glen Lee76469202015-10-20 17:13:59 +09001105 nic = netdev_priv(netdev);
1106 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001107
1108 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
1109
Johnny Kim8a143302015-06-10 17:06:46 +09001110 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001111
1112 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
1113 params->key[1],
1114 params->key[2]);
1115
1116
1117 switch (params->cipher) {
1118 case WLAN_CIPHER_SUITE_WEP40:
1119 case WLAN_CIPHER_SUITE_WEP104:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001120 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
1121
1122 priv->WILC_WFI_wep_default = key_index;
1123 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001124 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001125
1126 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
1127 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
1128
1129 for (i = 0; i < params->key_len; i++)
1130 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
1131
1132 tenuAuth_type = OPEN_SYSTEM;
1133
1134 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
1135 u8mode = ENCRYPT_ENABLED | WEP;
1136 else
1137 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
1138
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001139 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 +09001140 break;
1141 }
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001142 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001143 priv->WILC_WFI_wep_default = key_index;
1144 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001145 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001146
1147 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
1148 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
1149 if (INFO) {
1150 for (i = 0; i < params->key_len; i++)
1151 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
1152 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001153 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001154 }
1155
1156 break;
1157
1158 case WLAN_CIPHER_SUITE_TKIP:
1159 case WLAN_CIPHER_SUITE_CCMP:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001160 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
1161
1162 if (priv->wilc_gtk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001163 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001164 priv->wilc_gtk[key_index]->key = NULL;
1165 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001166
1167 }
1168 if (priv->wilc_ptk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001169 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001170 priv->wilc_ptk[key_index]->key = NULL;
1171 priv->wilc_ptk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001172 }
1173
1174
1175
Daniel Machon19132212015-08-05 08:18:31 +02001176 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001177 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1178 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1179 else
1180 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1181
1182 priv->wilc_groupkey = u8gmode;
1183
1184 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1185
1186 pu8TxMic = params->key + 24;
1187 pu8RxMic = params->key + 16;
1188 KeyLen = params->key_len - 16;
1189 }
1190 /* 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 +05301191 kfree(priv->wilc_gtk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001192
Glen Leef3052582015-09-10 12:03:04 +09001193 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001194 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001195
1196 /* 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 +05301197 kfree(priv->wilc_gtk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001198
1199 if ((params->seq_len) > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001200 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001201 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001202 }
1203
1204 priv->wilc_gtk[key_index]->cipher = params->cipher;
1205 priv->wilc_gtk[key_index]->key_len = params->key_len;
1206 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1207
1208 if (INFO) {
1209 for (i = 0; i < params->key_len; i++)
1210 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1211 for (i = 0; i < params->seq_len; i++)
1212 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1213 }
1214
1215
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001216 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001217 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode);
1218
1219 } else {
1220 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]);
1221
1222 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1223 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1224 else
1225 u8pmode = priv->wilc_groupkey | AES;
1226
1227
1228 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1229
1230 pu8TxMic = params->key + 24;
1231 pu8RxMic = params->key + 16;
1232 KeyLen = params->key_len - 16;
1233 }
1234
Shraddha Barkecccfc392015-10-12 20:49:19 +05301235 kfree(priv->wilc_ptk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001236
Glen Leef3052582015-09-10 12:03:04 +09001237 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001238
Shraddha Barkecccfc392015-10-12 20:49:19 +05301239 kfree(priv->wilc_ptk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001240
1241 if ((params->seq_len) > 0)
Glen Leef3052582015-09-10 12:03:04 +09001242 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001243
1244 if (INFO) {
1245 for (i = 0; i < params->key_len; i++)
1246 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1247
1248 for (i = 0; i < params->seq_len; i++)
1249 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1250 }
1251
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001252 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001253
1254 if ((params->seq_len) > 0)
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001255 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001256
1257 priv->wilc_ptk[key_index]->cipher = params->cipher;
1258 priv->wilc_ptk[key_index]->key_len = params->key_len;
1259 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1260
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001261 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001262 pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index);
1263 }
1264 break;
1265 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001266
1267 {
1268 u8mode = 0;
Daniel Machon19132212015-08-05 08:18:31 +02001269 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001270 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1271 /* swap the tx mic by rx mic */
1272 pu8RxMic = params->key + 24;
1273 pu8TxMic = params->key + 16;
1274 KeyLen = params->key_len - 16;
1275 }
1276
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001277 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001278 if (!g_gtk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001279 g_add_gtk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001280 g_add_gtk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001281 if (!mac_addr) {
1282 g_add_gtk_key_params.mac_addr = NULL;
1283 } else {
Glen Leef3052582015-09-10 12:03:04 +09001284 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001285 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1286 }
1287 g_key_gtk_params.key_len = params->key_len;
1288 g_key_gtk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001289 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001290 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1291 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001292 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001293 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1294 }
1295 g_key_gtk_params.cipher = params->cipher;
1296
1297 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1298 g_key_gtk_params.key[1],
1299 g_key_gtk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001300 g_gtk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001301 }
1302
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001303 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001304 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001305 } else {
1306 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1307 /* swap the tx mic by rx mic */
1308 pu8RxMic = params->key + 24;
1309 pu8TxMic = params->key + 16;
1310 KeyLen = params->key_len - 16;
1311 }
1312
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001313 /*save keys only on interface 0 (wifi interface)*/
Glen Lee76469202015-10-20 17:13:59 +09001314 if (!g_ptk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001315 g_add_ptk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001316 g_add_ptk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001317 if (!mac_addr) {
1318 g_add_ptk_key_params.mac_addr = NULL;
1319 } else {
Glen Leef3052582015-09-10 12:03:04 +09001320 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001321 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1322 }
1323 g_key_ptk_params.key_len = params->key_len;
1324 g_key_ptk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001325 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001326 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1327 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001328 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001329 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1330 }
1331 g_key_ptk_params.cipher = params->cipher;
1332
1333 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1334 g_key_ptk_params.key[1],
1335 g_key_ptk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001336 g_ptk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001337 }
1338
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001339 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001340 pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index);
1341 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1342 if (INFO) {
1343 for (i = 0; i < params->key_len; i++)
1344 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1345 }
1346 }
1347 }
1348 break;
1349
1350 default:
1351 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
1352 s32Error = -ENOTSUPP;
1353
1354 }
1355
1356 return s32Error;
1357}
1358
1359/**
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001360 * @brief del_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001361 * @details Remove a key given the @mac_addr (%NULL for a group key)
1362 * and @key_index, return -ENOENT if the key doesn't exist.
1363 * @param[in]
1364 * @return int : Return 0 on Success
1365 * @author mdaftedar
1366 * @date 01 MAR 2012
1367 * @version 1.0
1368 */
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001369static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1370 u8 key_index,
1371 bool pairwise,
1372 const u8 *mac_addr)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001373{
Chaehyun Lim27268872015-09-15 14:06:13 +09001374 struct wilc_priv *priv;
Glen Lee692e2ac2015-10-20 17:14:00 +09001375 struct wilc *wl;
1376 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001377
1378 priv = wiphy_priv(wiphy);
Glen Lee692e2ac2015-10-20 17:14:00 +09001379 nic = netdev_priv(netdev);
1380 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001381
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001382 /*delete saved keys, if any*/
Glen Lee692e2ac2015-10-20 17:14:00 +09001383 if (netdev == wl->vif[0].ndev) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09001384 g_ptk_keys_saved = false;
1385 g_gtk_keys_saved = false;
1386 g_wep_keys_saved = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001387
1388 /*Delete saved WEP keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301389 kfree(g_key_wep_params.key);
1390 g_key_wep_params.key = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001391
1392 /*freeing memory allocated by "wilc_gtk" and "wilc_ptk" in "WILC_WIFI_ADD_KEY"*/
1393
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001394 if ((priv->wilc_gtk[key_index]) != NULL) {
1395
Shraddha Barkecccfc392015-10-12 20:49:19 +05301396 kfree(priv->wilc_gtk[key_index]->key);
1397 priv->wilc_gtk[key_index]->key = NULL;
1398 kfree(priv->wilc_gtk[key_index]->seq);
1399 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001400
Chaehyun Lim49188af2015-08-11 10:32:41 +09001401 kfree(priv->wilc_gtk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001402 priv->wilc_gtk[key_index] = NULL;
1403
1404 }
1405
1406 if ((priv->wilc_ptk[key_index]) != NULL) {
1407
Shraddha Barkecccfc392015-10-12 20:49:19 +05301408 kfree(priv->wilc_ptk[key_index]->key);
1409 priv->wilc_ptk[key_index]->key = NULL;
1410 kfree(priv->wilc_ptk[key_index]->seq);
1411 priv->wilc_ptk[key_index]->seq = NULL;
Chaehyun Lim49188af2015-08-11 10:32:41 +09001412 kfree(priv->wilc_ptk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001413 priv->wilc_ptk[key_index] = NULL;
1414 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001415
1416 /*Delete saved PTK and GTK keys params, if any*/
Shraddha Barkecccfc392015-10-12 20:49:19 +05301417 kfree(g_key_ptk_params.key);
1418 g_key_ptk_params.key = NULL;
1419 kfree(g_key_ptk_params.seq);
1420 g_key_ptk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001421
Shraddha Barkecccfc392015-10-12 20:49:19 +05301422 kfree(g_key_gtk_params.key);
1423 g_key_gtk_params.key = NULL;
1424 kfree(g_key_gtk_params.seq);
1425 g_key_gtk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001426
1427 /*Reset WILC_CHANGING_VIR_IF register to allow adding futrue keys to CE H/W*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001428 wilc_set_machw_change_vir_if(netdev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001429 }
1430
1431 if (key_index >= 0 && key_index <= 3) {
Chaehyun Lim2cc46832015-08-07 09:02:01 +09001432 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001433 priv->WILC_WFI_wep_key_len[key_index] = 0;
1434
1435 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001436 wilc_remove_wep_key(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001437 } else {
1438 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001439 wilc_remove_key(priv->hWILCWFIDrv, mac_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001440 }
1441
Leo Kimaaed3292015-10-12 16:55:38 +09001442 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001443}
1444
1445/**
Chaehyun Limf4893df2015-09-14 12:24:07 +09001446 * @brief get_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001447 * @details Get information about the key with the given parameters.
1448 * @mac_addr will be %NULL when requesting information for a group
1449 * key. All pointers given to the @callback function need not be valid
1450 * after it returns. This function should return an error if it is
1451 * not possible to retrieve the key, -ENOENT if it doesn't exist.
1452 * @param[in]
1453 * @return int : Return 0 on Success
1454 * @author mdaftedar
1455 * @date 01 MAR 2012
1456 * @version 1.0
1457 */
Chaehyun Limf4893df2015-09-14 12:24:07 +09001458static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1459 bool pairwise,
1460 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001461{
Chaehyun Lim27268872015-09-15 14:06:13 +09001462 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001463 struct key_params key_params;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001464 u32 i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001465
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001466 priv = wiphy_priv(wiphy);
1467
1468
Alison Schofield3604af52015-10-12 13:22:44 -07001469 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001470 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1471
1472 key_params.key = priv->wilc_gtk[key_index]->key;
1473 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1474 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1475 key_params.seq = priv->wilc_gtk[key_index]->seq;
1476 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1477 if (INFO) {
1478 for (i = 0; i < key_params.key_len; i++)
1479 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1480 }
1481 } else {
1482 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1483
1484 key_params.key = priv->wilc_ptk[key_index]->key;
1485 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1486 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1487 key_params.seq = priv->wilc_ptk[key_index]->seq;
1488 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1489 }
1490
1491 callback(cookie, &key_params);
1492
Leo Kimaaed3292015-10-12 16:55:38 +09001493 return 0; /* priv->wilc_gtk->key_len ?0 : -ENOENT; */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001494}
1495
1496/**
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001497 * @brief set_default_key
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001498 * @details Set the default management frame key on an interface
1499 * @param[in]
1500 * @return int : Return 0 on Success.
1501 * @author mdaftedar
1502 * @date 01 MAR 2012
1503 * @version 1.0
1504 */
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001505static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1506 bool unicast, bool multicast)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001507{
Chaehyun Lim27268872015-09-15 14:06:13 +09001508 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001509
1510
1511 priv = wiphy_priv(wiphy);
1512
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301513 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001514
1515 if (key_index != priv->WILC_WFI_wep_default) {
1516
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001517 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001518 }
1519
Leo Kimaaed3292015-10-12 16:55:38 +09001520 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001521}
1522
1523/**
Chaehyun Limf06f5622015-09-14 12:24:18 +09001524 * @brief get_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001525 * @details Get station information for the station identified by @mac
1526 * @param[in] NONE
1527 * @return int : Return 0 on Success.
1528 * @author mdaftedar
1529 * @date 01 MAR 2012
1530 * @version 1.0
1531 */
1532
Chaehyun Limf06f5622015-09-14 12:24:18 +09001533static int get_station(struct wiphy *wiphy, struct net_device *dev,
1534 const u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001535{
Chaehyun Lim27268872015-09-15 14:06:13 +09001536 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001537 perInterface_wlan_t *nic;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001538 u32 i = 0;
1539 u32 associatedsta = 0;
1540 u32 inactive_time = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001541 priv = wiphy_priv(wiphy);
1542 nic = netdev_priv(dev);
1543
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001544 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
1545 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1546
1547 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1548
1549 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1550
1551 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1552 associatedsta = i;
1553 break;
1554 }
1555
1556 }
1557
1558 if (associatedsta == -1) {
Leo Kimaaed3292015-10-12 16:55:38 +09001559 PRINT_ER("Station required is not associated\n");
1560 return -ENOENT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001561 }
1562
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001563 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001564
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001565 wilc_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001566 sinfo->inactive_time = 1000 * inactive_time;
1567 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
1568
1569 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001570
1571 if (nic->iftype == STATION_MODE) {
Leo Kim03e7b9c2015-10-12 16:55:58 +09001572 struct rf_info strStatistics;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001573
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001574 wilc_get_statistics(priv->hWILCWFIDrv, &strStatistics);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001575
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001576 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
Chandra S Gorentla62129902015-08-05 22:11:57 +05301577 BIT(NL80211_STA_INFO_RX_PACKETS) |
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001578 BIT(NL80211_STA_INFO_TX_PACKETS) |
1579 BIT(NL80211_STA_INFO_TX_FAILED) |
1580 BIT(NL80211_STA_INFO_TX_BITRATE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001581
Leo Kim00c8dfc2015-10-29 12:05:30 +09001582 sinfo->signal = strStatistics.rssi;
Leo Kim9b992742015-10-29 12:05:32 +09001583 sinfo->rx_packets = strStatistics.rx_cnt;
Leo Kim54160372015-10-29 12:05:33 +09001584 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1585 sinfo->tx_failed = strStatistics.tx_fail_cnt;
Leo Kim5babeec2015-10-29 12:05:29 +09001586 sinfo->txrate.legacy = strStatistics.link_speed * 10;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001587
Leo Kim5babeec2015-10-29 12:05:29 +09001588 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1589 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001590 wilc_enable_tcp_ack_filter(true);
Leo Kim5babeec2015-10-29 12:05:29 +09001591 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001592 wilc_enable_tcp_ack_filter(false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001593
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001594 PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
1595 sinfo->tx_failed, sinfo->txrate.legacy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001596 }
Leo Kimaaed3292015-10-12 16:55:38 +09001597 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001598}
1599
1600
1601/**
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001602 * @brief change_bss
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001603 * @details Modify parameters for a given BSS.
1604 * @param[in]
1605 * -use_cts_prot: Whether to use CTS protection
1606 * (0 = no, 1 = yes, -1 = do not change)
1607 * -use_short_preamble: Whether the use of short preambles is allowed
1608 * (0 = no, 1 = yes, -1 = do not change)
1609 * -use_short_slot_time: Whether the use of short slot time is allowed
1610 * (0 = no, 1 = yes, -1 = do not change)
1611 * -basic_rates: basic rates in IEEE 802.11 format
1612 * (or NULL for no change)
1613 * -basic_rates_len: number of basic rates
1614 * -ap_isolate: do not forward packets between connected stations
1615 * -ht_opmode: HT Operation mode
1616 * (u16 = opmode, -1 = do not change)
1617 * @return int : Return 0 on Success.
1618 * @author mdaftedar
1619 * @date 01 MAR 2012
1620 * @version 1.0
1621 */
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001622static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1623 struct bss_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001624{
1625 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1626 return 0;
1627}
1628
1629/**
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001630 * @brief set_wiphy_params
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001631 * @details Notify that wiphy parameters have changed;
1632 * @param[in] Changed bitfield (see &enum wiphy_params_flags) describes which values
1633 * have changed.
1634 * @return int : Return 0 on Success
1635 * @author mdaftedar
1636 * @date 01 MAR 2012
1637 * @version 1.0
1638 */
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001639static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001640{
Leo Kime6e12662015-09-16 18:36:03 +09001641 s32 s32Error = 0;
Leo Kim95296502015-10-05 15:25:46 +09001642 struct cfg_param_val pstrCfgParamVal;
Chaehyun Lim27268872015-09-15 14:06:13 +09001643 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001644
1645 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001646
Tony Cho87c05b22015-10-12 16:56:07 +09001647 pstrCfgParamVal.flag = 0;
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301648 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001649
1650 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1651 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1652 priv->dev->ieee80211_ptr->wiphy->retry_short);
Tony Cho87c05b22015-10-12 16:56:07 +09001653 pstrCfgParamVal.flag |= RETRY_SHORT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001654 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1655 }
1656 if (changed & WIPHY_PARAM_RETRY_LONG) {
1657
1658 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 +09001659 pstrCfgParamVal.flag |= RETRY_LONG;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001660 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1661
1662 }
1663 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1664 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 +09001665 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001666 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1667
1668 }
1669
1670 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1671 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1672
Tony Cho87c05b22015-10-12 16:56:07 +09001673 pstrCfgParamVal.flag |= RTS_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001674 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1675
1676 }
1677
1678 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001679 s32Error = wilc_hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001680 if (s32Error)
1681 PRINT_ER("Error in setting WIPHY PARAMS\n");
1682
1683
1684 return s32Error;
1685}
Arnd Bergmanne5af0562015-05-29 22:52:12 +02001686
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001687/**
Chaehyun Lim4d466572015-09-14 12:24:22 +09001688 * @brief set_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001689 * @details Cache a PMKID for a BSSID. This is mostly useful for fullmac
1690 * devices running firmwares capable of generating the (re) association
1691 * RSN IE. It allows for faster roaming between WPA2 BSSIDs.
1692 * @param[in]
1693 * @return int : Return 0 on Success
1694 * @author mdaftedar
1695 * @date 01 MAR 2012
1696 * @version 1.0
1697 */
Chaehyun Lim4d466572015-09-14 12:24:22 +09001698static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1699 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001700{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001701 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001702 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001703 u8 flag = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001704
Chaehyun Lim27268872015-09-15 14:06:13 +09001705 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001706
1707 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1708
1709
1710 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001711 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001712 ETH_ALEN)) {
1713 /*If bssid already exists and pmkid value needs to reset*/
1714 flag = PMKID_FOUND;
1715 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1716 break;
1717 }
1718 }
1719 if (i < WILC_MAX_NUM_PMKIDS) {
1720 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001721 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001722 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001723 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001724 PMKID_LEN);
1725 if (!(flag == PMKID_FOUND))
1726 priv->pmkid_list.numpmkid++;
1727 } else {
1728 PRINT_ER("Invalid PMKID index\n");
1729 s32Error = -EINVAL;
1730 }
1731
1732 if (!s32Error) {
1733 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001734 s32Error = wilc_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001735 }
1736 return s32Error;
1737}
1738
1739/**
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001740 * @brief del_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001741 * @details Delete a cached PMKID.
1742 * @param[in]
1743 * @return int : Return 0 on Success
1744 * @author mdaftedar
1745 * @date 01 MAR 2012
1746 * @version 1.0
1747 */
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001748static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1749 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001750{
1751
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001752 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001753 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001754
Chaehyun Lim27268872015-09-15 14:06:13 +09001755 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001756
1757 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1758
1759 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001760 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001761 ETH_ALEN)) {
1762 /*If bssid is found, reset the values*/
1763 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
Leo Kimcd1e6cb2015-10-05 15:25:45 +09001764 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001765 break;
1766 }
1767 }
1768
1769 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1770 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001771 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001772 priv->pmkid_list.pmkidlist[i + 1].bssid,
1773 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001774 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001775 priv->pmkid_list.pmkidlist[i].pmkid,
1776 PMKID_LEN);
1777 }
1778 priv->pmkid_list.numpmkid--;
1779 } else {
1780 s32Error = -EINVAL;
1781 }
1782
1783 return s32Error;
1784}
1785
1786/**
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001787 * @brief flush_pmksa
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001788 * @details Flush all cached PMKIDs.
1789 * @param[in]
1790 * @return int : Return 0 on Success
1791 * @author mdaftedar
1792 * @date 01 MAR 2012
1793 * @version 1.0
1794 */
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001795static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001796{
Chaehyun Lim27268872015-09-15 14:06:13 +09001797 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001798
1799 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
1800
1801 /*Get cashed Pmkids and set all with zeros*/
Leo Kima949f902015-10-05 15:25:44 +09001802 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001803
1804 return 0;
1805}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001806
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001807
1808/**
1809 * @brief WILC_WFI_CfgParseRxAction
1810 * @details Function parses the received frames and modifies the following attributes:
1811 * -GO Intent
1812 * -Channel list
1813 * -Operating Channel
1814 *
1815 * @param[in] u8* Buffer, u32 length
1816 * @return NONE.
1817 * @author mdaftedar
1818 * @date 12 DEC 2012
1819 * @version
1820 */
1821
Arnd Bergmann1608c402015-11-16 15:04:53 +01001822static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001823{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001824 u32 index = 0;
1825 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001826
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001827 u8 op_channel_attr_index = 0;
1828 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001829
1830 while (index < len) {
1831 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001832 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001833 }
1834
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301835 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001836 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301837 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001838 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001839 index += buf[index + 1] + 3; /* ID,Length byte */
1840 }
Leo Kim0bd82742015-11-19 15:56:14 +09001841 if (wlan_channel != INVALID_CHANNEL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001842 /*Modify channel list attribute*/
1843 if (channel_list_attr_index) {
1844 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1845 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1846 if (buf[i] == 0x51) {
1847 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
Leo Kim0bd82742015-11-19 15:56:14 +09001848 buf[j] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001849 }
1850 break;
1851 }
1852 }
1853 }
1854 /*Modify operating channel attribute*/
1855 if (op_channel_attr_index) {
1856 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1857 buf[op_channel_attr_index + 6] = 0x51;
Leo Kim0bd82742015-11-19 15:56:14 +09001858 buf[op_channel_attr_index + 7] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001859 }
1860 }
1861}
1862
1863/**
1864 * @brief WILC_WFI_CfgParseTxAction
1865 * @details Function parses the transmitted action frames and modifies the
1866 * GO Intent attribute
1867 * @param[in] u8* Buffer, u32 length, bool bOperChan, u8 iftype
1868 * @return NONE.
1869 * @author mdaftedar
1870 * @date 12 DEC 2012
1871 * @version
1872 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01001873static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001874{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001875 u32 index = 0;
1876 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001877
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001878 u8 op_channel_attr_index = 0;
1879 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001880
1881 while (index < len) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001882 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001883 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001884
1885 break;
1886 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001887
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301888 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001889 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301890 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001891 op_channel_attr_index = index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001892 index += buf[index + 1] + 3; /* ID,Length byte */
1893 }
Leo Kim0bd82742015-11-19 15:56:14 +09001894 if (wlan_channel != INVALID_CHANNEL && bOperChan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001895 /*Modify channel list attribute*/
1896 if (channel_list_attr_index) {
1897 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1898 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1899 if (buf[i] == 0x51) {
1900 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
Leo Kim0bd82742015-11-19 15:56:14 +09001901 buf[j] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001902 }
1903 break;
1904 }
1905 }
1906 }
1907 /*Modify operating channel attribute*/
1908 if (op_channel_attr_index) {
1909 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1910 buf[op_channel_attr_index + 6] = 0x51;
Leo Kim0bd82742015-11-19 15:56:14 +09001911 buf[op_channel_attr_index + 7] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001912 }
1913 }
1914}
1915
1916/* @brief WILC_WFI_p2p_rx
1917 * @details
1918 * @param[in]
1919 *
1920 * @return None
1921 * @author Mai Daftedar
1922 * @date 2 JUN 2013
1923 * @version 1.0
1924 */
1925
Chaehyun Limfbc2fe12015-09-15 14:06:16 +09001926void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001927{
1928
Chaehyun Lim27268872015-09-15 14:06:13 +09001929 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001930 u32 header, pkt_offset;
Leo Kim441dc602015-10-12 16:55:35 +09001931 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001932 u32 i = 0;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001933 s32 s32Freq;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001934
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001935 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001936 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001937
1938 /* Get WILC header */
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001939 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001940
1941 /* The packet offset field conain info about what type of managment frame */
1942 /* we are dealing with and ack status */
1943 pkt_offset = GET_PKT_OFFSET(header);
1944
1945 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1946 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1947 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001948 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001949 return;
1950 } else {
1951 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
1952 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],
1953 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001954 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001955 } else {
1956 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],
1957 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001958 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001959 }
1960 return;
1961 }
1962 } else {
1963
1964 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
1965
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001966 /*Upper layer is informed that the frame is received on this freq*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001967 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001968
1969 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1970 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
1971
Leo Kim1229b1a2015-10-29 12:05:39 +09001972 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001973 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
1974 return;
1975 }
1976 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1977
1978 switch (buff[ACTION_SUBTYPE_ID]) {
1979 case GAS_INTIAL_REQ:
1980 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
1981 break;
1982
1983 case GAS_INTIAL_RSP:
1984 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
1985 break;
1986
1987 case PUBLIC_ACT_VENDORSPEC:
Leo Kim881eb5d2015-11-19 15:56:15 +09001988 if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001989 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
Leo Kima25d5182015-11-19 15:56:19 +09001990 if (!wilc_ie) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001991 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
Leo Kim86685942015-11-19 15:56:18 +09001992 if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09001993 p2p_recv_random = buff[i + 6];
Leo Kima25d5182015-11-19 15:56:19 +09001994 wilc_ie = true;
Leo Kimb84a3ac2015-11-19 15:56:17 +09001995 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", p2p_recv_random);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001996 break;
1997 }
1998 }
1999 }
2000 }
Leo Kimb84a3ac2015-11-19 15:56:17 +09002001 if (p2p_local_random > p2p_recv_random) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002002 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2003 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
2004 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
Leo Kim881eb5d2015-11-19 15:56:15 +09002005 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002006 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
2007 break;
2008 }
2009 }
2010 }
Leo Kim583d9722015-11-19 15:56:16 +09002011 } else {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002012 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 +09002013 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002014 }
2015
2016
Leo Kima25d5182015-11-19 15:56:19 +09002017 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 +09002018 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
2019 /* extra attribute for sig_dbm: signal strength in mBm, or 0 if unknown */
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002020 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002021 return;
2022 }
2023 break;
2024
2025 default:
2026 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
2027 break;
2028 }
2029 }
2030 }
2031
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002032 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002033 }
2034}
2035
2036/**
2037 * @brief WILC_WFI_mgmt_tx_complete
2038 * @details Returns result of writing mgmt frame to VMM (Tx buffers are freed here)
2039 * @param[in] priv
2040 * transmitting status
2041 * @return None
2042 * @author Amr Abdelmoghny
2043 * @date 20 MAY 2013
2044 * @version 1.0
2045 */
2046static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
2047{
2048 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
2049
2050
2051 kfree(pv_data->buff);
2052 kfree(pv_data);
2053}
2054
2055/**
2056 * @brief WILC_WFI_RemainOnChannelReady
2057 * @details Callback function, called from handle_remain_on_channel on being ready on channel
2058 * @param
2059 * @return none
2060 * @author Amr abdelmoghny
2061 * @date 9 JUNE 2013
2062 * @version
2063 */
2064
2065static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
2066{
Chaehyun Lim27268872015-09-15 14:06:13 +09002067 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002068
Chaehyun Lim27268872015-09-15 14:06:13 +09002069 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002070
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302071 PRINT_D(HOSTINF_DBG, "Remain on channel ready\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002072
Dean Lee72ed4dc2015-06-12 14:11:44 +09002073 priv->bInP2PlistenState = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002074
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002075 cfg80211_ready_on_channel(priv->wdev,
2076 priv->strRemainOnChanParams.u64ListenCookie,
2077 priv->strRemainOnChanParams.pstrListenChan,
2078 priv->strRemainOnChanParams.u32ListenDuration,
2079 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002080}
2081
2082/**
2083 * @brief WILC_WFI_RemainOnChannelExpired
2084 * @details Callback function, called on expiration of remain-on-channel duration
2085 * @param
2086 * @return none
2087 * @author Amr abdelmoghny
2088 * @date 15 MAY 2013
2089 * @version
2090 */
2091
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002092static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002093{
Chaehyun Lim27268872015-09-15 14:06:13 +09002094 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002095
Chaehyun Lim27268872015-09-15 14:06:13 +09002096 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002097
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002098 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302099 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002100
Dean Lee72ed4dc2015-06-12 14:11:44 +09002101 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002102
2103 /*Inform wpas of remain-on-channel expiration*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002104 cfg80211_remain_on_channel_expired(priv->wdev,
2105 priv->strRemainOnChanParams.u64ListenCookie,
2106 priv->strRemainOnChanParams.pstrListenChan,
2107 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002108 } else {
2109 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
2110 , priv->strRemainOnChanParams.u32ListenSessionID);
2111 }
2112}
2113
2114
2115/**
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002116 * @brief remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002117 * @details Request the driver to remain awake on the specified
2118 * channel for the specified duration to complete an off-channel
2119 * operation (e.g., public action frame exchange). When the driver is
2120 * ready on the requested channel, it must indicate this with an event
2121 * notification by calling cfg80211_ready_on_channel().
2122 * @param[in]
2123 * @return int : Return 0 on Success
2124 * @author mdaftedar
2125 * @date 01 MAR 2012
2126 * @version 1.0
2127 */
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002128static int remain_on_channel(struct wiphy *wiphy,
2129 struct wireless_dev *wdev,
2130 struct ieee80211_channel *chan,
2131 unsigned int duration, u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002132{
Leo Kime6e12662015-09-16 18:36:03 +09002133 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002134 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002135
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002136 priv = wiphy_priv(wiphy);
2137
2138 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
2139
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002140
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002141 if (wdev->iftype == NL80211_IFTYPE_AP) {
2142 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
2143 return s32Error;
2144 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002145
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002146 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002147
2148 /*Setting params needed by WILC_WFI_RemainOnChannelExpired()*/
2149 priv->strRemainOnChanParams.pstrListenChan = chan;
2150 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002151 priv->strRemainOnChanParams.u32ListenDuration = duration;
2152 priv->strRemainOnChanParams.u32ListenSessionID++;
2153
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002154 s32Error = wilc_remain_on_channel(priv->hWILCWFIDrv
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002155 , priv->strRemainOnChanParams.u32ListenSessionID
2156 , duration
2157 , chan->hw_value
2158 , WILC_WFI_RemainOnChannelExpired
2159 , WILC_WFI_RemainOnChannelReady
2160 , (void *)priv);
2161
2162 return s32Error;
2163}
2164
2165/**
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002166 * @brief cancel_remain_on_channel
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002167 * @details Cancel an on-going remain-on-channel operation.
2168 * This allows the operation to be terminated prior to timeout based on
2169 * the duration value.
2170 * @param[in] struct wiphy *wiphy,
2171 * @param[in] struct net_device *dev
2172 * @param[in] u64 cookie,
2173 * @return int : Return 0 on Success
2174 * @author mdaftedar
2175 * @date 01 MAR 2012
2176 * @version 1.0
2177 */
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002178static int cancel_remain_on_channel(struct wiphy *wiphy,
2179 struct wireless_dev *wdev,
2180 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002181{
Leo Kime6e12662015-09-16 18:36:03 +09002182 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002183 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002184
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002185 priv = wiphy_priv(wiphy);
2186
2187 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
2188
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002189 s32Error = wilc_listen_state_expired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002190 return s32Error;
2191}
2192/**
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002193 * @brief WILC_WFI_mgmt_tx_frame
2194 * @details
2195 *
2196 * @param[in]
2197 * @return NONE.
2198 * @author mdaftedar
2199 * @date 01 JUL 2012
2200 * @version
2201 */
Chaehyun Limc1560322015-09-22 18:34:51 +09002202static int mgmt_tx(struct wiphy *wiphy,
2203 struct wireless_dev *wdev,
2204 struct cfg80211_mgmt_tx_params *params,
2205 u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002206{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002207 struct ieee80211_channel *chan = params->chan;
2208 unsigned int wait = params->wait;
2209 const u8 *buf = params->buf;
2210 size_t len = params->len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002211 const struct ieee80211_mgmt *mgmt;
2212 struct p2p_mgmt_data *mgmt_tx;
Chaehyun Lim27268872015-09-15 14:06:13 +09002213 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002214 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09002215 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002216 perInterface_wlan_t *nic;
Leo Kim86685942015-11-19 15:56:18 +09002217 u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002218
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002219 nic = netdev_priv(wdev->netdev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002220 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002221 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002222
2223 *cookie = (unsigned long)buf;
2224 priv->u64tx_cookie = *cookie;
2225 mgmt = (const struct ieee80211_mgmt *) buf;
2226
2227 if (ieee80211_is_mgmt(mgmt->frame_control)) {
2228
2229 /*mgmt frame allocation*/
Glen Leef3052582015-09-10 12:03:04 +09002230 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002231 if (mgmt_tx == NULL) {
2232 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
Leo Kime6e12662015-09-16 18:36:03 +09002233 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002234 }
Glen Leef3052582015-09-10 12:03:04 +09002235 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002236 if (mgmt_tx->buff == NULL) {
2237 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
Tony Chof638dd32015-09-07 19:09:31 +09002238 kfree(mgmt_tx);
Leo Kime6e12662015-09-16 18:36:03 +09002239 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002240 }
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09002241 memcpy(mgmt_tx->buff, buf, len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002242 mgmt_tx->size = len;
2243
2244
2245 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
2246 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
2247 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002248 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002249 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002250 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002251 } else if (ieee80211_is_action(mgmt->frame_control)) {
Chaehyun Limd85f5322015-06-11 14:35:54 +09002252 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002253
2254
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002255 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002256 /*Only set the channel, if not a negotiation confirmation frame
2257 * (If Negotiation confirmation frame, force it
2258 * to be transmitted on the same negotiation channel)*/
2259
2260 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
2261 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
2262 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002263 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002264 /*Save the current channel after we tune to it*/
Chaehyun Lim866a2c22015-10-02 16:41:21 +09002265 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002266 }
2267 switch (buf[ACTION_SUBTYPE_ID]) {
2268 case GAS_INTIAL_REQ:
2269 {
2270 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
2271 break;
2272 }
2273
2274 case GAS_INTIAL_RSP:
2275 {
2276 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
2277 break;
2278 }
2279
2280 case PUBLIC_ACT_VENDORSPEC:
2281 {
Leo Kim881eb5d2015-11-19 15:56:15 +09002282 if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002283 /*For the connection of two WILC's connection generate a rand number to determine who will be a GO*/
2284 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002285 if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
Leo Kim583d9722015-11-19 15:56:16 +09002286 get_random_bytes(&p2p_local_random, 1);
2287 p2p_local_random++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002288 }
2289 }
2290
2291 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
2292 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002293 if (p2p_local_random > p2p_recv_random) {
2294 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 +09002295
2296 /*Search for the p2p information information element , after the Public action subtype theres a byte for teh dialog token, skip that*/
2297 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
Leo Kim881eb5d2015-11-19 15:56:15 +09002298 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002299 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
Dean Lee72ed4dc2015-06-12 14:11:44 +09002300 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002301
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002302 /*If using supplicant go intent, no need at all*/
2303 /*to parse transmitted negotiation frames*/
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002304 else
Dean Lee72ed4dc2015-06-12 14:11:44 +09002305 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002306 break;
2307 }
2308 }
2309
2310 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
Shivani Bhardwajd8060fc2015-10-29 00:30:01 +05302311 /*
2312 * Adding WILC information element to allow two WILC devices to
2313 * identify each other and connect
2314 */
Leo Kim86685942015-11-19 15:56:18 +09002315 memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
2316 mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002317 mgmt_tx->size = buf_len;
2318 }
Leo Kim583d9722015-11-19 15:56:16 +09002319 } else {
Leo Kimb84a3ac2015-11-19 15:56:17 +09002320 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 +09002321 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002322 }
2323
2324 } else {
2325 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
2326 }
2327
2328 break;
2329 }
2330
2331 default:
2332 {
2333 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
2334 break;
2335 }
2336 }
2337
2338 }
2339
2340 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 +09002341 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002342
Leo Kim1229b1a2015-10-29 12:05:39 +09002343 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n",
2344 jiffies, pstrWFIDrv->p2p_timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002345 }
2346
Glen Lee829c4772015-10-29 12:18:44 +09002347 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
2348 mgmt_tx->buff, mgmt_tx->size,
Glen Leec9d48342015-10-01 16:03:43 +09002349 WILC_WFI_mgmt_tx_complete);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002350 } else {
2351 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
2352 }
Leo Kimaaed3292015-10-12 16:55:38 +09002353 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002354}
2355
Chaehyun Lim85c587a2015-09-22 18:34:50 +09002356static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
2357 struct wireless_dev *wdev,
2358 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002359{
Chaehyun Lim27268872015-09-15 14:06:13 +09002360 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09002361 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002362
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002363 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09002364 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002365
2366
2367 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
Leo Kim1229b1a2015-10-29 12:05:39 +09002368 pstrWFIDrv->p2p_timeout = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002369
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +01002370 if (!priv->bInP2PlistenState) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002371 cfg80211_remain_on_channel_expired(priv->wdev,
2372 priv->strRemainOnChanParams.u64ListenCookie,
2373 priv->strRemainOnChanParams.pstrListenChan,
2374 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002375 }
2376
2377 return 0;
2378}
2379
2380/**
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002381 * @brief wilc_mgmt_frame_register
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002382 * @details Notify driver that a management frame type was
2383 * registered. Note that this callback may not sleep, and cannot run
2384 * concurrently with itself.
2385 * @param[in]
2386 * @return NONE.
2387 * @author mdaftedar
2388 * @date 01 JUL 2012
2389 * @version
2390 */
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002391void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
2392 u16 frame_type, bool reg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002393{
2394
Chaehyun Lim27268872015-09-15 14:06:13 +09002395 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002396 perInterface_wlan_t *nic;
Glen Lee1b869352015-10-20 17:14:01 +09002397 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002398
2399 priv = wiphy_priv(wiphy);
2400 nic = netdev_priv(priv->wdev->netdev);
Glen Lee1b869352015-10-20 17:14:01 +09002401 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002402
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002403 if (!frame_type)
2404 return;
2405
2406 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
2407 switch (frame_type) {
2408 case PROBE_REQ:
2409 {
2410 nic->g_struct_frame_reg[0].frame_type = frame_type;
2411 nic->g_struct_frame_reg[0].reg = reg;
2412 }
2413 break;
2414
2415 case ACTION:
2416 {
2417 nic->g_struct_frame_reg[1].frame_type = frame_type;
2418 nic->g_struct_frame_reg[1].reg = reg;
2419 }
2420 break;
2421
2422 default:
2423 {
2424 break;
2425 }
2426
2427 }
2428 /*If mac is closed, then return*/
Glen Lee1b869352015-10-20 17:14:01 +09002429 if (!wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002430 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
2431 return;
2432 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002433 wilc_frame_register(priv->hWILCWFIDrv, frame_type, reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002434
2435
2436}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002437
2438/**
Chaehyun Lima8047e22015-09-22 18:34:48 +09002439 * @brief set_cqm_rssi_config
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002440 * @details Configure connection quality monitor RSSI threshold.
2441 * @param[in] struct wiphy *wiphy:
2442 * @param[in] struct net_device *dev:
2443 * @param[in] s32 rssi_thold:
2444 * @param[in] u32 rssi_hyst:
2445 * @return int : Return 0 on Success
2446 * @author mdaftedar
2447 * @date 01 MAR 2012
2448 * @version 1.0
2449 */
Chaehyun Lima8047e22015-09-22 18:34:48 +09002450static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
2451 s32 rssi_thold, u32 rssi_hyst)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002452{
2453 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2454 return 0;
2455
2456}
2457/**
Chaehyun Limbdb63382015-09-14 12:24:19 +09002458 * @brief dump_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002459 * @details Configure connection quality monitor RSSI threshold.
2460 * @param[in] struct wiphy *wiphy:
2461 * @param[in] struct net_device *dev
2462 * @param[in] int idx
2463 * @param[in] u8 *mac
2464 * @param[in] struct station_info *sinfo
2465 * @return int : Return 0 on Success
2466 * @author mdaftedar
2467 * @date 01 MAR 2012
2468 * @version 1.0
2469 */
Chaehyun Limbdb63382015-09-14 12:24:19 +09002470static int dump_station(struct wiphy *wiphy, struct net_device *dev,
2471 int idx, u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002472{
Chaehyun Lim27268872015-09-15 14:06:13 +09002473 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002474
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002475 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2476
2477 if (idx != 0)
2478 return -ENOENT;
2479
2480 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002481
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002482 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002483
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002484 wilc_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002485
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002486 return 0;
2487
2488}
2489
2490
2491/**
Chaehyun Lim46530672015-09-22 18:34:46 +09002492 * @brief set_power_mgmt
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002493 * @details
2494 * @param[in]
2495 * @return int : Return 0 on Success.
2496 * @author mdaftedar
2497 * @date 01 JUL 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09002498 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002499 */
Chaehyun Lim46530672015-09-22 18:34:46 +09002500static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2501 bool enabled, int timeout)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002502{
Chaehyun Lim27268872015-09-15 14:06:13 +09002503 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002504
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002505 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2506
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002507 if (wiphy == NULL)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002508 return -ENOENT;
2509
2510 priv = wiphy_priv(wiphy);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002511 if (priv->hWILCWFIDrv == NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002512 PRINT_ER("Driver is NULL\n");
2513 return -EIO;
2514 }
2515
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002516 if (wilc_enable_ps)
2517 wilc_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002518
2519
Leo Kime6e12662015-09-16 18:36:03 +09002520 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002521
2522}
Glen Lee108b3432015-09-16 18:53:20 +09002523
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002524/**
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002525 * @brief change_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002526 * @details Change type/configuration of virtual interface,
2527 * keep the struct wireless_dev's iftype updated.
2528 * @param[in] NONE
2529 * @return int : Return 0 on Success.
2530 * @author mdaftedar
2531 * @date 01 MAR 2012
2532 * @version 1.0
2533 */
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002534static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2535 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002536{
Chaehyun Lim27268872015-09-15 14:06:13 +09002537 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002538 perInterface_wlan_t *nic;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002539 u8 interface_type;
Chaehyun Limd85f5322015-06-11 14:35:54 +09002540 u16 TID = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002541 u8 i;
Glen Lee299382c2015-10-20 17:13:56 +09002542 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002543
2544 nic = netdev_priv(dev);
2545 priv = wiphy_priv(wiphy);
Glen Lee299382c2015-10-20 17:13:56 +09002546 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002547
2548 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2549 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
Leo Kim583d9722015-11-19 15:56:16 +09002550 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +09002551 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +09002552 wilc_ie = false;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002553 wilc_optaining_ip = false;
2554 del_timer(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002555 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002556 /*Set WILC_CHANGING_VIR_IF register to disallow adding futrue keys to CE H/W*/
2557 if (g_ptk_keys_saved && g_gtk_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002558 wilc_set_machw_change_vir_if(dev, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002559 }
2560
2561 switch (type) {
2562 case NL80211_IFTYPE_STATION:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002563 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002564 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002565
2566 /* send delba over wlan interface */
2567
2568
2569 dev->ieee80211_ptr->iftype = type;
2570 priv->wdev->iftype = type;
2571 nic->monitor_flag = 0;
2572 nic->iftype = STATION_MODE;
2573
2574 /*Remove the enteries of the previously connected clients*/
2575 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002576 interface_type = nic->iftype;
2577 nic->iftype = STATION_MODE;
2578
Glen Lee299382c2015-10-20 17:13:56 +09002579 if (wl->initialized) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002580 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2581 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002582 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002583 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002584
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002585 /*Eliminate host interface blocking state*/
Glen Lee299382c2015-10-20 17:13:56 +09002586 up(&wl->cfg_event);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002587
Glen Lee53dc0cf2015-10-20 17:13:57 +09002588 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002589 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002590 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002591 nic->iftype = interface_type;
2592
2593 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002594 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2595 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002596 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002597 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002598
2599 /*Add saved WEP keys, if any*/
2600 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002601 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002602 g_key_wep_params.key_idx);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002603 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002604 g_key_wep_params.key,
2605 g_key_wep_params.key_len,
2606 g_key_wep_params.key_idx);
2607 }
2608
2609 /*No matter the driver handler passed here, it will be overwriiten*/
2610 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002611 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002612
2613 /*Add saved PTK and GTK keys, if any*/
2614 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2615 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2616 g_key_ptk_params.key[1],
2617 g_key_ptk_params.key[2]);
2618 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2619 g_key_gtk_params.key[1],
2620 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002621 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2622 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002623 g_add_ptk_key_params.key_idx,
2624 g_add_ptk_key_params.pairwise,
2625 g_add_ptk_key_params.mac_addr,
2626 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002627
Glen Lee299382c2015-10-20 17:13:56 +09002628 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2629 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002630 g_add_gtk_key_params.key_idx,
2631 g_add_gtk_key_params.pairwise,
2632 g_add_gtk_key_params.mac_addr,
2633 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002634 }
2635
Glen Lee299382c2015-10-20 17:13:56 +09002636 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002637 for (i = 0; i < num_reg_frame; i++) {
2638 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2639 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002640 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002641 nic->g_struct_frame_reg[i].frame_type,
2642 nic->g_struct_frame_reg[i].reg);
2643 }
2644 }
2645
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002646 wilc_enable_ps = true;
2647 wilc_set_power_mgmt(priv->hWILCWFIDrv, 1, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002648 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002649 break;
2650
2651 case NL80211_IFTYPE_P2P_CLIENT:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002652 wilc_enable_ps = false;
2653 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
2654 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002655 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002656
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002657 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2658 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002659
2660 dev->ieee80211_ptr->iftype = type;
2661 priv->wdev->iftype = type;
2662 nic->monitor_flag = 0;
2663
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002664 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2665 nic->iftype = CLIENT_MODE;
2666
2667
Glen Lee299382c2015-10-20 17:13:56 +09002668 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002669 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002670 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002671
Glen Lee53dc0cf2015-10-20 17:13:57 +09002672 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002673 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002674 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002675
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002676 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2677 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002678 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002679 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002680
2681 /*Add saved WEP keys, if any*/
2682 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002683 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2684 g_key_wep_params.key_idx);
2685 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
2686 g_key_wep_params.key,
2687 g_key_wep_params.key_len,
2688 g_key_wep_params.key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002689 }
2690
2691 /*No matter the driver handler passed here, it will be overwriiten*/
2692 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002693 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002694
2695 /*Add saved PTK and GTK keys, if any*/
2696 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2697 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2698 g_key_ptk_params.key[1],
2699 g_key_ptk_params.key[2]);
2700 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2701 g_key_gtk_params.key[1],
2702 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002703 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2704 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002705 g_add_ptk_key_params.key_idx,
2706 g_add_ptk_key_params.pairwise,
2707 g_add_ptk_key_params.mac_addr,
2708 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002709
Glen Lee299382c2015-10-20 17:13:56 +09002710 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2711 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002712 g_add_gtk_key_params.key_idx,
2713 g_add_gtk_key_params.pairwise,
2714 g_add_gtk_key_params.mac_addr,
2715 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002716 }
2717
2718 /*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 +09002719 refresh_scan(priv, 1, true);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002720 wilc_set_machw_change_vir_if(dev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002721
Glen Lee299382c2015-10-20 17:13:56 +09002722 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002723 for (i = 0; i < num_reg_frame; i++) {
2724 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2725 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002726 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002727 nic->g_struct_frame_reg[i].frame_type,
2728 nic->g_struct_frame_reg[i].reg);
2729 }
2730 }
2731 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002732 break;
2733
2734 case NL80211_IFTYPE_AP:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002735 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002736 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002737 dev->ieee80211_ptr->iftype = type;
2738 priv->wdev->iftype = type;
2739 nic->iftype = AP_MODE;
Johnny Kim8a143302015-06-10 17:06:46 +09002740 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002741
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002742 PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002743 wilc_wlan_get_firmware(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002744 /*If wilc is running, then close-open to actually get new firmware running (serves P2P)*/
Glen Lee299382c2015-10-20 17:13:56 +09002745 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002746 nic->iftype = AP_MODE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002747 wilc_mac_close(dev);
2748 wilc_mac_open(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002749
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002750 for (i = 0; i < num_reg_frame; i++) {
2751 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2752 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002753 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002754 nic->g_struct_frame_reg[i].frame_type,
2755 nic->g_struct_frame_reg[i].reg);
2756 }
2757 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002758 break;
2759
2760 case NL80211_IFTYPE_P2P_GO:
2761 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
2762
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002763 wilc_optaining_ip = true;
Leo Kim7e872df2015-11-19 15:56:20 +09002764 mod_timer(&wilc_during_ip_timer,
2765 jiffies + msecs_to_jiffies(during_ip_time));
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002766 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002767 /*Delete block ack has to be the latest config packet*/
2768 /*sent before downloading new FW. This is because it blocks on*/
2769 /*hWaitResponse semaphore, which allows previous config*/
2770 /*packets to actually take action on old FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002771 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2772 wl->vif[0].bssid, TID);
2773 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002774 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002775 dev->ieee80211_ptr->iftype = type;
2776 priv->wdev->iftype = type;
2777
Johnny Kim8a143302015-06-10 17:06:46 +09002778 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002779
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002780 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2781
2782
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002783 nic->iftype = GO_MODE;
2784
2785 /* ensure that the message Q is empty */
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002786 wilc_wait_msg_queue_idle();
Glen Lee53dc0cf2015-10-20 17:13:57 +09002787 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002788 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002789 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002790
2791
2792 /*Setting interface 1 drv handler and mac address in newly downloaded FW*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002793 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2794 wilc_set_mac_address(wl->vif[0].hif_drv,
2795 wl->vif[0].src_addr);
2796 wilc_set_operation_mode(priv->hWILCWFIDrv, AP_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002797
2798 /*Add saved WEP keys, if any*/
2799 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002800 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2801 g_key_wep_params.key_idx);
2802 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002803 g_key_wep_params.key,
2804 g_key_wep_params.key_len,
2805 g_key_wep_params.key_idx);
2806 }
2807
2808 /*No matter the driver handler passed here, it will be overwriiten*/
2809 /*in Handle_FlushConnect() with gu8FlushedJoinReqDrvHandler*/
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002810 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002811
2812 /*Add saved PTK and GTK keys, if any*/
2813 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2814 PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0],
2815 g_key_ptk_params.key[1],
2816 g_key_ptk_params.key[2],
2817 g_key_ptk_params.cipher);
2818 PRINT_D(CFG80211_DBG, "gtk %x %x %x cipher %x\n", g_key_gtk_params.key[0],
2819 g_key_gtk_params.key[1],
2820 g_key_gtk_params.key[2],
2821 g_key_gtk_params.cipher);
Glen Lee299382c2015-10-20 17:13:56 +09002822 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2823 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002824 g_add_ptk_key_params.key_idx,
2825 g_add_ptk_key_params.pairwise,
2826 g_add_ptk_key_params.mac_addr,
2827 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002828
Glen Lee299382c2015-10-20 17:13:56 +09002829 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2830 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002831 g_add_gtk_key_params.key_idx,
2832 g_add_gtk_key_params.pairwise,
2833 g_add_gtk_key_params.mac_addr,
2834 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002835 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002836
Glen Lee299382c2015-10-20 17:13:56 +09002837 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002838 for (i = 0; i < num_reg_frame; i++) {
2839 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2840 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002841 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002842 nic->g_struct_frame_reg[i].frame_type,
2843 nic->g_struct_frame_reg[i].reg);
2844 }
2845 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002846 break;
2847
2848 default:
2849 PRINT_ER("Unknown interface type= %d\n", type);
Leo Kimaaed3292015-10-12 16:55:38 +09002850 return -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002851 }
2852
Leo Kimaaed3292015-10-12 16:55:38 +09002853 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002854}
2855
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002856/* (austin.2013-07-23)
2857 *
2858 * To support revised cfg80211_ops
2859 *
2860 * add_beacon --> start_ap
2861 * set_beacon --> change_beacon
2862 * del_beacon --> stop_ap
2863 *
2864 * beacon_parameters --> cfg80211_ap_settings
2865 * cfg80211_beacon_data
2866 *
2867 * applicable for linux kernel 3.4+
2868 */
2869
2870/**
Chaehyun Lima13168d2015-09-14 12:24:12 +09002871 * @brief start_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002872 * @details Add a beacon with given parameters, @head, @interval
2873 * and @dtim_period will be valid, @tail is optional.
2874 * @param[in] wiphy
2875 * @param[in] dev The net device structure
2876 * @param[in] settings cfg80211_ap_settings parameters for the beacon to be added
2877 * @return int : Return 0 on Success.
2878 * @author austin
2879 * @date 23 JUL 2013
2880 * @version 1.0
2881 */
Chaehyun Lima13168d2015-09-14 12:24:12 +09002882static int start_ap(struct wiphy *wiphy, struct net_device *dev,
2883 struct cfg80211_ap_settings *settings)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002884{
2885 struct cfg80211_beacon_data *beacon = &(settings->beacon);
Chaehyun Lim27268872015-09-15 14:06:13 +09002886 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002887 s32 s32Error = 0;
Glen Lee684dc182015-10-20 17:14:02 +09002888 struct wilc *wl;
2889 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002890
2891 priv = wiphy_priv(wiphy);
Glen Lee684dc182015-10-20 17:14:02 +09002892 nic = netdev_priv(dev);
2893 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002894 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
2895
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302896 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 +09002897 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
2898
Chaehyun Lim80785a92015-09-14 12:24:01 +09002899 s32Error = set_channel(wiphy, &settings->chandef);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002900
Leo Kime6e12662015-09-16 18:36:03 +09002901 if (s32Error != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002902 PRINT_ER("Error in setting channel\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002903
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002904 wilc_wlan_set_bssid(dev, wl->vif[0].src_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002905
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002906 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002907 settings->beacon_interval,
2908 settings->dtim_period,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002909 beacon->head_len, (u8 *)beacon->head,
2910 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002911
2912 return s32Error;
2913}
2914
2915/**
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002916 * @brief change_beacon
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002917 * @details Add a beacon with given parameters, @head, @interval
2918 * and @dtim_period will be valid, @tail is optional.
2919 * @param[in] wiphy
2920 * @param[in] dev The net device structure
2921 * @param[in] beacon cfg80211_beacon_data for the beacon to be changed
2922 * @return int : Return 0 on Success.
2923 * @author austin
2924 * @date 23 JUL 2013
2925 * @version 1.0
2926 */
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002927static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
2928 struct cfg80211_beacon_data *beacon)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002929{
Chaehyun Lim27268872015-09-15 14:06:13 +09002930 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002931 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002932
2933 priv = wiphy_priv(wiphy);
2934 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
2935
2936
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002937 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002938 0,
2939 0,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002940 beacon->head_len, (u8 *)beacon->head,
2941 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002942
2943 return s32Error;
2944}
2945
2946/**
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002947 * @brief stop_ap
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002948 * @details Remove beacon configuration and stop sending the beacon.
2949 * @param[in]
2950 * @return int : Return 0 on Success.
2951 * @author austin
2952 * @date 23 JUL 2013
2953 * @version 1.0
2954 */
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002955static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002956{
Leo Kime6e12662015-09-16 18:36:03 +09002957 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002958 struct wilc_priv *priv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002959 u8 NullBssid[ETH_ALEN] = {0};
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002960
Leo Kim7ae43362015-09-16 18:35:59 +09002961 if (!wiphy)
2962 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002963
2964 priv = wiphy_priv(wiphy);
2965
2966 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
2967
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002968 wilc_wlan_set_bssid(dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002969
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002970 s32Error = wilc_del_beacon(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002971
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002972 if (s32Error)
2973 PRINT_ER("Host delete beacon fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002974
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002975 return s32Error;
2976}
2977
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002978/**
Chaehyun Limed269552015-09-14 12:24:15 +09002979 * @brief add_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002980 * @details Add a new station.
2981 * @param[in]
2982 * @return int : Return 0 on Success.
2983 * @author mdaftedar
2984 * @date 01 MAR 2012
2985 * @version 1.0
2986 */
Chaehyun Limed269552015-09-14 12:24:15 +09002987static int add_station(struct wiphy *wiphy, struct net_device *dev,
2988 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002989{
Leo Kime6e12662015-09-16 18:36:03 +09002990 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002991 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09002992 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002993 perInterface_wlan_t *nic;
2994
Leo Kim7ae43362015-09-16 18:35:59 +09002995 if (!wiphy)
2996 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002997
2998 priv = wiphy_priv(wiphy);
2999 nic = netdev_priv(dev);
3000
3001 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003002 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09003003 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003004 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003005 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003006 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003007
3008 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
3009
3010 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],
3011 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003012 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003013 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3014 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003015
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003016 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003017 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003018 } else {
Leo Kim22520122015-10-29 12:05:45 +09003019 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003020 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003021 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003022 memcpy(strStaParams.ht_supp_mcs_set,
3023 &params->ht_capa->mcs,
3024 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003025 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003026 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003027 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003028 }
3029
Leo Kimf676e172015-10-29 12:05:52 +09003030 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003031 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003032
Leo Kim22520122015-10-29 12:05:45 +09003033 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3034 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003035 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3036 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003037 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3038 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003039 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3040 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003041 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3042 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003043 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3044 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003045 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3046 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003047 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3048 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003049
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003050 s32Error = wilc_add_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003051 if (s32Error)
3052 PRINT_ER("Host add station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003053 }
3054
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003055 return s32Error;
3056}
3057
3058/**
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003059 * @brief del_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003060 * @details Remove a station; @mac may be NULL to remove all stations.
3061 * @param[in]
3062 * @return int : Return 0 on Success.
3063 * @author mdaftedar
3064 * @date 01 MAR 2012
3065 * @version 1.0
3066 */
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003067static int del_station(struct wiphy *wiphy, struct net_device *dev,
3068 struct station_del_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003069{
Arnd Bergmann057d1e92015-06-01 21:06:44 +02003070 const u8 *mac = params->mac;
Leo Kime6e12662015-09-16 18:36:03 +09003071 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003072 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003073 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003074
Leo Kim7ae43362015-09-16 18:35:59 +09003075 if (!wiphy)
3076 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003077
3078 priv = wiphy_priv(wiphy);
3079 nic = netdev_priv(dev);
3080
3081 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
3082 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
3083
3084
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003085 if (mac == NULL) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05303086 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003087 s32Error = wilc_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003088 } else {
3089 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]);
3090 }
3091
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003092 s32Error = wilc_del_station(priv->hWILCWFIDrv, mac);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003093
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003094 if (s32Error)
3095 PRINT_ER("Host delete station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003096 }
3097 return s32Error;
3098}
3099
3100/**
Chaehyun Lim14b42082015-09-14 12:24:17 +09003101 * @brief change_station
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003102 * @details Modify a given station.
3103 * @param[in]
3104 * @return int : Return 0 on Success.
3105 * @author mdaftedar
3106 * @date 01 MAR 2012
3107 * @version 1.0
3108 */
Chaehyun Lim14b42082015-09-14 12:24:17 +09003109static int change_station(struct wiphy *wiphy, struct net_device *dev,
3110 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003111{
Leo Kime6e12662015-09-16 18:36:03 +09003112 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09003113 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09003114 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003115 perInterface_wlan_t *nic;
3116
3117
3118 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
3119
Leo Kim7ae43362015-09-16 18:35:59 +09003120 if (!wiphy)
3121 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003122
3123 priv = wiphy_priv(wiphy);
3124 nic = netdev_priv(dev);
3125
3126 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09003127 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09003128 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09003129 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09003130 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003131
Leo Kim2353c382015-10-29 12:05:41 +09003132 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n",
3133 strStaParams.bssid[0], strStaParams.bssid[1],
3134 strStaParams.bssid[2], strStaParams.bssid[3],
3135 strStaParams.bssid[4], strStaParams.bssid[5]);
Leo Kim4101eb82015-10-29 12:05:42 +09003136 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09003137 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
3138 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003139
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09003140 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09003141 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003142 } else {
Leo Kim22520122015-10-29 12:05:45 +09003143 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09003144 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09003145 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09003146 memcpy(strStaParams.ht_supp_mcs_set,
3147 &params->ht_capa->mcs,
3148 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09003149 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09003150 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09003151 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003152 }
3153
Leo Kimf676e172015-10-29 12:05:52 +09003154 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09003155 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003156
Leo Kim22520122015-10-29 12:05:45 +09003157 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
3158 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09003159 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
3160 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09003161 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
3162 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09003163 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
3164 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09003165 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
3166 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09003167 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
3168 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09003169 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
3170 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09003171 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
3172 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003173
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003174 s32Error = wilc_edit_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09003175 if (s32Error)
3176 PRINT_ER("Host edit station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003177 }
3178 return s32Error;
3179}
3180
3181
3182/**
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003183 * @brief add_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003184 * @details
3185 * @param[in]
3186 * @return int : Return 0 on Success.
3187 * @author mdaftedar
3188 * @date 01 JUL 2012
3189 * @version 1.0
3190 */
Chaehyun Lim37316e82015-09-22 18:34:52 +09003191static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
3192 const char *name,
3193 unsigned char name_assign_type,
3194 enum nl80211_iftype type,
3195 u32 *flags,
3196 struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003197{
3198 perInterface_wlan_t *nic;
Chaehyun Lim27268872015-09-15 14:06:13 +09003199 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003200 struct net_device *new_ifc = NULL;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003201
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003202 priv = wiphy_priv(wiphy);
3203
3204
3205
3206 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
3207
3208 nic = netdev_priv(priv->wdev->netdev);
3209
3210
3211 if (type == NL80211_IFTYPE_MONITOR) {
3212 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
3213 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", nic->wilc_netdev);
3214 new_ifc = WILC_WFI_init_mon_interface(name, nic->wilc_netdev);
3215 if (new_ifc != NULL) {
3216 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003217 nic = netdev_priv(priv->wdev->netdev);
3218 nic->monitor_flag = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003219 } else
3220 PRINT_ER("Error in initializing monitor interface\n ");
3221 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003222 return priv->wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003223}
3224
3225/**
Chaehyun Limb4a73352015-09-14 12:24:10 +09003226 * @brief del_virtual_intf
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003227 * @details
3228 * @param[in]
3229 * @return int : Return 0 on Success.
3230 * @author mdaftedar
3231 * @date 01 JUL 2012
3232 * @version 1.0
3233 */
Chaehyun Lim956d7212015-09-22 18:34:49 +09003234static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003235{
3236 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
Leo Kime6e12662015-09-16 18:36:03 +09003237 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003238}
3239
Chaehyun Lim08241922015-09-15 14:06:12 +09003240static struct cfg80211_ops wilc_cfg80211_ops = {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003241
Chaehyun Lim80785a92015-09-14 12:24:01 +09003242 .set_monitor_channel = set_channel,
Chaehyun Lim0e30d062015-09-14 12:24:02 +09003243 .scan = scan,
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +09003244 .connect = connect,
Chaehyun Limb027cde2015-09-14 12:24:04 +09003245 .disconnect = disconnect,
Chaehyun Lim953d4172015-09-14 12:24:05 +09003246 .add_key = add_key,
Chaehyun Lim3044ba72015-09-14 12:24:06 +09003247 .del_key = del_key,
Chaehyun Limf4893df2015-09-14 12:24:07 +09003248 .get_key = get_key,
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09003249 .set_default_key = set_default_key,
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09003250 .add_virtual_intf = add_virtual_intf,
Chaehyun Limb4a73352015-09-14 12:24:10 +09003251 .del_virtual_intf = del_virtual_intf,
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09003252 .change_virtual_intf = change_virtual_intf,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003253
Chaehyun Lima13168d2015-09-14 12:24:12 +09003254 .start_ap = start_ap,
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09003255 .change_beacon = change_beacon,
Chaehyun Limc8cddd72015-09-14 12:24:14 +09003256 .stop_ap = stop_ap,
Chaehyun Limed269552015-09-14 12:24:15 +09003257 .add_station = add_station,
Chaehyun Lima0a8be92015-09-14 12:24:16 +09003258 .del_station = del_station,
Chaehyun Lim14b42082015-09-14 12:24:17 +09003259 .change_station = change_station,
Chaehyun Limf06f5622015-09-14 12:24:18 +09003260 .get_station = get_station,
Chaehyun Limbdb63382015-09-14 12:24:19 +09003261 .dump_station = dump_station,
Chaehyun Lima5f7db62015-09-14 12:24:20 +09003262 .change_bss = change_bss,
Chaehyun Lima76b63e2015-09-14 12:24:21 +09003263 .set_wiphy_params = set_wiphy_params,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003264
Chaehyun Lim4d466572015-09-14 12:24:22 +09003265 .set_pmksa = set_pmksa,
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09003266 .del_pmksa = del_pmksa,
Chaehyun Limb33c39b2015-09-14 12:24:24 +09003267 .flush_pmksa = flush_pmksa,
Chaehyun Lim6d19d692015-09-14 12:24:25 +09003268 .remain_on_channel = remain_on_channel,
Chaehyun Lim1dd54402015-09-14 12:24:26 +09003269 .cancel_remain_on_channel = cancel_remain_on_channel,
Chaehyun Lim4a2f9b32015-09-14 12:24:27 +09003270 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
Chaehyun Lim12a26a32015-09-14 12:24:28 +09003271 .mgmt_tx = mgmt_tx,
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09003272 .mgmt_frame_register = wilc_mgmt_frame_register,
Chaehyun Lim46530672015-09-22 18:34:46 +09003273 .set_power_mgmt = set_power_mgmt,
Chaehyun Lima8047e22015-09-22 18:34:48 +09003274 .set_cqm_rssi_config = set_cqm_rssi_config,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003275
3276};
3277
3278
3279
3280
3281
3282/**
3283 * @brief WILC_WFI_update_stats
3284 * @details Modify parameters for a given BSS.
3285 * @param[in]
3286 * @return int : Return 0 on Success.
3287 * @author mdaftedar
3288 * @date 01 MAR 2012
Chaehyun Limcdc9cba2015-09-22 18:34:47 +09003289 * @version 1.0
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003290 */
3291int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
3292{
3293
Chaehyun Lim27268872015-09-15 14:06:13 +09003294 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003295
3296 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003297 switch (changed) {
3298
3299 case WILC_WFI_RX_PKT:
3300 {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003301 priv->netstats.rx_packets++;
3302 priv->netstats.rx_bytes += pktlen;
3303 priv->netstats.rx_time = get_jiffies_64();
3304 }
3305 break;
3306
3307 case WILC_WFI_TX_PKT:
3308 {
3309 priv->netstats.tx_packets++;
3310 priv->netstats.tx_bytes += pktlen;
3311 priv->netstats.tx_time = get_jiffies_64();
3312
3313 }
3314 break;
3315
3316 default:
3317 break;
3318 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003319 return 0;
3320}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003321
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003322/**
3323 * @brief WILC_WFI_CfgAlloc
3324 * @details Allocation of the wireless device structure and assigning it
3325 * to the cfg80211 operations structure.
3326 * @param[in] NONE
3327 * @return wireless_dev : Returns pointer to wireless_dev structure.
3328 * @author mdaftedar
3329 * @date 01 MAR 2012
3330 * @version 1.0
3331 */
Arnd Bergmann1608c402015-11-16 15:04:53 +01003332static struct wireless_dev *WILC_WFI_CfgAlloc(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003333{
3334
3335 struct wireless_dev *wdev;
3336
3337
3338 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
3339 /*Allocating the wireless device structure*/
3340 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
3341 if (!wdev) {
3342 PRINT_ER("Cannot allocate wireless device\n");
3343 goto _fail_;
3344 }
3345
3346 /*Creating a new wiphy, linking wireless structure with the wiphy structure*/
Chaehyun Lim27268872015-09-15 14:06:13 +09003347 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003348 if (!wdev->wiphy) {
3349 PRINT_ER("Cannot allocate wiphy\n");
3350 goto _fail_mem_;
3351
3352 }
3353
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003354 /* enable 802.11n HT */
3355 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
3356 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
3357 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3358 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
3359 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003360
3361 /*wiphy bands*/
3362 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
3363
3364 return wdev;
3365
3366_fail_mem_:
3367 kfree(wdev);
3368_fail_:
3369 return NULL;
3370
3371}
3372/**
Chaehyun Lim8459fd52015-09-20 15:51:09 +09003373 * @brief wilc_create_wiphy
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003374 * @details Registering of the wiphy structure and interface modes
3375 * @param[in] NONE
3376 * @return NONE
3377 * @author mdaftedar
3378 * @date 01 MAR 2012
3379 * @version 1.0
3380 */
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01003381struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003382{
Chaehyun Lim27268872015-09-15 14:06:13 +09003383 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003384 struct wireless_dev *wdev;
Leo Kime6e12662015-09-16 18:36:03 +09003385 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003386
3387 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
3388
3389 wdev = WILC_WFI_CfgAlloc();
3390 if (wdev == NULL) {
3391 PRINT_ER("CfgAlloc Failed\n");
3392 return NULL;
3393 }
3394
3395
3396 /*Return hardware description structure (wiphy)'s priv*/
3397 priv = wdev_priv(wdev);
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003398 sema_init(&(priv->SemHandleUpdateStats), 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003399
3400 /*Link the wiphy with wireless structure*/
3401 priv->wdev = wdev;
3402
3403 /*Maximum number of probed ssid to be added by user for the scan request*/
3404 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003405 /*Maximum number of pmkids to be cashed*/
3406 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
3407 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003408
3409 wdev->wiphy->max_scan_ie_len = 1000;
3410
3411 /*signal strength in mBm (100*dBm) */
3412 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3413
3414 /*Set the availaible cipher suites*/
3415 wdev->wiphy->cipher_suites = cipher_suites;
3416 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003417 /*Setting default managment types: for register action frame: */
3418 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003419
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003420 wdev->wiphy->max_remain_on_channel_duration = 500;
3421 /*Setting the wiphy interfcae mode and type before registering the wiphy*/
3422 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
3423 BIT(NL80211_IFTYPE_P2P_CLIENT);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003424 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003425 wdev->iftype = NL80211_IFTYPE_STATION;
3426
3427
3428
3429 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
3430 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
3431 wdev->wiphy->interface_modes, wdev->iftype);
3432
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01003433 set_wiphy_dev(wdev->wiphy, dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003434
3435 /*Register wiphy structure*/
3436 s32Error = wiphy_register(wdev->wiphy);
3437 if (s32Error) {
3438 PRINT_ER("Cannot register wiphy device\n");
3439 /*should define what action to be taken in such failure*/
3440 } else {
3441 PRINT_D(CFG80211_DBG, "Successful Registering\n");
3442 }
3443
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003444 priv->dev = net;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003445 return wdev;
3446
3447
3448}
3449/**
3450 * @brief WILC_WFI_WiphyFree
3451 * @details Freeing allocation of the wireless device structure
3452 * @param[in] NONE
3453 * @return NONE
3454 * @author mdaftedar
3455 * @date 01 MAR 2012
3456 * @version 1.0
3457 */
Chaehyun Limdd4b6a82015-09-20 15:51:25 +09003458int wilc_init_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003459{
3460
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003461 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003462
Chaehyun Lim27268872015-09-15 14:06:13 +09003463 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003464
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003465 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
3466 priv = wdev_priv(net->ieee80211_ptr);
3467 if (op_ifcs == 0) {
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -07003468 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003469 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003470 }
3471 op_ifcs++;
3472 if (s32Error < 0) {
3473 PRINT_ER("Failed to creat refresh Timer\n");
3474 return s32Error;
3475 }
3476
Dean Lee72ed4dc2015-06-12 14:11:44 +09003477 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003478
Dean Lee72ed4dc2015-06-12 14:11:44 +09003479 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003480
Arnd Bergmann83383ea2015-06-01 21:06:43 +02003481 sema_init(&(priv->hSemScanReq), 1);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003482 s32Error = wilc_init(net, &priv->hWILCWFIDrv);
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003483 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003484 PRINT_ER("Error while initializing hostinterface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003485
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003486 return s32Error;
3487}
3488
3489/**
3490 * @brief WILC_WFI_WiphyFree
3491 * @details Freeing allocation of the wireless device structure
3492 * @param[in] NONE
3493 * @return NONE
3494 * @author mdaftedar
3495 * @date 01 MAR 2012
3496 * @version 1.0
3497 */
Chaehyun Lima9a16822015-09-20 15:51:24 +09003498int wilc_deinit_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003499{
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09003500 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003501
Chaehyun Lim27268872015-09-15 14:06:13 +09003502 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09003503
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003504 priv = wdev_priv(net->ieee80211_ptr);
3505
Dean Lee72ed4dc2015-06-12 14:11:44 +09003506 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003507
Dean Lee72ed4dc2015-06-12 14:11:44 +09003508 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003509
3510 op_ifcs--;
3511
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003512 s32Error = wilc_deinit(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003513
3514 /* Clear the Shadow scan */
Leo Kimd14991a2015-11-19 15:56:22 +09003515 clear_shadow_scan();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003516 if (op_ifcs == 0) {
3517 PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01003518 del_timer_sync(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003519 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003520
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003521 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003522 PRINT_ER("Error while deintializing host interface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09003523
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003524 return s32Error;
3525}
3526
3527
3528/**
3529 * @brief WILC_WFI_WiphyFree
3530 * @details Freeing allocation of the wireless device structure
3531 * @param[in] NONE
3532 * @return NONE
3533 * @author mdaftedar
3534 * @date 01 MAR 2012
3535 * @version 1.0
3536 */
Chaehyun Lim96da20a2015-09-20 15:51:08 +09003537void wilc_free_wiphy(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003538{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003539 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
3540
Chaehyun Lim619837a2015-09-20 15:51:10 +09003541 if (!net) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003542 PRINT_D(INIT_DBG, "net_device is NULL\n");
3543 return;
3544 }
3545
Chaehyun Lim619837a2015-09-20 15:51:10 +09003546 if (!net->ieee80211_ptr) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003547 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
3548 return;
3549 }
3550
Chaehyun Lim619837a2015-09-20 15:51:10 +09003551 if (!net->ieee80211_ptr->wiphy) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003552 PRINT_D(INIT_DBG, "wiphy is NULL\n");
3553 return;
3554 }
3555
3556 wiphy_unregister(net->ieee80211_ptr->wiphy);
3557
3558 PRINT_D(INIT_DBG, "Freeing wiphy\n");
3559 wiphy_free(net->ieee80211_ptr->wiphy);
3560 kfree(net->ieee80211_ptr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09003561}