blob: 792fdff4bca90caa97d0bc48c8176bbc85bcbc33 [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
Chaehyun Lima5f99432015-12-24 16:52:35 +0900199 kfree(last_scanned_shadow[i].pJoinParams);
Leo Kimf1ab1172015-11-19 15:56:11 +0900200 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
Chaehyun Lima5f99432015-12-24 16:52:35 +0900285 kfree(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)
Chaehyun Lima5f99432015-12-24 16:52:35 +0900379 kfree(last_scanned_shadow[ap_index].pJoinParams);
Leo Kimf1ab1172015-11-19 15:56:11 +0900380 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 Leefbf53792015-12-21 14:18:40 +0900607 result = wilc_set_mac_chnl_num(vif, 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 Lee31f0f692015-12-21 14:18:44 +0900631 wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif));
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) {
Chaehyun Lim245a1862016-01-05 13:26:32 +0900647 strHiddenNetwork.net_info = kmalloc(request->n_ssids * sizeof(struct hidden_network), GFP_KERNEL);
Chaehyun Lim40e05e82016-01-05 13:26:33 +0900648 strHiddenNetwork.n_ssids = request->n_ssids;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900649
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) {
Chaehyun Lim245a1862016-01-05 13:26:32 +0900654 strHiddenNetwork.net_info[i].ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
655 memcpy(strHiddenNetwork.net_info[i].ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
656 strHiddenNetwork.net_info[i].ssid_len = request->ssids[i].ssid_len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900657 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530658 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
Chaehyun Lim40e05e82016-01-05 13:26:33 +0900659 strHiddenNetwork.n_ssids -= 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900660 }
661 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530662 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Glen Leefbf53792015-12-21 14:18:40 +0900663 s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
664 au8ScanChanList,
665 request->n_channels,
666 (const u8 *)request->ie,
667 request->ie_len, CfgScanResult,
668 (void *)priv, &strHiddenNetwork);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900669 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530670 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Glen Leefbf53792015-12-21 14:18:40 +0900671 s32Error = wilc_scan(vif, USER_SCAN, ACTIVE_SCAN,
672 au8ScanChanList,
673 request->n_channels,
674 (const u8 *)request->ie,
675 request->ie_len, CfgScanResult,
676 (void *)priv, NULL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900677 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900678 } else {
679 PRINT_ER("Requested num of scanned channels is greater than the max, supported"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530680 " channels\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900681 }
682
Leo Kime6e12662015-09-16 18:36:03 +0900683 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900684 s32Error = -EBUSY;
685 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
686 }
687
688 return s32Error;
689}
690
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900691static int connect(struct wiphy *wiphy, struct net_device *dev,
692 struct cfg80211_connect_params *sme)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900693{
Leo Kime6e12662015-09-16 18:36:03 +0900694 s32 s32Error = 0;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900695 u32 i;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900696 u8 u8security = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +0900697 enum AUTHTYPE tenuAuth_type = ANY;
Dean Lee576917a2015-06-15 11:58:57 +0900698 char *pcgroup_encrypt_val = NULL;
699 char *pccipher_group = NULL;
700 char *pcwpa_version = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900701
Chaehyun Lim27268872015-09-15 14:06:13 +0900702 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +0900703 struct host_if_drv *pstrWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900704 tstrNetworkInfo *pstrNetworkInfo = NULL;
Glen Leecf601062015-12-21 14:18:39 +0900705 struct wilc_vif *vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900706
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100707 wilc_connecting = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900708 priv = wiphy_priv(wiphy);
Glen Leecf601062015-12-21 14:18:39 +0900709 vif = netdev_priv(priv->dev);
Leo Kim441dc602015-10-12 16:55:35 +0900710 pstrWFIDrv = (struct host_if_drv *)(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900711
Glen Lee31f0f692015-12-21 14:18:44 +0900712 wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(vif));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900713
Johnny Kim8a143302015-06-10 17:06:46 +0900714 PRINT_D(CFG80211_DBG, "Connecting to SSID [%s] on netdev [%p] host if [%p]\n", sme->ssid, dev, priv->hWILCWFIDrv);
Chaehyun Lim3f882892015-08-10 11:33:17 +0900715 if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900716 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
Leo Kimab16ec02015-10-29 12:05:40 +0900717 pstrWFIDrv->p2p_connect = 1;
718 } else {
719 pstrWFIDrv->p2p_connect = 0;
720 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530721 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900722
Leo Kim771fbae2015-11-19 15:56:10 +0900723 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900724 if ((sme->ssid_len == last_scanned_shadow[i].u8SsidLen) &&
725 memcmp(last_scanned_shadow[i].au8ssid,
726 sme->ssid,
727 sme->ssid_len) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900728 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
Leo Kim369a1d32015-12-21 14:18:23 +0900729 if (!sme->bssid) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900730 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
731 break;
732 } else {
Leo Kimf1ab1172015-11-19 15:56:11 +0900733 if (memcmp(last_scanned_shadow[i].au8bssid,
734 sme->bssid,
735 ETH_ALEN) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900736 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
737 break;
738 }
739 }
740 }
741 }
742
Leo Kim771fbae2015-11-19 15:56:10 +0900743 if (i < last_scanned_cnt) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900744 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
745
Leo Kimf1ab1172015-11-19 15:56:11 +0900746 pstrNetworkInfo = &last_scanned_shadow[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900747
748 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
749 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
750 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
751 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
752 } else {
753 s32Error = -ENOENT;
Leo Kim771fbae2015-11-19 15:56:10 +0900754 if (last_scanned_cnt == 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900755 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
756 else
757 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
758
759 goto done;
760 }
761
762 priv->WILC_WFI_wep_default = 0;
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900763 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
764 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900765
766 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
767 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
768
769 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
770
771 if (INFO) {
772 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
773 PRINT_D(CORECONFIG_DBG, "sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]);
774 }
775
776 if (sme->crypto.cipher_group != NO_ENCRYPT) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900777 pcwpa_version = "Default";
778 PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900779 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900780 u8security = ENCRYPT_ENABLED | WEP;
781 pcgroup_encrypt_val = "WEP40";
782 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
783 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
784
785 if (INFO) {
786 for (i = 0; i < sme->key_len; i++)
787 PRINT_D(CORECONFIG_DBG, "WEP Key Value[%d] = %d\n", i, sme->key[i]);
788 }
789 priv->WILC_WFI_wep_default = sme->key_idx;
790 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900791 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900792
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900793 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900794 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900795 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
796 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900797 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900798
Glen Leefbf53792015-12-21 14:18:40 +0900799 wilc_set_wep_default_keyid(vif, sme->key_idx);
800 wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
801 sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900802 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900803 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
804 pcgroup_encrypt_val = "WEP104";
805 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
806
807 priv->WILC_WFI_wep_default = sme->key_idx;
808 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900809 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900810
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900811 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900812 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900813 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
814 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900815 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900816
Glen Leefbf53792015-12-21 14:18:40 +0900817 wilc_set_wep_default_keyid(vif, sme->key_idx);
818 wilc_add_wep_key_bss_sta(vif, sme->key, sme->key_len,
819 sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900820 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900821 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900822 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
823 pcgroup_encrypt_val = "WPA2_TKIP";
824 pccipher_group = "TKIP";
Leo Kima89f7c52015-11-25 11:59:41 +0900825 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900826 u8security = ENCRYPT_ENABLED | WPA2 | AES;
827 pcgroup_encrypt_val = "WPA2_AES";
828 pccipher_group = "AES";
829 }
830 pcwpa_version = "WPA_VERSION_2";
831 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
832 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900833 u8security = ENCRYPT_ENABLED | WPA | TKIP;
834 pcgroup_encrypt_val = "WPA_TKIP";
835 pccipher_group = "TKIP";
Leo Kima89f7c52015-11-25 11:59:41 +0900836 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900837 u8security = ENCRYPT_ENABLED | WPA | AES;
838 pcgroup_encrypt_val = "WPA_AES";
839 pccipher_group = "AES";
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900840 }
841 pcwpa_version = "WPA_VERSION_1";
842
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900843 } else {
844 s32Error = -ENOTSUPP;
845 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
846
847 goto done;
848 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900849 }
850
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900851 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
852 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
853 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
854 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
855 u8security = u8security | TKIP;
Leo Kima89f7c52015-11-25 11:59:41 +0900856 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900857 u8security = u8security | AES;
858 }
859 }
860 }
861
862 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
863
864 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
865 switch (sme->auth_type) {
866 case NL80211_AUTHTYPE_OPEN_SYSTEM:
867 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
868 tenuAuth_type = OPEN_SYSTEM;
869 break;
870
871 case NL80211_AUTHTYPE_SHARED_KEY:
872 tenuAuth_type = SHARED_KEY;
873 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
874 break;
875
876 default:
877 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
878 }
879
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900880 if (sme->crypto.n_akm_suites) {
881 switch (sme->crypto.akm_suites[0]) {
882 case WLAN_AKM_SUITE_8021X:
883 tenuAuth_type = IEEE8021;
884 break;
885
886 default:
887 break;
888 }
889 }
890
891
892 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
893
894 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
895 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
896
Chaehyun Lim866a2c22015-10-02 16:41:21 +0900897 curr_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900898
Leo Kimab16ec02015-10-29 12:05:40 +0900899 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900900 wlan_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900901
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100902 wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900903
Glen Leefbf53792015-12-21 14:18:40 +0900904 s32Error = wilc_set_join_req(vif, pstrNetworkInfo->au8bssid, sme->ssid,
905 sme->ssid_len, sme->ie, sme->ie_len,
906 CfgConnectResult, (void *)priv,
907 u8security, tenuAuth_type,
908 pstrNetworkInfo->u8channel,
909 pstrNetworkInfo->pJoinParams);
Leo Kime6e12662015-09-16 18:36:03 +0900910 if (s32Error != 0) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100911 PRINT_ER("wilc_set_join_req(): Error(%d)\n", s32Error);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900912 s32Error = -ENOENT;
913 goto done;
914 }
915
916done:
917
918 return s32Error;
919}
920
Chaehyun Limb027cde2015-09-14 12:24:04 +0900921static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900922{
Leo Kime6e12662015-09-16 18:36:03 +0900923 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +0900924 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +0900925 struct host_if_drv *pstrWFIDrv;
Glen Leecf601062015-12-21 14:18:39 +0900926 struct wilc_vif *vif;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900927 u8 NullBssid[ETH_ALEN] = {0};
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900928
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100929 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900930 priv = wiphy_priv(wiphy);
Glen Leecf601062015-12-21 14:18:39 +0900931 vif = netdev_priv(priv->dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900932
Leo Kim441dc602015-10-12 16:55:35 +0900933 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Leo Kimab16ec02015-10-29 12:05:40 +0900934 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900935 wlan_channel = INVALID_CHANNEL;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100936 wilc_wlan_set_bssid(priv->dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900937
938 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
939
Leo Kim583d9722015-11-19 15:56:16 +0900940 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +0900941 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +0900942 wilc_ie = false;
Leo Kim1229b1a2015-10-29 12:05:39 +0900943 pstrWFIDrv->p2p_timeout = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900944
Glen Leefbf53792015-12-21 14:18:40 +0900945 s32Error = wilc_disconnect(vif, reason_code);
Leo Kime6e12662015-09-16 18:36:03 +0900946 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900947 PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
948 s32Error = -EINVAL;
949 }
950
951 return s32Error;
952}
953
Chaehyun Lim953d4172015-09-14 12:24:05 +0900954static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
955 bool pairwise,
956 const u8 *mac_addr, struct key_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900957
958{
Leo Kime6e12662015-09-16 18:36:03 +0900959 s32 s32Error = 0, KeyLen = params->key_len;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900960 u32 i;
Chaehyun Lim27268872015-09-15 14:06:13 +0900961 struct wilc_priv *priv;
Arnd Bergmann057d1e92015-06-01 21:06:44 +0200962 const u8 *pu8RxMic = NULL;
963 const u8 *pu8TxMic = NULL;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900964 u8 u8mode = NO_ENCRYPT;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900965 u8 u8gmode = NO_ENCRYPT;
966 u8 u8pmode = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +0900967 enum AUTHTYPE tenuAuth_type = ANY;
Glen Lee76469202015-10-20 17:13:59 +0900968 struct wilc *wl;
Glen Leea4cac482015-12-21 14:18:36 +0900969 struct wilc_vif *vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900970
971 priv = wiphy_priv(wiphy);
Glen Leea4cac482015-12-21 14:18:36 +0900972 vif = netdev_priv(netdev);
973 wl = vif->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900974
975 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
976
Johnny Kim8a143302015-06-10 17:06:46 +0900977 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900978
979 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
980 params->key[1],
981 params->key[2]);
982
983
984 switch (params->cipher) {
985 case WLAN_CIPHER_SUITE_WEP40:
986 case WLAN_CIPHER_SUITE_WEP104:
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900987 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900988 priv->WILC_WFI_wep_default = key_index;
989 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900990 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900991
992 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
993 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
994
995 for (i = 0; i < params->key_len; i++)
996 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
997
998 tenuAuth_type = OPEN_SYSTEM;
999
1000 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
1001 u8mode = ENCRYPT_ENABLED | WEP;
1002 else
1003 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
1004
Glen Leefbf53792015-12-21 14:18:40 +09001005 wilc_add_wep_key_bss_ap(vif, params->key,
1006 params->key_len, key_index,
1007 u8mode, tenuAuth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001008 break;
1009 }
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001010 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001011 priv->WILC_WFI_wep_default = key_index;
1012 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001013 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001014
1015 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
1016 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
1017 if (INFO) {
1018 for (i = 0; i < params->key_len; i++)
1019 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
1020 }
Glen Leefbf53792015-12-21 14:18:40 +09001021 wilc_add_wep_key_bss_sta(vif, params->key,
1022 params->key_len, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001023 }
1024
1025 break;
1026
1027 case WLAN_CIPHER_SUITE_TKIP:
1028 case WLAN_CIPHER_SUITE_CCMP:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001029 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
Leo Kim369a1d32015-12-21 14:18:23 +09001030 if (!priv->wilc_gtk[key_index]) {
Glen Leef3052582015-09-10 12:03:04 +09001031 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001032 priv->wilc_gtk[key_index]->key = NULL;
1033 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001034 }
Leo Kim369a1d32015-12-21 14:18:23 +09001035 if (!priv->wilc_ptk[key_index]) {
Glen Leef3052582015-09-10 12:03:04 +09001036 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001037 priv->wilc_ptk[key_index]->key = NULL;
1038 priv->wilc_ptk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001039 }
1040
1041
1042
Daniel Machon19132212015-08-05 08:18:31 +02001043 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001044 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1045 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1046 else
1047 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1048
1049 priv->wilc_groupkey = u8gmode;
1050
1051 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001052 pu8TxMic = params->key + 24;
1053 pu8RxMic = params->key + 16;
1054 KeyLen = params->key_len - 16;
1055 }
Shraddha Barkecccfc392015-10-12 20:49:19 +05301056 kfree(priv->wilc_gtk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001057
Glen Leef3052582015-09-10 12:03:04 +09001058 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001059 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
Shraddha Barkecccfc392015-10-12 20:49:19 +05301060 kfree(priv->wilc_gtk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001061
1062 if ((params->seq_len) > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001063 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001064 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001065 }
1066
1067 priv->wilc_gtk[key_index]->cipher = params->cipher;
1068 priv->wilc_gtk[key_index]->key_len = params->key_len;
1069 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1070
1071 if (INFO) {
1072 for (i = 0; i < params->key_len; i++)
1073 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1074 for (i = 0; i < params->seq_len; i++)
1075 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1076 }
1077
1078
Glen Leefbf53792015-12-21 14:18:40 +09001079 wilc_add_rx_gtk(vif, params->key, KeyLen,
1080 key_index, params->seq_len,
1081 params->seq, pu8RxMic,
1082 pu8TxMic, AP_MODE, u8gmode);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001083
1084 } else {
1085 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]);
1086
1087 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1088 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1089 else
1090 u8pmode = priv->wilc_groupkey | AES;
1091
1092
1093 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001094 pu8TxMic = params->key + 24;
1095 pu8RxMic = params->key + 16;
1096 KeyLen = params->key_len - 16;
1097 }
1098
Shraddha Barkecccfc392015-10-12 20:49:19 +05301099 kfree(priv->wilc_ptk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001100
Glen Leef3052582015-09-10 12:03:04 +09001101 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001102
Shraddha Barkecccfc392015-10-12 20:49:19 +05301103 kfree(priv->wilc_ptk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001104
1105 if ((params->seq_len) > 0)
Glen Leef3052582015-09-10 12:03:04 +09001106 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001107
1108 if (INFO) {
1109 for (i = 0; i < params->key_len; i++)
1110 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1111
1112 for (i = 0; i < params->seq_len; i++)
1113 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1114 }
1115
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001116 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001117
1118 if ((params->seq_len) > 0)
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001119 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001120
1121 priv->wilc_ptk[key_index]->cipher = params->cipher;
1122 priv->wilc_ptk[key_index]->key_len = params->key_len;
1123 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1124
Glen Leefbf53792015-12-21 14:18:40 +09001125 wilc_add_ptk(vif, params->key, KeyLen,
1126 mac_addr, pu8RxMic, pu8TxMic,
1127 AP_MODE, u8pmode, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001128 }
1129 break;
1130 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001131
1132 {
1133 u8mode = 0;
Daniel Machon19132212015-08-05 08:18:31 +02001134 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001135 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001136 pu8RxMic = params->key + 24;
1137 pu8TxMic = params->key + 16;
1138 KeyLen = params->key_len - 16;
1139 }
1140
Glen Lee1f435d22015-12-21 14:18:37 +09001141 if (!g_gtk_keys_saved && netdev == wl->vif[0]->ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001142 g_add_gtk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001143 g_add_gtk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001144 if (!mac_addr) {
1145 g_add_gtk_key_params.mac_addr = NULL;
1146 } else {
Glen Leef3052582015-09-10 12:03:04 +09001147 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001148 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1149 }
1150 g_key_gtk_params.key_len = params->key_len;
1151 g_key_gtk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001152 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001153 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1154 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001155 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001156 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1157 }
1158 g_key_gtk_params.cipher = params->cipher;
1159
1160 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1161 g_key_gtk_params.key[1],
1162 g_key_gtk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001163 g_gtk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001164 }
1165
Glen Leefbf53792015-12-21 14:18:40 +09001166 wilc_add_rx_gtk(vif, params->key, KeyLen,
1167 key_index, params->seq_len,
1168 params->seq, pu8RxMic,
1169 pu8TxMic, STATION_MODE,
1170 u8mode);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001171 } else {
1172 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001173 pu8RxMic = params->key + 24;
1174 pu8TxMic = params->key + 16;
1175 KeyLen = params->key_len - 16;
1176 }
1177
Glen Lee1f435d22015-12-21 14:18:37 +09001178 if (!g_ptk_keys_saved && netdev == wl->vif[0]->ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001179 g_add_ptk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001180 g_add_ptk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001181 if (!mac_addr) {
1182 g_add_ptk_key_params.mac_addr = NULL;
1183 } else {
Glen Leef3052582015-09-10 12:03:04 +09001184 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001185 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1186 }
1187 g_key_ptk_params.key_len = params->key_len;
1188 g_key_ptk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001189 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001190 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1191 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001192 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001193 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1194 }
1195 g_key_ptk_params.cipher = params->cipher;
1196
1197 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1198 g_key_ptk_params.key[1],
1199 g_key_ptk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001200 g_ptk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001201 }
1202
Glen Leefbf53792015-12-21 14:18:40 +09001203 wilc_add_ptk(vif, params->key, KeyLen,
1204 mac_addr, pu8RxMic, pu8TxMic,
1205 STATION_MODE, u8mode, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001206 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1207 if (INFO) {
1208 for (i = 0; i < params->key_len; i++)
1209 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1210 }
1211 }
1212 }
1213 break;
1214
1215 default:
1216 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
1217 s32Error = -ENOTSUPP;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001218 }
1219
1220 return s32Error;
1221}
1222
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001223static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1224 u8 key_index,
1225 bool pairwise,
1226 const u8 *mac_addr)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001227{
Chaehyun Lim27268872015-09-15 14:06:13 +09001228 struct wilc_priv *priv;
Glen Lee692e2ac2015-10-20 17:14:00 +09001229 struct wilc *wl;
Glen Leea4cac482015-12-21 14:18:36 +09001230 struct wilc_vif *vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001231
1232 priv = wiphy_priv(wiphy);
Glen Leea4cac482015-12-21 14:18:36 +09001233 vif = netdev_priv(netdev);
1234 wl = vif->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001235
Glen Lee1f435d22015-12-21 14:18:37 +09001236 if (netdev == wl->vif[0]->ndev) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09001237 g_ptk_keys_saved = false;
1238 g_gtk_keys_saved = false;
1239 g_wep_keys_saved = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001240
Shraddha Barkecccfc392015-10-12 20:49:19 +05301241 kfree(g_key_wep_params.key);
1242 g_key_wep_params.key = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001243
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001244 if ((priv->wilc_gtk[key_index]) != NULL) {
Shraddha Barkecccfc392015-10-12 20:49:19 +05301245 kfree(priv->wilc_gtk[key_index]->key);
1246 priv->wilc_gtk[key_index]->key = NULL;
1247 kfree(priv->wilc_gtk[key_index]->seq);
1248 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001249
Chaehyun Lim49188af2015-08-11 10:32:41 +09001250 kfree(priv->wilc_gtk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001251 priv->wilc_gtk[key_index] = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001252 }
1253
1254 if ((priv->wilc_ptk[key_index]) != NULL) {
Shraddha Barkecccfc392015-10-12 20:49:19 +05301255 kfree(priv->wilc_ptk[key_index]->key);
1256 priv->wilc_ptk[key_index]->key = NULL;
1257 kfree(priv->wilc_ptk[key_index]->seq);
1258 priv->wilc_ptk[key_index]->seq = NULL;
Chaehyun Lim49188af2015-08-11 10:32:41 +09001259 kfree(priv->wilc_ptk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001260 priv->wilc_ptk[key_index] = NULL;
1261 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001262
Shraddha Barkecccfc392015-10-12 20:49:19 +05301263 kfree(g_key_ptk_params.key);
1264 g_key_ptk_params.key = NULL;
1265 kfree(g_key_ptk_params.seq);
1266 g_key_ptk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001267
Shraddha Barkecccfc392015-10-12 20:49:19 +05301268 kfree(g_key_gtk_params.key);
1269 g_key_gtk_params.key = NULL;
1270 kfree(g_key_gtk_params.seq);
1271 g_key_gtk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001272
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001273 wilc_set_machw_change_vir_if(netdev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001274 }
1275
1276 if (key_index >= 0 && key_index <= 3) {
Chaehyun Lim2cc46832015-08-07 09:02:01 +09001277 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001278 priv->WILC_WFI_wep_key_len[key_index] = 0;
1279
1280 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
Glen Leefbf53792015-12-21 14:18:40 +09001281 wilc_remove_wep_key(vif, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001282 } else {
1283 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001284 wilc_remove_key(priv->hWILCWFIDrv, mac_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001285 }
1286
Leo Kimaaed3292015-10-12 16:55:38 +09001287 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001288}
1289
Chaehyun Limf4893df2015-09-14 12:24:07 +09001290static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1291 bool pairwise,
1292 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001293{
Chaehyun Lim27268872015-09-15 14:06:13 +09001294 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001295 struct key_params key_params;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001296 u32 i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001297
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001298 priv = wiphy_priv(wiphy);
1299
1300
Alison Schofield3604af52015-10-12 13:22:44 -07001301 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001302 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1303
1304 key_params.key = priv->wilc_gtk[key_index]->key;
1305 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1306 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1307 key_params.seq = priv->wilc_gtk[key_index]->seq;
1308 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1309 if (INFO) {
1310 for (i = 0; i < key_params.key_len; i++)
1311 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1312 }
1313 } else {
1314 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1315
1316 key_params.key = priv->wilc_ptk[key_index]->key;
1317 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1318 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1319 key_params.seq = priv->wilc_ptk[key_index]->seq;
1320 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1321 }
1322
1323 callback(cookie, &key_params);
1324
Leo Kima89f7c52015-11-25 11:59:41 +09001325 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001326}
1327
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001328static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1329 bool unicast, bool multicast)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001330{
Chaehyun Lim27268872015-09-15 14:06:13 +09001331 struct wilc_priv *priv;
Glen Leecf601062015-12-21 14:18:39 +09001332 struct wilc_vif *vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001333
1334 priv = wiphy_priv(wiphy);
Glen Leecf601062015-12-21 14:18:39 +09001335 vif = netdev_priv(priv->dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001336
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301337 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001338
1339 if (key_index != priv->WILC_WFI_wep_default) {
Glen Leefbf53792015-12-21 14:18:40 +09001340 wilc_set_wep_default_keyid(vif, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001341 }
1342
Leo Kimaaed3292015-10-12 16:55:38 +09001343 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001344}
1345
Chaehyun Limf06f5622015-09-14 12:24:18 +09001346static int get_station(struct wiphy *wiphy, struct net_device *dev,
1347 const u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001348{
Chaehyun Lim27268872015-09-15 14:06:13 +09001349 struct wilc_priv *priv;
Glen Leea4cac482015-12-21 14:18:36 +09001350 struct wilc_vif *vif;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001351 u32 i = 0;
1352 u32 associatedsta = 0;
1353 u32 inactive_time = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001354 priv = wiphy_priv(wiphy);
Glen Leea4cac482015-12-21 14:18:36 +09001355 vif = netdev_priv(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001356
Glen Leea4cac482015-12-21 14:18:36 +09001357 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001358 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1359
1360 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1361
1362 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001363 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1364 associatedsta = i;
1365 break;
1366 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001367 }
1368
1369 if (associatedsta == -1) {
Leo Kimaaed3292015-10-12 16:55:38 +09001370 PRINT_ER("Station required is not associated\n");
1371 return -ENOENT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001372 }
1373
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001374 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001375
Glen Leefbf53792015-12-21 14:18:40 +09001376 wilc_get_inactive_time(vif, mac, &inactive_time);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001377 sinfo->inactive_time = 1000 * inactive_time;
1378 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001379 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001380
Glen Leea4cac482015-12-21 14:18:36 +09001381 if (vif->iftype == STATION_MODE) {
Leo Kim03e7b9c2015-10-12 16:55:58 +09001382 struct rf_info strStatistics;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001383
Glen Leefbf53792015-12-21 14:18:40 +09001384 wilc_get_statistics(vif, &strStatistics);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001385
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001386 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
Chandra S Gorentla62129902015-08-05 22:11:57 +05301387 BIT(NL80211_STA_INFO_RX_PACKETS) |
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001388 BIT(NL80211_STA_INFO_TX_PACKETS) |
1389 BIT(NL80211_STA_INFO_TX_FAILED) |
1390 BIT(NL80211_STA_INFO_TX_BITRATE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001391
Leo Kim00c8dfc2015-10-29 12:05:30 +09001392 sinfo->signal = strStatistics.rssi;
Leo Kim9b992742015-10-29 12:05:32 +09001393 sinfo->rx_packets = strStatistics.rx_cnt;
Leo Kim54160372015-10-29 12:05:33 +09001394 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1395 sinfo->tx_failed = strStatistics.tx_fail_cnt;
Leo Kim5babeec2015-10-29 12:05:29 +09001396 sinfo->txrate.legacy = strStatistics.link_speed * 10;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001397
Leo Kim5babeec2015-10-29 12:05:29 +09001398 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1399 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001400 wilc_enable_tcp_ack_filter(true);
Leo Kim5babeec2015-10-29 12:05:29 +09001401 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001402 wilc_enable_tcp_ack_filter(false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001403
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001404 PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
1405 sinfo->tx_failed, sinfo->txrate.legacy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001406 }
Leo Kimaaed3292015-10-12 16:55:38 +09001407 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001408}
1409
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001410static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1411 struct bss_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001412{
1413 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1414 return 0;
1415}
1416
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001417static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001418{
Leo Kime6e12662015-09-16 18:36:03 +09001419 s32 s32Error = 0;
Leo Kim95296502015-10-05 15:25:46 +09001420 struct cfg_param_val pstrCfgParamVal;
Chaehyun Lim27268872015-09-15 14:06:13 +09001421 struct wilc_priv *priv;
Glen Leecf601062015-12-21 14:18:39 +09001422 struct wilc_vif *vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001423
1424 priv = wiphy_priv(wiphy);
Glen Leecf601062015-12-21 14:18:39 +09001425 vif = netdev_priv(priv->dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001426
Tony Cho87c05b22015-10-12 16:56:07 +09001427 pstrCfgParamVal.flag = 0;
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301428 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001429
1430 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1431 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1432 priv->dev->ieee80211_ptr->wiphy->retry_short);
Tony Cho87c05b22015-10-12 16:56:07 +09001433 pstrCfgParamVal.flag |= RETRY_SHORT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001434 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1435 }
1436 if (changed & WIPHY_PARAM_RETRY_LONG) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001437 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 +09001438 pstrCfgParamVal.flag |= RETRY_LONG;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001439 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001440 }
1441 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1442 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 +09001443 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001444 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001445 }
1446
1447 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1448 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1449
Tony Cho87c05b22015-10-12 16:56:07 +09001450 pstrCfgParamVal.flag |= RTS_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001451 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001452 }
1453
1454 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
Glen Leefbf53792015-12-21 14:18:40 +09001455 s32Error = wilc_hif_set_cfg(vif, &pstrCfgParamVal);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001456 if (s32Error)
1457 PRINT_ER("Error in setting WIPHY PARAMS\n");
1458
1459
1460 return s32Error;
1461}
Arnd Bergmanne5af0562015-05-29 22:52:12 +02001462
Chaehyun Lim4d466572015-09-14 12:24:22 +09001463static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1464 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001465{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001466 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001467 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001468 u8 flag = 0;
Glen Leecf601062015-12-21 14:18:39 +09001469 struct wilc_vif *vif;
Chaehyun Lim27268872015-09-15 14:06:13 +09001470 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001471
Glen Leecf601062015-12-21 14:18:39 +09001472 vif = netdev_priv(priv->dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001473 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1474
1475
1476 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001477 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001478 ETH_ALEN)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001479 flag = PMKID_FOUND;
1480 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1481 break;
1482 }
1483 }
1484 if (i < WILC_MAX_NUM_PMKIDS) {
1485 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001486 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001487 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001488 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001489 PMKID_LEN);
1490 if (!(flag == PMKID_FOUND))
1491 priv->pmkid_list.numpmkid++;
1492 } else {
1493 PRINT_ER("Invalid PMKID index\n");
1494 s32Error = -EINVAL;
1495 }
1496
1497 if (!s32Error) {
1498 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
Glen Leefbf53792015-12-21 14:18:40 +09001499 s32Error = wilc_set_pmkid_info(vif, &priv->pmkid_list);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001500 }
1501 return s32Error;
1502}
1503
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001504static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1505 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001506{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001507 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001508 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001509
Chaehyun Lim27268872015-09-15 14:06:13 +09001510 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001511
1512 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1513
1514 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001515 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001516 ETH_ALEN)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001517 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
Leo Kimcd1e6cb2015-10-05 15:25:45 +09001518 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001519 break;
1520 }
1521 }
1522
1523 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1524 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001525 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001526 priv->pmkid_list.pmkidlist[i + 1].bssid,
1527 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001528 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001529 priv->pmkid_list.pmkidlist[i].pmkid,
1530 PMKID_LEN);
1531 }
1532 priv->pmkid_list.numpmkid--;
1533 } else {
1534 s32Error = -EINVAL;
1535 }
1536
1537 return s32Error;
1538}
1539
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001540static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001541{
Chaehyun Lim27268872015-09-15 14:06:13 +09001542 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001543
1544 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
1545
Leo Kima949f902015-10-05 15:25:44 +09001546 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001547
1548 return 0;
1549}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001550
Arnd Bergmann1608c402015-11-16 15:04:53 +01001551static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001552{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001553 u32 index = 0;
1554 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001555
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001556 u8 op_channel_attr_index = 0;
1557 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001558
1559 while (index < len) {
1560 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001561 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001562 }
1563
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301564 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001565 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301566 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001567 op_channel_attr_index = index;
Leo Kima89f7c52015-11-25 11:59:41 +09001568 index += buf[index + 1] + 3;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001569 }
Leo Kim0bd82742015-11-19 15:56:14 +09001570 if (wlan_channel != INVALID_CHANNEL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001571 if (channel_list_attr_index) {
1572 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1573 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1574 if (buf[i] == 0x51) {
1575 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
Leo Kim0bd82742015-11-19 15:56:14 +09001576 buf[j] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001577 }
1578 break;
1579 }
1580 }
1581 }
Leo Kima89f7c52015-11-25 11:59:41 +09001582
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001583 if (op_channel_attr_index) {
1584 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1585 buf[op_channel_attr_index + 6] = 0x51;
Leo Kim0bd82742015-11-19 15:56:14 +09001586 buf[op_channel_attr_index + 7] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001587 }
1588 }
1589}
1590
Arnd Bergmann1608c402015-11-16 15:04:53 +01001591static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001592{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001593 u32 index = 0;
1594 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001595
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001596 u8 op_channel_attr_index = 0;
1597 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001598
1599 while (index < len) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001600 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001601 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001602
1603 break;
1604 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001605
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301606 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001607 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301608 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001609 op_channel_attr_index = index;
Leo Kima89f7c52015-11-25 11:59:41 +09001610 index += buf[index + 1] + 3;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001611 }
Leo Kim0bd82742015-11-19 15:56:14 +09001612 if (wlan_channel != INVALID_CHANNEL && bOperChan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001613 if (channel_list_attr_index) {
1614 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1615 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1616 if (buf[i] == 0x51) {
1617 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
Leo Kim0bd82742015-11-19 15:56:14 +09001618 buf[j] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001619 }
1620 break;
1621 }
1622 }
1623 }
Leo Kima89f7c52015-11-25 11:59:41 +09001624
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001625 if (op_channel_attr_index) {
1626 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1627 buf[op_channel_attr_index + 6] = 0x51;
Leo Kim0bd82742015-11-19 15:56:14 +09001628 buf[op_channel_attr_index + 7] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001629 }
1630 }
1631}
1632
Chaehyun Limfbc2fe12015-09-15 14:06:16 +09001633void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001634{
Chaehyun Lim27268872015-09-15 14:06:13 +09001635 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001636 u32 header, pkt_offset;
Leo Kim441dc602015-10-12 16:55:35 +09001637 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001638 u32 i = 0;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001639 s32 s32Freq;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001640
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001641 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001642 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001643
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001644 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001645
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001646 pkt_offset = GET_PKT_OFFSET(header);
1647
1648 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1649 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1650 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001651 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001652 return;
1653 } else {
1654 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
1655 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],
1656 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001657 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001658 } else {
1659 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],
1660 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001661 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001662 }
1663 return;
1664 }
1665 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001666 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
1667
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001668 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001669
1670 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1671 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
1672
Leo Kim1229b1a2015-10-29 12:05:39 +09001673 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001674 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
1675 return;
1676 }
1677 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001678 switch (buff[ACTION_SUBTYPE_ID]) {
1679 case GAS_INTIAL_REQ:
1680 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
1681 break;
1682
1683 case GAS_INTIAL_RSP:
1684 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
1685 break;
1686
1687 case PUBLIC_ACT_VENDORSPEC:
Leo Kim881eb5d2015-11-19 15:56:15 +09001688 if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001689 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
Leo Kima25d5182015-11-19 15:56:19 +09001690 if (!wilc_ie) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001691 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
Leo Kim86685942015-11-19 15:56:18 +09001692 if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09001693 p2p_recv_random = buff[i + 6];
Leo Kima25d5182015-11-19 15:56:19 +09001694 wilc_ie = true;
Leo Kimb84a3ac2015-11-19 15:56:17 +09001695 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", p2p_recv_random);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001696 break;
1697 }
1698 }
1699 }
1700 }
Leo Kimb84a3ac2015-11-19 15:56:17 +09001701 if (p2p_local_random > p2p_recv_random) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001702 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1703 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1704 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
Leo Kim881eb5d2015-11-19 15:56:15 +09001705 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001706 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
1707 break;
1708 }
1709 }
1710 }
Leo Kim583d9722015-11-19 15:56:16 +09001711 } else {
Leo Kimb84a3ac2015-11-19 15:56:17 +09001712 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 +09001713 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001714 }
1715
1716
Leo Kima25d5182015-11-19 15:56:19 +09001717 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 +09001718 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001719 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001720 return;
1721 }
1722 break;
1723
1724 default:
1725 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
1726 break;
1727 }
1728 }
1729 }
1730
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001731 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001732 }
1733}
1734
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001735static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
1736{
1737 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
1738
1739
1740 kfree(pv_data->buff);
1741 kfree(pv_data);
1742}
1743
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001744static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
1745{
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
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301750 PRINT_D(HOSTINF_DBG, "Remain on channel ready\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001751
Dean Lee72ed4dc2015-06-12 14:11:44 +09001752 priv->bInP2PlistenState = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001753
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001754 cfg80211_ready_on_channel(priv->wdev,
1755 priv->strRemainOnChanParams.u64ListenCookie,
1756 priv->strRemainOnChanParams.pstrListenChan,
1757 priv->strRemainOnChanParams.u32ListenDuration,
1758 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001759}
1760
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001761static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001762{
Chaehyun Lim27268872015-09-15 14:06:13 +09001763 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001764
Chaehyun Lim27268872015-09-15 14:06:13 +09001765 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001766
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001767 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301768 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001769
Dean Lee72ed4dc2015-06-12 14:11:44 +09001770 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001771
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001772 cfg80211_remain_on_channel_expired(priv->wdev,
1773 priv->strRemainOnChanParams.u64ListenCookie,
1774 priv->strRemainOnChanParams.pstrListenChan,
1775 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001776 } else {
1777 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
1778 , priv->strRemainOnChanParams.u32ListenSessionID);
1779 }
1780}
1781
Chaehyun Lim6d19d692015-09-14 12:24:25 +09001782static int remain_on_channel(struct wiphy *wiphy,
1783 struct wireless_dev *wdev,
1784 struct ieee80211_channel *chan,
1785 unsigned int duration, u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001786{
Leo Kime6e12662015-09-16 18:36:03 +09001787 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09001788 struct wilc_priv *priv;
Glen Leecf601062015-12-21 14:18:39 +09001789 struct wilc_vif *vif;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001790
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001791 priv = wiphy_priv(wiphy);
Glen Leecf601062015-12-21 14:18:39 +09001792 vif = netdev_priv(priv->dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001793
1794 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
1795
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001796
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001797 if (wdev->iftype == NL80211_IFTYPE_AP) {
1798 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
1799 return s32Error;
1800 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001801
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001802 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001803
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001804 priv->strRemainOnChanParams.pstrListenChan = chan;
1805 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001806 priv->strRemainOnChanParams.u32ListenDuration = duration;
1807 priv->strRemainOnChanParams.u32ListenSessionID++;
1808
Glen Leefbf53792015-12-21 14:18:40 +09001809 s32Error = wilc_remain_on_channel(vif,
1810 priv->strRemainOnChanParams.u32ListenSessionID,
1811 duration, chan->hw_value,
1812 WILC_WFI_RemainOnChannelExpired,
1813 WILC_WFI_RemainOnChannelReady, (void *)priv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001814
1815 return s32Error;
1816}
1817
Chaehyun Lim1dd54402015-09-14 12:24:26 +09001818static int cancel_remain_on_channel(struct wiphy *wiphy,
1819 struct wireless_dev *wdev,
1820 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001821{
Leo Kime6e12662015-09-16 18:36:03 +09001822 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09001823 struct wilc_priv *priv;
Glen Leecf601062015-12-21 14:18:39 +09001824 struct wilc_vif *vif;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001825
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001826 priv = wiphy_priv(wiphy);
Glen Leecf601062015-12-21 14:18:39 +09001827 vif = netdev_priv(priv->dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001828
1829 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
1830
Glen Leefbf53792015-12-21 14:18:40 +09001831 s32Error = wilc_listen_state_expired(vif, priv->strRemainOnChanParams.u32ListenSessionID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001832 return s32Error;
1833}
Leo Kima89f7c52015-11-25 11:59:41 +09001834
Chaehyun Limc1560322015-09-22 18:34:51 +09001835static int mgmt_tx(struct wiphy *wiphy,
1836 struct wireless_dev *wdev,
1837 struct cfg80211_mgmt_tx_params *params,
1838 u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001839{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001840 struct ieee80211_channel *chan = params->chan;
1841 unsigned int wait = params->wait;
1842 const u8 *buf = params->buf;
1843 size_t len = params->len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001844 const struct ieee80211_mgmt *mgmt;
1845 struct p2p_mgmt_data *mgmt_tx;
Chaehyun Lim27268872015-09-15 14:06:13 +09001846 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09001847 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001848 u32 i;
Glen Leea4cac482015-12-21 14:18:36 +09001849 struct wilc_vif *vif;
Leo Kim86685942015-11-19 15:56:18 +09001850 u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001851
Glen Leea4cac482015-12-21 14:18:36 +09001852 vif = netdev_priv(wdev->netdev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001853 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001854 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001855
1856 *cookie = (unsigned long)buf;
1857 priv->u64tx_cookie = *cookie;
1858 mgmt = (const struct ieee80211_mgmt *) buf;
1859
1860 if (ieee80211_is_mgmt(mgmt->frame_control)) {
Glen Leef3052582015-09-10 12:03:04 +09001861 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
Leo Kim369a1d32015-12-21 14:18:23 +09001862 if (!mgmt_tx) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001863 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
Leo Kime6e12662015-09-16 18:36:03 +09001864 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001865 }
Glen Leef3052582015-09-10 12:03:04 +09001866 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
Leo Kim369a1d32015-12-21 14:18:23 +09001867 if (!mgmt_tx->buff) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001868 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
Tony Chof638dd32015-09-07 19:09:31 +09001869 kfree(mgmt_tx);
Leo Kime6e12662015-09-16 18:36:03 +09001870 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001871 }
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001872 memcpy(mgmt_tx->buff, buf, len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001873 mgmt_tx->size = len;
1874
1875
1876 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
1877 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
1878 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Glen Leefbf53792015-12-21 14:18:40 +09001879 wilc_set_mac_chnl_num(vif, chan->hw_value);
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001880 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001881 } else if (ieee80211_is_action(mgmt->frame_control)) {
Chaehyun Limd85f5322015-06-11 14:35:54 +09001882 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001883
1884
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001885 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001886 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
1887 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
1888 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Glen Leefbf53792015-12-21 14:18:40 +09001889 wilc_set_mac_chnl_num(vif,
1890 chan->hw_value);
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001891 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001892 }
1893 switch (buf[ACTION_SUBTYPE_ID]) {
1894 case GAS_INTIAL_REQ:
1895 {
1896 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
1897 break;
1898 }
1899
1900 case GAS_INTIAL_RSP:
1901 {
1902 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
1903 break;
1904 }
1905
1906 case PUBLIC_ACT_VENDORSPEC:
1907 {
Leo Kim881eb5d2015-11-19 15:56:15 +09001908 if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001909 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09001910 if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
Leo Kim583d9722015-11-19 15:56:16 +09001911 get_random_bytes(&p2p_local_random, 1);
1912 p2p_local_random++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001913 }
1914 }
1915
1916 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1917 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09001918 if (p2p_local_random > p2p_recv_random) {
1919 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 +09001920
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001921 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
Leo Kim881eb5d2015-11-19 15:56:15 +09001922 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001923 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
Glen Leea4cac482015-12-21 14:18:36 +09001924 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, vif->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001925 else
Glen Leea4cac482015-12-21 14:18:36 +09001926 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, vif->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001927 break;
1928 }
1929 }
1930
1931 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
Leo Kim86685942015-11-19 15:56:18 +09001932 memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
1933 mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001934 mgmt_tx->size = buf_len;
1935 }
Leo Kim583d9722015-11-19 15:56:16 +09001936 } else {
Leo Kimb84a3ac2015-11-19 15:56:17 +09001937 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 +09001938 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001939 }
1940
1941 } else {
1942 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
1943 }
1944
1945 break;
1946 }
1947
1948 default:
1949 {
1950 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
1951 break;
1952 }
1953 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001954 }
1955
1956 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 +09001957 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001958
Leo Kim1229b1a2015-10-29 12:05:39 +09001959 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n",
1960 jiffies, pstrWFIDrv->p2p_timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001961 }
1962
Glen Lee829c4772015-10-29 12:18:44 +09001963 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
1964 mgmt_tx->buff, mgmt_tx->size,
Glen Leec9d48342015-10-01 16:03:43 +09001965 WILC_WFI_mgmt_tx_complete);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001966 } else {
1967 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
1968 }
Leo Kimaaed3292015-10-12 16:55:38 +09001969 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001970}
1971
Chaehyun Lim85c587a2015-09-22 18:34:50 +09001972static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
1973 struct wireless_dev *wdev,
1974 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001975{
Chaehyun Lim27268872015-09-15 14:06:13 +09001976 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09001977 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001978
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001979 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001980 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001981
1982
1983 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
Leo Kim1229b1a2015-10-29 12:05:39 +09001984 pstrWFIDrv->p2p_timeout = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001985
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +01001986 if (!priv->bInP2PlistenState) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001987 cfg80211_remain_on_channel_expired(priv->wdev,
1988 priv->strRemainOnChanParams.u64ListenCookie,
1989 priv->strRemainOnChanParams.pstrListenChan,
1990 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001991 }
1992
1993 return 0;
1994}
1995
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09001996void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
1997 u16 frame_type, bool reg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001998{
Chaehyun Lim27268872015-09-15 14:06:13 +09001999 struct wilc_priv *priv;
Glen Leea4cac482015-12-21 14:18:36 +09002000 struct wilc_vif *vif;
Glen Lee1b869352015-10-20 17:14:01 +09002001 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002002
2003 priv = wiphy_priv(wiphy);
Glen Leea4cac482015-12-21 14:18:36 +09002004 vif = netdev_priv(priv->wdev->netdev);
2005 wl = vif->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002006
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002007 if (!frame_type)
2008 return;
2009
2010 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
2011 switch (frame_type) {
2012 case PROBE_REQ:
2013 {
Glen Leea4cac482015-12-21 14:18:36 +09002014 vif->g_struct_frame_reg[0].frame_type = frame_type;
2015 vif->g_struct_frame_reg[0].reg = reg;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002016 }
2017 break;
2018
2019 case ACTION:
2020 {
Glen Leea4cac482015-12-21 14:18:36 +09002021 vif->g_struct_frame_reg[1].frame_type = frame_type;
2022 vif->g_struct_frame_reg[1].reg = reg;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002023 }
2024 break;
2025
2026 default:
2027 {
2028 break;
2029 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002030 }
Leo Kima89f7c52015-11-25 11:59:41 +09002031
Glen Lee1b869352015-10-20 17:14:01 +09002032 if (!wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002033 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
2034 return;
2035 }
Glen Leefbf53792015-12-21 14:18:40 +09002036 wilc_frame_register(vif, frame_type, reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002037}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002038
Chaehyun Lima8047e22015-09-22 18:34:48 +09002039static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
2040 s32 rssi_thold, u32 rssi_hyst)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002041{
2042 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2043 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002044}
Leo Kima89f7c52015-11-25 11:59:41 +09002045
Chaehyun Limbdb63382015-09-14 12:24:19 +09002046static int dump_station(struct wiphy *wiphy, struct net_device *dev,
2047 int idx, u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002048{
Chaehyun Lim27268872015-09-15 14:06:13 +09002049 struct wilc_priv *priv;
Glen Leecf601062015-12-21 14:18:39 +09002050 struct wilc_vif *vif;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002051
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002052 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2053
2054 if (idx != 0)
2055 return -ENOENT;
2056
2057 priv = wiphy_priv(wiphy);
Glen Leecf601062015-12-21 14:18:39 +09002058 vif = netdev_priv(priv->dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002059
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002060 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002061
Glen Leefbf53792015-12-21 14:18:40 +09002062 wilc_get_rssi(vif, &sinfo->signal);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002063
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002064 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002065}
2066
Chaehyun Lim46530672015-09-22 18:34:46 +09002067static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2068 bool enabled, int timeout)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002069{
Chaehyun Lim27268872015-09-15 14:06:13 +09002070 struct wilc_priv *priv;
Glen Leecf601062015-12-21 14:18:39 +09002071 struct wilc_vif *vif;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002072
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002073 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2074
Leo Kim369a1d32015-12-21 14:18:23 +09002075 if (!wiphy)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002076 return -ENOENT;
2077
2078 priv = wiphy_priv(wiphy);
Glen Leecf601062015-12-21 14:18:39 +09002079 vif = netdev_priv(priv->dev);
Leo Kim369a1d32015-12-21 14:18:23 +09002080 if (!priv->hWILCWFIDrv) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002081 PRINT_ER("Driver is NULL\n");
2082 return -EIO;
2083 }
2084
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002085 if (wilc_enable_ps)
Glen Leefbf53792015-12-21 14:18:40 +09002086 wilc_set_power_mgmt(vif, enabled, timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002087
2088
Leo Kime6e12662015-09-16 18:36:03 +09002089 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002090}
Glen Lee108b3432015-09-16 18:53:20 +09002091
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002092static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2093 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002094{
Chaehyun Lim27268872015-09-15 14:06:13 +09002095 struct wilc_priv *priv;
Glen Leea4cac482015-12-21 14:18:36 +09002096 struct wilc_vif *vif;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002097 u8 interface_type;
Chaehyun Limd85f5322015-06-11 14:35:54 +09002098 u16 TID = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002099 u8 i;
Glen Lee299382c2015-10-20 17:13:56 +09002100 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002101
Glen Leea4cac482015-12-21 14:18:36 +09002102 vif = netdev_priv(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002103 priv = wiphy_priv(wiphy);
Glen Leea4cac482015-12-21 14:18:36 +09002104 wl = vif->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002105
2106 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2107 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
Leo Kim583d9722015-11-19 15:56:16 +09002108 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +09002109 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +09002110 wilc_ie = false;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002111 wilc_optaining_ip = false;
2112 del_timer(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002113 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
Leo Kima89f7c52015-11-25 11:59:41 +09002114
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002115 if (g_ptk_keys_saved && g_gtk_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002116 wilc_set_machw_change_vir_if(dev, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002117 }
2118
2119 switch (type) {
2120 case NL80211_IFTYPE_STATION:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002121 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002122 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002123
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002124 dev->ieee80211_ptr->iftype = type;
2125 priv->wdev->iftype = type;
Glen Leea4cac482015-12-21 14:18:36 +09002126 vif->monitor_flag = 0;
2127 vif->iftype = STATION_MODE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002128
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002129 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
Glen Leea4cac482015-12-21 14:18:36 +09002130 interface_type = vif->iftype;
2131 vif->iftype = STATION_MODE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002132
Glen Lee299382c2015-10-20 17:13:56 +09002133 if (wl->initialized) {
Glen Leefbf53792015-12-21 14:18:40 +09002134 wilc_del_all_rx_ba_session(vif, wl->vif[0]->bssid,
2135 TID);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002136 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002137
Glen Lee299382c2015-10-20 17:13:56 +09002138 up(&wl->cfg_event);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002139
Glen Lee53dc0cf2015-10-20 17:13:57 +09002140 wilc1000_wlan_deinit(dev);
Glen Leea4cac482015-12-21 14:18:36 +09002141 wilc1000_wlan_init(dev, vif);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002142 wilc_initialized = 1;
Glen Leea4cac482015-12-21 14:18:36 +09002143 vif->iftype = interface_type;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002144
Glen Lee31f0f692015-12-21 14:18:44 +09002145 wilc_set_wfi_drv_handler(vif,
2146 wilc_get_vif_idx(wl->vif[0]));
Glen Leefbf53792015-12-21 14:18:40 +09002147 wilc_set_mac_address(wl->vif[0], wl->vif[0]->src_addr);
2148 wilc_set_operation_mode(vif, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002149
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002150 if (g_wep_keys_saved) {
Glen Leefbf53792015-12-21 14:18:40 +09002151 wilc_set_wep_default_keyid(wl->vif[0],
2152 g_key_wep_params.key_idx);
2153 wilc_add_wep_key_bss_sta(wl->vif[0],
2154 g_key_wep_params.key,
2155 g_key_wep_params.key_len,
2156 g_key_wep_params.key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002157 }
2158
Glen Leefbf53792015-12-21 14:18:40 +09002159 wilc_flush_join_req(vif);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002160
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002161 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2162 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2163 g_key_ptk_params.key[1],
2164 g_key_ptk_params.key[2]);
2165 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2166 g_key_gtk_params.key[1],
2167 g_key_gtk_params.key[2]);
Glen Lee1f435d22015-12-21 14:18:37 +09002168 add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy,
2169 wl->vif[0]->ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002170 g_add_ptk_key_params.key_idx,
2171 g_add_ptk_key_params.pairwise,
2172 g_add_ptk_key_params.mac_addr,
2173 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002174
Glen Lee1f435d22015-12-21 14:18:37 +09002175 add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy,
2176 wl->vif[0]->ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002177 g_add_gtk_key_params.key_idx,
2178 g_add_gtk_key_params.pairwise,
2179 g_add_gtk_key_params.mac_addr,
2180 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002181 }
2182
Glen Lee299382c2015-10-20 17:13:56 +09002183 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002184 for (i = 0; i < num_reg_frame; i++) {
Glen Leea4cac482015-12-21 14:18:36 +09002185 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type,
2186 vif->g_struct_frame_reg[i].reg);
Glen Leefbf53792015-12-21 14:18:40 +09002187 wilc_frame_register(vif,
Glen Leea4cac482015-12-21 14:18:36 +09002188 vif->g_struct_frame_reg[i].frame_type,
2189 vif->g_struct_frame_reg[i].reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002190 }
2191 }
2192
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002193 wilc_enable_ps = true;
Glen Leefbf53792015-12-21 14:18:40 +09002194 wilc_set_power_mgmt(vif, 1, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002195 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002196 break;
2197
2198 case NL80211_IFTYPE_P2P_CLIENT:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002199 wilc_enable_ps = false;
Glen Leefbf53792015-12-21 14:18:40 +09002200 wilc_set_power_mgmt(vif, 0, 0);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002201 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002202 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002203
Glen Leefbf53792015-12-21 14:18:40 +09002204 wilc_del_all_rx_ba_session(vif, wl->vif[0]->bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002205
2206 dev->ieee80211_ptr->iftype = type;
2207 priv->wdev->iftype = type;
Glen Leea4cac482015-12-21 14:18:36 +09002208 vif->monitor_flag = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002209
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002210 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
Glen Leea4cac482015-12-21 14:18:36 +09002211 vif->iftype = CLIENT_MODE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002212
2213
Glen Lee299382c2015-10-20 17:13:56 +09002214 if (wl->initialized) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002215 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002216
Glen Lee53dc0cf2015-10-20 17:13:57 +09002217 wilc1000_wlan_deinit(dev);
Glen Leea4cac482015-12-21 14:18:36 +09002218 wilc1000_wlan_init(dev, vif);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002219 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002220
Glen Lee31f0f692015-12-21 14:18:44 +09002221 wilc_set_wfi_drv_handler(vif,
2222 wilc_get_vif_idx(wl->vif[0]));
Glen Leefbf53792015-12-21 14:18:40 +09002223 wilc_set_mac_address(wl->vif[0], wl->vif[0]->src_addr);
2224 wilc_set_operation_mode(vif, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002225
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002226 if (g_wep_keys_saved) {
Glen Leefbf53792015-12-21 14:18:40 +09002227 wilc_set_wep_default_keyid(wl->vif[0],
2228 g_key_wep_params.key_idx);
2229 wilc_add_wep_key_bss_sta(wl->vif[0],
2230 g_key_wep_params.key,
2231 g_key_wep_params.key_len,
2232 g_key_wep_params.key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002233 }
2234
Glen Leefbf53792015-12-21 14:18:40 +09002235 wilc_flush_join_req(vif);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002236
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002237 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2238 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2239 g_key_ptk_params.key[1],
2240 g_key_ptk_params.key[2]);
2241 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2242 g_key_gtk_params.key[1],
2243 g_key_gtk_params.key[2]);
Glen Lee1f435d22015-12-21 14:18:37 +09002244 add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy,
2245 wl->vif[0]->ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002246 g_add_ptk_key_params.key_idx,
2247 g_add_ptk_key_params.pairwise,
2248 g_add_ptk_key_params.mac_addr,
2249 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002250
Glen Lee1f435d22015-12-21 14:18:37 +09002251 add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy,
2252 wl->vif[0]->ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002253 g_add_gtk_key_params.key_idx,
2254 g_add_gtk_key_params.pairwise,
2255 g_add_gtk_key_params.mac_addr,
2256 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002257 }
2258
Dean Lee72ed4dc2015-06-12 14:11:44 +09002259 refresh_scan(priv, 1, true);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002260 wilc_set_machw_change_vir_if(dev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002261
Glen Lee299382c2015-10-20 17:13:56 +09002262 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002263 for (i = 0; i < num_reg_frame; i++) {
Glen Leea4cac482015-12-21 14:18:36 +09002264 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type,
2265 vif->g_struct_frame_reg[i].reg);
Glen Leefbf53792015-12-21 14:18:40 +09002266 wilc_frame_register(vif,
Glen Leea4cac482015-12-21 14:18:36 +09002267 vif->g_struct_frame_reg[i].frame_type,
2268 vif->g_struct_frame_reg[i].reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002269 }
2270 }
2271 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002272 break;
2273
2274 case NL80211_IFTYPE_AP:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002275 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002276 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002277 dev->ieee80211_ptr->iftype = type;
2278 priv->wdev->iftype = type;
Glen Leea4cac482015-12-21 14:18:36 +09002279 vif->iftype = AP_MODE;
Johnny Kim8a143302015-06-10 17:06:46 +09002280 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002281
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002282 PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002283 wilc_wlan_get_firmware(dev);
Leo Kima89f7c52015-11-25 11:59:41 +09002284
Glen Lee299382c2015-10-20 17:13:56 +09002285 if (wl->initialized) {
Glen Leea4cac482015-12-21 14:18:36 +09002286 vif->iftype = AP_MODE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002287 wilc_mac_close(dev);
2288 wilc_mac_open(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002289
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002290 for (i = 0; i < num_reg_frame; i++) {
Glen Leea4cac482015-12-21 14:18:36 +09002291 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type,
2292 vif->g_struct_frame_reg[i].reg);
Glen Leefbf53792015-12-21 14:18:40 +09002293 wilc_frame_register(vif,
Glen Leea4cac482015-12-21 14:18:36 +09002294 vif->g_struct_frame_reg[i].frame_type,
2295 vif->g_struct_frame_reg[i].reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002296 }
2297 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002298 break;
2299
2300 case NL80211_IFTYPE_P2P_GO:
2301 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
2302
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002303 wilc_optaining_ip = true;
Leo Kim7e872df2015-11-19 15:56:20 +09002304 mod_timer(&wilc_during_ip_timer,
2305 jiffies + msecs_to_jiffies(during_ip_time));
Glen Leefbf53792015-12-21 14:18:40 +09002306 wilc_set_power_mgmt(vif, 0, 0);
2307 wilc_del_all_rx_ba_session(vif, wl->vif[0]->bssid, TID);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002308 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002309 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002310 dev->ieee80211_ptr->iftype = type;
2311 priv->wdev->iftype = type;
2312
Johnny Kim8a143302015-06-10 17:06:46 +09002313 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002314
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002315 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2316
2317
Glen Leea4cac482015-12-21 14:18:36 +09002318 vif->iftype = GO_MODE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002319
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002320 wilc_wait_msg_queue_idle();
Glen Lee53dc0cf2015-10-20 17:13:57 +09002321 wilc1000_wlan_deinit(dev);
Glen Leea4cac482015-12-21 14:18:36 +09002322 wilc1000_wlan_init(dev, vif);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002323 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002324
Glen Lee31f0f692015-12-21 14:18:44 +09002325 wilc_set_wfi_drv_handler(vif, wilc_get_vif_idx(wl->vif[0]));
Glen Leefbf53792015-12-21 14:18:40 +09002326 wilc_set_mac_address(wl->vif[0], wl->vif[0]->src_addr);
2327 wilc_set_operation_mode(vif, AP_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002328
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002329 if (g_wep_keys_saved) {
Glen Leefbf53792015-12-21 14:18:40 +09002330 wilc_set_wep_default_keyid(wl->vif[0],
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002331 g_key_wep_params.key_idx);
Glen Leefbf53792015-12-21 14:18:40 +09002332 wilc_add_wep_key_bss_sta(wl->vif[0],
2333 g_key_wep_params.key,
2334 g_key_wep_params.key_len,
2335 g_key_wep_params.key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002336 }
2337
Glen Leefbf53792015-12-21 14:18:40 +09002338 wilc_flush_join_req(vif);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002339
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002340 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2341 PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0],
2342 g_key_ptk_params.key[1],
2343 g_key_ptk_params.key[2],
2344 g_key_ptk_params.cipher);
2345 PRINT_D(CFG80211_DBG, "gtk %x %x %x cipher %x\n", g_key_gtk_params.key[0],
2346 g_key_gtk_params.key[1],
2347 g_key_gtk_params.key[2],
2348 g_key_gtk_params.cipher);
Glen Lee1f435d22015-12-21 14:18:37 +09002349 add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy,
2350 wl->vif[0]->ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002351 g_add_ptk_key_params.key_idx,
2352 g_add_ptk_key_params.pairwise,
2353 g_add_ptk_key_params.mac_addr,
2354 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002355
Glen Lee1f435d22015-12-21 14:18:37 +09002356 add_key(wl->vif[0]->ndev->ieee80211_ptr->wiphy,
2357 wl->vif[0]->ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002358 g_add_gtk_key_params.key_idx,
2359 g_add_gtk_key_params.pairwise,
2360 g_add_gtk_key_params.mac_addr,
2361 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002362 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002363
Glen Lee299382c2015-10-20 17:13:56 +09002364 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002365 for (i = 0; i < num_reg_frame; i++) {
Glen Leea4cac482015-12-21 14:18:36 +09002366 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", vif->g_struct_frame_reg[i].frame_type,
2367 vif->g_struct_frame_reg[i].reg);
Glen Leefbf53792015-12-21 14:18:40 +09002368 wilc_frame_register(vif,
Glen Leea4cac482015-12-21 14:18:36 +09002369 vif->g_struct_frame_reg[i].frame_type,
2370 vif->g_struct_frame_reg[i].reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002371 }
2372 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002373 break;
2374
2375 default:
2376 PRINT_ER("Unknown interface type= %d\n", type);
Leo Kimaaed3292015-10-12 16:55:38 +09002377 return -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002378 }
2379
Leo Kimaaed3292015-10-12 16:55:38 +09002380 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002381}
2382
Chaehyun Lima13168d2015-09-14 12:24:12 +09002383static int start_ap(struct wiphy *wiphy, struct net_device *dev,
2384 struct cfg80211_ap_settings *settings)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002385{
2386 struct cfg80211_beacon_data *beacon = &(settings->beacon);
Chaehyun Lim27268872015-09-15 14:06:13 +09002387 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002388 s32 s32Error = 0;
Glen Lee684dc182015-10-20 17:14:02 +09002389 struct wilc *wl;
Glen Leea4cac482015-12-21 14:18:36 +09002390 struct wilc_vif *vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002391
2392 priv = wiphy_priv(wiphy);
Glen Leea4cac482015-12-21 14:18:36 +09002393 vif = netdev_priv(dev);
2394 wl = vif ->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002395 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
2396
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302397 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 +09002398 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
2399
Chaehyun Lim80785a92015-09-14 12:24:01 +09002400 s32Error = set_channel(wiphy, &settings->chandef);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002401
Leo Kime6e12662015-09-16 18:36:03 +09002402 if (s32Error != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002403 PRINT_ER("Error in setting channel\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002404
Glen Lee1f435d22015-12-21 14:18:37 +09002405 wilc_wlan_set_bssid(dev, wl->vif[0]->src_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002406
Glen Leefbf53792015-12-21 14:18:40 +09002407 s32Error = wilc_add_beacon(vif, settings->beacon_interval,
2408 settings->dtim_period, beacon->head_len,
2409 (u8 *)beacon->head, beacon->tail_len,
2410 (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002411
2412 return s32Error;
2413}
2414
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002415static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
2416 struct cfg80211_beacon_data *beacon)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002417{
Chaehyun Lim27268872015-09-15 14:06:13 +09002418 struct wilc_priv *priv;
Glen Leecf601062015-12-21 14:18:39 +09002419 struct wilc_vif *vif;
Leo Kime6e12662015-09-16 18:36:03 +09002420 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002421
2422 priv = wiphy_priv(wiphy);
Glen Leecf601062015-12-21 14:18:39 +09002423 vif = netdev_priv(priv->dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002424 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
2425
2426
Glen Leefbf53792015-12-21 14:18:40 +09002427 s32Error = wilc_add_beacon(vif, 0, 0, beacon->head_len,
2428 (u8 *)beacon->head, beacon->tail_len,
2429 (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002430
2431 return s32Error;
2432}
2433
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002434static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002435{
Leo Kime6e12662015-09-16 18:36:03 +09002436 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002437 struct wilc_priv *priv;
Glen Leecf601062015-12-21 14:18:39 +09002438 struct wilc_vif *vif;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002439 u8 NullBssid[ETH_ALEN] = {0};
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002440
Leo Kim7ae43362015-09-16 18:35:59 +09002441 if (!wiphy)
2442 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002443
2444 priv = wiphy_priv(wiphy);
Glen Leecf601062015-12-21 14:18:39 +09002445 vif = netdev_priv(priv->dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002446
2447 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
2448
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002449 wilc_wlan_set_bssid(dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002450
Glen Leefbf53792015-12-21 14:18:40 +09002451 s32Error = wilc_del_beacon(vif);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002452
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002453 if (s32Error)
2454 PRINT_ER("Host delete beacon fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002455
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002456 return s32Error;
2457}
2458
Chaehyun Limed269552015-09-14 12:24:15 +09002459static int add_station(struct wiphy *wiphy, struct net_device *dev,
2460 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002461{
Leo Kime6e12662015-09-16 18:36:03 +09002462 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002463 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09002464 struct add_sta_param strStaParams = { {0} };
Glen Leea4cac482015-12-21 14:18:36 +09002465 struct wilc_vif *vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002466
Leo Kim7ae43362015-09-16 18:35:59 +09002467 if (!wiphy)
2468 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002469
2470 priv = wiphy_priv(wiphy);
Glen Leea4cac482015-12-21 14:18:36 +09002471 vif = netdev_priv(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002472
Glen Leea4cac482015-12-21 14:18:36 +09002473 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09002474 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09002475 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09002476 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09002477 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09002478 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002479
2480 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
2481
2482 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],
2483 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
Leo Kim4101eb82015-10-29 12:05:42 +09002484 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09002485 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
2486 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002487
Leo Kim369a1d32015-12-21 14:18:23 +09002488 if (!params->ht_capa) {
Leo Kim22520122015-10-29 12:05:45 +09002489 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002490 } else {
Leo Kim22520122015-10-29 12:05:45 +09002491 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09002492 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09002493 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09002494 memcpy(strStaParams.ht_supp_mcs_set,
2495 &params->ht_capa->mcs,
2496 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09002497 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09002498 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09002499 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002500 }
2501
Leo Kimf676e172015-10-29 12:05:52 +09002502 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09002503 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002504
Leo Kim22520122015-10-29 12:05:45 +09002505 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
2506 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09002507 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
2508 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09002509 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
2510 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09002511 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
2512 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09002513 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
2514 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09002515 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
2516 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09002517 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
2518 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09002519 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
2520 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002521
Glen Leefbf53792015-12-21 14:18:40 +09002522 s32Error = wilc_add_station(vif, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002523 if (s32Error)
2524 PRINT_ER("Host add station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002525 }
2526
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002527 return s32Error;
2528}
2529
Chaehyun Lima0a8be92015-09-14 12:24:16 +09002530static int del_station(struct wiphy *wiphy, struct net_device *dev,
2531 struct station_del_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002532{
Arnd Bergmann057d1e92015-06-01 21:06:44 +02002533 const u8 *mac = params->mac;
Leo Kime6e12662015-09-16 18:36:03 +09002534 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002535 struct wilc_priv *priv;
Glen Leea4cac482015-12-21 14:18:36 +09002536 struct wilc_vif *vif;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002537
Leo Kim7ae43362015-09-16 18:35:59 +09002538 if (!wiphy)
2539 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002540
2541 priv = wiphy_priv(wiphy);
Glen Leea4cac482015-12-21 14:18:36 +09002542 vif = netdev_priv(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002543
Glen Leea4cac482015-12-21 14:18:36 +09002544 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002545 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
2546
2547
Leo Kim369a1d32015-12-21 14:18:23 +09002548 if (!mac) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302549 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
Glen Leefbf53792015-12-21 14:18:40 +09002550 s32Error = wilc_del_allstation(vif,
2551 priv->assoc_stainfo.au8Sta_AssociatedBss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002552 } else {
2553 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]);
2554 }
2555
Glen Leefbf53792015-12-21 14:18:40 +09002556 s32Error = wilc_del_station(vif, mac);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002557
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002558 if (s32Error)
2559 PRINT_ER("Host delete station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002560 }
2561 return s32Error;
2562}
2563
Chaehyun Lim14b42082015-09-14 12:24:17 +09002564static int change_station(struct wiphy *wiphy, struct net_device *dev,
2565 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002566{
Leo Kime6e12662015-09-16 18:36:03 +09002567 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002568 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09002569 struct add_sta_param strStaParams = { {0} };
Glen Leea4cac482015-12-21 14:18:36 +09002570 struct wilc_vif *vif;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002571
2572
2573 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
2574
Leo Kim7ae43362015-09-16 18:35:59 +09002575 if (!wiphy)
2576 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002577
2578 priv = wiphy_priv(wiphy);
Glen Leea4cac482015-12-21 14:18:36 +09002579 vif = netdev_priv(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002580
Glen Leea4cac482015-12-21 14:18:36 +09002581 if (vif->iftype == AP_MODE || vif->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09002582 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09002583 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09002584 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09002585 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002586
Leo Kim2353c382015-10-29 12:05:41 +09002587 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n",
2588 strStaParams.bssid[0], strStaParams.bssid[1],
2589 strStaParams.bssid[2], strStaParams.bssid[3],
2590 strStaParams.bssid[4], strStaParams.bssid[5]);
Leo Kim4101eb82015-10-29 12:05:42 +09002591 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09002592 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
2593 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002594
Leo Kim369a1d32015-12-21 14:18:23 +09002595 if (!params->ht_capa) {
Leo Kim22520122015-10-29 12:05:45 +09002596 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002597 } else {
Leo Kim22520122015-10-29 12:05:45 +09002598 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09002599 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09002600 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09002601 memcpy(strStaParams.ht_supp_mcs_set,
2602 &params->ht_capa->mcs,
2603 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09002604 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09002605 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09002606 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002607 }
2608
Leo Kimf676e172015-10-29 12:05:52 +09002609 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09002610 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002611
Leo Kim22520122015-10-29 12:05:45 +09002612 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
2613 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09002614 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
2615 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09002616 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
2617 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09002618 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
2619 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09002620 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
2621 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09002622 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
2623 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09002624 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
2625 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09002626 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
2627 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002628
Glen Leefbf53792015-12-21 14:18:40 +09002629 s32Error = wilc_edit_station(vif, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002630 if (s32Error)
2631 PRINT_ER("Host edit station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002632 }
2633 return s32Error;
2634}
2635
Chaehyun Lim37316e82015-09-22 18:34:52 +09002636static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
2637 const char *name,
2638 unsigned char name_assign_type,
2639 enum nl80211_iftype type,
2640 u32 *flags,
2641 struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002642{
Glen Leea4cac482015-12-21 14:18:36 +09002643 struct wilc_vif *vif;
Chaehyun Lim27268872015-09-15 14:06:13 +09002644 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002645 struct net_device *new_ifc = NULL;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002646
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002647 priv = wiphy_priv(wiphy);
2648
2649
2650
2651 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
2652
Glen Leea4cac482015-12-21 14:18:36 +09002653 vif = netdev_priv(priv->wdev->netdev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002654
2655
2656 if (type == NL80211_IFTYPE_MONITOR) {
2657 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
Glen Lee1006b5c2015-12-21 14:18:38 +09002658 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", vif->ndev);
2659 new_ifc = WILC_WFI_init_mon_interface(name, vif->ndev);
Leo Kim369a1d32015-12-21 14:18:23 +09002660 if (new_ifc) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002661 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
Glen Leea4cac482015-12-21 14:18:36 +09002662 vif = netdev_priv(priv->wdev->netdev);
2663 vif->monitor_flag = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002664 } else
2665 PRINT_ER("Error in initializing monitor interface\n ");
2666 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002667 return priv->wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002668}
2669
Chaehyun Lim956d7212015-09-22 18:34:49 +09002670static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002671{
2672 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
Leo Kime6e12662015-09-16 18:36:03 +09002673 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002674}
2675
Chaehyun Lim08241922015-09-15 14:06:12 +09002676static struct cfg80211_ops wilc_cfg80211_ops = {
Chaehyun Lim80785a92015-09-14 12:24:01 +09002677 .set_monitor_channel = set_channel,
Chaehyun Lim0e30d062015-09-14 12:24:02 +09002678 .scan = scan,
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +09002679 .connect = connect,
Chaehyun Limb027cde2015-09-14 12:24:04 +09002680 .disconnect = disconnect,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002681 .add_key = add_key,
Chaehyun Lim3044ba72015-09-14 12:24:06 +09002682 .del_key = del_key,
Chaehyun Limf4893df2015-09-14 12:24:07 +09002683 .get_key = get_key,
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09002684 .set_default_key = set_default_key,
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09002685 .add_virtual_intf = add_virtual_intf,
Chaehyun Limb4a73352015-09-14 12:24:10 +09002686 .del_virtual_intf = del_virtual_intf,
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002687 .change_virtual_intf = change_virtual_intf,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002688
Chaehyun Lima13168d2015-09-14 12:24:12 +09002689 .start_ap = start_ap,
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002690 .change_beacon = change_beacon,
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002691 .stop_ap = stop_ap,
Chaehyun Limed269552015-09-14 12:24:15 +09002692 .add_station = add_station,
Chaehyun Lima0a8be92015-09-14 12:24:16 +09002693 .del_station = del_station,
Chaehyun Lim14b42082015-09-14 12:24:17 +09002694 .change_station = change_station,
Chaehyun Limf06f5622015-09-14 12:24:18 +09002695 .get_station = get_station,
Chaehyun Limbdb63382015-09-14 12:24:19 +09002696 .dump_station = dump_station,
Chaehyun Lima5f7db62015-09-14 12:24:20 +09002697 .change_bss = change_bss,
Chaehyun Lima76b63e2015-09-14 12:24:21 +09002698 .set_wiphy_params = set_wiphy_params,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002699
Chaehyun Lim4d466572015-09-14 12:24:22 +09002700 .set_pmksa = set_pmksa,
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09002701 .del_pmksa = del_pmksa,
Chaehyun Limb33c39b2015-09-14 12:24:24 +09002702 .flush_pmksa = flush_pmksa,
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002703 .remain_on_channel = remain_on_channel,
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002704 .cancel_remain_on_channel = cancel_remain_on_channel,
Chaehyun Lim4a2f9b32015-09-14 12:24:27 +09002705 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
Chaehyun Lim12a26a32015-09-14 12:24:28 +09002706 .mgmt_tx = mgmt_tx,
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002707 .mgmt_frame_register = wilc_mgmt_frame_register,
Chaehyun Lim46530672015-09-22 18:34:46 +09002708 .set_power_mgmt = set_power_mgmt,
Chaehyun Lima8047e22015-09-22 18:34:48 +09002709 .set_cqm_rssi_config = set_cqm_rssi_config,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002710
2711};
2712
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002713int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
2714{
Chaehyun Lim27268872015-09-15 14:06:13 +09002715 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002716
2717 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002718 switch (changed) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002719 case WILC_WFI_RX_PKT:
2720 {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002721 priv->netstats.rx_packets++;
2722 priv->netstats.rx_bytes += pktlen;
2723 priv->netstats.rx_time = get_jiffies_64();
2724 }
2725 break;
2726
2727 case WILC_WFI_TX_PKT:
2728 {
2729 priv->netstats.tx_packets++;
2730 priv->netstats.tx_bytes += pktlen;
2731 priv->netstats.tx_time = get_jiffies_64();
2732
2733 }
2734 break;
2735
2736 default:
2737 break;
2738 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002739 return 0;
2740}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002741
Arnd Bergmann1608c402015-11-16 15:04:53 +01002742static struct wireless_dev *WILC_WFI_CfgAlloc(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002743{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002744 struct wireless_dev *wdev;
2745
2746
2747 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
Leo Kima89f7c52015-11-25 11:59:41 +09002748
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002749 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2750 if (!wdev) {
2751 PRINT_ER("Cannot allocate wireless device\n");
2752 goto _fail_;
2753 }
2754
Chaehyun Lim27268872015-09-15 14:06:13 +09002755 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002756 if (!wdev->wiphy) {
2757 PRINT_ER("Cannot allocate wiphy\n");
2758 goto _fail_mem_;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002759 }
2760
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002761 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
2762 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
2763 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
2764 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
2765 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002766
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002767 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
2768
2769 return wdev;
2770
2771_fail_mem_:
2772 kfree(wdev);
2773_fail_:
2774 return NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002775}
Leo Kima89f7c52015-11-25 11:59:41 +09002776
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01002777struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002778{
Chaehyun Lim27268872015-09-15 14:06:13 +09002779 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002780 struct wireless_dev *wdev;
Leo Kime6e12662015-09-16 18:36:03 +09002781 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002782
2783 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
2784
2785 wdev = WILC_WFI_CfgAlloc();
Leo Kim369a1d32015-12-21 14:18:23 +09002786 if (!wdev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002787 PRINT_ER("CfgAlloc Failed\n");
2788 return NULL;
2789 }
2790
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002791 priv = wdev_priv(wdev);
Arnd Bergmann83383ea2015-06-01 21:06:43 +02002792 sema_init(&(priv->SemHandleUpdateStats), 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002793 priv->wdev = wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002794 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002795 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
2796 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002797
2798 wdev->wiphy->max_scan_ie_len = 1000;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002799 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002800 wdev->wiphy->cipher_suites = cipher_suites;
2801 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002802 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002803
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002804 wdev->wiphy->max_remain_on_channel_duration = 500;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002805 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
2806 BIT(NL80211_IFTYPE_P2P_CLIENT);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002807 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002808 wdev->iftype = NL80211_IFTYPE_STATION;
2809
2810
2811
2812 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
2813 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
2814 wdev->wiphy->interface_modes, wdev->iftype);
2815
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01002816 set_wiphy_dev(wdev->wiphy, dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002817
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002818 s32Error = wiphy_register(wdev->wiphy);
2819 if (s32Error) {
2820 PRINT_ER("Cannot register wiphy device\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002821 } else {
2822 PRINT_D(CFG80211_DBG, "Successful Registering\n");
2823 }
2824
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002825 priv->dev = net;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002826 return wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002827}
Leo Kima89f7c52015-11-25 11:59:41 +09002828
Chaehyun Limdd4b6a82015-09-20 15:51:25 +09002829int wilc_init_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002830{
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09002831 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002832
Chaehyun Lim27268872015-09-15 14:06:13 +09002833 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002834
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002835 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
2836 priv = wdev_priv(net->ieee80211_ptr);
2837 if (op_ifcs == 0) {
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -07002838 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002839 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002840 }
2841 op_ifcs++;
2842 if (s32Error < 0) {
2843 PRINT_ER("Failed to creat refresh Timer\n");
2844 return s32Error;
2845 }
2846
Dean Lee72ed4dc2015-06-12 14:11:44 +09002847 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002848
Dean Lee72ed4dc2015-06-12 14:11:44 +09002849 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002850
Arnd Bergmann83383ea2015-06-01 21:06:43 +02002851 sema_init(&(priv->hSemScanReq), 1);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002852 s32Error = wilc_init(net, &priv->hWILCWFIDrv);
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09002853 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002854 PRINT_ER("Error while initializing hostinterface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09002855
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002856 return s32Error;
2857}
2858
Chaehyun Lima9a16822015-09-20 15:51:24 +09002859int wilc_deinit_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002860{
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09002861 int s32Error = 0;
Glen Leecf601062015-12-21 14:18:39 +09002862 struct wilc_vif *vif;
Chaehyun Lim27268872015-09-15 14:06:13 +09002863 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002864
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002865 priv = wdev_priv(net->ieee80211_ptr);
Glen Leecf601062015-12-21 14:18:39 +09002866 vif = netdev_priv(priv->dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002867
Dean Lee72ed4dc2015-06-12 14:11:44 +09002868 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002869
Dean Lee72ed4dc2015-06-12 14:11:44 +09002870 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002871
2872 op_ifcs--;
2873
Glen Leefbf53792015-12-21 14:18:40 +09002874 s32Error = wilc_deinit(vif);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002875
Leo Kimd14991a2015-11-19 15:56:22 +09002876 clear_shadow_scan();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002877 if (op_ifcs == 0) {
2878 PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002879 del_timer_sync(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002880 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002881
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09002882 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002883 PRINT_ER("Error while deintializing host interface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09002884
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002885 return s32Error;
2886}
2887
Chaehyun Lim96da20a2015-09-20 15:51:08 +09002888void wilc_free_wiphy(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002889{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002890 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
2891
Chaehyun Lim619837a2015-09-20 15:51:10 +09002892 if (!net) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002893 PRINT_D(INIT_DBG, "net_device is NULL\n");
2894 return;
2895 }
2896
Chaehyun Lim619837a2015-09-20 15:51:10 +09002897 if (!net->ieee80211_ptr) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002898 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
2899 return;
2900 }
2901
Chaehyun Lim619837a2015-09-20 15:51:10 +09002902 if (!net->ieee80211_ptr->wiphy) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002903 PRINT_D(INIT_DBG, "wiphy is NULL\n");
2904 return;
2905 }
2906
2907 wiphy_unregister(net->ieee80211_ptr->wiphy);
2908
2909 PRINT_D(INIT_DBG, "Freeing wiphy\n");
2910 wiphy_free(net->ieee80211_ptr->wiphy);
2911 kfree(net->ieee80211_ptr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002912}