blob: bfef022c315b5c1a4fc67b1e8db70e19dcba26c7 [file] [log] [blame]
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001#include "wilc_wfi_cfgoperations.h"
Arnd Bergmann491880e2015-11-16 15:04:55 +01002#include "host_interface.h"
Leo Kim7ae43362015-09-16 18:35:59 +09003#include <linux/errno.h>
Johnny Kimc5c77ba2015-05-11 14:30:56 +09004
Arnd Bergmann15162fb2015-11-16 15:04:57 +01005#define NO_ENCRYPT 0
6#define ENCRYPT_ENABLED BIT(0)
7#define WEP BIT(1)
8#define WEP_EXTENDED BIT(2)
9#define WPA BIT(3)
10#define WPA2 BIT(4)
11#define AES BIT(5)
12#define TKIP BIT(6)
13
Arnd Bergmann15162fb2015-11-16 15:04:57 +010014#define FRAME_TYPE_ID 0
15#define ACTION_CAT_ID 24
16#define ACTION_SUBTYPE_ID 25
17#define P2P_PUB_ACTION_SUBTYPE 30
18
Arnd Bergmann15162fb2015-11-16 15:04:57 +010019#define ACTION_FRAME 0xd0
20#define GO_INTENT_ATTR_ID 0x04
21#define CHANLIST_ATTR_ID 0x0b
22#define OPERCHAN_ATTR_ID 0x11
23#define PUB_ACTION_ATTR_ID 0x04
24#define P2PELEM_ATTR_ID 0xdd
25
Arnd Bergmann15162fb2015-11-16 15:04:57 +010026#define GO_NEG_REQ 0x00
27#define GO_NEG_RSP 0x01
28#define GO_NEG_CONF 0x02
29#define P2P_INV_REQ 0x03
30#define P2P_INV_RSP 0x04
31#define PUBLIC_ACT_VENDORSPEC 0x09
32#define GAS_INTIAL_REQ 0x0a
33#define GAS_INTIAL_RSP 0x0b
34
35#define INVALID_CHANNEL 0
36
37#define nl80211_SCAN_RESULT_EXPIRE (3 * HZ)
38#define SCAN_RESULT_EXPIRE (40 * HZ)
39
40static const u32 cipher_suites[] = {
41 WLAN_CIPHER_SUITE_WEP40,
42 WLAN_CIPHER_SUITE_WEP104,
43 WLAN_CIPHER_SUITE_TKIP,
44 WLAN_CIPHER_SUITE_CCMP,
45 WLAN_CIPHER_SUITE_AES_CMAC,
46};
47
48static const struct ieee80211_txrx_stypes
49 wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = {
50 [NL80211_IFTYPE_STATION] = {
51 .tx = 0xffff,
52 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
53 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
54 },
55 [NL80211_IFTYPE_AP] = {
56 .tx = 0xffff,
57 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
58 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
59 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
60 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
61 BIT(IEEE80211_STYPE_AUTH >> 4) |
62 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
63 BIT(IEEE80211_STYPE_ACTION >> 4)
64 },
65 [NL80211_IFTYPE_P2P_CLIENT] = {
66 .tx = 0xffff,
67 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
68 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
69 BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
70 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
71 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
72 BIT(IEEE80211_STYPE_AUTH >> 4) |
73 BIT(IEEE80211_STYPE_DEAUTH >> 4)
74 }
75};
76
Arnd Bergmann15162fb2015-11-16 15:04:57 +010077#define WILC_WFI_DWELL_PASSIVE 100
78#define WILC_WFI_DWELL_ACTIVE 40
79
80#define TCP_ACK_FILTER_LINK_SPEED_THRESH 54
81#define DEFAULT_LINK_SPEED 72
82
83
Johnny Kimc5c77ba2015-05-11 14:30:56 +090084#define IS_MANAGMEMENT 0x100
85#define IS_MANAGMEMENT_CALLBACK 0x080
86#define IS_MGMT_STATUS_SUCCES 0x040
87#define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff)
88
Arnd Bergmann0e1af732015-11-16 15:04:54 +010089extern int wilc_mac_open(struct net_device *ndev);
90extern int wilc_mac_close(struct net_device *ndev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +090091
Leo Kimf1ab1172015-11-19 15:56:11 +090092static tstrNetworkInfo last_scanned_shadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
Leo Kim771fbae2015-11-19 15:56:10 +090093static u32 last_scanned_cnt;
Arnd Bergmann0e1af732015-11-16 15:04:54 +010094struct timer_list wilc_during_ip_timer;
Arnd Bergmann1608c402015-11-16 15:04:53 +010095static struct timer_list hAgingTimer;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +090096static u8 op_ifcs;
Johnny Kimc5c77ba2015-05-11 14:30:56 +090097
Arnd Bergmann0e1af732015-11-16 15:04:54 +010098u8 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +090099
100#define CHAN2G(_channel, _freq, _flags) { \
101 .band = IEEE80211_BAND_2GHZ, \
102 .center_freq = (_freq), \
103 .hw_value = (_channel), \
104 .flags = (_flags), \
105 .max_antenna_gain = 0, \
106 .max_power = 30, \
107}
108
Leo Kim2736f472015-11-19 15:56:12 +0900109static struct ieee80211_channel ieee80211_2ghz_channels[] = {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900110 CHAN2G(1, 2412, 0),
111 CHAN2G(2, 2417, 0),
112 CHAN2G(3, 2422, 0),
113 CHAN2G(4, 2427, 0),
114 CHAN2G(5, 2432, 0),
115 CHAN2G(6, 2437, 0),
116 CHAN2G(7, 2442, 0),
117 CHAN2G(8, 2447, 0),
118 CHAN2G(9, 2452, 0),
119 CHAN2G(10, 2457, 0),
120 CHAN2G(11, 2462, 0),
121 CHAN2G(12, 2467, 0),
122 CHAN2G(13, 2472, 0),
123 CHAN2G(14, 2484, 0),
124};
125
126#define RATETAB_ENT(_rate, _hw_value, _flags) { \
127 .bitrate = (_rate), \
128 .hw_value = (_hw_value), \
129 .flags = (_flags), \
130}
131
Leo Kim8d48b5b2015-11-19 15:56:13 +0900132static struct ieee80211_rate ieee80211_bitrates[] = {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900133 RATETAB_ENT(10, 0, 0),
134 RATETAB_ENT(20, 1, 0),
135 RATETAB_ENT(55, 2, 0),
136 RATETAB_ENT(110, 3, 0),
137 RATETAB_ENT(60, 9, 0),
138 RATETAB_ENT(90, 6, 0),
139 RATETAB_ENT(120, 7, 0),
140 RATETAB_ENT(180, 8, 0),
141 RATETAB_ENT(240, 9, 0),
142 RATETAB_ENT(360, 10, 0),
143 RATETAB_ENT(480, 11, 0),
144 RATETAB_ENT(540, 12, 0),
145};
146
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900147struct p2p_mgmt_data {
148 int size;
149 u8 *buff;
150};
151
Leo Kim0bd82742015-11-19 15:56:14 +0900152static u8 wlan_channel = INVALID_CHANNEL;
Arnd Bergmann1608c402015-11-16 15:04:53 +0100153static u8 curr_channel;
Leo Kim881eb5d2015-11-19 15:56:15 +0900154static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09};
Leo Kim583d9722015-11-19 15:56:16 +0900155static u8 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +0900156static u8 p2p_recv_random = 0x00;
Leo Kim86685942015-11-19 15:56:18 +0900157static u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
Leo Kima25d5182015-11-19 15:56:19 +0900158static bool wilc_ie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900159
160static struct ieee80211_supported_band WILC_WFI_band_2ghz = {
Leo Kim2736f472015-11-19 15:56:12 +0900161 .channels = ieee80211_2ghz_channels,
162 .n_channels = ARRAY_SIZE(ieee80211_2ghz_channels),
Leo Kim8d48b5b2015-11-19 15:56:13 +0900163 .bitrates = ieee80211_bitrates,
164 .n_bitrates = ARRAY_SIZE(ieee80211_bitrates),
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900165};
166
167
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900168struct add_key_params {
169 u8 key_idx;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900170 bool pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900171 u8 *mac_addr;
172};
Arnd Bergmann1608c402015-11-16 15:04:53 +0100173static struct add_key_params g_add_gtk_key_params;
174static struct wilc_wfi_key g_key_gtk_params;
175static struct add_key_params g_add_ptk_key_params;
176static struct wilc_wfi_key g_key_ptk_params;
177static struct wilc_wfi_wep_key g_key_wep_params;
178static bool g_ptk_keys_saved;
179static bool g_gtk_keys_saved;
180static bool g_wep_keys_saved;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900181
182#define AGING_TIME (9 * 1000)
Leo Kim7e872df2015-11-19 15:56:20 +0900183#define during_ip_time 15000
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900184
Leo Kimd14991a2015-11-19 15:56:22 +0900185static void clear_shadow_scan(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900186{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900187 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900188
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900189 if (op_ifcs == 0) {
Greg Kroah-Hartman4183e972015-08-14 20:11:16 -0700190 del_timer_sync(&hAgingTimer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900191 PRINT_INFO(CORECONFIG_DBG, "destroy aging timer\n");
192
Leo Kim771fbae2015-11-19 15:56:10 +0900193 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900194 if (last_scanned_shadow[last_scanned_cnt].pu8IEs) {
195 kfree(last_scanned_shadow[i].pu8IEs);
196 last_scanned_shadow[last_scanned_cnt].pu8IEs = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900197 }
198
Leo Kimf1ab1172015-11-19 15:56:11 +0900199 wilc_free_join_params(last_scanned_shadow[i].pJoinParams);
200 last_scanned_shadow[i].pJoinParams = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900201 }
Leo Kim771fbae2015-11-19 15:56:10 +0900202 last_scanned_cnt = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900203 }
204
205}
206
Leo Kim0b8bea12015-11-19 15:56:35 +0900207static u32 get_rssi_avg(tstrNetworkInfo *network_info)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900208{
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900209 u8 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900210 int rssi_v = 0;
Leo Kim0b8bea12015-11-19 15:56:35 +0900211 u8 num_rssi = (network_info->strRssi.u8Full) ? NUM_RSSI : (network_info->strRssi.u8Index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900212
213 for (i = 0; i < num_rssi; i++)
Leo Kim0b8bea12015-11-19 15:56:35 +0900214 rssi_v += network_info->strRssi.as8RSSI[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900215
216 rssi_v /= num_rssi;
217 return rssi_v;
218}
219
Leo Kim48ee7ba2015-11-19 15:56:24 +0900220static void refresh_scan(void *user_void, u8 all, bool direct_scan)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900221{
Chaehyun Lim27268872015-09-15 14:06:13 +0900222 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900223 struct wiphy *wiphy;
224 struct cfg80211_bss *bss = NULL;
225 int i;
226 int rssi = 0;
227
Leo Kim84df0e62015-11-19 15:56:23 +0900228 priv = (struct wilc_priv *)user_void;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900229 wiphy = priv->dev->ieee80211_ptr->wiphy;
230
Leo Kim771fbae2015-11-19 15:56:10 +0900231 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimce3b1b52015-11-19 15:56:25 +0900232 tstrNetworkInfo *network_info;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900233
Leo Kimce3b1b52015-11-19 15:56:25 +0900234 network_info = &last_scanned_shadow[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900235
Leo Kimce3b1b52015-11-19 15:56:25 +0900236 if (!network_info->u8Found || all) {
Leo Kimc6f5e3a2015-11-19 15:56:26 +0900237 s32 freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900238 struct ieee80211_channel *channel;
239
Leo Kimce3b1b52015-11-19 15:56:25 +0900240 if (network_info) {
Leo Kimc6f5e3a2015-11-19 15:56:26 +0900241 freq = ieee80211_channel_to_frequency((s32)network_info->u8channel, IEEE80211_BAND_2GHZ);
242 channel = ieee80211_get_channel(wiphy, freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900243
Leo Kimce3b1b52015-11-19 15:56:25 +0900244 rssi = get_rssi_avg(network_info);
245 if (memcmp("DIRECT-", network_info->au8ssid, 7) ||
Leo Kim48ee7ba2015-11-19 15:56:24 +0900246 direct_scan) {
Leo Kimce3b1b52015-11-19 15:56:25 +0900247 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, network_info->au8bssid, network_info->u64Tsf, network_info->u16CapInfo,
248 network_info->u16BeaconPeriod, (const u8 *)network_info->pu8IEs,
249 (size_t)network_info->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900250 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900251 }
252 }
253
254 }
255 }
256
257}
258
Leo Kim12b01382015-11-19 15:56:27 +0900259static void reset_shadow_found(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900260{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900261 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900262
Leo Kim771fbae2015-11-19 15:56:10 +0900263 for (i = 0; i < last_scanned_cnt; i++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900264 last_scanned_shadow[i].u8Found = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900265}
266
Leo Kim5e51d8b2015-11-19 15:56:28 +0900267static void update_scan_time(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900268{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900269 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900270
Leo Kim771fbae2015-11-19 15:56:10 +0900271 for (i = 0; i < last_scanned_cnt; i++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900272 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900273}
274
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700275static void remove_network_from_shadow(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900276{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900277 unsigned long now = jiffies;
278 int i, j;
279
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900280
Leo Kim771fbae2015-11-19 15:56:10 +0900281 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900282 if (time_after(now, last_scanned_shadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) {
283 PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", last_scanned_shadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900284
Leo Kimf1ab1172015-11-19 15:56:11 +0900285 kfree(last_scanned_shadow[i].pu8IEs);
286 last_scanned_shadow[i].pu8IEs = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900287
Leo Kimf1ab1172015-11-19 15:56:11 +0900288 wilc_free_join_params(last_scanned_shadow[i].pJoinParams);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900289
Leo Kim771fbae2015-11-19 15:56:10 +0900290 for (j = i; (j < last_scanned_cnt - 1); j++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900291 last_scanned_shadow[j] = last_scanned_shadow[j + 1];
Leo Kim771fbae2015-11-19 15:56:10 +0900292
293 last_scanned_cnt--;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900294 }
295 }
296
Leo Kim771fbae2015-11-19 15:56:10 +0900297 PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n",
298 last_scanned_cnt);
299 if (last_scanned_cnt != 0) {
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700300 hAgingTimer.data = arg;
301 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
302 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900303 PRINT_D(CFG80211_DBG, "No need to restart Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700304 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900305}
306
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700307static void clear_duringIP(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900308{
309 PRINT_D(GENERIC_DBG, "GO:IP Obtained , enable scan\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100310 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900311}
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900312
Leo Kim157814f2015-11-19 15:56:29 +0900313static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo,
314 void *user_void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900315{
Chaehyun Lima74cc6b2015-10-02 16:41:17 +0900316 int state = -1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900317 int i;
318
Leo Kim771fbae2015-11-19 15:56:10 +0900319 if (last_scanned_cnt == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900320 PRINT_D(CFG80211_DBG, "Starting Aging timer\n");
Leo Kim157814f2015-11-19 15:56:29 +0900321 hAgingTimer.data = (unsigned long)user_void;
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700322 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900323 state = -1;
324 } else {
Leo Kim771fbae2015-11-19 15:56:10 +0900325 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900326 if (memcmp(last_scanned_shadow[i].au8bssid,
327 pstrNetworkInfo->au8bssid, 6) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900328 state = i;
329 break;
330 }
331 }
332 }
333 return state;
334}
335
Leo Kim5c4cf0d2015-11-19 15:56:30 +0900336static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo,
337 void *user_void, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900338{
Leo Kim5c4cf0d2015-11-19 15:56:30 +0900339 int ap_found = is_network_in_shadow(pstrNetworkInfo, user_void);
Chaehyun Limfbc2fe12015-09-15 14:06:16 +0900340 u32 ap_index = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900341 u8 rssi_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900342
Leo Kim771fbae2015-11-19 15:56:10 +0900343 if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900344 PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
345 return;
346 }
347 if (ap_found == -1) {
Leo Kim771fbae2015-11-19 15:56:10 +0900348 ap_index = last_scanned_cnt;
349 last_scanned_cnt++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900350
351 } else {
352 ap_index = ap_found;
353 }
Leo Kimf1ab1172015-11-19 15:56:11 +0900354 rssi_index = last_scanned_shadow[ap_index].strRssi.u8Index;
355 last_scanned_shadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900356 if (rssi_index == NUM_RSSI) {
357 rssi_index = 0;
Leo Kimf1ab1172015-11-19 15:56:11 +0900358 last_scanned_shadow[ap_index].strRssi.u8Full = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900359 }
Leo Kimf1ab1172015-11-19 15:56:11 +0900360 last_scanned_shadow[ap_index].strRssi.u8Index = rssi_index;
361 last_scanned_shadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
362 last_scanned_shadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
363 last_scanned_shadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
364 memcpy(last_scanned_shadow[ap_index].au8ssid,
365 pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
366 memcpy(last_scanned_shadow[ap_index].au8bssid,
367 pstrNetworkInfo->au8bssid, ETH_ALEN);
368 last_scanned_shadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
369 last_scanned_shadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
370 last_scanned_shadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
371 last_scanned_shadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
372 last_scanned_shadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900373 if (ap_found != -1)
Leo Kimf1ab1172015-11-19 15:56:11 +0900374 kfree(last_scanned_shadow[ap_index].pu8IEs);
375 last_scanned_shadow[ap_index].pu8IEs =
Leo Kima89f7c52015-11-25 11:59:41 +0900376 kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL);
Leo Kimf1ab1172015-11-19 15:56:11 +0900377 memcpy(last_scanned_shadow[ap_index].pu8IEs,
378 pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
379 last_scanned_shadow[ap_index].u32TimeRcvdInScan = jiffies;
380 last_scanned_shadow[ap_index].u32TimeRcvdInScanCached = jiffies;
381 last_scanned_shadow[ap_index].u8Found = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900382 if (ap_found != -1)
Leo Kimf1ab1172015-11-19 15:56:11 +0900383 wilc_free_join_params(last_scanned_shadow[ap_index].pJoinParams);
384 last_scanned_shadow[ap_index].pJoinParams = pJoinParams;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900385}
386
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900387static void CfgScanResult(enum scan_event scan_event,
Leo Kim0551a722015-11-19 15:56:32 +0900388 tstrNetworkInfo *network_info,
Leo Kim30cd10c2015-11-19 15:56:33 +0900389 void *user_void,
Leo Kimbdd34602015-11-19 15:56:34 +0900390 void *join_params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900391{
Chaehyun Lim27268872015-09-15 14:06:13 +0900392 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900393 struct wiphy *wiphy;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900394 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900395 struct ieee80211_channel *channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900396 struct cfg80211_bss *bss = NULL;
397
Leo Kim30cd10c2015-11-19 15:56:33 +0900398 priv = (struct wilc_priv *)user_void;
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100399 if (priv->bCfgScanning) {
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900400 if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900401 wiphy = priv->dev->ieee80211_ptr->wiphy;
Leo Kim7ae43362015-09-16 18:35:59 +0900402
403 if (!wiphy)
404 return;
405
Leo Kim0551a722015-11-19 15:56:32 +0900406 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
407 (((s32)network_info->s8rssi * 100) < 0 ||
408 ((s32)network_info->s8rssi * 100) > 100)) {
Leo Kim24db7132015-09-16 18:36:01 +0900409 PRINT_ER("wiphy signal type fial\n");
410 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900411 }
412
Leo Kim0551a722015-11-19 15:56:32 +0900413 if (network_info) {
414 s32Freq = ieee80211_channel_to_frequency((s32)network_info->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900415 channel = ieee80211_get_channel(wiphy, s32Freq);
416
Leo Kim7ae43362015-09-16 18:35:59 +0900417 if (!channel)
418 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900419
420 PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
Leo Kim0551a722015-11-19 15:56:32 +0900421 "BeaconPeriod: %d\n", channel->center_freq, (((s32)network_info->s8rssi) * 100),
422 network_info->u16CapInfo, network_info->u16BeaconPeriod);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900423
Leo Kim0551a722015-11-19 15:56:32 +0900424 if (network_info->bNewNetwork) {
Leo Kima89f7c52015-11-25 11:59:41 +0900425 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) {
Leo Kim0551a722015-11-19 15:56:32 +0900426 PRINT_D(CFG80211_DBG, "Network %s found\n", network_info->au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900427 priv->u32RcvdChCount++;
428
Leo Kimbdd34602015-11-19 15:56:34 +0900429 if (!join_params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900430 PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n");
Leo Kimbdd34602015-11-19 15:56:34 +0900431 add_network_to_shadow(network_info, priv, join_params);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900432
Leo Kim0551a722015-11-19 15:56:32 +0900433 if (!(memcmp("DIRECT-", network_info->au8ssid, 7))) {
434 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, network_info->au8bssid, network_info->u64Tsf, network_info->u16CapInfo,
435 network_info->u16BeaconPeriod, (const u8 *)network_info->pu8IEs,
436 (size_t)network_info->u16IEsLen, (((s32)network_info->s8rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900437 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900438 }
439
440
441 } else {
442 PRINT_ER("Discovered networks exceeded the max limit\n");
443 }
444 } else {
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900445 u32 i;
Leo Kima89f7c52015-11-25 11:59:41 +0900446
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900447 for (i = 0; i < priv->u32RcvdChCount; i++) {
Leo Kim0551a722015-11-19 15:56:32 +0900448 if (memcmp(last_scanned_shadow[i].au8bssid, network_info->au8bssid, 6) == 0) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900449 PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", last_scanned_shadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900450
Leo Kim0551a722015-11-19 15:56:32 +0900451 last_scanned_shadow[i].s8rssi = network_info->s8rssi;
Leo Kimf1ab1172015-11-19 15:56:11 +0900452 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900453 break;
454 }
455 }
456 }
457 }
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900458 } else if (scan_event == SCAN_EVENT_DONE) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530459 PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev);
460 PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n");
Dean Lee72ed4dc2015-06-12 14:11:44 +0900461 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900462
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530463 if (priv->u32RcvdChCount > 0)
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530464 PRINT_D(CFG80211_DBG, "%d Network(s) found\n", priv->u32RcvdChCount);
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530465 else
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530466 PRINT_D(CFG80211_DBG, "No networks found\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900467
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200468 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900469
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900470 if (priv->pstrScanReq != NULL) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900471 cfg80211_scan_done(priv->pstrScanReq, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900472 priv->u32RcvdChCount = 0;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900473 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900474 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900475 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200476 up(&(priv->hSemScanReq));
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900477 } else if (scan_event == SCAN_EVENT_ABORTED) {
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200478 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900479
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530480 PRINT_D(CFG80211_DBG, "Scan Aborted\n");
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900481 if (priv->pstrScanReq != NULL) {
Leo Kim5e51d8b2015-11-19 15:56:28 +0900482 update_scan_time();
Dean Lee72ed4dc2015-06-12 14:11:44 +0900483 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900484
Dean Lee72ed4dc2015-06-12 14:11:44 +0900485 cfg80211_scan_done(priv->pstrScanReq, false);
486 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900487 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900488 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200489 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900490 }
491 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900492}
493
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100494int wilc_connecting;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900495
Leo Kimed3f0372015-10-12 16:56:01 +0900496static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900497 tstrConnectInfo *pstrConnectInfo,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900498 u8 u8MacStatus,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900499 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
500 void *pUserVoid)
501{
Chaehyun Lim27268872015-09-15 14:06:13 +0900502 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900503 struct net_device *dev;
Leo Kim441dc602015-10-12 16:55:35 +0900504 struct host_if_drv *pstrWFIDrv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900505 u8 NullBssid[ETH_ALEN] = {0};
Glen Leec1ec2c12015-10-20 17:13:58 +0900506 struct wilc *wl;
507 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900508
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100509 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900510
Chaehyun Lim27268872015-09-15 14:06:13 +0900511 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900512 dev = priv->dev;
Glen Leec1ec2c12015-10-20 17:13:58 +0900513 nic = netdev_priv(dev);
514 wl = nic->wilc;
Leo Kim441dc602015-10-12 16:55:35 +0900515 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900516
517 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
Amitoj Kaur Chawlababa7c72015-10-15 13:48:29 +0530518 u16 u16ConnectStatus;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900519
520 u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
521
522 PRINT_D(CFG80211_DBG, " Connection response received = %d\n", u8MacStatus);
523
524 if ((u8MacStatus == MAC_DISCONNECTED) &&
525 (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900526 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100527 wilc_wlan_set_bssid(priv->dev, NullBssid);
Leo Kime554a302015-11-19 15:56:21 +0900528 eth_zero_addr(wilc_connected_ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900529
Leo Kimab16ec02015-10-29 12:05:40 +0900530 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900531 wlan_channel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900532
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530533 PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d\n", u16ConnectStatus, u8MacStatus);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900534 }
535
536 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900537 bool bNeedScanRefresh = false;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900538 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900539
540 PRINT_INFO(CFG80211_DBG, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo->au8bssid[0],
541 pstrConnectInfo->au8bssid[1], pstrConnectInfo->au8bssid[2], pstrConnectInfo->au8bssid[3], pstrConnectInfo->au8bssid[4], pstrConnectInfo->au8bssid[5]);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900542 memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900543
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900544
Leo Kim771fbae2015-11-19 15:56:10 +0900545 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900546 if (memcmp(last_scanned_shadow[i].au8bssid,
547 pstrConnectInfo->au8bssid, ETH_ALEN) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900548 unsigned long now = jiffies;
549
550 if (time_after(now,
Leo Kimf1ab1172015-11-19 15:56:11 +0900551 last_scanned_shadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900552 bNeedScanRefresh = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900553 }
554
555 break;
556 }
557 }
558
Leo Kima89f7c52015-11-25 11:59:41 +0900559 if (bNeedScanRefresh)
Dean Lee72ed4dc2015-06-12 14:11:44 +0900560 refresh_scan(priv, 1, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900561 }
562
563
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530564 PRINT_D(CFG80211_DBG, "Association request info elements length = %zu\n", pstrConnectInfo->ReqIEsLen);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900565
566 PRINT_D(CFG80211_DBG, "Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen);
567
568 cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
569 pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
570 pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
Leo Kima89f7c52015-11-25 11:59:41 +0900571 u16ConnectStatus, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900572 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100573 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900574 PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n",
575 pstrDisconnectNotifInfo->u16reason, priv->dev);
Leo Kim583d9722015-11-19 15:56:16 +0900576 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +0900577 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +0900578 wilc_ie = false;
Shraddha Barkebcf02652015-10-05 17:00:32 +0530579 eth_zero_addr(priv->au8AssociatedBss);
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100580 wilc_wlan_set_bssid(priv->dev, NullBssid);
Leo Kime554a302015-11-19 15:56:21 +0900581 eth_zero_addr(wilc_connected_ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900582
Leo Kimab16ec02015-10-29 12:05:40 +0900583 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900584 wlan_channel = INVALID_CHANNEL;
Glen Leec1ec2c12015-10-20 17:13:58 +0900585 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900586 pstrDisconnectNotifInfo->u16reason = 3;
Leo Kima89f7c52015-11-25 11:59:41 +0900587 } else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900588 pstrDisconnectNotifInfo->u16reason = 1;
589 }
590 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
Sudip Mukherjeee26bb712015-06-30 13:51:51 +0530591 pstrDisconnectNotifInfo->ie_len, false,
592 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900593
594 }
595
596}
597
Chaehyun Lim80785a92015-09-14 12:24:01 +0900598static int set_channel(struct wiphy *wiphy,
599 struct cfg80211_chan_def *chandef)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900600{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900601 u32 channelnum = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +0900602 struct wilc_priv *priv;
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900603 int result = 0;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900604
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900605 priv = wiphy_priv(wiphy);
606
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900607 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
608 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900609
Chaehyun Lim866a2c22015-10-02 16:41:21 +0900610 curr_channel = channelnum;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100611 result = wilc_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900612
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900613 if (result != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900614 PRINT_ER("Error in setting channel %d\n", channelnum);
615
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900616 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900617}
618
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900619static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900620{
Chaehyun Lim27268872015-09-15 14:06:13 +0900621 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900622 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +0900623 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900624 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
Leo Kim607db442015-10-05 15:25:37 +0900625 struct hidden_network strHiddenNetwork;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900626
627 priv = wiphy_priv(wiphy);
628
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900629 priv->pstrScanReq = request;
630
631 priv->u32RcvdChCount = 0;
632
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100633 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Leo Kim12b01382015-11-19 15:56:27 +0900634 reset_shadow_found();
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900635
Dean Lee72ed4dc2015-06-12 14:11:44 +0900636 priv->bCfgScanning = true;
Leo Kima89f7c52015-11-25 11:59:41 +0900637 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900638 for (i = 0; i < request->n_channels; i++) {
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900639 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900640 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
641 }
642
643 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530644 PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900645
646 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
647
648 if (request->n_ssids >= 1) {
649
650
Leo Kim607db442015-10-05 15:25:37 +0900651 strHiddenNetwork.pstrHiddenNetworkInfo = kmalloc(request->n_ssids * sizeof(struct hidden_network), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900652 strHiddenNetwork.u8ssidnum = request->n_ssids;
653
654
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900655 for (i = 0; i < request->n_ssids; i++) {
656
657 if (request->ssids[i].ssid != NULL && request->ssids[i].ssid_len != 0) {
Glen Leef3052582015-09-10 12:03:04 +0900658 strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900659 memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900660 strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len;
661 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530662 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900663 strHiddenNetwork.u8ssidnum -= 1;
664 }
665 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530666 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100667 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900668 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900669 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900670 CfgScanResult, (void *)priv, &strHiddenNetwork);
671 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530672 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100673 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900674 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900675 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900676 CfgScanResult, (void *)priv, NULL);
677 }
678
679 } else {
680 PRINT_ER("Requested num of scanned channels is greater than the max, supported"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530681 " channels\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900682 }
683
Leo Kime6e12662015-09-16 18:36:03 +0900684 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900685 s32Error = -EBUSY;
686 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
687 }
688
689 return s32Error;
690}
691
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900692static int connect(struct wiphy *wiphy, struct net_device *dev,
693 struct cfg80211_connect_params *sme)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900694{
Leo Kime6e12662015-09-16 18:36:03 +0900695 s32 s32Error = 0;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900696 u32 i;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900697 u8 u8security = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +0900698 enum AUTHTYPE tenuAuth_type = ANY;
Dean Lee576917a2015-06-15 11:58:57 +0900699 char *pcgroup_encrypt_val = NULL;
700 char *pccipher_group = NULL;
701 char *pcwpa_version = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900702
Chaehyun Lim27268872015-09-15 14:06:13 +0900703 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +0900704 struct host_if_drv *pstrWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900705 tstrNetworkInfo *pstrNetworkInfo = NULL;
706
707
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100708 wilc_connecting = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900709 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +0900710 pstrWFIDrv = (struct host_if_drv *)(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900711
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100712 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900713
Johnny Kim8a143302015-06-10 17:06:46 +0900714 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 +0900715 if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900716 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
Leo Kimab16ec02015-10-29 12:05:40 +0900717 pstrWFIDrv->p2p_connect = 1;
718 } else {
719 pstrWFIDrv->p2p_connect = 0;
720 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530721 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900722
Leo Kim771fbae2015-11-19 15:56:10 +0900723 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900724 if ((sme->ssid_len == last_scanned_shadow[i].u8SsidLen) &&
725 memcmp(last_scanned_shadow[i].au8ssid,
726 sme->ssid,
727 sme->ssid_len) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900728 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
729 if (sme->bssid == NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900730 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
731 break;
732 } else {
Leo Kimf1ab1172015-11-19 15:56:11 +0900733 if (memcmp(last_scanned_shadow[i].au8bssid,
734 sme->bssid,
735 ETH_ALEN) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900736 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
737 break;
738 }
739 }
740 }
741 }
742
Leo Kim771fbae2015-11-19 15:56:10 +0900743 if (i < last_scanned_cnt) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900744 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
745
Leo Kimf1ab1172015-11-19 15:56:11 +0900746 pstrNetworkInfo = &last_scanned_shadow[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900747
748 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
749 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
750 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
751 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
752 } else {
753 s32Error = -ENOENT;
Leo Kim771fbae2015-11-19 15:56:10 +0900754 if (last_scanned_cnt == 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900755 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
756 else
757 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
758
759 goto done;
760 }
761
762 priv->WILC_WFI_wep_default = 0;
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900763 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
764 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900765
766 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
767 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
768
769 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
770
771 if (INFO) {
772 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
773 PRINT_D(CORECONFIG_DBG, "sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]);
774 }
775
776 if (sme->crypto.cipher_group != NO_ENCRYPT) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900777 pcwpa_version = "Default";
778 PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900779 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900780 u8security = ENCRYPT_ENABLED | WEP;
781 pcgroup_encrypt_val = "WEP40";
782 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
783 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
784
785 if (INFO) {
786 for (i = 0; i < sme->key_len; i++)
787 PRINT_D(CORECONFIG_DBG, "WEP Key Value[%d] = %d\n", i, sme->key[i]);
788 }
789 priv->WILC_WFI_wep_default = sme->key_idx;
790 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900791 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900792
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900793 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900794 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900795 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
796 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900797 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900798
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100799 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
800 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900801 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900802 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
803 pcgroup_encrypt_val = "WEP104";
804 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
805
806 priv->WILC_WFI_wep_default = sme->key_idx;
807 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900808 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900809
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900810 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900811 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900812 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
813 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900814 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900815
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100816 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
817 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900818 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900819 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900820 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
821 pcgroup_encrypt_val = "WPA2_TKIP";
822 pccipher_group = "TKIP";
Leo Kima89f7c52015-11-25 11:59:41 +0900823 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900824 u8security = ENCRYPT_ENABLED | WPA2 | AES;
825 pcgroup_encrypt_val = "WPA2_AES";
826 pccipher_group = "AES";
827 }
828 pcwpa_version = "WPA_VERSION_2";
829 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
830 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900831 u8security = ENCRYPT_ENABLED | WPA | TKIP;
832 pcgroup_encrypt_val = "WPA_TKIP";
833 pccipher_group = "TKIP";
Leo Kima89f7c52015-11-25 11:59:41 +0900834 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900835 u8security = ENCRYPT_ENABLED | WPA | AES;
836 pcgroup_encrypt_val = "WPA_AES";
837 pccipher_group = "AES";
838
839 }
840 pcwpa_version = "WPA_VERSION_1";
841
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900842 } else {
843 s32Error = -ENOTSUPP;
844 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
845
846 goto done;
847 }
848
849 }
850
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900851 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
852 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
853 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
854 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
855 u8security = u8security | TKIP;
Leo Kima89f7c52015-11-25 11:59:41 +0900856 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900857 u8security = u8security | AES;
858 }
859 }
860 }
861
862 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
863
864 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
865 switch (sme->auth_type) {
866 case NL80211_AUTHTYPE_OPEN_SYSTEM:
867 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
868 tenuAuth_type = OPEN_SYSTEM;
869 break;
870
871 case NL80211_AUTHTYPE_SHARED_KEY:
872 tenuAuth_type = SHARED_KEY;
873 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
874 break;
875
876 default:
877 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
878 }
879
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900880 if (sme->crypto.n_akm_suites) {
881 switch (sme->crypto.akm_suites[0]) {
882 case WLAN_AKM_SUITE_8021X:
883 tenuAuth_type = IEEE8021;
884 break;
885
886 default:
887 break;
888 }
889 }
890
891
892 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
893
894 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
895 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
896
Chaehyun Lim866a2c22015-10-02 16:41:21 +0900897 curr_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900898
Leo Kimab16ec02015-10-29 12:05:40 +0900899 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900900 wlan_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900901
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100902 wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900903
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100904 s32Error = wilc_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900905 sme->ssid_len, sme->ie, sme->ie_len,
906 CfgConnectResult, (void *)priv, u8security,
907 tenuAuth_type, pstrNetworkInfo->u8channel,
908 pstrNetworkInfo->pJoinParams);
Leo Kime6e12662015-09-16 18:36:03 +0900909 if (s32Error != 0) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100910 PRINT_ER("wilc_set_join_req(): Error(%d)\n", s32Error);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900911 s32Error = -ENOENT;
912 goto done;
913 }
914
915done:
916
917 return s32Error;
918}
919
Chaehyun Limb027cde2015-09-14 12:24:04 +0900920static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900921{
Leo Kime6e12662015-09-16 18:36:03 +0900922 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +0900923 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +0900924 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900925 u8 NullBssid[ETH_ALEN] = {0};
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900926
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100927 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900928 priv = wiphy_priv(wiphy);
929
Leo Kim441dc602015-10-12 16:55:35 +0900930 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Leo Kimab16ec02015-10-29 12:05:40 +0900931 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900932 wlan_channel = INVALID_CHANNEL;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100933 wilc_wlan_set_bssid(priv->dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900934
935 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
936
Leo Kim583d9722015-11-19 15:56:16 +0900937 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +0900938 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +0900939 wilc_ie = false;
Leo Kim1229b1a2015-10-29 12:05:39 +0900940 pstrWFIDrv->p2p_timeout = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900941
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100942 s32Error = wilc_disconnect(priv->hWILCWFIDrv, reason_code);
Leo Kime6e12662015-09-16 18:36:03 +0900943 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900944 PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
945 s32Error = -EINVAL;
946 }
947
948 return s32Error;
949}
950
Chaehyun Lim953d4172015-09-14 12:24:05 +0900951static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
952 bool pairwise,
953 const u8 *mac_addr, struct key_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900954
955{
Leo Kime6e12662015-09-16 18:36:03 +0900956 s32 s32Error = 0, KeyLen = params->key_len;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900957 u32 i;
Chaehyun Lim27268872015-09-15 14:06:13 +0900958 struct wilc_priv *priv;
Arnd Bergmann057d1e92015-06-01 21:06:44 +0200959 const u8 *pu8RxMic = NULL;
960 const u8 *pu8TxMic = NULL;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900961 u8 u8mode = NO_ENCRYPT;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900962 u8 u8gmode = NO_ENCRYPT;
963 u8 u8pmode = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +0900964 enum AUTHTYPE tenuAuth_type = ANY;
Glen Lee76469202015-10-20 17:13:59 +0900965 struct wilc *wl;
966 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900967
968 priv = wiphy_priv(wiphy);
Glen Lee76469202015-10-20 17:13:59 +0900969 nic = netdev_priv(netdev);
970 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900971
972 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
973
Johnny Kim8a143302015-06-10 17:06:46 +0900974 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900975
976 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
977 params->key[1],
978 params->key[2]);
979
980
981 switch (params->cipher) {
982 case WLAN_CIPHER_SUITE_WEP40:
983 case WLAN_CIPHER_SUITE_WEP104:
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900984 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
985
986 priv->WILC_WFI_wep_default = key_index;
987 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900988 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900989
990 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
991 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
992
993 for (i = 0; i < params->key_len; i++)
994 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
995
996 tenuAuth_type = OPEN_SYSTEM;
997
998 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
999 u8mode = ENCRYPT_ENABLED | WEP;
1000 else
1001 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
1002
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001003 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 +09001004 break;
1005 }
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001006 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001007 priv->WILC_WFI_wep_default = key_index;
1008 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001009 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001010
1011 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
1012 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
1013 if (INFO) {
1014 for (i = 0; i < params->key_len; i++)
1015 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
1016 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001017 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001018 }
1019
1020 break;
1021
1022 case WLAN_CIPHER_SUITE_TKIP:
1023 case WLAN_CIPHER_SUITE_CCMP:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001024 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
1025
1026 if (priv->wilc_gtk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001027 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001028 priv->wilc_gtk[key_index]->key = NULL;
1029 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001030
1031 }
1032 if (priv->wilc_ptk[key_index] == NULL) {
Glen Leef3052582015-09-10 12:03:04 +09001033 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001034 priv->wilc_ptk[key_index]->key = NULL;
1035 priv->wilc_ptk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001036 }
1037
1038
1039
Daniel Machon19132212015-08-05 08:18:31 +02001040 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001041 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1042 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1043 else
1044 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1045
1046 priv->wilc_groupkey = u8gmode;
1047
1048 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1049
1050 pu8TxMic = params->key + 24;
1051 pu8RxMic = params->key + 16;
1052 KeyLen = params->key_len - 16;
1053 }
Shraddha Barkecccfc392015-10-12 20:49:19 +05301054 kfree(priv->wilc_gtk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001055
Glen Leef3052582015-09-10 12:03:04 +09001056 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001057 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
Shraddha Barkecccfc392015-10-12 20:49:19 +05301058 kfree(priv->wilc_gtk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001059
1060 if ((params->seq_len) > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001061 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001062 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001063 }
1064
1065 priv->wilc_gtk[key_index]->cipher = params->cipher;
1066 priv->wilc_gtk[key_index]->key_len = params->key_len;
1067 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1068
1069 if (INFO) {
1070 for (i = 0; i < params->key_len; i++)
1071 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1072 for (i = 0; i < params->seq_len; i++)
1073 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1074 }
1075
1076
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001077 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001078 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode);
1079
1080 } else {
1081 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]);
1082
1083 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1084 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1085 else
1086 u8pmode = priv->wilc_groupkey | AES;
1087
1088
1089 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1090
1091 pu8TxMic = params->key + 24;
1092 pu8RxMic = params->key + 16;
1093 KeyLen = params->key_len - 16;
1094 }
1095
Shraddha Barkecccfc392015-10-12 20:49:19 +05301096 kfree(priv->wilc_ptk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001097
Glen Leef3052582015-09-10 12:03:04 +09001098 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001099
Shraddha Barkecccfc392015-10-12 20:49:19 +05301100 kfree(priv->wilc_ptk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001101
1102 if ((params->seq_len) > 0)
Glen Leef3052582015-09-10 12:03:04 +09001103 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001104
1105 if (INFO) {
1106 for (i = 0; i < params->key_len; i++)
1107 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1108
1109 for (i = 0; i < params->seq_len; i++)
1110 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1111 }
1112
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001113 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001114
1115 if ((params->seq_len) > 0)
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001116 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001117
1118 priv->wilc_ptk[key_index]->cipher = params->cipher;
1119 priv->wilc_ptk[key_index]->key_len = params->key_len;
1120 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1121
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001122 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001123 pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index);
1124 }
1125 break;
1126 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001127
1128 {
1129 u8mode = 0;
Daniel Machon19132212015-08-05 08:18:31 +02001130 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001131 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001132 pu8RxMic = params->key + 24;
1133 pu8TxMic = params->key + 16;
1134 KeyLen = params->key_len - 16;
1135 }
1136
Glen Lee76469202015-10-20 17:13:59 +09001137 if (!g_gtk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001138 g_add_gtk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001139 g_add_gtk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001140 if (!mac_addr) {
1141 g_add_gtk_key_params.mac_addr = NULL;
1142 } else {
Glen Leef3052582015-09-10 12:03:04 +09001143 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001144 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1145 }
1146 g_key_gtk_params.key_len = params->key_len;
1147 g_key_gtk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001148 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001149 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1150 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001151 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001152 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1153 }
1154 g_key_gtk_params.cipher = params->cipher;
1155
1156 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1157 g_key_gtk_params.key[1],
1158 g_key_gtk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001159 g_gtk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001160 }
1161
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001162 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001163 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001164 } else {
1165 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001166 pu8RxMic = params->key + 24;
1167 pu8TxMic = params->key + 16;
1168 KeyLen = params->key_len - 16;
1169 }
1170
Glen Lee76469202015-10-20 17:13:59 +09001171 if (!g_ptk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001172 g_add_ptk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001173 g_add_ptk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001174 if (!mac_addr) {
1175 g_add_ptk_key_params.mac_addr = NULL;
1176 } else {
Glen Leef3052582015-09-10 12:03:04 +09001177 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001178 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1179 }
1180 g_key_ptk_params.key_len = params->key_len;
1181 g_key_ptk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001182 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001183 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1184 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001185 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001186 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1187 }
1188 g_key_ptk_params.cipher = params->cipher;
1189
1190 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1191 g_key_ptk_params.key[1],
1192 g_key_ptk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001193 g_ptk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001194 }
1195
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001196 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001197 pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index);
1198 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1199 if (INFO) {
1200 for (i = 0; i < params->key_len; i++)
1201 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1202 }
1203 }
1204 }
1205 break;
1206
1207 default:
1208 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
1209 s32Error = -ENOTSUPP;
1210
1211 }
1212
1213 return s32Error;
1214}
1215
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001216static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1217 u8 key_index,
1218 bool pairwise,
1219 const u8 *mac_addr)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001220{
Chaehyun Lim27268872015-09-15 14:06:13 +09001221 struct wilc_priv *priv;
Glen Lee692e2ac2015-10-20 17:14:00 +09001222 struct wilc *wl;
1223 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001224
1225 priv = wiphy_priv(wiphy);
Glen Lee692e2ac2015-10-20 17:14:00 +09001226 nic = netdev_priv(netdev);
1227 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001228
Glen Lee692e2ac2015-10-20 17:14:00 +09001229 if (netdev == wl->vif[0].ndev) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09001230 g_ptk_keys_saved = false;
1231 g_gtk_keys_saved = false;
1232 g_wep_keys_saved = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001233
Shraddha Barkecccfc392015-10-12 20:49:19 +05301234 kfree(g_key_wep_params.key);
1235 g_key_wep_params.key = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001236
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001237 if ((priv->wilc_gtk[key_index]) != NULL) {
1238
Shraddha Barkecccfc392015-10-12 20:49:19 +05301239 kfree(priv->wilc_gtk[key_index]->key);
1240 priv->wilc_gtk[key_index]->key = NULL;
1241 kfree(priv->wilc_gtk[key_index]->seq);
1242 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001243
Chaehyun Lim49188af2015-08-11 10:32:41 +09001244 kfree(priv->wilc_gtk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001245 priv->wilc_gtk[key_index] = NULL;
1246
1247 }
1248
1249 if ((priv->wilc_ptk[key_index]) != NULL) {
1250
Shraddha Barkecccfc392015-10-12 20:49:19 +05301251 kfree(priv->wilc_ptk[key_index]->key);
1252 priv->wilc_ptk[key_index]->key = NULL;
1253 kfree(priv->wilc_ptk[key_index]->seq);
1254 priv->wilc_ptk[key_index]->seq = NULL;
Chaehyun Lim49188af2015-08-11 10:32:41 +09001255 kfree(priv->wilc_ptk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001256 priv->wilc_ptk[key_index] = NULL;
1257 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001258
Shraddha Barkecccfc392015-10-12 20:49:19 +05301259 kfree(g_key_ptk_params.key);
1260 g_key_ptk_params.key = NULL;
1261 kfree(g_key_ptk_params.seq);
1262 g_key_ptk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001263
Shraddha Barkecccfc392015-10-12 20:49:19 +05301264 kfree(g_key_gtk_params.key);
1265 g_key_gtk_params.key = NULL;
1266 kfree(g_key_gtk_params.seq);
1267 g_key_gtk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001268
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001269 wilc_set_machw_change_vir_if(netdev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001270 }
1271
1272 if (key_index >= 0 && key_index <= 3) {
Chaehyun Lim2cc46832015-08-07 09:02:01 +09001273 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001274 priv->WILC_WFI_wep_key_len[key_index] = 0;
1275
1276 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001277 wilc_remove_wep_key(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001278 } else {
1279 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001280 wilc_remove_key(priv->hWILCWFIDrv, mac_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001281 }
1282
Leo Kimaaed3292015-10-12 16:55:38 +09001283 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001284}
1285
Chaehyun Limf4893df2015-09-14 12:24:07 +09001286static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1287 bool pairwise,
1288 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001289{
Chaehyun Lim27268872015-09-15 14:06:13 +09001290 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001291 struct key_params key_params;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001292 u32 i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001293
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001294 priv = wiphy_priv(wiphy);
1295
1296
Alison Schofield3604af52015-10-12 13:22:44 -07001297 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001298 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1299
1300 key_params.key = priv->wilc_gtk[key_index]->key;
1301 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1302 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1303 key_params.seq = priv->wilc_gtk[key_index]->seq;
1304 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1305 if (INFO) {
1306 for (i = 0; i < key_params.key_len; i++)
1307 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1308 }
1309 } else {
1310 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1311
1312 key_params.key = priv->wilc_ptk[key_index]->key;
1313 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1314 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1315 key_params.seq = priv->wilc_ptk[key_index]->seq;
1316 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1317 }
1318
1319 callback(cookie, &key_params);
1320
Leo Kima89f7c52015-11-25 11:59:41 +09001321 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001322}
1323
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001324static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1325 bool unicast, bool multicast)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001326{
Chaehyun Lim27268872015-09-15 14:06:13 +09001327 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001328
1329
1330 priv = wiphy_priv(wiphy);
1331
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301332 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001333
1334 if (key_index != priv->WILC_WFI_wep_default) {
1335
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001336 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001337 }
1338
Leo Kimaaed3292015-10-12 16:55:38 +09001339 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001340}
1341
Chaehyun Limf06f5622015-09-14 12:24:18 +09001342static int get_station(struct wiphy *wiphy, struct net_device *dev,
1343 const u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001344{
Chaehyun Lim27268872015-09-15 14:06:13 +09001345 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001346 perInterface_wlan_t *nic;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001347 u32 i = 0;
1348 u32 associatedsta = 0;
1349 u32 inactive_time = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001350 priv = wiphy_priv(wiphy);
1351 nic = netdev_priv(dev);
1352
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001353 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
1354 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1355
1356 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1357
1358 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
1359
1360 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1361 associatedsta = i;
1362 break;
1363 }
1364
1365 }
1366
1367 if (associatedsta == -1) {
Leo Kimaaed3292015-10-12 16:55:38 +09001368 PRINT_ER("Station required is not associated\n");
1369 return -ENOENT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001370 }
1371
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001372 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001373
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001374 wilc_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001375 sinfo->inactive_time = 1000 * inactive_time;
1376 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
1377
1378 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001379
1380 if (nic->iftype == STATION_MODE) {
Leo Kim03e7b9c2015-10-12 16:55:58 +09001381 struct rf_info strStatistics;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001382
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001383 wilc_get_statistics(priv->hWILCWFIDrv, &strStatistics);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001384
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001385 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
Chandra S Gorentla62129902015-08-05 22:11:57 +05301386 BIT(NL80211_STA_INFO_RX_PACKETS) |
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001387 BIT(NL80211_STA_INFO_TX_PACKETS) |
1388 BIT(NL80211_STA_INFO_TX_FAILED) |
1389 BIT(NL80211_STA_INFO_TX_BITRATE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001390
Leo Kim00c8dfc2015-10-29 12:05:30 +09001391 sinfo->signal = strStatistics.rssi;
Leo Kim9b992742015-10-29 12:05:32 +09001392 sinfo->rx_packets = strStatistics.rx_cnt;
Leo Kim54160372015-10-29 12:05:33 +09001393 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1394 sinfo->tx_failed = strStatistics.tx_fail_cnt;
Leo Kim5babeec2015-10-29 12:05:29 +09001395 sinfo->txrate.legacy = strStatistics.link_speed * 10;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001396
Leo Kim5babeec2015-10-29 12:05:29 +09001397 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1398 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001399 wilc_enable_tcp_ack_filter(true);
Leo Kim5babeec2015-10-29 12:05:29 +09001400 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001401 wilc_enable_tcp_ack_filter(false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001402
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001403 PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
1404 sinfo->tx_failed, sinfo->txrate.legacy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001405 }
Leo Kimaaed3292015-10-12 16:55:38 +09001406 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001407}
1408
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001409static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1410 struct bss_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001411{
1412 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1413 return 0;
1414}
1415
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001416static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001417{
Leo Kime6e12662015-09-16 18:36:03 +09001418 s32 s32Error = 0;
Leo Kim95296502015-10-05 15:25:46 +09001419 struct cfg_param_val pstrCfgParamVal;
Chaehyun Lim27268872015-09-15 14:06:13 +09001420 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001421
1422 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001423
Tony Cho87c05b22015-10-12 16:56:07 +09001424 pstrCfgParamVal.flag = 0;
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301425 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001426
1427 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1428 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1429 priv->dev->ieee80211_ptr->wiphy->retry_short);
Tony Cho87c05b22015-10-12 16:56:07 +09001430 pstrCfgParamVal.flag |= RETRY_SHORT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001431 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1432 }
1433 if (changed & WIPHY_PARAM_RETRY_LONG) {
1434
1435 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 +09001436 pstrCfgParamVal.flag |= RETRY_LONG;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001437 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
1438
1439 }
1440 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1441 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 +09001442 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001443 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
1444
1445 }
1446
1447 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1448 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1449
Tony Cho87c05b22015-10-12 16:56:07 +09001450 pstrCfgParamVal.flag |= RTS_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001451 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
1452
1453 }
1454
1455 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001456 s32Error = wilc_hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001457 if (s32Error)
1458 PRINT_ER("Error in setting WIPHY PARAMS\n");
1459
1460
1461 return s32Error;
1462}
Arnd Bergmanne5af0562015-05-29 22:52:12 +02001463
Chaehyun Lim4d466572015-09-14 12:24:22 +09001464static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1465 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001466{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001467 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001468 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001469 u8 flag = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001470
Chaehyun Lim27268872015-09-15 14:06:13 +09001471 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001472
1473 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1474
1475
1476 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001477 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001478 ETH_ALEN)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001479 flag = PMKID_FOUND;
1480 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1481 break;
1482 }
1483 }
1484 if (i < WILC_MAX_NUM_PMKIDS) {
1485 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001486 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001487 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001488 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001489 PMKID_LEN);
1490 if (!(flag == PMKID_FOUND))
1491 priv->pmkid_list.numpmkid++;
1492 } else {
1493 PRINT_ER("Invalid PMKID index\n");
1494 s32Error = -EINVAL;
1495 }
1496
1497 if (!s32Error) {
1498 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001499 s32Error = wilc_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001500 }
1501 return s32Error;
1502}
1503
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001504static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1505 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001506{
1507
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001508 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001509 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001510
Chaehyun Lim27268872015-09-15 14:06:13 +09001511 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001512
1513 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1514
1515 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001516 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001517 ETH_ALEN)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001518 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
Leo Kimcd1e6cb2015-10-05 15:25:45 +09001519 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001520 break;
1521 }
1522 }
1523
1524 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1525 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001526 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001527 priv->pmkid_list.pmkidlist[i + 1].bssid,
1528 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001529 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001530 priv->pmkid_list.pmkidlist[i].pmkid,
1531 PMKID_LEN);
1532 }
1533 priv->pmkid_list.numpmkid--;
1534 } else {
1535 s32Error = -EINVAL;
1536 }
1537
1538 return s32Error;
1539}
1540
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001541static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001542{
Chaehyun Lim27268872015-09-15 14:06:13 +09001543 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001544
1545 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
1546
Leo Kima949f902015-10-05 15:25:44 +09001547 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001548
1549 return 0;
1550}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001551
Arnd Bergmann1608c402015-11-16 15:04:53 +01001552static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001553{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001554 u32 index = 0;
1555 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001556
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001557 u8 op_channel_attr_index = 0;
1558 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001559
1560 while (index < len) {
1561 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001562 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001563 }
1564
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301565 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001566 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301567 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001568 op_channel_attr_index = index;
Leo Kima89f7c52015-11-25 11:59:41 +09001569 index += buf[index + 1] + 3;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001570 }
Leo Kim0bd82742015-11-19 15:56:14 +09001571 if (wlan_channel != INVALID_CHANNEL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001572 if (channel_list_attr_index) {
1573 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1574 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1575 if (buf[i] == 0x51) {
1576 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
Leo Kim0bd82742015-11-19 15:56:14 +09001577 buf[j] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001578 }
1579 break;
1580 }
1581 }
1582 }
Leo Kima89f7c52015-11-25 11:59:41 +09001583
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001584 if (op_channel_attr_index) {
1585 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1586 buf[op_channel_attr_index + 6] = 0x51;
Leo Kim0bd82742015-11-19 15:56:14 +09001587 buf[op_channel_attr_index + 7] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001588 }
1589 }
1590}
1591
Arnd Bergmann1608c402015-11-16 15:04:53 +01001592static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001593{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001594 u32 index = 0;
1595 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001596
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001597 u8 op_channel_attr_index = 0;
1598 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001599
1600 while (index < len) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001601 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001602 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001603
1604 break;
1605 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001606
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301607 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001608 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301609 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001610 op_channel_attr_index = index;
Leo Kima89f7c52015-11-25 11:59:41 +09001611 index += buf[index + 1] + 3;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001612 }
Leo Kim0bd82742015-11-19 15:56:14 +09001613 if (wlan_channel != INVALID_CHANNEL && bOperChan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001614 if (channel_list_attr_index) {
1615 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1616 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1617 if (buf[i] == 0x51) {
1618 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
Leo Kim0bd82742015-11-19 15:56:14 +09001619 buf[j] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001620 }
1621 break;
1622 }
1623 }
1624 }
Leo Kima89f7c52015-11-25 11:59:41 +09001625
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001626 if (op_channel_attr_index) {
1627 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1628 buf[op_channel_attr_index + 6] = 0x51;
Leo Kim0bd82742015-11-19 15:56:14 +09001629 buf[op_channel_attr_index + 7] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001630 }
1631 }
1632}
1633
Chaehyun Limfbc2fe12015-09-15 14:06:16 +09001634void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001635{
1636
Chaehyun Lim27268872015-09-15 14:06:13 +09001637 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001638 u32 header, pkt_offset;
Leo Kim441dc602015-10-12 16:55:35 +09001639 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001640 u32 i = 0;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001641 s32 s32Freq;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001642
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001643 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001644 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001645
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001646 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001647
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001648 pkt_offset = GET_PKT_OFFSET(header);
1649
1650 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1651 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1652 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001653 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001654 return;
1655 } else {
1656 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
1657 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],
1658 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001659 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001660 } else {
1661 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],
1662 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001663 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001664 }
1665 return;
1666 }
1667 } else {
1668
1669 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
1670
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001671 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001672
1673 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1674 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
1675
Leo Kim1229b1a2015-10-29 12:05:39 +09001676 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001677 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
1678 return;
1679 }
1680 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
1681
1682 switch (buff[ACTION_SUBTYPE_ID]) {
1683 case GAS_INTIAL_REQ:
1684 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
1685 break;
1686
1687 case GAS_INTIAL_RSP:
1688 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
1689 break;
1690
1691 case PUBLIC_ACT_VENDORSPEC:
Leo Kim881eb5d2015-11-19 15:56:15 +09001692 if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001693 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
Leo Kima25d5182015-11-19 15:56:19 +09001694 if (!wilc_ie) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001695 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
Leo Kim86685942015-11-19 15:56:18 +09001696 if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09001697 p2p_recv_random = buff[i + 6];
Leo Kima25d5182015-11-19 15:56:19 +09001698 wilc_ie = true;
Leo Kimb84a3ac2015-11-19 15:56:17 +09001699 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", p2p_recv_random);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001700 break;
1701 }
1702 }
1703 }
1704 }
Leo Kimb84a3ac2015-11-19 15:56:17 +09001705 if (p2p_local_random > p2p_recv_random) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001706 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1707 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1708 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
Leo Kim881eb5d2015-11-19 15:56:15 +09001709 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001710 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
1711 break;
1712 }
1713 }
1714 }
Leo Kim583d9722015-11-19 15:56:16 +09001715 } else {
Leo Kimb84a3ac2015-11-19 15:56:17 +09001716 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 +09001717 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001718 }
1719
1720
Leo Kima25d5182015-11-19 15:56:19 +09001721 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 +09001722 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001723 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001724 return;
1725 }
1726 break;
1727
1728 default:
1729 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
1730 break;
1731 }
1732 }
1733 }
1734
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001735 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001736 }
1737}
1738
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001739static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
1740{
1741 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
1742
1743
1744 kfree(pv_data->buff);
1745 kfree(pv_data);
1746}
1747
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001748static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
1749{
Chaehyun Lim27268872015-09-15 14:06:13 +09001750 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001751
Chaehyun Lim27268872015-09-15 14:06:13 +09001752 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001753
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301754 PRINT_D(HOSTINF_DBG, "Remain on channel ready\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001755
Dean Lee72ed4dc2015-06-12 14:11:44 +09001756 priv->bInP2PlistenState = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001757
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001758 cfg80211_ready_on_channel(priv->wdev,
1759 priv->strRemainOnChanParams.u64ListenCookie,
1760 priv->strRemainOnChanParams.pstrListenChan,
1761 priv->strRemainOnChanParams.u32ListenDuration,
1762 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001763}
1764
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001765static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001766{
Chaehyun Lim27268872015-09-15 14:06:13 +09001767 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001768
Chaehyun Lim27268872015-09-15 14:06:13 +09001769 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001770
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001771 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301772 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001773
Dean Lee72ed4dc2015-06-12 14:11:44 +09001774 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001775
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001776 cfg80211_remain_on_channel_expired(priv->wdev,
1777 priv->strRemainOnChanParams.u64ListenCookie,
1778 priv->strRemainOnChanParams.pstrListenChan,
1779 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001780 } else {
1781 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
1782 , priv->strRemainOnChanParams.u32ListenSessionID);
1783 }
1784}
1785
Chaehyun Lim6d19d692015-09-14 12:24:25 +09001786static int remain_on_channel(struct wiphy *wiphy,
1787 struct wireless_dev *wdev,
1788 struct ieee80211_channel *chan,
1789 unsigned int duration, u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001790{
Leo Kime6e12662015-09-16 18:36:03 +09001791 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09001792 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001793
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001794 priv = wiphy_priv(wiphy);
1795
1796 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
1797
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001798
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001799 if (wdev->iftype == NL80211_IFTYPE_AP) {
1800 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
1801 return s32Error;
1802 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001803
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001804 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001805
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001806 priv->strRemainOnChanParams.pstrListenChan = chan;
1807 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001808 priv->strRemainOnChanParams.u32ListenDuration = duration;
1809 priv->strRemainOnChanParams.u32ListenSessionID++;
1810
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001811 s32Error = wilc_remain_on_channel(priv->hWILCWFIDrv
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001812 , priv->strRemainOnChanParams.u32ListenSessionID
1813 , duration
1814 , chan->hw_value
1815 , WILC_WFI_RemainOnChannelExpired
1816 , WILC_WFI_RemainOnChannelReady
1817 , (void *)priv);
1818
1819 return s32Error;
1820}
1821
Chaehyun Lim1dd54402015-09-14 12:24:26 +09001822static int cancel_remain_on_channel(struct wiphy *wiphy,
1823 struct wireless_dev *wdev,
1824 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001825{
Leo Kime6e12662015-09-16 18:36:03 +09001826 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09001827 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001828
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001829 priv = wiphy_priv(wiphy);
1830
1831 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
1832
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001833 s32Error = wilc_listen_state_expired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001834 return s32Error;
1835}
Leo Kima89f7c52015-11-25 11:59:41 +09001836
Chaehyun Limc1560322015-09-22 18:34:51 +09001837static int mgmt_tx(struct wiphy *wiphy,
1838 struct wireless_dev *wdev,
1839 struct cfg80211_mgmt_tx_params *params,
1840 u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001841{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001842 struct ieee80211_channel *chan = params->chan;
1843 unsigned int wait = params->wait;
1844 const u8 *buf = params->buf;
1845 size_t len = params->len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001846 const struct ieee80211_mgmt *mgmt;
1847 struct p2p_mgmt_data *mgmt_tx;
Chaehyun Lim27268872015-09-15 14:06:13 +09001848 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09001849 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001850 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001851 perInterface_wlan_t *nic;
Leo Kim86685942015-11-19 15:56:18 +09001852 u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001853
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001854 nic = netdev_priv(wdev->netdev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001855 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001856 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001857
1858 *cookie = (unsigned long)buf;
1859 priv->u64tx_cookie = *cookie;
1860 mgmt = (const struct ieee80211_mgmt *) buf;
1861
1862 if (ieee80211_is_mgmt(mgmt->frame_control)) {
Glen Leef3052582015-09-10 12:03:04 +09001863 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001864 if (mgmt_tx == NULL) {
1865 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
Leo Kime6e12662015-09-16 18:36:03 +09001866 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001867 }
Glen Leef3052582015-09-10 12:03:04 +09001868 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001869 if (mgmt_tx->buff == NULL) {
1870 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
Tony Chof638dd32015-09-07 19:09:31 +09001871 kfree(mgmt_tx);
Leo Kime6e12662015-09-16 18:36:03 +09001872 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001873 }
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001874 memcpy(mgmt_tx->buff, buf, len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001875 mgmt_tx->size = len;
1876
1877
1878 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
1879 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
1880 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001881 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001882 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001883 } else if (ieee80211_is_action(mgmt->frame_control)) {
Chaehyun Limd85f5322015-06-11 14:35:54 +09001884 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001885
1886
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001887 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001888 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
1889 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
1890 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001891 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001892 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001893 }
1894 switch (buf[ACTION_SUBTYPE_ID]) {
1895 case GAS_INTIAL_REQ:
1896 {
1897 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
1898 break;
1899 }
1900
1901 case GAS_INTIAL_RSP:
1902 {
1903 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
1904 break;
1905 }
1906
1907 case PUBLIC_ACT_VENDORSPEC:
1908 {
Leo Kim881eb5d2015-11-19 15:56:15 +09001909 if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001910 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09001911 if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
Leo Kim583d9722015-11-19 15:56:16 +09001912 get_random_bytes(&p2p_local_random, 1);
1913 p2p_local_random++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001914 }
1915 }
1916
1917 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1918 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09001919 if (p2p_local_random > p2p_recv_random) {
1920 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 +09001921
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001922 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
Leo Kim881eb5d2015-11-19 15:56:15 +09001923 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001924 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
Dean Lee72ed4dc2015-06-12 14:11:44 +09001925 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001926 else
Dean Lee72ed4dc2015-06-12 14:11:44 +09001927 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001928 break;
1929 }
1930 }
1931
1932 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
Leo Kim86685942015-11-19 15:56:18 +09001933 memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
1934 mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001935 mgmt_tx->size = buf_len;
1936 }
Leo Kim583d9722015-11-19 15:56:16 +09001937 } else {
Leo Kimb84a3ac2015-11-19 15:56:17 +09001938 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 +09001939 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001940 }
1941
1942 } else {
1943 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
1944 }
1945
1946 break;
1947 }
1948
1949 default:
1950 {
1951 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
1952 break;
1953 }
1954 }
1955
1956 }
1957
1958 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 +09001959 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001960
Leo Kim1229b1a2015-10-29 12:05:39 +09001961 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n",
1962 jiffies, pstrWFIDrv->p2p_timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001963 }
1964
Glen Lee829c4772015-10-29 12:18:44 +09001965 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
1966 mgmt_tx->buff, mgmt_tx->size,
Glen Leec9d48342015-10-01 16:03:43 +09001967 WILC_WFI_mgmt_tx_complete);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001968 } else {
1969 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
1970 }
Leo Kimaaed3292015-10-12 16:55:38 +09001971 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001972}
1973
Chaehyun Lim85c587a2015-09-22 18:34:50 +09001974static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
1975 struct wireless_dev *wdev,
1976 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001977{
Chaehyun Lim27268872015-09-15 14:06:13 +09001978 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09001979 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001980
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001981 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001982 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001983
1984
1985 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
Leo Kim1229b1a2015-10-29 12:05:39 +09001986 pstrWFIDrv->p2p_timeout = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001987
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +01001988 if (!priv->bInP2PlistenState) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001989 cfg80211_remain_on_channel_expired(priv->wdev,
1990 priv->strRemainOnChanParams.u64ListenCookie,
1991 priv->strRemainOnChanParams.pstrListenChan,
1992 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001993 }
1994
1995 return 0;
1996}
1997
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09001998void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
1999 u16 frame_type, bool reg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002000{
2001
Chaehyun Lim27268872015-09-15 14:06:13 +09002002 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002003 perInterface_wlan_t *nic;
Glen Lee1b869352015-10-20 17:14:01 +09002004 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002005
2006 priv = wiphy_priv(wiphy);
2007 nic = netdev_priv(priv->wdev->netdev);
Glen Lee1b869352015-10-20 17:14:01 +09002008 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002009
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002010 if (!frame_type)
2011 return;
2012
2013 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
2014 switch (frame_type) {
2015 case PROBE_REQ:
2016 {
2017 nic->g_struct_frame_reg[0].frame_type = frame_type;
2018 nic->g_struct_frame_reg[0].reg = reg;
2019 }
2020 break;
2021
2022 case ACTION:
2023 {
2024 nic->g_struct_frame_reg[1].frame_type = frame_type;
2025 nic->g_struct_frame_reg[1].reg = reg;
2026 }
2027 break;
2028
2029 default:
2030 {
2031 break;
2032 }
2033
2034 }
Leo Kima89f7c52015-11-25 11:59:41 +09002035
Glen Lee1b869352015-10-20 17:14:01 +09002036 if (!wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002037 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
2038 return;
2039 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002040 wilc_frame_register(priv->hWILCWFIDrv, frame_type, reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002041
2042
2043}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002044
Chaehyun Lima8047e22015-09-22 18:34:48 +09002045static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
2046 s32 rssi_thold, u32 rssi_hyst)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002047{
2048 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2049 return 0;
2050
2051}
Leo Kima89f7c52015-11-25 11:59:41 +09002052
Chaehyun Limbdb63382015-09-14 12:24:19 +09002053static int dump_station(struct wiphy *wiphy, struct net_device *dev,
2054 int idx, u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002055{
Chaehyun Lim27268872015-09-15 14:06:13 +09002056 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002057
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002058 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2059
2060 if (idx != 0)
2061 return -ENOENT;
2062
2063 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002064
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002065 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002066
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002067 wilc_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002068
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002069 return 0;
2070
2071}
2072
Chaehyun Lim46530672015-09-22 18:34:46 +09002073static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2074 bool enabled, int timeout)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002075{
Chaehyun Lim27268872015-09-15 14:06:13 +09002076 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002077
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002078 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2079
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002080 if (wiphy == NULL)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002081 return -ENOENT;
2082
2083 priv = wiphy_priv(wiphy);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002084 if (priv->hWILCWFIDrv == NULL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002085 PRINT_ER("Driver is NULL\n");
2086 return -EIO;
2087 }
2088
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002089 if (wilc_enable_ps)
2090 wilc_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002091
2092
Leo Kime6e12662015-09-16 18:36:03 +09002093 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002094
2095}
Glen Lee108b3432015-09-16 18:53:20 +09002096
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002097static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2098 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002099{
Chaehyun Lim27268872015-09-15 14:06:13 +09002100 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002101 perInterface_wlan_t *nic;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002102 u8 interface_type;
Chaehyun Limd85f5322015-06-11 14:35:54 +09002103 u16 TID = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002104 u8 i;
Glen Lee299382c2015-10-20 17:13:56 +09002105 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002106
2107 nic = netdev_priv(dev);
2108 priv = wiphy_priv(wiphy);
Glen Lee299382c2015-10-20 17:13:56 +09002109 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002110
2111 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2112 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
Leo Kim583d9722015-11-19 15:56:16 +09002113 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +09002114 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +09002115 wilc_ie = false;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002116 wilc_optaining_ip = false;
2117 del_timer(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002118 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
Leo Kima89f7c52015-11-25 11:59:41 +09002119
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002120 if (g_ptk_keys_saved && g_gtk_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002121 wilc_set_machw_change_vir_if(dev, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002122 }
2123
2124 switch (type) {
2125 case NL80211_IFTYPE_STATION:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002126 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002127 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002128
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002129 dev->ieee80211_ptr->iftype = type;
2130 priv->wdev->iftype = type;
2131 nic->monitor_flag = 0;
2132 nic->iftype = STATION_MODE;
2133
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002134 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002135 interface_type = nic->iftype;
2136 nic->iftype = STATION_MODE;
2137
Glen Lee299382c2015-10-20 17:13:56 +09002138 if (wl->initialized) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002139 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2140 wl->vif[0].bssid, TID);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002141 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002142
Glen Lee299382c2015-10-20 17:13:56 +09002143 up(&wl->cfg_event);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002144
Glen Lee53dc0cf2015-10-20 17:13:57 +09002145 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002146 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002147 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002148 nic->iftype = interface_type;
2149
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002150 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2151 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002152 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002153 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002154
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002155 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002156 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002157 g_key_wep_params.key_idx);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002158 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002159 g_key_wep_params.key,
2160 g_key_wep_params.key_len,
2161 g_key_wep_params.key_idx);
2162 }
2163
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002164 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002165
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002166 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2167 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2168 g_key_ptk_params.key[1],
2169 g_key_ptk_params.key[2]);
2170 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2171 g_key_gtk_params.key[1],
2172 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002173 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2174 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002175 g_add_ptk_key_params.key_idx,
2176 g_add_ptk_key_params.pairwise,
2177 g_add_ptk_key_params.mac_addr,
2178 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002179
Glen Lee299382c2015-10-20 17:13:56 +09002180 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2181 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002182 g_add_gtk_key_params.key_idx,
2183 g_add_gtk_key_params.pairwise,
2184 g_add_gtk_key_params.mac_addr,
2185 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002186 }
2187
Glen Lee299382c2015-10-20 17:13:56 +09002188 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002189 for (i = 0; i < num_reg_frame; i++) {
2190 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2191 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002192 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002193 nic->g_struct_frame_reg[i].frame_type,
2194 nic->g_struct_frame_reg[i].reg);
2195 }
2196 }
2197
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002198 wilc_enable_ps = true;
2199 wilc_set_power_mgmt(priv->hWILCWFIDrv, 1, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002200 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002201 break;
2202
2203 case NL80211_IFTYPE_P2P_CLIENT:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002204 wilc_enable_ps = false;
2205 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
2206 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002207 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002208
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002209 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2210 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002211
2212 dev->ieee80211_ptr->iftype = type;
2213 priv->wdev->iftype = type;
2214 nic->monitor_flag = 0;
2215
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002216 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2217 nic->iftype = CLIENT_MODE;
2218
2219
Glen Lee299382c2015-10-20 17:13:56 +09002220 if (wl->initialized) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002221 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002222
Glen Lee53dc0cf2015-10-20 17:13:57 +09002223 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002224 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002225 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002226
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002227 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2228 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002229 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002230 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002231
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002232 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002233 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2234 g_key_wep_params.key_idx);
2235 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
2236 g_key_wep_params.key,
2237 g_key_wep_params.key_len,
2238 g_key_wep_params.key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002239 }
2240
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002241 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002242
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002243 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2244 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2245 g_key_ptk_params.key[1],
2246 g_key_ptk_params.key[2]);
2247 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2248 g_key_gtk_params.key[1],
2249 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002250 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2251 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002252 g_add_ptk_key_params.key_idx,
2253 g_add_ptk_key_params.pairwise,
2254 g_add_ptk_key_params.mac_addr,
2255 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002256
Glen Lee299382c2015-10-20 17:13:56 +09002257 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2258 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002259 g_add_gtk_key_params.key_idx,
2260 g_add_gtk_key_params.pairwise,
2261 g_add_gtk_key_params.mac_addr,
2262 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002263 }
2264
Dean Lee72ed4dc2015-06-12 14:11:44 +09002265 refresh_scan(priv, 1, true);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002266 wilc_set_machw_change_vir_if(dev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002267
Glen Lee299382c2015-10-20 17:13:56 +09002268 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002269 for (i = 0; i < num_reg_frame; i++) {
2270 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2271 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002272 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002273 nic->g_struct_frame_reg[i].frame_type,
2274 nic->g_struct_frame_reg[i].reg);
2275 }
2276 }
2277 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002278 break;
2279
2280 case NL80211_IFTYPE_AP:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002281 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002282 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002283 dev->ieee80211_ptr->iftype = type;
2284 priv->wdev->iftype = type;
2285 nic->iftype = AP_MODE;
Johnny Kim8a143302015-06-10 17:06:46 +09002286 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002287
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002288 PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002289 wilc_wlan_get_firmware(dev);
Leo Kima89f7c52015-11-25 11:59:41 +09002290
Glen Lee299382c2015-10-20 17:13:56 +09002291 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002292 nic->iftype = AP_MODE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002293 wilc_mac_close(dev);
2294 wilc_mac_open(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002295
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002296 for (i = 0; i < num_reg_frame; i++) {
2297 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2298 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002299 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002300 nic->g_struct_frame_reg[i].frame_type,
2301 nic->g_struct_frame_reg[i].reg);
2302 }
2303 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002304 break;
2305
2306 case NL80211_IFTYPE_P2P_GO:
2307 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
2308
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002309 wilc_optaining_ip = true;
Leo Kim7e872df2015-11-19 15:56:20 +09002310 mod_timer(&wilc_during_ip_timer,
2311 jiffies + msecs_to_jiffies(during_ip_time));
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002312 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002313 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2314 wl->vif[0].bssid, TID);
2315 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002316 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002317 dev->ieee80211_ptr->iftype = type;
2318 priv->wdev->iftype = type;
2319
Johnny Kim8a143302015-06-10 17:06:46 +09002320 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002321
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002322 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2323
2324
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002325 nic->iftype = GO_MODE;
2326
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002327 wilc_wait_msg_queue_idle();
Glen Lee53dc0cf2015-10-20 17:13:57 +09002328 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002329 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002330 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002331
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002332 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2333 wilc_set_mac_address(wl->vif[0].hif_drv,
2334 wl->vif[0].src_addr);
2335 wilc_set_operation_mode(priv->hWILCWFIDrv, AP_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002336
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002337 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002338 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2339 g_key_wep_params.key_idx);
2340 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002341 g_key_wep_params.key,
2342 g_key_wep_params.key_len,
2343 g_key_wep_params.key_idx);
2344 }
2345
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002346 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002347
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002348 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2349 PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0],
2350 g_key_ptk_params.key[1],
2351 g_key_ptk_params.key[2],
2352 g_key_ptk_params.cipher);
2353 PRINT_D(CFG80211_DBG, "gtk %x %x %x cipher %x\n", g_key_gtk_params.key[0],
2354 g_key_gtk_params.key[1],
2355 g_key_gtk_params.key[2],
2356 g_key_gtk_params.cipher);
Glen Lee299382c2015-10-20 17:13:56 +09002357 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2358 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002359 g_add_ptk_key_params.key_idx,
2360 g_add_ptk_key_params.pairwise,
2361 g_add_ptk_key_params.mac_addr,
2362 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002363
Glen Lee299382c2015-10-20 17:13:56 +09002364 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2365 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002366 g_add_gtk_key_params.key_idx,
2367 g_add_gtk_key_params.pairwise,
2368 g_add_gtk_key_params.mac_addr,
2369 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002370 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002371
Glen Lee299382c2015-10-20 17:13:56 +09002372 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002373 for (i = 0; i < num_reg_frame; i++) {
2374 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2375 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002376 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002377 nic->g_struct_frame_reg[i].frame_type,
2378 nic->g_struct_frame_reg[i].reg);
2379 }
2380 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002381 break;
2382
2383 default:
2384 PRINT_ER("Unknown interface type= %d\n", type);
Leo Kimaaed3292015-10-12 16:55:38 +09002385 return -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002386 }
2387
Leo Kimaaed3292015-10-12 16:55:38 +09002388 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002389}
2390
Chaehyun Lima13168d2015-09-14 12:24:12 +09002391static int start_ap(struct wiphy *wiphy, struct net_device *dev,
2392 struct cfg80211_ap_settings *settings)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002393{
2394 struct cfg80211_beacon_data *beacon = &(settings->beacon);
Chaehyun Lim27268872015-09-15 14:06:13 +09002395 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002396 s32 s32Error = 0;
Glen Lee684dc182015-10-20 17:14:02 +09002397 struct wilc *wl;
2398 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002399
2400 priv = wiphy_priv(wiphy);
Glen Lee684dc182015-10-20 17:14:02 +09002401 nic = netdev_priv(dev);
2402 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002403 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
2404
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302405 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 +09002406 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
2407
Chaehyun Lim80785a92015-09-14 12:24:01 +09002408 s32Error = set_channel(wiphy, &settings->chandef);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002409
Leo Kime6e12662015-09-16 18:36:03 +09002410 if (s32Error != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002411 PRINT_ER("Error in setting channel\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002412
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002413 wilc_wlan_set_bssid(dev, wl->vif[0].src_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002414
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002415 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002416 settings->beacon_interval,
2417 settings->dtim_period,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002418 beacon->head_len, (u8 *)beacon->head,
2419 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002420
2421 return s32Error;
2422}
2423
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002424static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
2425 struct cfg80211_beacon_data *beacon)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002426{
Chaehyun Lim27268872015-09-15 14:06:13 +09002427 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002428 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002429
2430 priv = wiphy_priv(wiphy);
2431 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
2432
2433
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002434 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002435 0,
2436 0,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002437 beacon->head_len, (u8 *)beacon->head,
2438 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002439
2440 return s32Error;
2441}
2442
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002443static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002444{
Leo Kime6e12662015-09-16 18:36:03 +09002445 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002446 struct wilc_priv *priv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002447 u8 NullBssid[ETH_ALEN] = {0};
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002448
Leo Kim7ae43362015-09-16 18:35:59 +09002449 if (!wiphy)
2450 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002451
2452 priv = wiphy_priv(wiphy);
2453
2454 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
2455
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002456 wilc_wlan_set_bssid(dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002457
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002458 s32Error = wilc_del_beacon(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002459
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002460 if (s32Error)
2461 PRINT_ER("Host delete beacon fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002462
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002463 return s32Error;
2464}
2465
Chaehyun Limed269552015-09-14 12:24:15 +09002466static int add_station(struct wiphy *wiphy, struct net_device *dev,
2467 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002468{
Leo Kime6e12662015-09-16 18:36:03 +09002469 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002470 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09002471 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002472 perInterface_wlan_t *nic;
2473
Leo Kim7ae43362015-09-16 18:35:59 +09002474 if (!wiphy)
2475 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002476
2477 priv = wiphy_priv(wiphy);
2478 nic = netdev_priv(dev);
2479
2480 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09002481 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09002482 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09002483 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09002484 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09002485 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002486
2487 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
2488
2489 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],
2490 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
Leo Kim4101eb82015-10-29 12:05:42 +09002491 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09002492 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
2493 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002494
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002495 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09002496 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002497 } else {
Leo Kim22520122015-10-29 12:05:45 +09002498 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09002499 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09002500 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09002501 memcpy(strStaParams.ht_supp_mcs_set,
2502 &params->ht_capa->mcs,
2503 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09002504 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09002505 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09002506 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002507 }
2508
Leo Kimf676e172015-10-29 12:05:52 +09002509 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09002510 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002511
Leo Kim22520122015-10-29 12:05:45 +09002512 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
2513 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09002514 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
2515 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09002516 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
2517 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09002518 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
2519 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09002520 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
2521 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09002522 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
2523 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09002524 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
2525 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09002526 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
2527 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002528
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002529 s32Error = wilc_add_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002530 if (s32Error)
2531 PRINT_ER("Host add station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002532 }
2533
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002534 return s32Error;
2535}
2536
Chaehyun Lima0a8be92015-09-14 12:24:16 +09002537static int del_station(struct wiphy *wiphy, struct net_device *dev,
2538 struct station_del_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002539{
Arnd Bergmann057d1e92015-06-01 21:06:44 +02002540 const u8 *mac = params->mac;
Leo Kime6e12662015-09-16 18:36:03 +09002541 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002542 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002543 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002544
Leo Kim7ae43362015-09-16 18:35:59 +09002545 if (!wiphy)
2546 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002547
2548 priv = wiphy_priv(wiphy);
2549 nic = netdev_priv(dev);
2550
2551 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
2552 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
2553
2554
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002555 if (mac == NULL) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302556 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002557 s32Error = wilc_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002558 } else {
2559 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]);
2560 }
2561
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002562 s32Error = wilc_del_station(priv->hWILCWFIDrv, mac);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002563
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002564 if (s32Error)
2565 PRINT_ER("Host delete station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002566 }
2567 return s32Error;
2568}
2569
Chaehyun Lim14b42082015-09-14 12:24:17 +09002570static int change_station(struct wiphy *wiphy, struct net_device *dev,
2571 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002572{
Leo Kime6e12662015-09-16 18:36:03 +09002573 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002574 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09002575 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002576 perInterface_wlan_t *nic;
2577
2578
2579 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
2580
Leo Kim7ae43362015-09-16 18:35:59 +09002581 if (!wiphy)
2582 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002583
2584 priv = wiphy_priv(wiphy);
2585 nic = netdev_priv(dev);
2586
2587 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09002588 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09002589 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09002590 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09002591 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002592
Leo Kim2353c382015-10-29 12:05:41 +09002593 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n",
2594 strStaParams.bssid[0], strStaParams.bssid[1],
2595 strStaParams.bssid[2], strStaParams.bssid[3],
2596 strStaParams.bssid[4], strStaParams.bssid[5]);
Leo Kim4101eb82015-10-29 12:05:42 +09002597 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09002598 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
2599 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002600
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09002601 if (params->ht_capa == NULL) {
Leo Kim22520122015-10-29 12:05:45 +09002602 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002603 } else {
Leo Kim22520122015-10-29 12:05:45 +09002604 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09002605 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09002606 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09002607 memcpy(strStaParams.ht_supp_mcs_set,
2608 &params->ht_capa->mcs,
2609 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09002610 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09002611 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09002612 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002613 }
2614
Leo Kimf676e172015-10-29 12:05:52 +09002615 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09002616 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002617
Leo Kim22520122015-10-29 12:05:45 +09002618 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
2619 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09002620 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
2621 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09002622 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
2623 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09002624 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
2625 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09002626 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
2627 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09002628 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
2629 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09002630 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
2631 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09002632 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
2633 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002634
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002635 s32Error = wilc_edit_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002636 if (s32Error)
2637 PRINT_ER("Host edit station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002638 }
2639 return s32Error;
2640}
2641
Chaehyun Lim37316e82015-09-22 18:34:52 +09002642static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
2643 const char *name,
2644 unsigned char name_assign_type,
2645 enum nl80211_iftype type,
2646 u32 *flags,
2647 struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002648{
2649 perInterface_wlan_t *nic;
Chaehyun Lim27268872015-09-15 14:06:13 +09002650 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002651 struct net_device *new_ifc = NULL;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002652
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002653 priv = wiphy_priv(wiphy);
2654
2655
2656
2657 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
2658
2659 nic = netdev_priv(priv->wdev->netdev);
2660
2661
2662 if (type == NL80211_IFTYPE_MONITOR) {
2663 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
2664 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", nic->wilc_netdev);
2665 new_ifc = WILC_WFI_init_mon_interface(name, nic->wilc_netdev);
2666 if (new_ifc != NULL) {
2667 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002668 nic = netdev_priv(priv->wdev->netdev);
2669 nic->monitor_flag = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002670 } else
2671 PRINT_ER("Error in initializing monitor interface\n ");
2672 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002673 return priv->wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002674}
2675
Chaehyun Lim956d7212015-09-22 18:34:49 +09002676static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002677{
2678 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
Leo Kime6e12662015-09-16 18:36:03 +09002679 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002680}
2681
Chaehyun Lim08241922015-09-15 14:06:12 +09002682static struct cfg80211_ops wilc_cfg80211_ops = {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002683
Chaehyun Lim80785a92015-09-14 12:24:01 +09002684 .set_monitor_channel = set_channel,
Chaehyun Lim0e30d062015-09-14 12:24:02 +09002685 .scan = scan,
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +09002686 .connect = connect,
Chaehyun Limb027cde2015-09-14 12:24:04 +09002687 .disconnect = disconnect,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002688 .add_key = add_key,
Chaehyun Lim3044ba72015-09-14 12:24:06 +09002689 .del_key = del_key,
Chaehyun Limf4893df2015-09-14 12:24:07 +09002690 .get_key = get_key,
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09002691 .set_default_key = set_default_key,
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09002692 .add_virtual_intf = add_virtual_intf,
Chaehyun Limb4a73352015-09-14 12:24:10 +09002693 .del_virtual_intf = del_virtual_intf,
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002694 .change_virtual_intf = change_virtual_intf,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002695
Chaehyun Lima13168d2015-09-14 12:24:12 +09002696 .start_ap = start_ap,
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002697 .change_beacon = change_beacon,
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002698 .stop_ap = stop_ap,
Chaehyun Limed269552015-09-14 12:24:15 +09002699 .add_station = add_station,
Chaehyun Lima0a8be92015-09-14 12:24:16 +09002700 .del_station = del_station,
Chaehyun Lim14b42082015-09-14 12:24:17 +09002701 .change_station = change_station,
Chaehyun Limf06f5622015-09-14 12:24:18 +09002702 .get_station = get_station,
Chaehyun Limbdb63382015-09-14 12:24:19 +09002703 .dump_station = dump_station,
Chaehyun Lima5f7db62015-09-14 12:24:20 +09002704 .change_bss = change_bss,
Chaehyun Lima76b63e2015-09-14 12:24:21 +09002705 .set_wiphy_params = set_wiphy_params,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002706
Chaehyun Lim4d466572015-09-14 12:24:22 +09002707 .set_pmksa = set_pmksa,
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09002708 .del_pmksa = del_pmksa,
Chaehyun Limb33c39b2015-09-14 12:24:24 +09002709 .flush_pmksa = flush_pmksa,
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002710 .remain_on_channel = remain_on_channel,
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002711 .cancel_remain_on_channel = cancel_remain_on_channel,
Chaehyun Lim4a2f9b32015-09-14 12:24:27 +09002712 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
Chaehyun Lim12a26a32015-09-14 12:24:28 +09002713 .mgmt_tx = mgmt_tx,
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002714 .mgmt_frame_register = wilc_mgmt_frame_register,
Chaehyun Lim46530672015-09-22 18:34:46 +09002715 .set_power_mgmt = set_power_mgmt,
Chaehyun Lima8047e22015-09-22 18:34:48 +09002716 .set_cqm_rssi_config = set_cqm_rssi_config,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002717
2718};
2719
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002720int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
2721{
2722
Chaehyun Lim27268872015-09-15 14:06:13 +09002723 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002724
2725 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002726 switch (changed) {
2727
2728 case WILC_WFI_RX_PKT:
2729 {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002730 priv->netstats.rx_packets++;
2731 priv->netstats.rx_bytes += pktlen;
2732 priv->netstats.rx_time = get_jiffies_64();
2733 }
2734 break;
2735
2736 case WILC_WFI_TX_PKT:
2737 {
2738 priv->netstats.tx_packets++;
2739 priv->netstats.tx_bytes += pktlen;
2740 priv->netstats.tx_time = get_jiffies_64();
2741
2742 }
2743 break;
2744
2745 default:
2746 break;
2747 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002748 return 0;
2749}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002750
Arnd Bergmann1608c402015-11-16 15:04:53 +01002751static struct wireless_dev *WILC_WFI_CfgAlloc(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002752{
2753
2754 struct wireless_dev *wdev;
2755
2756
2757 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
Leo Kima89f7c52015-11-25 11:59:41 +09002758
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002759 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2760 if (!wdev) {
2761 PRINT_ER("Cannot allocate wireless device\n");
2762 goto _fail_;
2763 }
2764
Chaehyun Lim27268872015-09-15 14:06:13 +09002765 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002766 if (!wdev->wiphy) {
2767 PRINT_ER("Cannot allocate wiphy\n");
2768 goto _fail_mem_;
2769
2770 }
2771
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002772 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
2773 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
2774 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
2775 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
2776 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002777
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002778 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
2779
2780 return wdev;
2781
2782_fail_mem_:
2783 kfree(wdev);
2784_fail_:
2785 return NULL;
2786
2787}
Leo Kima89f7c52015-11-25 11:59:41 +09002788
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01002789struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002790{
Chaehyun Lim27268872015-09-15 14:06:13 +09002791 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002792 struct wireless_dev *wdev;
Leo Kime6e12662015-09-16 18:36:03 +09002793 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002794
2795 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
2796
2797 wdev = WILC_WFI_CfgAlloc();
2798 if (wdev == NULL) {
2799 PRINT_ER("CfgAlloc Failed\n");
2800 return NULL;
2801 }
2802
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002803 priv = wdev_priv(wdev);
Arnd Bergmann83383ea2015-06-01 21:06:43 +02002804 sema_init(&(priv->SemHandleUpdateStats), 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002805 priv->wdev = wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002806 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002807 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
2808 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002809
2810 wdev->wiphy->max_scan_ie_len = 1000;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002811 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002812 wdev->wiphy->cipher_suites = cipher_suites;
2813 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002814 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002815
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002816 wdev->wiphy->max_remain_on_channel_duration = 500;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002817 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
2818 BIT(NL80211_IFTYPE_P2P_CLIENT);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002819 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002820 wdev->iftype = NL80211_IFTYPE_STATION;
2821
2822
2823
2824 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
2825 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
2826 wdev->wiphy->interface_modes, wdev->iftype);
2827
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01002828 set_wiphy_dev(wdev->wiphy, dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002829
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002830 s32Error = wiphy_register(wdev->wiphy);
2831 if (s32Error) {
2832 PRINT_ER("Cannot register wiphy device\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002833 } else {
2834 PRINT_D(CFG80211_DBG, "Successful Registering\n");
2835 }
2836
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002837 priv->dev = net;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002838 return wdev;
2839
2840
2841}
Leo Kima89f7c52015-11-25 11:59:41 +09002842
Chaehyun Limdd4b6a82015-09-20 15:51:25 +09002843int wilc_init_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002844{
2845
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09002846 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002847
Chaehyun Lim27268872015-09-15 14:06:13 +09002848 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002849
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002850 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
2851 priv = wdev_priv(net->ieee80211_ptr);
2852 if (op_ifcs == 0) {
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -07002853 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002854 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002855 }
2856 op_ifcs++;
2857 if (s32Error < 0) {
2858 PRINT_ER("Failed to creat refresh Timer\n");
2859 return s32Error;
2860 }
2861
Dean Lee72ed4dc2015-06-12 14:11:44 +09002862 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002863
Dean Lee72ed4dc2015-06-12 14:11:44 +09002864 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002865
Arnd Bergmann83383ea2015-06-01 21:06:43 +02002866 sema_init(&(priv->hSemScanReq), 1);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002867 s32Error = wilc_init(net, &priv->hWILCWFIDrv);
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09002868 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002869 PRINT_ER("Error while initializing hostinterface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09002870
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002871 return s32Error;
2872}
2873
Chaehyun Lima9a16822015-09-20 15:51:24 +09002874int wilc_deinit_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002875{
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09002876 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002877
Chaehyun Lim27268872015-09-15 14:06:13 +09002878 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002879
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002880 priv = wdev_priv(net->ieee80211_ptr);
2881
Dean Lee72ed4dc2015-06-12 14:11:44 +09002882 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002883
Dean Lee72ed4dc2015-06-12 14:11:44 +09002884 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002885
2886 op_ifcs--;
2887
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002888 s32Error = wilc_deinit(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002889
Leo Kimd14991a2015-11-19 15:56:22 +09002890 clear_shadow_scan();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002891 if (op_ifcs == 0) {
2892 PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002893 del_timer_sync(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002894 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002895
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09002896 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002897 PRINT_ER("Error while deintializing host interface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09002898
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002899 return s32Error;
2900}
2901
Chaehyun Lim96da20a2015-09-20 15:51:08 +09002902void wilc_free_wiphy(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002903{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002904 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
2905
Chaehyun Lim619837a2015-09-20 15:51:10 +09002906 if (!net) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002907 PRINT_D(INIT_DBG, "net_device is NULL\n");
2908 return;
2909 }
2910
Chaehyun Lim619837a2015-09-20 15:51:10 +09002911 if (!net->ieee80211_ptr) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002912 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
2913 return;
2914 }
2915
Chaehyun Lim619837a2015-09-20 15:51:10 +09002916 if (!net->ieee80211_ptr->wiphy) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002917 PRINT_D(INIT_DBG, "wiphy is NULL\n");
2918 return;
2919 }
2920
2921 wiphy_unregister(net->ieee80211_ptr->wiphy);
2922
2923 PRINT_D(INIT_DBG, "Freeing wiphy\n");
2924 wiphy_free(net->ieee80211_ptr->wiphy);
2925 kfree(net->ieee80211_ptr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002926}