blob: 309a0cc6446e7b2c2c6a499c0166e8369dd98dee [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 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900204}
205
Leo Kim0b8bea12015-11-19 15:56:35 +0900206static u32 get_rssi_avg(tstrNetworkInfo *network_info)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900207{
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900208 u8 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900209 int rssi_v = 0;
Leo Kim0b8bea12015-11-19 15:56:35 +0900210 u8 num_rssi = (network_info->strRssi.u8Full) ? NUM_RSSI : (network_info->strRssi.u8Index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900211
212 for (i = 0; i < num_rssi; i++)
Leo Kim0b8bea12015-11-19 15:56:35 +0900213 rssi_v += network_info->strRssi.as8RSSI[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900214
215 rssi_v /= num_rssi;
216 return rssi_v;
217}
218
Leo Kim48ee7ba2015-11-19 15:56:24 +0900219static void refresh_scan(void *user_void, u8 all, bool direct_scan)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900220{
Chaehyun Lim27268872015-09-15 14:06:13 +0900221 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900222 struct wiphy *wiphy;
223 struct cfg80211_bss *bss = NULL;
224 int i;
225 int rssi = 0;
226
Leo Kim84df0e62015-11-19 15:56:23 +0900227 priv = (struct wilc_priv *)user_void;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900228 wiphy = priv->dev->ieee80211_ptr->wiphy;
229
Leo Kim771fbae2015-11-19 15:56:10 +0900230 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimce3b1b52015-11-19 15:56:25 +0900231 tstrNetworkInfo *network_info;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900232
Leo Kimce3b1b52015-11-19 15:56:25 +0900233 network_info = &last_scanned_shadow[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900234
Leo Kimce3b1b52015-11-19 15:56:25 +0900235 if (!network_info->u8Found || all) {
Leo Kimc6f5e3a2015-11-19 15:56:26 +0900236 s32 freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900237 struct ieee80211_channel *channel;
238
Leo Kimce3b1b52015-11-19 15:56:25 +0900239 if (network_info) {
Leo Kimc6f5e3a2015-11-19 15:56:26 +0900240 freq = ieee80211_channel_to_frequency((s32)network_info->u8channel, IEEE80211_BAND_2GHZ);
241 channel = ieee80211_get_channel(wiphy, freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900242
Leo Kimce3b1b52015-11-19 15:56:25 +0900243 rssi = get_rssi_avg(network_info);
244 if (memcmp("DIRECT-", network_info->au8ssid, 7) ||
Leo Kim48ee7ba2015-11-19 15:56:24 +0900245 direct_scan) {
Leo Kimce3b1b52015-11-19 15:56:25 +0900246 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, network_info->au8bssid, network_info->u64Tsf, network_info->u16CapInfo,
247 network_info->u16BeaconPeriod, (const u8 *)network_info->pu8IEs,
248 (size_t)network_info->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900249 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900250 }
251 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900252 }
253 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900254}
255
Leo Kim12b01382015-11-19 15:56:27 +0900256static void reset_shadow_found(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900257{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900258 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900259
Leo Kim771fbae2015-11-19 15:56:10 +0900260 for (i = 0; i < last_scanned_cnt; i++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900261 last_scanned_shadow[i].u8Found = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900262}
263
Leo Kim5e51d8b2015-11-19 15:56:28 +0900264static void update_scan_time(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900265{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900266 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900267
Leo Kim771fbae2015-11-19 15:56:10 +0900268 for (i = 0; i < last_scanned_cnt; i++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900269 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900270}
271
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700272static void remove_network_from_shadow(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900273{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900274 unsigned long now = jiffies;
275 int i, j;
276
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900277
Leo Kim771fbae2015-11-19 15:56:10 +0900278 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900279 if (time_after(now, last_scanned_shadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) {
280 PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", last_scanned_shadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900281
Leo Kimf1ab1172015-11-19 15:56:11 +0900282 kfree(last_scanned_shadow[i].pu8IEs);
283 last_scanned_shadow[i].pu8IEs = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900284
Leo Kimf1ab1172015-11-19 15:56:11 +0900285 wilc_free_join_params(last_scanned_shadow[i].pJoinParams);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900286
Leo Kim771fbae2015-11-19 15:56:10 +0900287 for (j = i; (j < last_scanned_cnt - 1); j++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900288 last_scanned_shadow[j] = last_scanned_shadow[j + 1];
Leo Kim771fbae2015-11-19 15:56:10 +0900289
290 last_scanned_cnt--;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900291 }
292 }
293
Leo Kim771fbae2015-11-19 15:56:10 +0900294 PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n",
295 last_scanned_cnt);
296 if (last_scanned_cnt != 0) {
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700297 hAgingTimer.data = arg;
298 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
299 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900300 PRINT_D(CFG80211_DBG, "No need to restart Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700301 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900302}
303
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700304static void clear_duringIP(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900305{
306 PRINT_D(GENERIC_DBG, "GO:IP Obtained , enable scan\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100307 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900308}
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900309
Leo Kim157814f2015-11-19 15:56:29 +0900310static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo,
311 void *user_void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900312{
Chaehyun Lima74cc6b2015-10-02 16:41:17 +0900313 int state = -1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900314 int i;
315
Leo Kim771fbae2015-11-19 15:56:10 +0900316 if (last_scanned_cnt == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900317 PRINT_D(CFG80211_DBG, "Starting Aging timer\n");
Leo Kim157814f2015-11-19 15:56:29 +0900318 hAgingTimer.data = (unsigned long)user_void;
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700319 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900320 state = -1;
321 } else {
Leo Kim771fbae2015-11-19 15:56:10 +0900322 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900323 if (memcmp(last_scanned_shadow[i].au8bssid,
324 pstrNetworkInfo->au8bssid, 6) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900325 state = i;
326 break;
327 }
328 }
329 }
330 return state;
331}
332
Leo Kim5c4cf0d2015-11-19 15:56:30 +0900333static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo,
334 void *user_void, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900335{
Leo Kim5c4cf0d2015-11-19 15:56:30 +0900336 int ap_found = is_network_in_shadow(pstrNetworkInfo, user_void);
Chaehyun Limfbc2fe12015-09-15 14:06:16 +0900337 u32 ap_index = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900338 u8 rssi_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900339
Leo Kim771fbae2015-11-19 15:56:10 +0900340 if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900341 PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
342 return;
343 }
344 if (ap_found == -1) {
Leo Kim771fbae2015-11-19 15:56:10 +0900345 ap_index = last_scanned_cnt;
346 last_scanned_cnt++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900347 } else {
348 ap_index = ap_found;
349 }
Leo Kimf1ab1172015-11-19 15:56:11 +0900350 rssi_index = last_scanned_shadow[ap_index].strRssi.u8Index;
351 last_scanned_shadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900352 if (rssi_index == NUM_RSSI) {
353 rssi_index = 0;
Leo Kimf1ab1172015-11-19 15:56:11 +0900354 last_scanned_shadow[ap_index].strRssi.u8Full = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900355 }
Leo Kimf1ab1172015-11-19 15:56:11 +0900356 last_scanned_shadow[ap_index].strRssi.u8Index = rssi_index;
357 last_scanned_shadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
358 last_scanned_shadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
359 last_scanned_shadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
360 memcpy(last_scanned_shadow[ap_index].au8ssid,
361 pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
362 memcpy(last_scanned_shadow[ap_index].au8bssid,
363 pstrNetworkInfo->au8bssid, ETH_ALEN);
364 last_scanned_shadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
365 last_scanned_shadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
366 last_scanned_shadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
367 last_scanned_shadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
368 last_scanned_shadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900369 if (ap_found != -1)
Leo Kimf1ab1172015-11-19 15:56:11 +0900370 kfree(last_scanned_shadow[ap_index].pu8IEs);
371 last_scanned_shadow[ap_index].pu8IEs =
Leo Kima89f7c52015-11-25 11:59:41 +0900372 kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL);
Leo Kimf1ab1172015-11-19 15:56:11 +0900373 memcpy(last_scanned_shadow[ap_index].pu8IEs,
374 pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
375 last_scanned_shadow[ap_index].u32TimeRcvdInScan = jiffies;
376 last_scanned_shadow[ap_index].u32TimeRcvdInScanCached = jiffies;
377 last_scanned_shadow[ap_index].u8Found = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900378 if (ap_found != -1)
Leo Kimf1ab1172015-11-19 15:56:11 +0900379 wilc_free_join_params(last_scanned_shadow[ap_index].pJoinParams);
380 last_scanned_shadow[ap_index].pJoinParams = pJoinParams;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900381}
382
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900383static void CfgScanResult(enum scan_event scan_event,
Leo Kim0551a722015-11-19 15:56:32 +0900384 tstrNetworkInfo *network_info,
Leo Kim30cd10c2015-11-19 15:56:33 +0900385 void *user_void,
Leo Kimbdd34602015-11-19 15:56:34 +0900386 void *join_params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900387{
Chaehyun Lim27268872015-09-15 14:06:13 +0900388 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900389 struct wiphy *wiphy;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900390 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900391 struct ieee80211_channel *channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900392 struct cfg80211_bss *bss = NULL;
393
Leo Kim30cd10c2015-11-19 15:56:33 +0900394 priv = (struct wilc_priv *)user_void;
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100395 if (priv->bCfgScanning) {
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900396 if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900397 wiphy = priv->dev->ieee80211_ptr->wiphy;
Leo Kim7ae43362015-09-16 18:35:59 +0900398
399 if (!wiphy)
400 return;
401
Leo Kim0551a722015-11-19 15:56:32 +0900402 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
403 (((s32)network_info->s8rssi * 100) < 0 ||
404 ((s32)network_info->s8rssi * 100) > 100)) {
Leo Kim24db7132015-09-16 18:36:01 +0900405 PRINT_ER("wiphy signal type fial\n");
406 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900407 }
408
Leo Kim0551a722015-11-19 15:56:32 +0900409 if (network_info) {
410 s32Freq = ieee80211_channel_to_frequency((s32)network_info->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900411 channel = ieee80211_get_channel(wiphy, s32Freq);
412
Leo Kim7ae43362015-09-16 18:35:59 +0900413 if (!channel)
414 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900415
416 PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
Leo Kim0551a722015-11-19 15:56:32 +0900417 "BeaconPeriod: %d\n", channel->center_freq, (((s32)network_info->s8rssi) * 100),
418 network_info->u16CapInfo, network_info->u16BeaconPeriod);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900419
Leo Kim0551a722015-11-19 15:56:32 +0900420 if (network_info->bNewNetwork) {
Leo Kima89f7c52015-11-25 11:59:41 +0900421 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) {
Leo Kim0551a722015-11-19 15:56:32 +0900422 PRINT_D(CFG80211_DBG, "Network %s found\n", network_info->au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900423 priv->u32RcvdChCount++;
424
Leo Kimbdd34602015-11-19 15:56:34 +0900425 if (!join_params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900426 PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n");
Leo Kimbdd34602015-11-19 15:56:34 +0900427 add_network_to_shadow(network_info, priv, join_params);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900428
Leo Kim0551a722015-11-19 15:56:32 +0900429 if (!(memcmp("DIRECT-", network_info->au8ssid, 7))) {
430 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, network_info->au8bssid, network_info->u64Tsf, network_info->u16CapInfo,
431 network_info->u16BeaconPeriod, (const u8 *)network_info->pu8IEs,
432 (size_t)network_info->u16IEsLen, (((s32)network_info->s8rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900433 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900434 }
435
436
437 } else {
438 PRINT_ER("Discovered networks exceeded the max limit\n");
439 }
440 } else {
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900441 u32 i;
Leo Kima89f7c52015-11-25 11:59:41 +0900442
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900443 for (i = 0; i < priv->u32RcvdChCount; i++) {
Leo Kim0551a722015-11-19 15:56:32 +0900444 if (memcmp(last_scanned_shadow[i].au8bssid, network_info->au8bssid, 6) == 0) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900445 PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", last_scanned_shadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900446
Leo Kim0551a722015-11-19 15:56:32 +0900447 last_scanned_shadow[i].s8rssi = network_info->s8rssi;
Leo Kimf1ab1172015-11-19 15:56:11 +0900448 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900449 break;
450 }
451 }
452 }
453 }
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900454 } else if (scan_event == SCAN_EVENT_DONE) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530455 PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev);
456 PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n");
Dean Lee72ed4dc2015-06-12 14:11:44 +0900457 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900458
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530459 if (priv->u32RcvdChCount > 0)
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530460 PRINT_D(CFG80211_DBG, "%d Network(s) found\n", priv->u32RcvdChCount);
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530461 else
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530462 PRINT_D(CFG80211_DBG, "No networks found\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900463
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200464 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900465
Leo Kim369a1d32015-12-21 14:18:23 +0900466 if (priv->pstrScanReq) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900467 cfg80211_scan_done(priv->pstrScanReq, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900468 priv->u32RcvdChCount = 0;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900469 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900470 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900471 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200472 up(&(priv->hSemScanReq));
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900473 } else if (scan_event == SCAN_EVENT_ABORTED) {
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200474 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900475
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530476 PRINT_D(CFG80211_DBG, "Scan Aborted\n");
Leo Kim369a1d32015-12-21 14:18:23 +0900477 if (priv->pstrScanReq) {
Leo Kim5e51d8b2015-11-19 15:56:28 +0900478 update_scan_time();
Dean Lee72ed4dc2015-06-12 14:11:44 +0900479 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900480
Dean Lee72ed4dc2015-06-12 14:11:44 +0900481 cfg80211_scan_done(priv->pstrScanReq, false);
482 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900483 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900484 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200485 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900486 }
487 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900488}
489
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100490int wilc_connecting;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900491
Leo Kimed3f0372015-10-12 16:56:01 +0900492static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900493 tstrConnectInfo *pstrConnectInfo,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900494 u8 u8MacStatus,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900495 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
496 void *pUserVoid)
497{
Chaehyun Lim27268872015-09-15 14:06:13 +0900498 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900499 struct net_device *dev;
Leo Kim441dc602015-10-12 16:55:35 +0900500 struct host_if_drv *pstrWFIDrv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900501 u8 NullBssid[ETH_ALEN] = {0};
Glen Leec1ec2c12015-10-20 17:13:58 +0900502 struct wilc *wl;
Glen Leea4cac482015-12-21 14:18:36 +0900503 struct wilc_vif *vif;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900504
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100505 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900506
Chaehyun Lim27268872015-09-15 14:06:13 +0900507 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900508 dev = priv->dev;
Glen Leea4cac482015-12-21 14:18:36 +0900509 vif = netdev_priv(dev);
510 wl = vif->wilc;
Leo Kim441dc602015-10-12 16:55:35 +0900511 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900512
513 if (enuConnDisconnEvent == CONN_DISCONN_EVENT_CONN_RESP) {
Amitoj Kaur Chawlababa7c72015-10-15 13:48:29 +0530514 u16 u16ConnectStatus;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900515
516 u16ConnectStatus = pstrConnectInfo->u16ConnectStatus;
517
518 PRINT_D(CFG80211_DBG, " Connection response received = %d\n", u8MacStatus);
519
520 if ((u8MacStatus == MAC_DISCONNECTED) &&
521 (pstrConnectInfo->u16ConnectStatus == SUCCESSFUL_STATUSCODE)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900522 u16ConnectStatus = WLAN_STATUS_UNSPECIFIED_FAILURE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100523 wilc_wlan_set_bssid(priv->dev, NullBssid);
Leo Kime554a302015-11-19 15:56:21 +0900524 eth_zero_addr(wilc_connected_ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900525
Leo Kimab16ec02015-10-29 12:05:40 +0900526 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900527 wlan_channel = INVALID_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900528
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530529 PRINT_ER("Unspecified failure: Connection status %d : MAC status = %d\n", u16ConnectStatus, u8MacStatus);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900530 }
531
532 if (u16ConnectStatus == WLAN_STATUS_SUCCESS) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900533 bool bNeedScanRefresh = false;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900534 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900535
536 PRINT_INFO(CFG80211_DBG, "Connection Successful:: BSSID: %x%x%x%x%x%x\n", pstrConnectInfo->au8bssid[0],
537 pstrConnectInfo->au8bssid[1], pstrConnectInfo->au8bssid[2], pstrConnectInfo->au8bssid[3], pstrConnectInfo->au8bssid[4], pstrConnectInfo->au8bssid[5]);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900538 memcpy(priv->au8AssociatedBss, pstrConnectInfo->au8bssid, ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900539
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900540
Leo Kim771fbae2015-11-19 15:56:10 +0900541 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900542 if (memcmp(last_scanned_shadow[i].au8bssid,
543 pstrConnectInfo->au8bssid, ETH_ALEN) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900544 unsigned long now = jiffies;
545
546 if (time_after(now,
Leo Kimf1ab1172015-11-19 15:56:11 +0900547 last_scanned_shadow[i].u32TimeRcvdInScanCached + (unsigned long)(nl80211_SCAN_RESULT_EXPIRE - (1 * HZ)))) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900548 bNeedScanRefresh = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900549 }
550
551 break;
552 }
553 }
554
Leo Kima89f7c52015-11-25 11:59:41 +0900555 if (bNeedScanRefresh)
Dean Lee72ed4dc2015-06-12 14:11:44 +0900556 refresh_scan(priv, 1, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900557 }
558
559
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530560 PRINT_D(CFG80211_DBG, "Association request info elements length = %zu\n", pstrConnectInfo->ReqIEsLen);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900561
562 PRINT_D(CFG80211_DBG, "Association response info elements length = %d\n", pstrConnectInfo->u16RespIEsLen);
563
564 cfg80211_connect_result(dev, pstrConnectInfo->au8bssid,
565 pstrConnectInfo->pu8ReqIEs, pstrConnectInfo->ReqIEsLen,
566 pstrConnectInfo->pu8RespIEs, pstrConnectInfo->u16RespIEsLen,
Leo Kima89f7c52015-11-25 11:59:41 +0900567 u16ConnectStatus, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900568 } else if (enuConnDisconnEvent == CONN_DISCONN_EVENT_DISCONN_NOTIF) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100569 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900570 PRINT_ER("Received MAC_DISCONNECTED from firmware with reason %d on dev [%p]\n",
571 pstrDisconnectNotifInfo->u16reason, priv->dev);
Leo Kim583d9722015-11-19 15:56:16 +0900572 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +0900573 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +0900574 wilc_ie = false;
Shraddha Barkebcf02652015-10-05 17:00:32 +0530575 eth_zero_addr(priv->au8AssociatedBss);
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100576 wilc_wlan_set_bssid(priv->dev, NullBssid);
Leo Kime554a302015-11-19 15:56:21 +0900577 eth_zero_addr(wilc_connected_ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900578
Leo Kimab16ec02015-10-29 12:05:40 +0900579 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900580 wlan_channel = INVALID_CHANNEL;
Glen Lee1f435d22015-12-21 14:18:37 +0900581 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900582 pstrDisconnectNotifInfo->u16reason = 3;
Glen Lee1f435d22015-12-21 14:18:37 +0900583 } else if ((!pstrWFIDrv->IFC_UP) && (dev == wl->vif[1]->ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900584 pstrDisconnectNotifInfo->u16reason = 1;
585 }
586 cfg80211_disconnected(dev, pstrDisconnectNotifInfo->u16reason, pstrDisconnectNotifInfo->ie,
Sudip Mukherjeee26bb712015-06-30 13:51:51 +0530587 pstrDisconnectNotifInfo->ie_len, false,
588 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900589 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900590}
591
Chaehyun Lim80785a92015-09-14 12:24:01 +0900592static int set_channel(struct wiphy *wiphy,
593 struct cfg80211_chan_def *chandef)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900594{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900595 u32 channelnum = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +0900596 struct wilc_priv *priv;
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900597 int result = 0;
Glen Leecf601062015-12-21 14:18:39 +0900598 struct wilc_vif *vif;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900599
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900600 priv = wiphy_priv(wiphy);
Glen Leecf601062015-12-21 14:18:39 +0900601 vif = netdev_priv(priv->dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900602
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900603 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
604 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900605
Chaehyun Lim866a2c22015-10-02 16:41:21 +0900606 curr_channel = channelnum;
Glen Leecf601062015-12-21 14:18:39 +0900607 result = wilc_set_mac_chnl_num(vif, priv->hWILCWFIDrv, channelnum);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900608
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900609 if (result != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900610 PRINT_ER("Error in setting channel %d\n", channelnum);
611
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900612 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900613}
614
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900615static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900616{
Chaehyun Lim27268872015-09-15 14:06:13 +0900617 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900618 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +0900619 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900620 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
Leo Kim607db442015-10-05 15:25:37 +0900621 struct hidden_network strHiddenNetwork;
Glen Leecf601062015-12-21 14:18:39 +0900622 struct wilc_vif *vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900623
624 priv = wiphy_priv(wiphy);
Glen Leecf601062015-12-21 14:18:39 +0900625 vif = netdev_priv(priv->dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900626
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900627 priv->pstrScanReq = request;
628
629 priv->u32RcvdChCount = 0;
630
Glen Leecf601062015-12-21 14:18:39 +0900631 wilc_set_wfi_drv_handler(vif, priv->hWILCWFIDrv);
Leo Kim12b01382015-11-19 15:56:27 +0900632 reset_shadow_found();
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900633
Dean Lee72ed4dc2015-06-12 14:11:44 +0900634 priv->bCfgScanning = true;
Leo Kima89f7c52015-11-25 11:59:41 +0900635 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900636 for (i = 0; i < request->n_channels; i++) {
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900637 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900638 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
639 }
640
641 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530642 PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900643
644 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
645
646 if (request->n_ssids >= 1) {
Leo Kim607db442015-10-05 15:25:37 +0900647 strHiddenNetwork.pstrHiddenNetworkInfo = kmalloc(request->n_ssids * sizeof(struct hidden_network), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900648 strHiddenNetwork.u8ssidnum = request->n_ssids;
649
650
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900651 for (i = 0; i < request->n_ssids; i++) {
Leo Kim369a1d32015-12-21 14:18:23 +0900652 if (request->ssids[i].ssid &&
653 request->ssids[i].ssid_len != 0) {
Glen Leef3052582015-09-10 12:03:04 +0900654 strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900655 memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900656 strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len;
657 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530658 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900659 strHiddenNetwork.u8ssidnum -= 1;
660 }
661 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530662 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Glen Leecf601062015-12-21 14:18:39 +0900663 s32Error = wilc_scan(vif, priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900664 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900665 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900666 CfgScanResult, (void *)priv, &strHiddenNetwork);
667 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530668 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Glen Leecf601062015-12-21 14:18:39 +0900669 s32Error = wilc_scan(vif, priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900670 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900671 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900672 CfgScanResult, (void *)priv, NULL);
673 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900674 } else {
675 PRINT_ER("Requested num of scanned channels is greater than the max, supported"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530676 " channels\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900677 }
678
Leo Kime6e12662015-09-16 18:36:03 +0900679 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900680 s32Error = -EBUSY;
681 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
682 }
683
684 return s32Error;
685}
686
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900687static int connect(struct wiphy *wiphy, struct net_device *dev,
688 struct cfg80211_connect_params *sme)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900689{
Leo Kime6e12662015-09-16 18:36:03 +0900690 s32 s32Error = 0;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900691 u32 i;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900692 u8 u8security = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +0900693 enum AUTHTYPE tenuAuth_type = ANY;
Dean Lee576917a2015-06-15 11:58:57 +0900694 char *pcgroup_encrypt_val = NULL;
695 char *pccipher_group = NULL;
696 char *pcwpa_version = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900697
Chaehyun Lim27268872015-09-15 14:06:13 +0900698 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +0900699 struct host_if_drv *pstrWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900700 tstrNetworkInfo *pstrNetworkInfo = NULL;
Glen Leecf601062015-12-21 14:18:39 +0900701 struct wilc_vif *vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900702
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100703 wilc_connecting = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900704 priv = wiphy_priv(wiphy);
Glen Leecf601062015-12-21 14:18:39 +0900705 vif = netdev_priv(priv->dev);
Leo Kim441dc602015-10-12 16:55:35 +0900706 pstrWFIDrv = (struct host_if_drv *)(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900707
Glen Leecf601062015-12-21 14:18:39 +0900708 wilc_set_wfi_drv_handler(vif, priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900709
Johnny Kim8a143302015-06-10 17:06:46 +0900710 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 +0900711 if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900712 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
Leo Kimab16ec02015-10-29 12:05:40 +0900713 pstrWFIDrv->p2p_connect = 1;
714 } else {
715 pstrWFIDrv->p2p_connect = 0;
716 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530717 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900718
Leo Kim771fbae2015-11-19 15:56:10 +0900719 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900720 if ((sme->ssid_len == last_scanned_shadow[i].u8SsidLen) &&
721 memcmp(last_scanned_shadow[i].au8ssid,
722 sme->ssid,
723 sme->ssid_len) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900724 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
Leo Kim369a1d32015-12-21 14:18:23 +0900725 if (!sme->bssid) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900726 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
727 break;
728 } else {
Leo Kimf1ab1172015-11-19 15:56:11 +0900729 if (memcmp(last_scanned_shadow[i].au8bssid,
730 sme->bssid,
731 ETH_ALEN) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900732 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
733 break;
734 }
735 }
736 }
737 }
738
Leo Kim771fbae2015-11-19 15:56:10 +0900739 if (i < last_scanned_cnt) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900740 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
741
Leo Kimf1ab1172015-11-19 15:56:11 +0900742 pstrNetworkInfo = &last_scanned_shadow[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900743
744 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
745 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
746 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
747 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
748 } else {
749 s32Error = -ENOENT;
Leo Kim771fbae2015-11-19 15:56:10 +0900750 if (last_scanned_cnt == 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900751 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
752 else
753 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
754
755 goto done;
756 }
757
758 priv->WILC_WFI_wep_default = 0;
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900759 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
760 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900761
762 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
763 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
764
765 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
766
767 if (INFO) {
768 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
769 PRINT_D(CORECONFIG_DBG, "sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]);
770 }
771
772 if (sme->crypto.cipher_group != NO_ENCRYPT) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900773 pcwpa_version = "Default";
774 PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900775 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900776 u8security = ENCRYPT_ENABLED | WEP;
777 pcgroup_encrypt_val = "WEP40";
778 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
779 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
780
781 if (INFO) {
782 for (i = 0; i < sme->key_len; i++)
783 PRINT_D(CORECONFIG_DBG, "WEP Key Value[%d] = %d\n", i, sme->key[i]);
784 }
785 priv->WILC_WFI_wep_default = sme->key_idx;
786 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900787 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900788
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900789 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900790 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900791 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
792 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900793 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900794
Glen Leecf601062015-12-21 14:18:39 +0900795 wilc_set_wep_default_keyid(vif, priv->hWILCWFIDrv, sme->key_idx);
796 wilc_add_wep_key_bss_sta(vif, priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900797 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900798 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
799 pcgroup_encrypt_val = "WEP104";
800 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
801
802 priv->WILC_WFI_wep_default = sme->key_idx;
803 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900804 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900805
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900806 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900807 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900808 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
809 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900810 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900811
Glen Leecf601062015-12-21 14:18:39 +0900812 wilc_set_wep_default_keyid(vif, priv->hWILCWFIDrv, sme->key_idx);
813 wilc_add_wep_key_bss_sta(vif, priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900814 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900815 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900816 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
817 pcgroup_encrypt_val = "WPA2_TKIP";
818 pccipher_group = "TKIP";
Leo Kima89f7c52015-11-25 11:59:41 +0900819 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900820 u8security = ENCRYPT_ENABLED | WPA2 | AES;
821 pcgroup_encrypt_val = "WPA2_AES";
822 pccipher_group = "AES";
823 }
824 pcwpa_version = "WPA_VERSION_2";
825 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
826 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900827 u8security = ENCRYPT_ENABLED | WPA | TKIP;
828 pcgroup_encrypt_val = "WPA_TKIP";
829 pccipher_group = "TKIP";
Leo Kima89f7c52015-11-25 11:59:41 +0900830 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900831 u8security = ENCRYPT_ENABLED | WPA | AES;
832 pcgroup_encrypt_val = "WPA_AES";
833 pccipher_group = "AES";
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900834 }
835 pcwpa_version = "WPA_VERSION_1";
836
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900837 } else {
838 s32Error = -ENOTSUPP;
839 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
840
841 goto done;
842 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900843 }
844
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900845 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
846 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
847 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
848 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
849 u8security = u8security | TKIP;
Leo Kima89f7c52015-11-25 11:59:41 +0900850 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900851 u8security = u8security | AES;
852 }
853 }
854 }
855
856 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
857
858 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
859 switch (sme->auth_type) {
860 case NL80211_AUTHTYPE_OPEN_SYSTEM:
861 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
862 tenuAuth_type = OPEN_SYSTEM;
863 break;
864
865 case NL80211_AUTHTYPE_SHARED_KEY:
866 tenuAuth_type = SHARED_KEY;
867 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
868 break;
869
870 default:
871 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
872 }
873
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900874 if (sme->crypto.n_akm_suites) {
875 switch (sme->crypto.akm_suites[0]) {
876 case WLAN_AKM_SUITE_8021X:
877 tenuAuth_type = IEEE8021;
878 break;
879
880 default:
881 break;
882 }
883 }
884
885
886 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
887
888 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
889 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
890
Chaehyun Lim866a2c22015-10-02 16:41:21 +0900891 curr_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900892
Leo Kimab16ec02015-10-29 12:05:40 +0900893 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900894 wlan_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900895
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100896 wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900897
Glen Leecf601062015-12-21 14:18:39 +0900898 s32Error = wilc_set_join_req(vif, priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900899 sme->ssid_len, sme->ie, sme->ie_len,
900 CfgConnectResult, (void *)priv, u8security,
901 tenuAuth_type, pstrNetworkInfo->u8channel,
902 pstrNetworkInfo->pJoinParams);
Leo Kime6e12662015-09-16 18:36:03 +0900903 if (s32Error != 0) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100904 PRINT_ER("wilc_set_join_req(): Error(%d)\n", s32Error);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900905 s32Error = -ENOENT;
906 goto done;
907 }
908
909done:
910
911 return s32Error;
912}
913
Chaehyun Limb027cde2015-09-14 12:24:04 +0900914static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900915{
Leo Kime6e12662015-09-16 18:36:03 +0900916 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +0900917 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +0900918 struct host_if_drv *pstrWFIDrv;
Glen Leecf601062015-12-21 14:18:39 +0900919 struct wilc_vif *vif;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900920 u8 NullBssid[ETH_ALEN] = {0};
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900921
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100922 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900923 priv = wiphy_priv(wiphy);
Glen Leecf601062015-12-21 14:18:39 +0900924 vif = netdev_priv(priv->dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900925
Leo Kim441dc602015-10-12 16:55:35 +0900926 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Leo Kimab16ec02015-10-29 12:05:40 +0900927 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900928 wlan_channel = INVALID_CHANNEL;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100929 wilc_wlan_set_bssid(priv->dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900930
931 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
932
Leo Kim583d9722015-11-19 15:56:16 +0900933 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +0900934 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +0900935 wilc_ie = false;
Leo Kim1229b1a2015-10-29 12:05:39 +0900936 pstrWFIDrv->p2p_timeout = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900937
Glen Leecf601062015-12-21 14:18:39 +0900938 s32Error = wilc_disconnect(vif, priv->hWILCWFIDrv, reason_code);
Leo Kime6e12662015-09-16 18:36:03 +0900939 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900940 PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
941 s32Error = -EINVAL;
942 }
943
944 return s32Error;
945}
946
Chaehyun Lim953d4172015-09-14 12:24:05 +0900947static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
948 bool pairwise,
949 const u8 *mac_addr, struct key_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900950
951{
Leo Kime6e12662015-09-16 18:36:03 +0900952 s32 s32Error = 0, KeyLen = params->key_len;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900953 u32 i;
Chaehyun Lim27268872015-09-15 14:06:13 +0900954 struct wilc_priv *priv;
Arnd Bergmann057d1e92015-06-01 21:06:44 +0200955 const u8 *pu8RxMic = NULL;
956 const u8 *pu8TxMic = NULL;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900957 u8 u8mode = NO_ENCRYPT;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900958 u8 u8gmode = NO_ENCRYPT;
959 u8 u8pmode = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +0900960 enum AUTHTYPE tenuAuth_type = ANY;
Glen Lee76469202015-10-20 17:13:59 +0900961 struct wilc *wl;
Glen Leea4cac482015-12-21 14:18:36 +0900962 struct wilc_vif *vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900963
964 priv = wiphy_priv(wiphy);
Glen Leea4cac482015-12-21 14:18:36 +0900965 vif = netdev_priv(netdev);
966 wl = vif->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900967
968 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
969
Johnny Kim8a143302015-06-10 17:06:46 +0900970 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900971
972 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
973 params->key[1],
974 params->key[2]);
975
976
977 switch (params->cipher) {
978 case WLAN_CIPHER_SUITE_WEP40:
979 case WLAN_CIPHER_SUITE_WEP104:
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900980 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900981 priv->WILC_WFI_wep_default = key_index;
982 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900983 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900984
985 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
986 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
987
988 for (i = 0; i < params->key_len; i++)
989 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
990
991 tenuAuth_type = OPEN_SYSTEM;
992
993 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
994 u8mode = ENCRYPT_ENABLED | WEP;
995 else
996 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
997
Glen Leecf601062015-12-21 14:18:39 +0900998 wilc_add_wep_key_bss_ap(vif, priv->hWILCWFIDrv, params->key, params->key_len, key_index, u8mode, tenuAuth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900999 break;
1000 }
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001001 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001002 priv->WILC_WFI_wep_default = key_index;
1003 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001004 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001005
1006 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
1007 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
1008 if (INFO) {
1009 for (i = 0; i < params->key_len; i++)
1010 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
1011 }
Glen Leecf601062015-12-21 14:18:39 +09001012 wilc_add_wep_key_bss_sta(vif, priv->hWILCWFIDrv, params->key, params->key_len, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001013 }
1014
1015 break;
1016
1017 case WLAN_CIPHER_SUITE_TKIP:
1018 case WLAN_CIPHER_SUITE_CCMP:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001019 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
Leo Kim369a1d32015-12-21 14:18:23 +09001020 if (!priv->wilc_gtk[key_index]) {
Glen Leef3052582015-09-10 12:03:04 +09001021 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001022 priv->wilc_gtk[key_index]->key = NULL;
1023 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001024 }
Leo Kim369a1d32015-12-21 14:18:23 +09001025 if (!priv->wilc_ptk[key_index]) {
Glen Leef3052582015-09-10 12:03:04 +09001026 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001027 priv->wilc_ptk[key_index]->key = NULL;
1028 priv->wilc_ptk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001029 }
1030
1031
1032
Daniel Machon19132212015-08-05 08:18:31 +02001033 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001034 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1035 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1036 else
1037 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1038
1039 priv->wilc_groupkey = u8gmode;
1040
1041 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001042 pu8TxMic = params->key + 24;
1043 pu8RxMic = params->key + 16;
1044 KeyLen = params->key_len - 16;
1045 }
Shraddha Barkecccfc392015-10-12 20:49:19 +05301046 kfree(priv->wilc_gtk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001047
Glen Leef3052582015-09-10 12:03:04 +09001048 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001049 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
Shraddha Barkecccfc392015-10-12 20:49:19 +05301050 kfree(priv->wilc_gtk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001051
1052 if ((params->seq_len) > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001053 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001054 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001055 }
1056
1057 priv->wilc_gtk[key_index]->cipher = params->cipher;
1058 priv->wilc_gtk[key_index]->key_len = params->key_len;
1059 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1060
1061 if (INFO) {
1062 for (i = 0; i < params->key_len; i++)
1063 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1064 for (i = 0; i < params->seq_len; i++)
1065 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1066 }
1067
1068
Glen Leecf601062015-12-21 14:18:39 +09001069 wilc_add_rx_gtk(vif, priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001070 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode);
1071
1072 } else {
1073 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]);
1074
1075 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1076 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1077 else
1078 u8pmode = priv->wilc_groupkey | AES;
1079
1080
1081 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001082 pu8TxMic = params->key + 24;
1083 pu8RxMic = params->key + 16;
1084 KeyLen = params->key_len - 16;
1085 }
1086
Shraddha Barkecccfc392015-10-12 20:49:19 +05301087 kfree(priv->wilc_ptk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001088
Glen Leef3052582015-09-10 12:03:04 +09001089 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001090
Shraddha Barkecccfc392015-10-12 20:49:19 +05301091 kfree(priv->wilc_ptk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001092
1093 if ((params->seq_len) > 0)
Glen Leef3052582015-09-10 12:03:04 +09001094 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001095
1096 if (INFO) {
1097 for (i = 0; i < params->key_len; i++)
1098 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1099
1100 for (i = 0; i < params->seq_len; i++)
1101 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1102 }
1103
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001104 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001105
1106 if ((params->seq_len) > 0)
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001107 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001108
1109 priv->wilc_ptk[key_index]->cipher = params->cipher;
1110 priv->wilc_ptk[key_index]->key_len = params->key_len;
1111 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1112
Glen Leecf601062015-12-21 14:18:39 +09001113 wilc_add_ptk(vif, priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001114 pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index);
1115 }
1116 break;
1117 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001118
1119 {
1120 u8mode = 0;
Daniel Machon19132212015-08-05 08:18:31 +02001121 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001122 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001123 pu8RxMic = params->key + 24;
1124 pu8TxMic = params->key + 16;
1125 KeyLen = params->key_len - 16;
1126 }
1127
Glen Lee1f435d22015-12-21 14:18:37 +09001128 if (!g_gtk_keys_saved && netdev == wl->vif[0]->ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001129 g_add_gtk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001130 g_add_gtk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001131 if (!mac_addr) {
1132 g_add_gtk_key_params.mac_addr = NULL;
1133 } else {
Glen Leef3052582015-09-10 12:03:04 +09001134 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001135 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1136 }
1137 g_key_gtk_params.key_len = params->key_len;
1138 g_key_gtk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001139 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001140 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1141 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001142 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001143 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1144 }
1145 g_key_gtk_params.cipher = params->cipher;
1146
1147 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1148 g_key_gtk_params.key[1],
1149 g_key_gtk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001150 g_gtk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001151 }
1152
Glen Leecf601062015-12-21 14:18:39 +09001153 wilc_add_rx_gtk(vif, priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001154 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001155 } else {
1156 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001157 pu8RxMic = params->key + 24;
1158 pu8TxMic = params->key + 16;
1159 KeyLen = params->key_len - 16;
1160 }
1161
Glen Lee1f435d22015-12-21 14:18:37 +09001162 if (!g_ptk_keys_saved && netdev == wl->vif[0]->ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001163 g_add_ptk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001164 g_add_ptk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001165 if (!mac_addr) {
1166 g_add_ptk_key_params.mac_addr = NULL;
1167 } else {
Glen Leef3052582015-09-10 12:03:04 +09001168 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001169 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1170 }
1171 g_key_ptk_params.key_len = params->key_len;
1172 g_key_ptk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001173 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001174 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1175 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001176 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001177 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1178 }
1179 g_key_ptk_params.cipher = params->cipher;
1180
1181 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1182 g_key_ptk_params.key[1],
1183 g_key_ptk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001184 g_ptk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001185 }
1186
Glen Leecf601062015-12-21 14:18:39 +09001187 wilc_add_ptk(vif, priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001188 pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index);
1189 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1190 if (INFO) {
1191 for (i = 0; i < params->key_len; i++)
1192 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1193 }
1194 }
1195 }
1196 break;
1197
1198 default:
1199 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
1200 s32Error = -ENOTSUPP;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001201 }
1202
1203 return s32Error;
1204}
1205
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001206static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1207 u8 key_index,
1208 bool pairwise,
1209 const u8 *mac_addr)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001210{
Chaehyun Lim27268872015-09-15 14:06:13 +09001211 struct wilc_priv *priv;
Glen Lee692e2ac2015-10-20 17:14:00 +09001212 struct wilc *wl;
Glen Leea4cac482015-12-21 14:18:36 +09001213 struct wilc_vif *vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001214
1215 priv = wiphy_priv(wiphy);
Glen Leea4cac482015-12-21 14:18:36 +09001216 vif = netdev_priv(netdev);
1217 wl = vif->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001218
Glen Lee1f435d22015-12-21 14:18:37 +09001219 if (netdev == wl->vif[0]->ndev) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09001220 g_ptk_keys_saved = false;
1221 g_gtk_keys_saved = false;
1222 g_wep_keys_saved = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001223
Shraddha Barkecccfc392015-10-12 20:49:19 +05301224 kfree(g_key_wep_params.key);
1225 g_key_wep_params.key = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001226
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001227 if ((priv->wilc_gtk[key_index]) != NULL) {
Shraddha Barkecccfc392015-10-12 20:49:19 +05301228 kfree(priv->wilc_gtk[key_index]->key);
1229 priv->wilc_gtk[key_index]->key = NULL;
1230 kfree(priv->wilc_gtk[key_index]->seq);
1231 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001232
Chaehyun Lim49188af2015-08-11 10:32:41 +09001233 kfree(priv->wilc_gtk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001234 priv->wilc_gtk[key_index] = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001235 }
1236
1237 if ((priv->wilc_ptk[key_index]) != NULL) {
Shraddha Barkecccfc392015-10-12 20:49:19 +05301238 kfree(priv->wilc_ptk[key_index]->key);
1239 priv->wilc_ptk[key_index]->key = NULL;
1240 kfree(priv->wilc_ptk[key_index]->seq);
1241 priv->wilc_ptk[key_index]->seq = NULL;
Chaehyun Lim49188af2015-08-11 10:32:41 +09001242 kfree(priv->wilc_ptk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001243 priv->wilc_ptk[key_index] = NULL;
1244 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001245
Shraddha Barkecccfc392015-10-12 20:49:19 +05301246 kfree(g_key_ptk_params.key);
1247 g_key_ptk_params.key = NULL;
1248 kfree(g_key_ptk_params.seq);
1249 g_key_ptk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001250
Shraddha Barkecccfc392015-10-12 20:49:19 +05301251 kfree(g_key_gtk_params.key);
1252 g_key_gtk_params.key = NULL;
1253 kfree(g_key_gtk_params.seq);
1254 g_key_gtk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001255
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001256 wilc_set_machw_change_vir_if(netdev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001257 }
1258
1259 if (key_index >= 0 && key_index <= 3) {
Chaehyun Lim2cc46832015-08-07 09:02:01 +09001260 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001261 priv->WILC_WFI_wep_key_len[key_index] = 0;
1262
1263 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
Glen Leecf601062015-12-21 14:18:39 +09001264 wilc_remove_wep_key(vif, priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001265 } else {
1266 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001267 wilc_remove_key(priv->hWILCWFIDrv, mac_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001268 }
1269
Leo Kimaaed3292015-10-12 16:55:38 +09001270 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001271}
1272
Chaehyun Limf4893df2015-09-14 12:24:07 +09001273static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1274 bool pairwise,
1275 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001276{
Chaehyun Lim27268872015-09-15 14:06:13 +09001277 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001278 struct key_params key_params;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001279 u32 i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001280
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001281 priv = wiphy_priv(wiphy);
1282
1283
Alison Schofield3604af52015-10-12 13:22:44 -07001284 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001285 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1286
1287 key_params.key = priv->wilc_gtk[key_index]->key;
1288 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1289 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1290 key_params.seq = priv->wilc_gtk[key_index]->seq;
1291 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1292 if (INFO) {
1293 for (i = 0; i < key_params.key_len; i++)
1294 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1295 }
1296 } else {
1297 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1298
1299 key_params.key = priv->wilc_ptk[key_index]->key;
1300 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1301 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1302 key_params.seq = priv->wilc_ptk[key_index]->seq;
1303 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1304 }
1305
1306 callback(cookie, &key_params);
1307
Leo Kima89f7c52015-11-25 11:59:41 +09001308 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001309}
1310
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001311static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1312 bool unicast, bool multicast)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001313{
Chaehyun Lim27268872015-09-15 14:06:13 +09001314 struct wilc_priv *priv;
Glen Leecf601062015-12-21 14:18:39 +09001315 struct wilc_vif *vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001316
1317 priv = wiphy_priv(wiphy);
Glen Leecf601062015-12-21 14:18:39 +09001318 vif = netdev_priv(priv->dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001319
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301320 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001321
1322 if (key_index != priv->WILC_WFI_wep_default) {
Glen Leecf601062015-12-21 14:18:39 +09001323 wilc_set_wep_default_keyid(vif, priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001324 }
1325
Leo Kimaaed3292015-10-12 16:55:38 +09001326 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001327}
1328
Chaehyun Limf06f5622015-09-14 12:24:18 +09001329static int get_station(struct wiphy *wiphy, struct net_device *dev,
1330 const u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001331{
Chaehyun Lim27268872015-09-15 14:06:13 +09001332 struct wilc_priv *priv;
Glen Leea4cac482015-12-21 14:18:36 +09001333 struct wilc_vif *vif;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001334 u32 i = 0;
1335 u32 associatedsta = 0;
1336 u32 inactive_time = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001337 priv = wiphy_priv(wiphy);
Glen Leea4cac482015-12-21 14:18:36 +09001338 vif = netdev_priv(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001339
Glen Leea4cac482015-12-21 14:18:36 +09001340 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001341 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1342
1343 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1344
1345 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001346 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1347 associatedsta = i;
1348 break;
1349 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001350 }
1351
1352 if (associatedsta == -1) {
Leo Kimaaed3292015-10-12 16:55:38 +09001353 PRINT_ER("Station required is not associated\n");
1354 return -ENOENT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001355 }
1356
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001357 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001358
Glen Leecf601062015-12-21 14:18:39 +09001359 wilc_get_inactive_time(vif, priv->hWILCWFIDrv, mac, &(inactive_time));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001360 sinfo->inactive_time = 1000 * inactive_time;
1361 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001362 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001363
Glen Leea4cac482015-12-21 14:18:36 +09001364 if (vif->iftype == STATION_MODE) {
Leo Kim03e7b9c2015-10-12 16:55:58 +09001365 struct rf_info strStatistics;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001366
Glen Leecf601062015-12-21 14:18:39 +09001367 wilc_get_statistics(vif, priv->hWILCWFIDrv, &strStatistics);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001368
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001369 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
Chandra S Gorentla62129902015-08-05 22:11:57 +05301370 BIT(NL80211_STA_INFO_RX_PACKETS) |
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001371 BIT(NL80211_STA_INFO_TX_PACKETS) |
1372 BIT(NL80211_STA_INFO_TX_FAILED) |
1373 BIT(NL80211_STA_INFO_TX_BITRATE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001374
Leo Kim00c8dfc2015-10-29 12:05:30 +09001375 sinfo->signal = strStatistics.rssi;
Leo Kim9b992742015-10-29 12:05:32 +09001376 sinfo->rx_packets = strStatistics.rx_cnt;
Leo Kim54160372015-10-29 12:05:33 +09001377 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1378 sinfo->tx_failed = strStatistics.tx_fail_cnt;
Leo Kim5babeec2015-10-29 12:05:29 +09001379 sinfo->txrate.legacy = strStatistics.link_speed * 10;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001380
Leo Kim5babeec2015-10-29 12:05:29 +09001381 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1382 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001383 wilc_enable_tcp_ack_filter(true);
Leo Kim5babeec2015-10-29 12:05:29 +09001384 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001385 wilc_enable_tcp_ack_filter(false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001386
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001387 PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
1388 sinfo->tx_failed, sinfo->txrate.legacy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001389 }
Leo Kimaaed3292015-10-12 16:55:38 +09001390 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001391}
1392
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001393static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1394 struct bss_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001395{
1396 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1397 return 0;
1398}
1399
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001400static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001401{
Leo Kime6e12662015-09-16 18:36:03 +09001402 s32 s32Error = 0;
Leo Kim95296502015-10-05 15:25:46 +09001403 struct cfg_param_val pstrCfgParamVal;
Chaehyun Lim27268872015-09-15 14:06:13 +09001404 struct wilc_priv *priv;
Glen Leecf601062015-12-21 14:18:39 +09001405 struct wilc_vif *vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001406
1407 priv = wiphy_priv(wiphy);
Glen Leecf601062015-12-21 14:18:39 +09001408 vif = netdev_priv(priv->dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001409
Tony Cho87c05b22015-10-12 16:56:07 +09001410 pstrCfgParamVal.flag = 0;
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301411 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001412
1413 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1414 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1415 priv->dev->ieee80211_ptr->wiphy->retry_short);
Tony Cho87c05b22015-10-12 16:56:07 +09001416 pstrCfgParamVal.flag |= RETRY_SHORT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001417 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1418 }
1419 if (changed & WIPHY_PARAM_RETRY_LONG) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001420 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 +09001421 pstrCfgParamVal.flag |= RETRY_LONG;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001422 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001423 }
1424 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1425 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 +09001426 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001427 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001428 }
1429
1430 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1431 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1432
Tony Cho87c05b22015-10-12 16:56:07 +09001433 pstrCfgParamVal.flag |= RTS_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001434 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001435 }
1436
1437 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
Glen Leecf601062015-12-21 14:18:39 +09001438 s32Error = wilc_hif_set_cfg(vif, priv->hWILCWFIDrv, &pstrCfgParamVal);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001439 if (s32Error)
1440 PRINT_ER("Error in setting WIPHY PARAMS\n");
1441
1442
1443 return s32Error;
1444}
Arnd Bergmanne5af0562015-05-29 22:52:12 +02001445
Chaehyun Lim4d466572015-09-14 12:24:22 +09001446static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1447 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001448{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001449 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001450 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001451 u8 flag = 0;
Glen Leecf601062015-12-21 14:18:39 +09001452 struct wilc_vif *vif;
Chaehyun Lim27268872015-09-15 14:06:13 +09001453 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001454
Glen Leecf601062015-12-21 14:18:39 +09001455 vif = netdev_priv(priv->dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001456 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1457
1458
1459 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001460 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001461 ETH_ALEN)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001462 flag = PMKID_FOUND;
1463 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1464 break;
1465 }
1466 }
1467 if (i < WILC_MAX_NUM_PMKIDS) {
1468 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001469 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001470 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001471 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001472 PMKID_LEN);
1473 if (!(flag == PMKID_FOUND))
1474 priv->pmkid_list.numpmkid++;
1475 } else {
1476 PRINT_ER("Invalid PMKID index\n");
1477 s32Error = -EINVAL;
1478 }
1479
1480 if (!s32Error) {
1481 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
Glen Leecf601062015-12-21 14:18:39 +09001482 s32Error = wilc_set_pmkid_info(vif, priv->hWILCWFIDrv, &priv->pmkid_list);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001483 }
1484 return s32Error;
1485}
1486
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001487static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1488 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001489{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001490 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001491 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001492
Chaehyun Lim27268872015-09-15 14:06:13 +09001493 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001494
1495 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1496
1497 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001498 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001499 ETH_ALEN)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001500 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
Leo Kimcd1e6cb2015-10-05 15:25:45 +09001501 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001502 break;
1503 }
1504 }
1505
1506 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1507 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001508 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001509 priv->pmkid_list.pmkidlist[i + 1].bssid,
1510 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001511 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001512 priv->pmkid_list.pmkidlist[i].pmkid,
1513 PMKID_LEN);
1514 }
1515 priv->pmkid_list.numpmkid--;
1516 } else {
1517 s32Error = -EINVAL;
1518 }
1519
1520 return s32Error;
1521}
1522
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001523static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001524{
Chaehyun Lim27268872015-09-15 14:06:13 +09001525 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001526
1527 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
1528
Leo Kima949f902015-10-05 15:25:44 +09001529 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001530
1531 return 0;
1532}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001533
Arnd Bergmann1608c402015-11-16 15:04:53 +01001534static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001535{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001536 u32 index = 0;
1537 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001538
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001539 u8 op_channel_attr_index = 0;
1540 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001541
1542 while (index < len) {
1543 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001544 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001545 }
1546
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301547 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001548 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301549 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001550 op_channel_attr_index = index;
Leo Kima89f7c52015-11-25 11:59:41 +09001551 index += buf[index + 1] + 3;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001552 }
Leo Kim0bd82742015-11-19 15:56:14 +09001553 if (wlan_channel != INVALID_CHANNEL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001554 if (channel_list_attr_index) {
1555 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1556 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1557 if (buf[i] == 0x51) {
1558 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
Leo Kim0bd82742015-11-19 15:56:14 +09001559 buf[j] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001560 }
1561 break;
1562 }
1563 }
1564 }
Leo Kima89f7c52015-11-25 11:59:41 +09001565
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001566 if (op_channel_attr_index) {
1567 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1568 buf[op_channel_attr_index + 6] = 0x51;
Leo Kim0bd82742015-11-19 15:56:14 +09001569 buf[op_channel_attr_index + 7] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001570 }
1571 }
1572}
1573
Arnd Bergmann1608c402015-11-16 15:04:53 +01001574static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001575{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001576 u32 index = 0;
1577 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001578
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001579 u8 op_channel_attr_index = 0;
1580 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001581
1582 while (index < len) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001583 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001584 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001585
1586 break;
1587 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001588
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301589 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001590 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301591 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001592 op_channel_attr_index = index;
Leo Kima89f7c52015-11-25 11:59:41 +09001593 index += buf[index + 1] + 3;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001594 }
Leo Kim0bd82742015-11-19 15:56:14 +09001595 if (wlan_channel != INVALID_CHANNEL && bOperChan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001596 if (channel_list_attr_index) {
1597 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1598 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1599 if (buf[i] == 0x51) {
1600 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
Leo Kim0bd82742015-11-19 15:56:14 +09001601 buf[j] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001602 }
1603 break;
1604 }
1605 }
1606 }
Leo Kima89f7c52015-11-25 11:59:41 +09001607
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001608 if (op_channel_attr_index) {
1609 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1610 buf[op_channel_attr_index + 6] = 0x51;
Leo Kim0bd82742015-11-19 15:56:14 +09001611 buf[op_channel_attr_index + 7] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001612 }
1613 }
1614}
1615
Chaehyun Limfbc2fe12015-09-15 14:06:16 +09001616void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001617{
Chaehyun Lim27268872015-09-15 14:06:13 +09001618 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001619 u32 header, pkt_offset;
Leo Kim441dc602015-10-12 16:55:35 +09001620 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001621 u32 i = 0;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001622 s32 s32Freq;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001623
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001624 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001625 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001626
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001627 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001628
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001629 pkt_offset = GET_PKT_OFFSET(header);
1630
1631 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1632 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1633 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001634 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001635 return;
1636 } else {
1637 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
1638 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],
1639 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001640 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001641 } else {
1642 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],
1643 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001644 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001645 }
1646 return;
1647 }
1648 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001649 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
1650
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001651 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001652
1653 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1654 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
1655
Leo Kim1229b1a2015-10-29 12:05:39 +09001656 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001657 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
1658 return;
1659 }
1660 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001661 switch (buff[ACTION_SUBTYPE_ID]) {
1662 case GAS_INTIAL_REQ:
1663 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
1664 break;
1665
1666 case GAS_INTIAL_RSP:
1667 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
1668 break;
1669
1670 case PUBLIC_ACT_VENDORSPEC:
Leo Kim881eb5d2015-11-19 15:56:15 +09001671 if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001672 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
Leo Kima25d5182015-11-19 15:56:19 +09001673 if (!wilc_ie) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001674 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
Leo Kim86685942015-11-19 15:56:18 +09001675 if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09001676 p2p_recv_random = buff[i + 6];
Leo Kima25d5182015-11-19 15:56:19 +09001677 wilc_ie = true;
Leo Kimb84a3ac2015-11-19 15:56:17 +09001678 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", p2p_recv_random);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001679 break;
1680 }
1681 }
1682 }
1683 }
Leo Kimb84a3ac2015-11-19 15:56:17 +09001684 if (p2p_local_random > p2p_recv_random) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001685 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1686 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1687 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
Leo Kim881eb5d2015-11-19 15:56:15 +09001688 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001689 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
1690 break;
1691 }
1692 }
1693 }
Leo Kim583d9722015-11-19 15:56:16 +09001694 } else {
Leo Kimb84a3ac2015-11-19 15:56:17 +09001695 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 +09001696 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001697 }
1698
1699
Leo Kima25d5182015-11-19 15:56:19 +09001700 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 +09001701 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001702 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001703 return;
1704 }
1705 break;
1706
1707 default:
1708 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
1709 break;
1710 }
1711 }
1712 }
1713
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001714 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001715 }
1716}
1717
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001718static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
1719{
1720 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
1721
1722
1723 kfree(pv_data->buff);
1724 kfree(pv_data);
1725}
1726
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001727static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
1728{
Chaehyun Lim27268872015-09-15 14:06:13 +09001729 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001730
Chaehyun Lim27268872015-09-15 14:06:13 +09001731 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001732
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301733 PRINT_D(HOSTINF_DBG, "Remain on channel ready\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001734
Dean Lee72ed4dc2015-06-12 14:11:44 +09001735 priv->bInP2PlistenState = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001736
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001737 cfg80211_ready_on_channel(priv->wdev,
1738 priv->strRemainOnChanParams.u64ListenCookie,
1739 priv->strRemainOnChanParams.pstrListenChan,
1740 priv->strRemainOnChanParams.u32ListenDuration,
1741 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001742}
1743
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001744static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001745{
Chaehyun Lim27268872015-09-15 14:06:13 +09001746 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001747
Chaehyun Lim27268872015-09-15 14:06:13 +09001748 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001749
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001750 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301751 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001752
Dean Lee72ed4dc2015-06-12 14:11:44 +09001753 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001754
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001755 cfg80211_remain_on_channel_expired(priv->wdev,
1756 priv->strRemainOnChanParams.u64ListenCookie,
1757 priv->strRemainOnChanParams.pstrListenChan,
1758 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001759 } else {
1760 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
1761 , priv->strRemainOnChanParams.u32ListenSessionID);
1762 }
1763}
1764
Chaehyun Lim6d19d692015-09-14 12:24:25 +09001765static int remain_on_channel(struct wiphy *wiphy,
1766 struct wireless_dev *wdev,
1767 struct ieee80211_channel *chan,
1768 unsigned int duration, u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001769{
Leo Kime6e12662015-09-16 18:36:03 +09001770 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09001771 struct wilc_priv *priv;
Glen Leecf601062015-12-21 14:18:39 +09001772 struct wilc_vif *vif;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001773
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001774 priv = wiphy_priv(wiphy);
Glen Leecf601062015-12-21 14:18:39 +09001775 vif = netdev_priv(priv->dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001776
1777 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
1778
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001779
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001780 if (wdev->iftype == NL80211_IFTYPE_AP) {
1781 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
1782 return s32Error;
1783 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001784
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001785 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001786
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001787 priv->strRemainOnChanParams.pstrListenChan = chan;
1788 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001789 priv->strRemainOnChanParams.u32ListenDuration = duration;
1790 priv->strRemainOnChanParams.u32ListenSessionID++;
1791
Glen Leecf601062015-12-21 14:18:39 +09001792 s32Error = wilc_remain_on_channel(vif, priv->hWILCWFIDrv
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001793 , priv->strRemainOnChanParams.u32ListenSessionID
1794 , duration
1795 , chan->hw_value
1796 , WILC_WFI_RemainOnChannelExpired
1797 , WILC_WFI_RemainOnChannelReady
1798 , (void *)priv);
1799
1800 return s32Error;
1801}
1802
Chaehyun Lim1dd54402015-09-14 12:24:26 +09001803static int cancel_remain_on_channel(struct wiphy *wiphy,
1804 struct wireless_dev *wdev,
1805 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001806{
Leo Kime6e12662015-09-16 18:36:03 +09001807 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09001808 struct wilc_priv *priv;
Glen Leecf601062015-12-21 14:18:39 +09001809 struct wilc_vif *vif;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001810
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001811 priv = wiphy_priv(wiphy);
Glen Leecf601062015-12-21 14:18:39 +09001812 vif = netdev_priv(priv->dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001813
1814 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
1815
Glen Leecf601062015-12-21 14:18:39 +09001816 s32Error = wilc_listen_state_expired(vif, priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001817 return s32Error;
1818}
Leo Kima89f7c52015-11-25 11:59:41 +09001819
Chaehyun Limc1560322015-09-22 18:34:51 +09001820static int mgmt_tx(struct wiphy *wiphy,
1821 struct wireless_dev *wdev,
1822 struct cfg80211_mgmt_tx_params *params,
1823 u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001824{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001825 struct ieee80211_channel *chan = params->chan;
1826 unsigned int wait = params->wait;
1827 const u8 *buf = params->buf;
1828 size_t len = params->len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001829 const struct ieee80211_mgmt *mgmt;
1830 struct p2p_mgmt_data *mgmt_tx;
Chaehyun Lim27268872015-09-15 14:06:13 +09001831 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09001832 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001833 u32 i;
Glen Leea4cac482015-12-21 14:18:36 +09001834 struct wilc_vif *vif;
Leo Kim86685942015-11-19 15:56:18 +09001835 u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001836
Glen Leea4cac482015-12-21 14:18:36 +09001837 vif = netdev_priv(wdev->netdev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001838 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001839 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001840
1841 *cookie = (unsigned long)buf;
1842 priv->u64tx_cookie = *cookie;
1843 mgmt = (const struct ieee80211_mgmt *) buf;
1844
1845 if (ieee80211_is_mgmt(mgmt->frame_control)) {
Glen Leef3052582015-09-10 12:03:04 +09001846 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
Leo Kim369a1d32015-12-21 14:18:23 +09001847 if (!mgmt_tx) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001848 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
Leo Kime6e12662015-09-16 18:36:03 +09001849 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001850 }
Glen Leef3052582015-09-10 12:03:04 +09001851 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
Leo Kim369a1d32015-12-21 14:18:23 +09001852 if (!mgmt_tx->buff) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001853 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
Tony Chof638dd32015-09-07 19:09:31 +09001854 kfree(mgmt_tx);
Leo Kime6e12662015-09-16 18:36:03 +09001855 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001856 }
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001857 memcpy(mgmt_tx->buff, buf, len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001858 mgmt_tx->size = len;
1859
1860
1861 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
1862 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
1863 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Glen Leecf601062015-12-21 14:18:39 +09001864 wilc_set_mac_chnl_num(vif, priv->hWILCWFIDrv, chan->hw_value);
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001865 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001866 } else if (ieee80211_is_action(mgmt->frame_control)) {
Chaehyun Limd85f5322015-06-11 14:35:54 +09001867 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001868
1869
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001870 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001871 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
1872 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
1873 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Glen Leecf601062015-12-21 14:18:39 +09001874 wilc_set_mac_chnl_num(vif, priv->hWILCWFIDrv, chan->hw_value);
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001875 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001876 }
1877 switch (buf[ACTION_SUBTYPE_ID]) {
1878 case GAS_INTIAL_REQ:
1879 {
1880 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
1881 break;
1882 }
1883
1884 case GAS_INTIAL_RSP:
1885 {
1886 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
1887 break;
1888 }
1889
1890 case PUBLIC_ACT_VENDORSPEC:
1891 {
Leo Kim881eb5d2015-11-19 15:56:15 +09001892 if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001893 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09001894 if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
Leo Kim583d9722015-11-19 15:56:16 +09001895 get_random_bytes(&p2p_local_random, 1);
1896 p2p_local_random++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001897 }
1898 }
1899
1900 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1901 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09001902 if (p2p_local_random > p2p_recv_random) {
1903 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 +09001904
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001905 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
Leo Kim881eb5d2015-11-19 15:56:15 +09001906 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001907 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
Glen Leea4cac482015-12-21 14:18:36 +09001908 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, vif->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001909 else
Glen Leea4cac482015-12-21 14:18:36 +09001910 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, vif->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001911 break;
1912 }
1913 }
1914
1915 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
Leo Kim86685942015-11-19 15:56:18 +09001916 memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
1917 mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001918 mgmt_tx->size = buf_len;
1919 }
Leo Kim583d9722015-11-19 15:56:16 +09001920 } else {
Leo Kimb84a3ac2015-11-19 15:56:17 +09001921 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 +09001922 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001923 }
1924
1925 } else {
1926 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
1927 }
1928
1929 break;
1930 }
1931
1932 default:
1933 {
1934 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
1935 break;
1936 }
1937 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001938 }
1939
1940 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 +09001941 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001942
Leo Kim1229b1a2015-10-29 12:05:39 +09001943 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n",
1944 jiffies, pstrWFIDrv->p2p_timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001945 }
1946
Glen Lee829c4772015-10-29 12:18:44 +09001947 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
1948 mgmt_tx->buff, mgmt_tx->size,
Glen Leec9d48342015-10-01 16:03:43 +09001949 WILC_WFI_mgmt_tx_complete);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001950 } else {
1951 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
1952 }
Leo Kimaaed3292015-10-12 16:55:38 +09001953 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001954}
1955
Chaehyun Lim85c587a2015-09-22 18:34:50 +09001956static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
1957 struct wireless_dev *wdev,
1958 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001959{
Chaehyun Lim27268872015-09-15 14:06:13 +09001960 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09001961 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001962
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001963 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001964 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001965
1966
1967 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
Leo Kim1229b1a2015-10-29 12:05:39 +09001968 pstrWFIDrv->p2p_timeout = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001969
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +01001970 if (!priv->bInP2PlistenState) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001971 cfg80211_remain_on_channel_expired(priv->wdev,
1972 priv->strRemainOnChanParams.u64ListenCookie,
1973 priv->strRemainOnChanParams.pstrListenChan,
1974 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001975 }
1976
1977 return 0;
1978}
1979
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09001980void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
1981 u16 frame_type, bool reg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001982{
Chaehyun Lim27268872015-09-15 14:06:13 +09001983 struct wilc_priv *priv;
Glen Leea4cac482015-12-21 14:18:36 +09001984 struct wilc_vif *vif;
Glen Lee1b869352015-10-20 17:14:01 +09001985 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001986
1987 priv = wiphy_priv(wiphy);
Glen Leea4cac482015-12-21 14:18:36 +09001988 vif = netdev_priv(priv->wdev->netdev);
1989 wl = vif->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001990
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001991 if (!frame_type)
1992 return;
1993
1994 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
1995 switch (frame_type) {
1996 case PROBE_REQ:
1997 {
Glen Leea4cac482015-12-21 14:18:36 +09001998 vif->g_struct_frame_reg[0].frame_type = frame_type;
1999 vif->g_struct_frame_reg[0].reg = reg;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002000 }
2001 break;
2002
2003 case ACTION:
2004 {
Glen Leea4cac482015-12-21 14:18:36 +09002005 vif->g_struct_frame_reg[1].frame_type = frame_type;
2006 vif->g_struct_frame_reg[1].reg = reg;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002007 }
2008 break;
2009
2010 default:
2011 {
2012 break;
2013 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002014 }
Leo Kima89f7c52015-11-25 11:59:41 +09002015
Glen Lee1b869352015-10-20 17:14:01 +09002016 if (!wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002017 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
2018 return;
2019 }
Glen Leecf601062015-12-21 14:18:39 +09002020 wilc_frame_register(vif, priv->hWILCWFIDrv, frame_type, reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002021}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002022
Chaehyun Lima8047e22015-09-22 18:34:48 +09002023static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
2024 s32 rssi_thold, u32 rssi_hyst)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002025{
2026 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2027 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002028}
Leo Kima89f7c52015-11-25 11:59:41 +09002029
Chaehyun Limbdb63382015-09-14 12:24:19 +09002030static int dump_station(struct wiphy *wiphy, struct net_device *dev,
2031 int idx, u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002032{
Chaehyun Lim27268872015-09-15 14:06:13 +09002033 struct wilc_priv *priv;
Glen Leecf601062015-12-21 14:18:39 +09002034 struct wilc_vif *vif;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002035
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002036 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2037
2038 if (idx != 0)
2039 return -ENOENT;
2040
2041 priv = wiphy_priv(wiphy);
Glen Leecf601062015-12-21 14:18:39 +09002042 vif = netdev_priv(priv->dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002043
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002044 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002045
Glen Leecf601062015-12-21 14:18:39 +09002046 wilc_get_rssi(vif, priv->hWILCWFIDrv, &(sinfo->signal));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002047
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002048 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002049}
2050
Chaehyun Lim46530672015-09-22 18:34:46 +09002051static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2052 bool enabled, int timeout)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002053{
Chaehyun Lim27268872015-09-15 14:06:13 +09002054 struct wilc_priv *priv;
Glen Leecf601062015-12-21 14:18:39 +09002055 struct wilc_vif *vif;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002056
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002057 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2058
Leo Kim369a1d32015-12-21 14:18:23 +09002059 if (!wiphy)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002060 return -ENOENT;
2061
2062 priv = wiphy_priv(wiphy);
Glen Leecf601062015-12-21 14:18:39 +09002063 vif = netdev_priv(priv->dev);
Leo Kim369a1d32015-12-21 14:18:23 +09002064 if (!priv->hWILCWFIDrv) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002065 PRINT_ER("Driver is NULL\n");
2066 return -EIO;
2067 }
2068
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002069 if (wilc_enable_ps)
Glen Leecf601062015-12-21 14:18:39 +09002070 wilc_set_power_mgmt(vif, priv->hWILCWFIDrv, enabled, timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002071
2072
Leo Kime6e12662015-09-16 18:36:03 +09002073 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002074}
Glen Lee108b3432015-09-16 18:53:20 +09002075
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002076static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2077 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002078{
Chaehyun Lim27268872015-09-15 14:06:13 +09002079 struct wilc_priv *priv;
Glen Leea4cac482015-12-21 14:18:36 +09002080 struct wilc_vif *vif;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002081 u8 interface_type;
Chaehyun Limd85f5322015-06-11 14:35:54 +09002082 u16 TID = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002083 u8 i;
Glen Lee299382c2015-10-20 17:13:56 +09002084 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002085
Glen Leea4cac482015-12-21 14:18:36 +09002086 vif = netdev_priv(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002087 priv = wiphy_priv(wiphy);
Glen Leea4cac482015-12-21 14:18:36 +09002088 wl = vif->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002089
2090 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2091 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
Leo Kim583d9722015-11-19 15:56:16 +09002092 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +09002093 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +09002094 wilc_ie = false;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002095 wilc_optaining_ip = false;
2096 del_timer(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002097 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
Leo Kima89f7c52015-11-25 11:59:41 +09002098
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002099 if (g_ptk_keys_saved && g_gtk_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002100 wilc_set_machw_change_vir_if(dev, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002101 }
2102
2103 switch (type) {
2104 case NL80211_IFTYPE_STATION:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002105 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002106 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002107
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002108 dev->ieee80211_ptr->iftype = type;
2109 priv->wdev->iftype = type;
Glen Leea4cac482015-12-21 14:18:36 +09002110 vif->monitor_flag = 0;
2111 vif->iftype = STATION_MODE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002112
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002113 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
Glen Leea4cac482015-12-21 14:18:36 +09002114 interface_type = vif->iftype;
2115 vif->iftype = STATION_MODE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002116
Glen Lee299382c2015-10-20 17:13:56 +09002117 if (wl->initialized) {
Glen Leecf601062015-12-21 14:18:39 +09002118 wilc_del_all_rx_ba_session(vif, priv->hWILCWFIDrv,
Glen Lee1f435d22015-12-21 14:18:37 +09002119 wl->vif[0]->bssid, TID);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002120 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002121
Glen Lee299382c2015-10-20 17:13:56 +09002122 up(&wl->cfg_event);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002123
Glen Lee53dc0cf2015-10-20 17:13:57 +09002124 wilc1000_wlan_deinit(dev);
Glen Leea4cac482015-12-21 14:18:36 +09002125 wilc1000_wlan_init(dev, vif);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002126 wilc_initialized = 1;
Glen Leea4cac482015-12-21 14:18:36 +09002127 vif->iftype = interface_type;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002128
Glen Leecf601062015-12-21 14:18:39 +09002129 wilc_set_wfi_drv_handler(vif, wl->vif[0]->hif_drv);
2130 wilc_set_mac_address(vif, wl->vif[0]->hif_drv,
Glen Lee1f435d22015-12-21 14:18:37 +09002131 wl->vif[0]->src_addr);
Glen Leecf601062015-12-21 14:18:39 +09002132 wilc_set_operation_mode(vif, priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002133
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002134 if (g_wep_keys_saved) {
Glen Leecf601062015-12-21 14:18:39 +09002135 wilc_set_wep_default_keyid(vif, wl->vif[0]->hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002136 g_key_wep_params.key_idx);
Glen Leecf601062015-12-21 14:18:39 +09002137 wilc_add_wep_key_bss_sta(vif, wl->vif[0]->hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002138 g_key_wep_params.key,
2139 g_key_wep_params.key_len,
2140 g_key_wep_params.key_idx);
2141 }
2142
Glen Leecf601062015-12-21 14:18:39 +09002143 wilc_flush_join_req(vif, priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002144
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002145 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2146 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2147 g_key_ptk_params.key[1],
2148 g_key_ptk_params.key[2]);
2149 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2150 g_key_gtk_params.key[1],
2151 g_key_gtk_params.key[2]);
Glen Lee1f435d22015-12-21 14:18:37 +09002152 add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy,
2153 wl->vif[0]->ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002154 g_add_ptk_key_params.key_idx,
2155 g_add_ptk_key_params.pairwise,
2156 g_add_ptk_key_params.mac_addr,
2157 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002158
Glen Lee1f435d22015-12-21 14:18:37 +09002159 add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy,
2160 wl->vif[0]->ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002161 g_add_gtk_key_params.key_idx,
2162 g_add_gtk_key_params.pairwise,
2163 g_add_gtk_key_params.mac_addr,
2164 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002165 }
2166
Glen Lee299382c2015-10-20 17:13:56 +09002167 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002168 for (i = 0; i < num_reg_frame; i++) {
Glen Leea4cac482015-12-21 14:18:36 +09002169 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type,
2170 vif->g_struct_frame_reg[i].reg);
Glen Leecf601062015-12-21 14:18:39 +09002171 wilc_frame_register(vif, priv->hWILCWFIDrv,
Glen Leea4cac482015-12-21 14:18:36 +09002172 vif->g_struct_frame_reg[i].frame_type,
2173 vif->g_struct_frame_reg[i].reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002174 }
2175 }
2176
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002177 wilc_enable_ps = true;
Glen Leecf601062015-12-21 14:18:39 +09002178 wilc_set_power_mgmt(vif, priv->hWILCWFIDrv, 1, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002179 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002180 break;
2181
2182 case NL80211_IFTYPE_P2P_CLIENT:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002183 wilc_enable_ps = false;
Glen Leecf601062015-12-21 14:18:39 +09002184 wilc_set_power_mgmt(vif, priv->hWILCWFIDrv, 0, 0);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002185 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002186 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002187
Glen Leecf601062015-12-21 14:18:39 +09002188 wilc_del_all_rx_ba_session(vif, priv->hWILCWFIDrv,
Glen Lee1f435d22015-12-21 14:18:37 +09002189 wl->vif[0]->bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002190
2191 dev->ieee80211_ptr->iftype = type;
2192 priv->wdev->iftype = type;
Glen Leea4cac482015-12-21 14:18:36 +09002193 vif->monitor_flag = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002194
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002195 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
Glen Leea4cac482015-12-21 14:18:36 +09002196 vif->iftype = CLIENT_MODE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002197
2198
Glen Lee299382c2015-10-20 17:13:56 +09002199 if (wl->initialized) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002200 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002201
Glen Lee53dc0cf2015-10-20 17:13:57 +09002202 wilc1000_wlan_deinit(dev);
Glen Leea4cac482015-12-21 14:18:36 +09002203 wilc1000_wlan_init(dev, vif);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002204 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002205
Glen Leecf601062015-12-21 14:18:39 +09002206 wilc_set_wfi_drv_handler(vif, wl->vif[0]->hif_drv);
2207 wilc_set_mac_address(vif, wl->vif[0]->hif_drv,
Glen Lee1f435d22015-12-21 14:18:37 +09002208 wl->vif[0]->src_addr);
Glen Leecf601062015-12-21 14:18:39 +09002209 wilc_set_operation_mode(vif, priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002210
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002211 if (g_wep_keys_saved) {
Glen Leecf601062015-12-21 14:18:39 +09002212 wilc_set_wep_default_keyid(vif, wl->vif[0]->hif_drv,
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002213 g_key_wep_params.key_idx);
Glen Leecf601062015-12-21 14:18:39 +09002214 wilc_add_wep_key_bss_sta(vif, wl->vif[0]->hif_drv,
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002215 g_key_wep_params.key,
2216 g_key_wep_params.key_len,
2217 g_key_wep_params.key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002218 }
2219
Glen Leecf601062015-12-21 14:18:39 +09002220 wilc_flush_join_req(vif, priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002221
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002222 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2223 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2224 g_key_ptk_params.key[1],
2225 g_key_ptk_params.key[2]);
2226 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2227 g_key_gtk_params.key[1],
2228 g_key_gtk_params.key[2]);
Glen Lee1f435d22015-12-21 14:18:37 +09002229 add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy,
2230 wl->vif[0]->ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002231 g_add_ptk_key_params.key_idx,
2232 g_add_ptk_key_params.pairwise,
2233 g_add_ptk_key_params.mac_addr,
2234 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002235
Glen Lee1f435d22015-12-21 14:18:37 +09002236 add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy,
2237 wl->vif[0]->ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002238 g_add_gtk_key_params.key_idx,
2239 g_add_gtk_key_params.pairwise,
2240 g_add_gtk_key_params.mac_addr,
2241 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002242 }
2243
Dean Lee72ed4dc2015-06-12 14:11:44 +09002244 refresh_scan(priv, 1, true);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002245 wilc_set_machw_change_vir_if(dev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002246
Glen Lee299382c2015-10-20 17:13:56 +09002247 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002248 for (i = 0; i < num_reg_frame; i++) {
Glen Leea4cac482015-12-21 14:18:36 +09002249 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type,
2250 vif->g_struct_frame_reg[i].reg);
Glen Leecf601062015-12-21 14:18:39 +09002251 wilc_frame_register(vif, priv->hWILCWFIDrv,
Glen Leea4cac482015-12-21 14:18:36 +09002252 vif->g_struct_frame_reg[i].frame_type,
2253 vif->g_struct_frame_reg[i].reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002254 }
2255 }
2256 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002257 break;
2258
2259 case NL80211_IFTYPE_AP:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002260 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002261 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002262 dev->ieee80211_ptr->iftype = type;
2263 priv->wdev->iftype = type;
Glen Leea4cac482015-12-21 14:18:36 +09002264 vif->iftype = AP_MODE;
Johnny Kim8a143302015-06-10 17:06:46 +09002265 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002266
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002267 PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002268 wilc_wlan_get_firmware(dev);
Leo Kima89f7c52015-11-25 11:59:41 +09002269
Glen Lee299382c2015-10-20 17:13:56 +09002270 if (wl->initialized) {
Glen Leea4cac482015-12-21 14:18:36 +09002271 vif->iftype = AP_MODE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002272 wilc_mac_close(dev);
2273 wilc_mac_open(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002274
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002275 for (i = 0; i < num_reg_frame; i++) {
Glen Leea4cac482015-12-21 14:18:36 +09002276 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type,
2277 vif->g_struct_frame_reg[i].reg);
Glen Leecf601062015-12-21 14:18:39 +09002278 wilc_frame_register(vif, priv->hWILCWFIDrv,
Glen Leea4cac482015-12-21 14:18:36 +09002279 vif->g_struct_frame_reg[i].frame_type,
2280 vif->g_struct_frame_reg[i].reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002281 }
2282 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002283 break;
2284
2285 case NL80211_IFTYPE_P2P_GO:
2286 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
2287
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002288 wilc_optaining_ip = true;
Leo Kim7e872df2015-11-19 15:56:20 +09002289 mod_timer(&wilc_during_ip_timer,
2290 jiffies + msecs_to_jiffies(during_ip_time));
Glen Leecf601062015-12-21 14:18:39 +09002291 wilc_set_power_mgmt(vif, priv->hWILCWFIDrv, 0, 0);
2292 wilc_del_all_rx_ba_session(vif, priv->hWILCWFIDrv,
Glen Lee1f435d22015-12-21 14:18:37 +09002293 wl->vif[0]->bssid, TID);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002294 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002295 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002296 dev->ieee80211_ptr->iftype = type;
2297 priv->wdev->iftype = type;
2298
Johnny Kim8a143302015-06-10 17:06:46 +09002299 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002300
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002301 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2302
2303
Glen Leea4cac482015-12-21 14:18:36 +09002304 vif->iftype = GO_MODE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002305
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002306 wilc_wait_msg_queue_idle();
Glen Lee53dc0cf2015-10-20 17:13:57 +09002307 wilc1000_wlan_deinit(dev);
Glen Leea4cac482015-12-21 14:18:36 +09002308 wilc1000_wlan_init(dev, vif);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002309 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002310
Glen Leecf601062015-12-21 14:18:39 +09002311 wilc_set_wfi_drv_handler(vif, wl->vif[0]->hif_drv);
2312 wilc_set_mac_address(vif, wl->vif[0]->hif_drv,
Glen Lee1f435d22015-12-21 14:18:37 +09002313 wl->vif[0]->src_addr);
Glen Leecf601062015-12-21 14:18:39 +09002314 wilc_set_operation_mode(vif, priv->hWILCWFIDrv, AP_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002315
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002316 if (g_wep_keys_saved) {
Glen Leecf601062015-12-21 14:18:39 +09002317 wilc_set_wep_default_keyid(vif, wl->vif[0]->hif_drv,
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002318 g_key_wep_params.key_idx);
Glen Leecf601062015-12-21 14:18:39 +09002319 wilc_add_wep_key_bss_sta(vif, wl->vif[0]->hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002320 g_key_wep_params.key,
2321 g_key_wep_params.key_len,
2322 g_key_wep_params.key_idx);
2323 }
2324
Glen Leecf601062015-12-21 14:18:39 +09002325 wilc_flush_join_req(vif, priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002326
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002327 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2328 PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0],
2329 g_key_ptk_params.key[1],
2330 g_key_ptk_params.key[2],
2331 g_key_ptk_params.cipher);
2332 PRINT_D(CFG80211_DBG, "gtk %x %x %x cipher %x\n", g_key_gtk_params.key[0],
2333 g_key_gtk_params.key[1],
2334 g_key_gtk_params.key[2],
2335 g_key_gtk_params.cipher);
Glen Lee1f435d22015-12-21 14:18:37 +09002336 add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy,
2337 wl->vif[0]->ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002338 g_add_ptk_key_params.key_idx,
2339 g_add_ptk_key_params.pairwise,
2340 g_add_ptk_key_params.mac_addr,
2341 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002342
Glen Lee1f435d22015-12-21 14:18:37 +09002343 add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy,
2344 wl->vif[0]->ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002345 g_add_gtk_key_params.key_idx,
2346 g_add_gtk_key_params.pairwise,
2347 g_add_gtk_key_params.mac_addr,
2348 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002349 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002350
Glen Lee299382c2015-10-20 17:13:56 +09002351 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002352 for (i = 0; i < num_reg_frame; i++) {
Glen Leea4cac482015-12-21 14:18:36 +09002353 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type,
2354 vif->g_struct_frame_reg[i].reg);
Glen Leecf601062015-12-21 14:18:39 +09002355 wilc_frame_register(vif, priv->hWILCWFIDrv,
Glen Leea4cac482015-12-21 14:18:36 +09002356 vif->g_struct_frame_reg[i].frame_type,
2357 vif->g_struct_frame_reg[i].reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002358 }
2359 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002360 break;
2361
2362 default:
2363 PRINT_ER("Unknown interface type= %d\n", type);
Leo Kimaaed3292015-10-12 16:55:38 +09002364 return -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002365 }
2366
Leo Kimaaed3292015-10-12 16:55:38 +09002367 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002368}
2369
Chaehyun Lima13168d2015-09-14 12:24:12 +09002370static int start_ap(struct wiphy *wiphy, struct net_device *dev,
2371 struct cfg80211_ap_settings *settings)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002372{
2373 struct cfg80211_beacon_data *beacon = &(settings->beacon);
Chaehyun Lim27268872015-09-15 14:06:13 +09002374 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002375 s32 s32Error = 0;
Glen Lee684dc182015-10-20 17:14:02 +09002376 struct wilc *wl;
Glen Leea4cac482015-12-21 14:18:36 +09002377 struct wilc_vif *vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002378
2379 priv = wiphy_priv(wiphy);
Glen Leea4cac482015-12-21 14:18:36 +09002380 vif = netdev_priv(dev);
2381 wl = vif ->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002382 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
2383
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302384 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 +09002385 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
2386
Chaehyun Lim80785a92015-09-14 12:24:01 +09002387 s32Error = set_channel(wiphy, &settings->chandef);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002388
Leo Kime6e12662015-09-16 18:36:03 +09002389 if (s32Error != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002390 PRINT_ER("Error in setting channel\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002391
Glen Lee1f435d22015-12-21 14:18:37 +09002392 wilc_wlan_set_bssid(dev, wl->vif[0]->src_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002393
Glen Leecf601062015-12-21 14:18:39 +09002394 s32Error = wilc_add_beacon(vif, priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002395 settings->beacon_interval,
2396 settings->dtim_period,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002397 beacon->head_len, (u8 *)beacon->head,
2398 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002399
2400 return s32Error;
2401}
2402
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002403static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
2404 struct cfg80211_beacon_data *beacon)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002405{
Chaehyun Lim27268872015-09-15 14:06:13 +09002406 struct wilc_priv *priv;
Glen Leecf601062015-12-21 14:18:39 +09002407 struct wilc_vif *vif;
Leo Kime6e12662015-09-16 18:36:03 +09002408 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002409
2410 priv = wiphy_priv(wiphy);
Glen Leecf601062015-12-21 14:18:39 +09002411 vif = netdev_priv(priv->dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002412 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
2413
2414
Glen Leecf601062015-12-21 14:18:39 +09002415 s32Error = wilc_add_beacon(vif, priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002416 0,
2417 0,
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 Limc8cddd72015-09-14 12:24:14 +09002424static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002425{
Leo Kime6e12662015-09-16 18:36:03 +09002426 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002427 struct wilc_priv *priv;
Glen Leecf601062015-12-21 14:18:39 +09002428 struct wilc_vif *vif;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002429 u8 NullBssid[ETH_ALEN] = {0};
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002430
Leo Kim7ae43362015-09-16 18:35:59 +09002431 if (!wiphy)
2432 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002433
2434 priv = wiphy_priv(wiphy);
Glen Leecf601062015-12-21 14:18:39 +09002435 vif = netdev_priv(priv->dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002436
2437 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
2438
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002439 wilc_wlan_set_bssid(dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002440
Glen Leecf601062015-12-21 14:18:39 +09002441 s32Error = wilc_del_beacon(vif, priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002442
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002443 if (s32Error)
2444 PRINT_ER("Host delete beacon fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002445
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002446 return s32Error;
2447}
2448
Chaehyun Limed269552015-09-14 12:24:15 +09002449static int add_station(struct wiphy *wiphy, struct net_device *dev,
2450 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002451{
Leo Kime6e12662015-09-16 18:36:03 +09002452 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002453 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09002454 struct add_sta_param strStaParams = { {0} };
Glen Leea4cac482015-12-21 14:18:36 +09002455 struct wilc_vif *vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002456
Leo Kim7ae43362015-09-16 18:35:59 +09002457 if (!wiphy)
2458 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002459
2460 priv = wiphy_priv(wiphy);
Glen Leea4cac482015-12-21 14:18:36 +09002461 vif = netdev_priv(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002462
Glen Leea4cac482015-12-21 14:18:36 +09002463 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09002464 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09002465 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09002466 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09002467 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09002468 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002469
2470 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
2471
2472 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],
2473 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
Leo Kim4101eb82015-10-29 12:05:42 +09002474 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09002475 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
2476 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002477
Leo Kim369a1d32015-12-21 14:18:23 +09002478 if (!params->ht_capa) {
Leo Kim22520122015-10-29 12:05:45 +09002479 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002480 } else {
Leo Kim22520122015-10-29 12:05:45 +09002481 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09002482 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09002483 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09002484 memcpy(strStaParams.ht_supp_mcs_set,
2485 &params->ht_capa->mcs,
2486 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09002487 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09002488 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09002489 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002490 }
2491
Leo Kimf676e172015-10-29 12:05:52 +09002492 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09002493 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002494
Leo Kim22520122015-10-29 12:05:45 +09002495 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
2496 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09002497 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
2498 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09002499 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
2500 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09002501 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
2502 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09002503 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
2504 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09002505 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
2506 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09002507 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
2508 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09002509 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
2510 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002511
Glen Leecf601062015-12-21 14:18:39 +09002512 s32Error = wilc_add_station(vif, priv->hWILCWFIDrv,
2513 &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002514 if (s32Error)
2515 PRINT_ER("Host add station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002516 }
2517
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002518 return s32Error;
2519}
2520
Chaehyun Lima0a8be92015-09-14 12:24:16 +09002521static int del_station(struct wiphy *wiphy, struct net_device *dev,
2522 struct station_del_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002523{
Arnd Bergmann057d1e92015-06-01 21:06:44 +02002524 const u8 *mac = params->mac;
Leo Kime6e12662015-09-16 18:36:03 +09002525 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002526 struct wilc_priv *priv;
Glen Leea4cac482015-12-21 14:18:36 +09002527 struct wilc_vif *vif;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002528
Leo Kim7ae43362015-09-16 18:35:59 +09002529 if (!wiphy)
2530 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002531
2532 priv = wiphy_priv(wiphy);
Glen Leea4cac482015-12-21 14:18:36 +09002533 vif = netdev_priv(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002534
Glen Leea4cac482015-12-21 14:18:36 +09002535 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002536 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
2537
2538
Leo Kim369a1d32015-12-21 14:18:23 +09002539 if (!mac) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302540 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
Glen Leecf601062015-12-21 14:18:39 +09002541 s32Error = wilc_del_allstation(vif, priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002542 } else {
2543 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]);
2544 }
2545
Glen Leecf601062015-12-21 14:18:39 +09002546 s32Error = wilc_del_station(vif, priv->hWILCWFIDrv, mac);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002547
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002548 if (s32Error)
2549 PRINT_ER("Host delete station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002550 }
2551 return s32Error;
2552}
2553
Chaehyun Lim14b42082015-09-14 12:24:17 +09002554static int change_station(struct wiphy *wiphy, struct net_device *dev,
2555 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002556{
Leo Kime6e12662015-09-16 18:36:03 +09002557 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002558 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09002559 struct add_sta_param strStaParams = { {0} };
Glen Leea4cac482015-12-21 14:18:36 +09002560 struct wilc_vif *vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002561
2562
2563 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
2564
Leo Kim7ae43362015-09-16 18:35:59 +09002565 if (!wiphy)
2566 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002567
2568 priv = wiphy_priv(wiphy);
Glen Leea4cac482015-12-21 14:18:36 +09002569 vif = netdev_priv(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002570
Glen Leea4cac482015-12-21 14:18:36 +09002571 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09002572 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09002573 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09002574 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09002575 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002576
Leo Kim2353c382015-10-29 12:05:41 +09002577 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n",
2578 strStaParams.bssid[0], strStaParams.bssid[1],
2579 strStaParams.bssid[2], strStaParams.bssid[3],
2580 strStaParams.bssid[4], strStaParams.bssid[5]);
Leo Kim4101eb82015-10-29 12:05:42 +09002581 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09002582 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
2583 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002584
Leo Kim369a1d32015-12-21 14:18:23 +09002585 if (!params->ht_capa) {
Leo Kim22520122015-10-29 12:05:45 +09002586 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002587 } else {
Leo Kim22520122015-10-29 12:05:45 +09002588 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09002589 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09002590 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09002591 memcpy(strStaParams.ht_supp_mcs_set,
2592 &params->ht_capa->mcs,
2593 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09002594 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09002595 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09002596 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002597 }
2598
Leo Kimf676e172015-10-29 12:05:52 +09002599 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09002600 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002601
Leo Kim22520122015-10-29 12:05:45 +09002602 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
2603 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09002604 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
2605 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09002606 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
2607 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09002608 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
2609 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09002610 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
2611 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09002612 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
2613 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09002614 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
2615 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09002616 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
2617 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002618
Glen Leecf601062015-12-21 14:18:39 +09002619 s32Error = wilc_edit_station(vif, priv->hWILCWFIDrv,
2620 &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002621 if (s32Error)
2622 PRINT_ER("Host edit station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002623 }
2624 return s32Error;
2625}
2626
Chaehyun Lim37316e82015-09-22 18:34:52 +09002627static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
2628 const char *name,
2629 unsigned char name_assign_type,
2630 enum nl80211_iftype type,
2631 u32 *flags,
2632 struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002633{
Glen Leea4cac482015-12-21 14:18:36 +09002634 struct wilc_vif *vif;
Chaehyun Lim27268872015-09-15 14:06:13 +09002635 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002636 struct net_device *new_ifc = NULL;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002637
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002638 priv = wiphy_priv(wiphy);
2639
2640
2641
2642 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
2643
Glen Leea4cac482015-12-21 14:18:36 +09002644 vif = netdev_priv(priv->wdev->netdev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002645
2646
2647 if (type == NL80211_IFTYPE_MONITOR) {
2648 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
Glen Lee1006b5c2015-12-21 14:18:38 +09002649 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", vif->ndev);
2650 new_ifc = WILC_WFI_init_mon_interface(name, vif->ndev);
Leo Kim369a1d32015-12-21 14:18:23 +09002651 if (new_ifc) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002652 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
Glen Leea4cac482015-12-21 14:18:36 +09002653 vif = netdev_priv(priv->wdev->netdev);
2654 vif->monitor_flag = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002655 } else
2656 PRINT_ER("Error in initializing monitor interface\n ");
2657 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002658 return priv->wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002659}
2660
Chaehyun Lim956d7212015-09-22 18:34:49 +09002661static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002662{
2663 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
Leo Kime6e12662015-09-16 18:36:03 +09002664 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002665}
2666
Chaehyun Lim08241922015-09-15 14:06:12 +09002667static struct cfg80211_ops wilc_cfg80211_ops = {
Chaehyun Lim80785a92015-09-14 12:24:01 +09002668 .set_monitor_channel = set_channel,
Chaehyun Lim0e30d062015-09-14 12:24:02 +09002669 .scan = scan,
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +09002670 .connect = connect,
Chaehyun Limb027cde2015-09-14 12:24:04 +09002671 .disconnect = disconnect,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002672 .add_key = add_key,
Chaehyun Lim3044ba72015-09-14 12:24:06 +09002673 .del_key = del_key,
Chaehyun Limf4893df2015-09-14 12:24:07 +09002674 .get_key = get_key,
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09002675 .set_default_key = set_default_key,
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09002676 .add_virtual_intf = add_virtual_intf,
Chaehyun Limb4a73352015-09-14 12:24:10 +09002677 .del_virtual_intf = del_virtual_intf,
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002678 .change_virtual_intf = change_virtual_intf,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002679
Chaehyun Lima13168d2015-09-14 12:24:12 +09002680 .start_ap = start_ap,
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002681 .change_beacon = change_beacon,
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002682 .stop_ap = stop_ap,
Chaehyun Limed269552015-09-14 12:24:15 +09002683 .add_station = add_station,
Chaehyun Lima0a8be92015-09-14 12:24:16 +09002684 .del_station = del_station,
Chaehyun Lim14b42082015-09-14 12:24:17 +09002685 .change_station = change_station,
Chaehyun Limf06f5622015-09-14 12:24:18 +09002686 .get_station = get_station,
Chaehyun Limbdb63382015-09-14 12:24:19 +09002687 .dump_station = dump_station,
Chaehyun Lima5f7db62015-09-14 12:24:20 +09002688 .change_bss = change_bss,
Chaehyun Lima76b63e2015-09-14 12:24:21 +09002689 .set_wiphy_params = set_wiphy_params,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002690
Chaehyun Lim4d466572015-09-14 12:24:22 +09002691 .set_pmksa = set_pmksa,
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09002692 .del_pmksa = del_pmksa,
Chaehyun Limb33c39b2015-09-14 12:24:24 +09002693 .flush_pmksa = flush_pmksa,
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002694 .remain_on_channel = remain_on_channel,
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002695 .cancel_remain_on_channel = cancel_remain_on_channel,
Chaehyun Lim4a2f9b32015-09-14 12:24:27 +09002696 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
Chaehyun Lim12a26a32015-09-14 12:24:28 +09002697 .mgmt_tx = mgmt_tx,
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002698 .mgmt_frame_register = wilc_mgmt_frame_register,
Chaehyun Lim46530672015-09-22 18:34:46 +09002699 .set_power_mgmt = set_power_mgmt,
Chaehyun Lima8047e22015-09-22 18:34:48 +09002700 .set_cqm_rssi_config = set_cqm_rssi_config,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002701
2702};
2703
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002704int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
2705{
Chaehyun Lim27268872015-09-15 14:06:13 +09002706 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002707
2708 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002709 switch (changed) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002710 case WILC_WFI_RX_PKT:
2711 {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002712 priv->netstats.rx_packets++;
2713 priv->netstats.rx_bytes += pktlen;
2714 priv->netstats.rx_time = get_jiffies_64();
2715 }
2716 break;
2717
2718 case WILC_WFI_TX_PKT:
2719 {
2720 priv->netstats.tx_packets++;
2721 priv->netstats.tx_bytes += pktlen;
2722 priv->netstats.tx_time = get_jiffies_64();
2723
2724 }
2725 break;
2726
2727 default:
2728 break;
2729 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002730 return 0;
2731}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002732
Arnd Bergmann1608c402015-11-16 15:04:53 +01002733static struct wireless_dev *WILC_WFI_CfgAlloc(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002734{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002735 struct wireless_dev *wdev;
2736
2737
2738 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
Leo Kima89f7c52015-11-25 11:59:41 +09002739
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002740 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2741 if (!wdev) {
2742 PRINT_ER("Cannot allocate wireless device\n");
2743 goto _fail_;
2744 }
2745
Chaehyun Lim27268872015-09-15 14:06:13 +09002746 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002747 if (!wdev->wiphy) {
2748 PRINT_ER("Cannot allocate wiphy\n");
2749 goto _fail_mem_;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002750 }
2751
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002752 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
2753 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
2754 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
2755 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
2756 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002757
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002758 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
2759
2760 return wdev;
2761
2762_fail_mem_:
2763 kfree(wdev);
2764_fail_:
2765 return NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002766}
Leo Kima89f7c52015-11-25 11:59:41 +09002767
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01002768struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002769{
Chaehyun Lim27268872015-09-15 14:06:13 +09002770 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002771 struct wireless_dev *wdev;
Leo Kime6e12662015-09-16 18:36:03 +09002772 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002773
2774 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
2775
2776 wdev = WILC_WFI_CfgAlloc();
Leo Kim369a1d32015-12-21 14:18:23 +09002777 if (!wdev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002778 PRINT_ER("CfgAlloc Failed\n");
2779 return NULL;
2780 }
2781
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002782 priv = wdev_priv(wdev);
Arnd Bergmann83383ea2015-06-01 21:06:43 +02002783 sema_init(&(priv->SemHandleUpdateStats), 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002784 priv->wdev = wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002785 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002786 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
2787 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002788
2789 wdev->wiphy->max_scan_ie_len = 1000;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002790 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002791 wdev->wiphy->cipher_suites = cipher_suites;
2792 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002793 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002794
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002795 wdev->wiphy->max_remain_on_channel_duration = 500;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002796 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
2797 BIT(NL80211_IFTYPE_P2P_CLIENT);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002798 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002799 wdev->iftype = NL80211_IFTYPE_STATION;
2800
2801
2802
2803 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
2804 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
2805 wdev->wiphy->interface_modes, wdev->iftype);
2806
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01002807 set_wiphy_dev(wdev->wiphy, dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002808
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002809 s32Error = wiphy_register(wdev->wiphy);
2810 if (s32Error) {
2811 PRINT_ER("Cannot register wiphy device\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002812 } else {
2813 PRINT_D(CFG80211_DBG, "Successful Registering\n");
2814 }
2815
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002816 priv->dev = net;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002817 return wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002818}
Leo Kima89f7c52015-11-25 11:59:41 +09002819
Chaehyun Limdd4b6a82015-09-20 15:51:25 +09002820int wilc_init_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002821{
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09002822 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002823
Chaehyun Lim27268872015-09-15 14:06:13 +09002824 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002825
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002826 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
2827 priv = wdev_priv(net->ieee80211_ptr);
2828 if (op_ifcs == 0) {
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -07002829 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002830 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002831 }
2832 op_ifcs++;
2833 if (s32Error < 0) {
2834 PRINT_ER("Failed to creat refresh Timer\n");
2835 return s32Error;
2836 }
2837
Dean Lee72ed4dc2015-06-12 14:11:44 +09002838 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002839
Dean Lee72ed4dc2015-06-12 14:11:44 +09002840 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002841
Arnd Bergmann83383ea2015-06-01 21:06:43 +02002842 sema_init(&(priv->hSemScanReq), 1);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002843 s32Error = wilc_init(net, &priv->hWILCWFIDrv);
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09002844 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002845 PRINT_ER("Error while initializing hostinterface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09002846
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002847 return s32Error;
2848}
2849
Chaehyun Lima9a16822015-09-20 15:51:24 +09002850int wilc_deinit_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002851{
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09002852 int s32Error = 0;
Glen Leecf601062015-12-21 14:18:39 +09002853 struct wilc_vif *vif;
Chaehyun Lim27268872015-09-15 14:06:13 +09002854 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002855
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002856 priv = wdev_priv(net->ieee80211_ptr);
Glen Leecf601062015-12-21 14:18:39 +09002857 vif = netdev_priv(priv->dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002858
Dean Lee72ed4dc2015-06-12 14:11:44 +09002859 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002860
Dean Lee72ed4dc2015-06-12 14:11:44 +09002861 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002862
2863 op_ifcs--;
2864
Glen Leecf601062015-12-21 14:18:39 +09002865 s32Error = wilc_deinit(vif, priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002866
Leo Kimd14991a2015-11-19 15:56:22 +09002867 clear_shadow_scan();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002868 if (op_ifcs == 0) {
2869 PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002870 del_timer_sync(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002871 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002872
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09002873 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002874 PRINT_ER("Error while deintializing host interface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09002875
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002876 return s32Error;
2877}
2878
Chaehyun Lim96da20a2015-09-20 15:51:08 +09002879void wilc_free_wiphy(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002880{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002881 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
2882
Chaehyun Lim619837a2015-09-20 15:51:10 +09002883 if (!net) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002884 PRINT_D(INIT_DBG, "net_device is NULL\n");
2885 return;
2886 }
2887
Chaehyun Lim619837a2015-09-20 15:51:10 +09002888 if (!net->ieee80211_ptr) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002889 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
2890 return;
2891 }
2892
Chaehyun Lim619837a2015-09-20 15:51:10 +09002893 if (!net->ieee80211_ptr->wiphy) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002894 PRINT_D(INIT_DBG, "wiphy is NULL\n");
2895 return;
2896 }
2897
2898 wiphy_unregister(net->ieee80211_ptr->wiphy);
2899
2900 PRINT_D(INIT_DBG, "Freeing wiphy\n");
2901 wiphy_free(net->ieee80211_ptr->wiphy);
2902 kfree(net->ieee80211_ptr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002903}