blob: bdc4537d876043d9f012b1dd0d0788d19ef47564 [file] [log] [blame]
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001#include "wilc_wfi_cfgoperations.h"
Arnd Bergmann491880e2015-11-16 15:04:55 +01002#include "host_interface.h"
Leo Kim7ae43362015-09-16 18:35:59 +09003#include <linux/errno.h>
Johnny Kimc5c77ba2015-05-11 14:30:56 +09004
Arnd Bergmann15162fb2015-11-16 15:04:57 +01005#define NO_ENCRYPT 0
6#define ENCRYPT_ENABLED BIT(0)
7#define WEP BIT(1)
8#define WEP_EXTENDED BIT(2)
9#define WPA BIT(3)
10#define WPA2 BIT(4)
11#define AES BIT(5)
12#define TKIP BIT(6)
13
Arnd Bergmann15162fb2015-11-16 15:04:57 +010014#define FRAME_TYPE_ID 0
15#define ACTION_CAT_ID 24
16#define ACTION_SUBTYPE_ID 25
17#define P2P_PUB_ACTION_SUBTYPE 30
18
Arnd Bergmann15162fb2015-11-16 15:04:57 +010019#define ACTION_FRAME 0xd0
20#define GO_INTENT_ATTR_ID 0x04
21#define CHANLIST_ATTR_ID 0x0b
22#define OPERCHAN_ATTR_ID 0x11
23#define PUB_ACTION_ATTR_ID 0x04
24#define P2PELEM_ATTR_ID 0xdd
25
Arnd Bergmann15162fb2015-11-16 15:04:57 +010026#define GO_NEG_REQ 0x00
27#define GO_NEG_RSP 0x01
28#define GO_NEG_CONF 0x02
29#define P2P_INV_REQ 0x03
30#define P2P_INV_RSP 0x04
31#define PUBLIC_ACT_VENDORSPEC 0x09
32#define GAS_INTIAL_REQ 0x0a
33#define GAS_INTIAL_RSP 0x0b
34
35#define INVALID_CHANNEL 0
36
37#define nl80211_SCAN_RESULT_EXPIRE (3 * HZ)
38#define SCAN_RESULT_EXPIRE (40 * HZ)
39
40static const u32 cipher_suites[] = {
41 WLAN_CIPHER_SUITE_WEP40,
42 WLAN_CIPHER_SUITE_WEP104,
43 WLAN_CIPHER_SUITE_TKIP,
44 WLAN_CIPHER_SUITE_CCMP,
45 WLAN_CIPHER_SUITE_AES_CMAC,
46};
47
48static const struct ieee80211_txrx_stypes
49 wilc_wfi_cfg80211_mgmt_types[NUM_NL80211_IFTYPES] = {
50 [NL80211_IFTYPE_STATION] = {
51 .tx = 0xffff,
52 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
53 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
54 },
55 [NL80211_IFTYPE_AP] = {
56 .tx = 0xffff,
57 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
58 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
59 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
60 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
61 BIT(IEEE80211_STYPE_AUTH >> 4) |
62 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
63 BIT(IEEE80211_STYPE_ACTION >> 4)
64 },
65 [NL80211_IFTYPE_P2P_CLIENT] = {
66 .tx = 0xffff,
67 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
68 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
69 BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
70 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
71 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
72 BIT(IEEE80211_STYPE_AUTH >> 4) |
73 BIT(IEEE80211_STYPE_DEAUTH >> 4)
74 }
75};
76
Arnd Bergmann15162fb2015-11-16 15:04:57 +010077#define WILC_WFI_DWELL_PASSIVE 100
78#define WILC_WFI_DWELL_ACTIVE 40
79
80#define TCP_ACK_FILTER_LINK_SPEED_THRESH 54
81#define DEFAULT_LINK_SPEED 72
82
83
Johnny Kimc5c77ba2015-05-11 14:30:56 +090084#define IS_MANAGMEMENT 0x100
85#define IS_MANAGMEMENT_CALLBACK 0x080
86#define IS_MGMT_STATUS_SUCCES 0x040
87#define GET_PKT_OFFSET(a) (((a) >> 22) & 0x1ff)
88
Arnd Bergmann0e1af732015-11-16 15:04:54 +010089extern int wilc_mac_open(struct net_device *ndev);
90extern int wilc_mac_close(struct net_device *ndev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +090091
Leo Kimf1ab1172015-11-19 15:56:11 +090092static tstrNetworkInfo last_scanned_shadow[MAX_NUM_SCANNED_NETWORKS_SHADOW];
Leo Kim771fbae2015-11-19 15:56:10 +090093static u32 last_scanned_cnt;
Arnd Bergmann0e1af732015-11-16 15:04:54 +010094struct timer_list wilc_during_ip_timer;
Arnd Bergmann1608c402015-11-16 15:04:53 +010095static struct timer_list hAgingTimer;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +090096static u8 op_ifcs;
Johnny Kimc5c77ba2015-05-11 14:30:56 +090097
Arnd Bergmann0e1af732015-11-16 15:04:54 +010098u8 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +090099
100#define CHAN2G(_channel, _freq, _flags) { \
101 .band = IEEE80211_BAND_2GHZ, \
102 .center_freq = (_freq), \
103 .hw_value = (_channel), \
104 .flags = (_flags), \
105 .max_antenna_gain = 0, \
106 .max_power = 30, \
107}
108
Leo Kim2736f472015-11-19 15:56:12 +0900109static struct ieee80211_channel ieee80211_2ghz_channels[] = {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900110 CHAN2G(1, 2412, 0),
111 CHAN2G(2, 2417, 0),
112 CHAN2G(3, 2422, 0),
113 CHAN2G(4, 2427, 0),
114 CHAN2G(5, 2432, 0),
115 CHAN2G(6, 2437, 0),
116 CHAN2G(7, 2442, 0),
117 CHAN2G(8, 2447, 0),
118 CHAN2G(9, 2452, 0),
119 CHAN2G(10, 2457, 0),
120 CHAN2G(11, 2462, 0),
121 CHAN2G(12, 2467, 0),
122 CHAN2G(13, 2472, 0),
123 CHAN2G(14, 2484, 0),
124};
125
126#define RATETAB_ENT(_rate, _hw_value, _flags) { \
127 .bitrate = (_rate), \
128 .hw_value = (_hw_value), \
129 .flags = (_flags), \
130}
131
Leo Kim8d48b5b2015-11-19 15:56:13 +0900132static struct ieee80211_rate ieee80211_bitrates[] = {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900133 RATETAB_ENT(10, 0, 0),
134 RATETAB_ENT(20, 1, 0),
135 RATETAB_ENT(55, 2, 0),
136 RATETAB_ENT(110, 3, 0),
137 RATETAB_ENT(60, 9, 0),
138 RATETAB_ENT(90, 6, 0),
139 RATETAB_ENT(120, 7, 0),
140 RATETAB_ENT(180, 8, 0),
141 RATETAB_ENT(240, 9, 0),
142 RATETAB_ENT(360, 10, 0),
143 RATETAB_ENT(480, 11, 0),
144 RATETAB_ENT(540, 12, 0),
145};
146
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900147struct p2p_mgmt_data {
148 int size;
149 u8 *buff;
150};
151
Leo Kim0bd82742015-11-19 15:56:14 +0900152static u8 wlan_channel = INVALID_CHANNEL;
Arnd Bergmann1608c402015-11-16 15:04:53 +0100153static u8 curr_channel;
Leo Kim881eb5d2015-11-19 15:56:15 +0900154static u8 p2p_oui[] = {0x50, 0x6f, 0x9A, 0x09};
Leo Kim583d9722015-11-19 15:56:16 +0900155static u8 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +0900156static u8 p2p_recv_random = 0x00;
Leo Kim86685942015-11-19 15:56:18 +0900157static u8 p2p_vendor_spec[] = {0xdd, 0x05, 0x00, 0x08, 0x40, 0x03};
Leo Kima25d5182015-11-19 15:56:19 +0900158static bool wilc_ie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900159
160static struct ieee80211_supported_band WILC_WFI_band_2ghz = {
Leo Kim2736f472015-11-19 15:56:12 +0900161 .channels = ieee80211_2ghz_channels,
162 .n_channels = ARRAY_SIZE(ieee80211_2ghz_channels),
Leo Kim8d48b5b2015-11-19 15:56:13 +0900163 .bitrates = ieee80211_bitrates,
164 .n_bitrates = ARRAY_SIZE(ieee80211_bitrates),
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900165};
166
167
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900168struct add_key_params {
169 u8 key_idx;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900170 bool pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900171 u8 *mac_addr;
172};
Arnd Bergmann1608c402015-11-16 15:04:53 +0100173static struct add_key_params g_add_gtk_key_params;
174static struct wilc_wfi_key g_key_gtk_params;
175static struct add_key_params g_add_ptk_key_params;
176static struct wilc_wfi_key g_key_ptk_params;
177static struct wilc_wfi_wep_key g_key_wep_params;
178static bool g_ptk_keys_saved;
179static bool g_gtk_keys_saved;
180static bool g_wep_keys_saved;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900181
182#define AGING_TIME (9 * 1000)
Leo Kim7e872df2015-11-19 15:56:20 +0900183#define during_ip_time 15000
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900184
Leo Kimd14991a2015-11-19 15:56:22 +0900185static void clear_shadow_scan(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900186{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900187 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900188
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900189 if (op_ifcs == 0) {
Greg Kroah-Hartman4183e972015-08-14 20:11:16 -0700190 del_timer_sync(&hAgingTimer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900191 PRINT_INFO(CORECONFIG_DBG, "destroy aging timer\n");
192
Leo Kim771fbae2015-11-19 15:56:10 +0900193 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900194 if (last_scanned_shadow[last_scanned_cnt].pu8IEs) {
195 kfree(last_scanned_shadow[i].pu8IEs);
196 last_scanned_shadow[last_scanned_cnt].pu8IEs = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900197 }
198
Leo Kimf1ab1172015-11-19 15:56:11 +0900199 wilc_free_join_params(last_scanned_shadow[i].pJoinParams);
200 last_scanned_shadow[i].pJoinParams = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900201 }
Leo Kim771fbae2015-11-19 15:56:10 +0900202 last_scanned_cnt = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900203 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900204}
205
Leo Kim0b8bea12015-11-19 15:56:35 +0900206static u32 get_rssi_avg(tstrNetworkInfo *network_info)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900207{
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900208 u8 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900209 int rssi_v = 0;
Leo Kim0b8bea12015-11-19 15:56:35 +0900210 u8 num_rssi = (network_info->strRssi.u8Full) ? NUM_RSSI : (network_info->strRssi.u8Index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900211
212 for (i = 0; i < num_rssi; i++)
Leo Kim0b8bea12015-11-19 15:56:35 +0900213 rssi_v += network_info->strRssi.as8RSSI[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900214
215 rssi_v /= num_rssi;
216 return rssi_v;
217}
218
Leo Kim48ee7ba2015-11-19 15:56:24 +0900219static void refresh_scan(void *user_void, u8 all, bool direct_scan)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900220{
Chaehyun Lim27268872015-09-15 14:06:13 +0900221 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900222 struct wiphy *wiphy;
223 struct cfg80211_bss *bss = NULL;
224 int i;
225 int rssi = 0;
226
Leo Kim84df0e62015-11-19 15:56:23 +0900227 priv = (struct wilc_priv *)user_void;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900228 wiphy = priv->dev->ieee80211_ptr->wiphy;
229
Leo Kim771fbae2015-11-19 15:56:10 +0900230 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimce3b1b52015-11-19 15:56:25 +0900231 tstrNetworkInfo *network_info;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900232
Leo Kimce3b1b52015-11-19 15:56:25 +0900233 network_info = &last_scanned_shadow[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900234
Leo Kimce3b1b52015-11-19 15:56:25 +0900235 if (!network_info->u8Found || all) {
Leo Kimc6f5e3a2015-11-19 15:56:26 +0900236 s32 freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900237 struct ieee80211_channel *channel;
238
Leo Kimce3b1b52015-11-19 15:56:25 +0900239 if (network_info) {
Leo Kimc6f5e3a2015-11-19 15:56:26 +0900240 freq = ieee80211_channel_to_frequency((s32)network_info->u8channel, IEEE80211_BAND_2GHZ);
241 channel = ieee80211_get_channel(wiphy, freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900242
Leo Kimce3b1b52015-11-19 15:56:25 +0900243 rssi = get_rssi_avg(network_info);
244 if (memcmp("DIRECT-", network_info->au8ssid, 7) ||
Leo Kim48ee7ba2015-11-19 15:56:24 +0900245 direct_scan) {
Leo Kimce3b1b52015-11-19 15:56:25 +0900246 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, network_info->au8bssid, network_info->u64Tsf, network_info->u16CapInfo,
247 network_info->u16BeaconPeriod, (const u8 *)network_info->pu8IEs,
248 (size_t)network_info->u16IEsLen, (((s32)rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900249 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900250 }
251 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900252 }
253 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900254}
255
Leo Kim12b01382015-11-19 15:56:27 +0900256static void reset_shadow_found(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900257{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900258 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900259
Leo Kim771fbae2015-11-19 15:56:10 +0900260 for (i = 0; i < last_scanned_cnt; i++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900261 last_scanned_shadow[i].u8Found = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900262}
263
Leo Kim5e51d8b2015-11-19 15:56:28 +0900264static void update_scan_time(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900265{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900266 int i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900267
Leo Kim771fbae2015-11-19 15:56:10 +0900268 for (i = 0; i < last_scanned_cnt; i++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900269 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900270}
271
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700272static void remove_network_from_shadow(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900273{
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900274 unsigned long now = jiffies;
275 int i, j;
276
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900277
Leo Kim771fbae2015-11-19 15:56:10 +0900278 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900279 if (time_after(now, last_scanned_shadow[i].u32TimeRcvdInScan + (unsigned long)(SCAN_RESULT_EXPIRE))) {
280 PRINT_D(CFG80211_DBG, "Network expired in ScanShadow: %s\n", last_scanned_shadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900281
Leo Kimf1ab1172015-11-19 15:56:11 +0900282 kfree(last_scanned_shadow[i].pu8IEs);
283 last_scanned_shadow[i].pu8IEs = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900284
Leo Kimf1ab1172015-11-19 15:56:11 +0900285 wilc_free_join_params(last_scanned_shadow[i].pJoinParams);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900286
Leo Kim771fbae2015-11-19 15:56:10 +0900287 for (j = i; (j < last_scanned_cnt - 1); j++)
Leo Kimf1ab1172015-11-19 15:56:11 +0900288 last_scanned_shadow[j] = last_scanned_shadow[j + 1];
Leo Kim771fbae2015-11-19 15:56:10 +0900289
290 last_scanned_cnt--;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900291 }
292 }
293
Leo Kim771fbae2015-11-19 15:56:10 +0900294 PRINT_D(CFG80211_DBG, "Number of cached networks: %d\n",
295 last_scanned_cnt);
296 if (last_scanned_cnt != 0) {
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700297 hAgingTimer.data = arg;
298 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
299 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900300 PRINT_D(CFG80211_DBG, "No need to restart Aging timer\n");
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700301 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900302}
303
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -0700304static void clear_duringIP(unsigned long arg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900305{
306 PRINT_D(GENERIC_DBG, "GO:IP Obtained , enable scan\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100307 wilc_optaining_ip = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900308}
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900309
Leo Kim157814f2015-11-19 15:56:29 +0900310static int is_network_in_shadow(tstrNetworkInfo *pstrNetworkInfo,
311 void *user_void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900312{
Chaehyun Lima74cc6b2015-10-02 16:41:17 +0900313 int state = -1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900314 int i;
315
Leo Kim771fbae2015-11-19 15:56:10 +0900316 if (last_scanned_cnt == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900317 PRINT_D(CFG80211_DBG, "Starting Aging timer\n");
Leo Kim157814f2015-11-19 15:56:29 +0900318 hAgingTimer.data = (unsigned long)user_void;
Greg Kroah-Hartman9eb06642015-08-17 11:10:55 -0700319 mod_timer(&hAgingTimer, jiffies + msecs_to_jiffies(AGING_TIME));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900320 state = -1;
321 } else {
Leo Kim771fbae2015-11-19 15:56:10 +0900322 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900323 if (memcmp(last_scanned_shadow[i].au8bssid,
324 pstrNetworkInfo->au8bssid, 6) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900325 state = i;
326 break;
327 }
328 }
329 }
330 return state;
331}
332
Leo Kim5c4cf0d2015-11-19 15:56:30 +0900333static void add_network_to_shadow(tstrNetworkInfo *pstrNetworkInfo,
334 void *user_void, void *pJoinParams)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900335{
Leo Kim5c4cf0d2015-11-19 15:56:30 +0900336 int ap_found = is_network_in_shadow(pstrNetworkInfo, user_void);
Chaehyun Limfbc2fe12015-09-15 14:06:16 +0900337 u32 ap_index = 0;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900338 u8 rssi_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900339
Leo Kim771fbae2015-11-19 15:56:10 +0900340 if (last_scanned_cnt >= MAX_NUM_SCANNED_NETWORKS_SHADOW) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900341 PRINT_D(CFG80211_DBG, "Shadow network reached its maximum limit\n");
342 return;
343 }
344 if (ap_found == -1) {
Leo Kim771fbae2015-11-19 15:56:10 +0900345 ap_index = last_scanned_cnt;
346 last_scanned_cnt++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900347 } else {
348 ap_index = ap_found;
349 }
Leo Kimf1ab1172015-11-19 15:56:11 +0900350 rssi_index = last_scanned_shadow[ap_index].strRssi.u8Index;
351 last_scanned_shadow[ap_index].strRssi.as8RSSI[rssi_index++] = pstrNetworkInfo->s8rssi;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900352 if (rssi_index == NUM_RSSI) {
353 rssi_index = 0;
Leo Kimf1ab1172015-11-19 15:56:11 +0900354 last_scanned_shadow[ap_index].strRssi.u8Full = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900355 }
Leo Kimf1ab1172015-11-19 15:56:11 +0900356 last_scanned_shadow[ap_index].strRssi.u8Index = rssi_index;
357 last_scanned_shadow[ap_index].s8rssi = pstrNetworkInfo->s8rssi;
358 last_scanned_shadow[ap_index].u16CapInfo = pstrNetworkInfo->u16CapInfo;
359 last_scanned_shadow[ap_index].u8SsidLen = pstrNetworkInfo->u8SsidLen;
360 memcpy(last_scanned_shadow[ap_index].au8ssid,
361 pstrNetworkInfo->au8ssid, pstrNetworkInfo->u8SsidLen);
362 memcpy(last_scanned_shadow[ap_index].au8bssid,
363 pstrNetworkInfo->au8bssid, ETH_ALEN);
364 last_scanned_shadow[ap_index].u16BeaconPeriod = pstrNetworkInfo->u16BeaconPeriod;
365 last_scanned_shadow[ap_index].u8DtimPeriod = pstrNetworkInfo->u8DtimPeriod;
366 last_scanned_shadow[ap_index].u8channel = pstrNetworkInfo->u8channel;
367 last_scanned_shadow[ap_index].u16IEsLen = pstrNetworkInfo->u16IEsLen;
368 last_scanned_shadow[ap_index].u64Tsf = pstrNetworkInfo->u64Tsf;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900369 if (ap_found != -1)
Leo Kimf1ab1172015-11-19 15:56:11 +0900370 kfree(last_scanned_shadow[ap_index].pu8IEs);
371 last_scanned_shadow[ap_index].pu8IEs =
Leo Kima89f7c52015-11-25 11:59:41 +0900372 kmalloc(pstrNetworkInfo->u16IEsLen, GFP_KERNEL);
Leo Kimf1ab1172015-11-19 15:56:11 +0900373 memcpy(last_scanned_shadow[ap_index].pu8IEs,
374 pstrNetworkInfo->pu8IEs, pstrNetworkInfo->u16IEsLen);
375 last_scanned_shadow[ap_index].u32TimeRcvdInScan = jiffies;
376 last_scanned_shadow[ap_index].u32TimeRcvdInScanCached = jiffies;
377 last_scanned_shadow[ap_index].u8Found = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900378 if (ap_found != -1)
Leo Kimf1ab1172015-11-19 15:56:11 +0900379 wilc_free_join_params(last_scanned_shadow[ap_index].pJoinParams);
380 last_scanned_shadow[ap_index].pJoinParams = pJoinParams;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900381}
382
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900383static void CfgScanResult(enum scan_event scan_event,
Leo Kim0551a722015-11-19 15:56:32 +0900384 tstrNetworkInfo *network_info,
Leo Kim30cd10c2015-11-19 15:56:33 +0900385 void *user_void,
Leo Kimbdd34602015-11-19 15:56:34 +0900386 void *join_params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900387{
Chaehyun Lim27268872015-09-15 14:06:13 +0900388 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900389 struct wiphy *wiphy;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +0900390 s32 s32Freq;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900391 struct ieee80211_channel *channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900392 struct cfg80211_bss *bss = NULL;
393
Leo Kim30cd10c2015-11-19 15:56:33 +0900394 priv = (struct wilc_priv *)user_void;
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +0100395 if (priv->bCfgScanning) {
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900396 if (scan_event == SCAN_EVENT_NETWORK_FOUND) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900397 wiphy = priv->dev->ieee80211_ptr->wiphy;
Leo Kim7ae43362015-09-16 18:35:59 +0900398
399 if (!wiphy)
400 return;
401
Leo Kim0551a722015-11-19 15:56:32 +0900402 if (wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
403 (((s32)network_info->s8rssi * 100) < 0 ||
404 ((s32)network_info->s8rssi * 100) > 100)) {
Leo Kim24db7132015-09-16 18:36:01 +0900405 PRINT_ER("wiphy signal type fial\n");
406 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900407 }
408
Leo Kim0551a722015-11-19 15:56:32 +0900409 if (network_info) {
410 s32Freq = ieee80211_channel_to_frequency((s32)network_info->u8channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900411 channel = ieee80211_get_channel(wiphy, s32Freq);
412
Leo Kim7ae43362015-09-16 18:35:59 +0900413 if (!channel)
414 return;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900415
416 PRINT_INFO(CFG80211_DBG, "Network Info:: CHANNEL Frequency: %d, RSSI: %d, CapabilityInfo: %d,"
Leo Kim0551a722015-11-19 15:56:32 +0900417 "BeaconPeriod: %d\n", channel->center_freq, (((s32)network_info->s8rssi) * 100),
418 network_info->u16CapInfo, network_info->u16BeaconPeriod);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900419
Leo Kim0551a722015-11-19 15:56:32 +0900420 if (network_info->bNewNetwork) {
Leo Kima89f7c52015-11-25 11:59:41 +0900421 if (priv->u32RcvdChCount < MAX_NUM_SCANNED_NETWORKS) {
Leo Kim0551a722015-11-19 15:56:32 +0900422 PRINT_D(CFG80211_DBG, "Network %s found\n", network_info->au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900423 priv->u32RcvdChCount++;
424
Leo Kimbdd34602015-11-19 15:56:34 +0900425 if (!join_params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900426 PRINT_INFO(CORECONFIG_DBG, ">> Something really bad happened\n");
Leo Kimbdd34602015-11-19 15:56:34 +0900427 add_network_to_shadow(network_info, priv, join_params);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900428
Leo Kim0551a722015-11-19 15:56:32 +0900429 if (!(memcmp("DIRECT-", network_info->au8ssid, 7))) {
430 bss = cfg80211_inform_bss(wiphy, channel, CFG80211_BSS_FTYPE_UNKNOWN, network_info->au8bssid, network_info->u64Tsf, network_info->u16CapInfo,
431 network_info->u16BeaconPeriod, (const u8 *)network_info->pu8IEs,
432 (size_t)network_info->u16IEsLen, (((s32)network_info->s8rssi) * 100), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900433 cfg80211_put_bss(wiphy, bss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900434 }
435
436
437 } else {
438 PRINT_ER("Discovered networks exceeded the max limit\n");
439 }
440 } else {
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900441 u32 i;
Leo Kima89f7c52015-11-25 11:59:41 +0900442
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900443 for (i = 0; i < priv->u32RcvdChCount; i++) {
Leo Kim0551a722015-11-19 15:56:32 +0900444 if (memcmp(last_scanned_shadow[i].au8bssid, network_info->au8bssid, 6) == 0) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900445 PRINT_D(CFG80211_DBG, "Update RSSI of %s\n", last_scanned_shadow[i].au8ssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900446
Leo Kim0551a722015-11-19 15:56:32 +0900447 last_scanned_shadow[i].s8rssi = network_info->s8rssi;
Leo Kimf1ab1172015-11-19 15:56:11 +0900448 last_scanned_shadow[i].u32TimeRcvdInScan = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900449 break;
450 }
451 }
452 }
453 }
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900454 } else if (scan_event == SCAN_EVENT_DONE) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530455 PRINT_D(CFG80211_DBG, "Scan Done[%p]\n", priv->dev);
456 PRINT_D(CFG80211_DBG, "Refreshing Scan ...\n");
Dean Lee72ed4dc2015-06-12 14:11:44 +0900457 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900458
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530459 if (priv->u32RcvdChCount > 0)
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530460 PRINT_D(CFG80211_DBG, "%d Network(s) found\n", priv->u32RcvdChCount);
Chandra S Gorentla78174ad2015-08-08 17:41:36 +0530461 else
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530462 PRINT_D(CFG80211_DBG, "No networks found\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900463
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200464 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900465
Leo Kim369a1d32015-12-21 14:18:23 +0900466 if (priv->pstrScanReq) {
Dean Lee72ed4dc2015-06-12 14:11:44 +0900467 cfg80211_scan_done(priv->pstrScanReq, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900468 priv->u32RcvdChCount = 0;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900469 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900470 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900471 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200472 up(&(priv->hSemScanReq));
Leo Kim1a4c8ce2015-11-19 15:56:31 +0900473 } else if (scan_event == SCAN_EVENT_ABORTED) {
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200474 down(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900475
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530476 PRINT_D(CFG80211_DBG, "Scan Aborted\n");
Leo Kim369a1d32015-12-21 14:18:23 +0900477 if (priv->pstrScanReq) {
Leo Kim5e51d8b2015-11-19 15:56:28 +0900478 update_scan_time();
Dean Lee72ed4dc2015-06-12 14:11:44 +0900479 refresh_scan(priv, 1, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900480
Dean Lee72ed4dc2015-06-12 14:11:44 +0900481 cfg80211_scan_done(priv->pstrScanReq, false);
482 priv->bCfgScanning = false;
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +0900483 priv->pstrScanReq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900484 }
Arnd Bergmann83383ea2015-06-01 21:06:43 +0200485 up(&(priv->hSemScanReq));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900486 }
487 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900488}
489
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100490int wilc_connecting;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900491
Leo Kimed3f0372015-10-12 16:56:01 +0900492static void CfgConnectResult(enum conn_event enuConnDisconnEvent,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900493 tstrConnectInfo *pstrConnectInfo,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900494 u8 u8MacStatus,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900495 tstrDisconnectNotifInfo *pstrDisconnectNotifInfo,
496 void *pUserVoid)
497{
Chaehyun Lim27268872015-09-15 14:06:13 +0900498 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900499 struct net_device *dev;
Leo Kim441dc602015-10-12 16:55:35 +0900500 struct host_if_drv *pstrWFIDrv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900501 u8 NullBssid[ETH_ALEN] = {0};
Glen Leec1ec2c12015-10-20 17:13:58 +0900502 struct wilc *wl;
503 perInterface_wlan_t *nic;
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 Leec1ec2c12015-10-20 17:13:58 +0900509 nic = netdev_priv(dev);
510 wl = nic->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 Leec1ec2c12015-10-20 17:13:58 +0900581 if ((pstrWFIDrv->IFC_UP) && (dev == wl->vif[1].ndev)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900582 pstrDisconnectNotifInfo->u16reason = 3;
Leo Kima89f7c52015-11-25 11:59:41 +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;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900598
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900599 priv = wiphy_priv(wiphy);
600
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900601 channelnum = ieee80211_frequency_to_channel(chandef->chan->center_freq);
602 PRINT_D(CFG80211_DBG, "Setting channel %d with frequency %d\n", channelnum, chandef->chan->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900603
Chaehyun Lim866a2c22015-10-02 16:41:21 +0900604 curr_channel = channelnum;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100605 result = wilc_set_mac_chnl_num(priv->hWILCWFIDrv, channelnum);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900606
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900607 if (result != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900608 PRINT_ER("Error in setting channel %d\n", channelnum);
609
Chaehyun Limdd739ea2015-10-02 16:41:20 +0900610 return result;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900611}
612
Chaehyun Lim0e30d062015-09-14 12:24:02 +0900613static int scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900614{
Chaehyun Lim27268872015-09-15 14:06:13 +0900615 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900616 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +0900617 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900618 u8 au8ScanChanList[MAX_NUM_SCANNED_NETWORKS];
Leo Kim607db442015-10-05 15:25:37 +0900619 struct hidden_network strHiddenNetwork;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900620
621 priv = wiphy_priv(wiphy);
622
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900623 priv->pstrScanReq = request;
624
625 priv->u32RcvdChCount = 0;
626
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100627 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Leo Kim12b01382015-11-19 15:56:27 +0900628 reset_shadow_found();
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900629
Dean Lee72ed4dc2015-06-12 14:11:44 +0900630 priv->bCfgScanning = true;
Leo Kima89f7c52015-11-25 11:59:41 +0900631 if (request->n_channels <= MAX_NUM_SCANNED_NETWORKS) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900632 for (i = 0; i < request->n_channels; i++) {
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900633 au8ScanChanList[i] = (u8)ieee80211_frequency_to_channel(request->channels[i]->center_freq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900634 PRINT_INFO(CFG80211_DBG, "ScanChannel List[%d] = %d,", i, au8ScanChanList[i]);
635 }
636
637 PRINT_D(CFG80211_DBG, "Requested num of scan channel %d\n", request->n_channels);
Sudip Mukherjee52db75202015-06-02 14:28:17 +0530638 PRINT_D(CFG80211_DBG, "Scan Request IE len = %zu\n", request->ie_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900639
640 PRINT_D(CFG80211_DBG, "Number of SSIDs %d\n", request->n_ssids);
641
642 if (request->n_ssids >= 1) {
Leo Kim607db442015-10-05 15:25:37 +0900643 strHiddenNetwork.pstrHiddenNetworkInfo = kmalloc(request->n_ssids * sizeof(struct hidden_network), GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900644 strHiddenNetwork.u8ssidnum = request->n_ssids;
645
646
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900647 for (i = 0; i < request->n_ssids; i++) {
Leo Kim369a1d32015-12-21 14:18:23 +0900648 if (request->ssids[i].ssid &&
649 request->ssids[i].ssid_len != 0) {
Glen Leef3052582015-09-10 12:03:04 +0900650 strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid = kmalloc(request->ssids[i].ssid_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900651 memcpy(strHiddenNetwork.pstrHiddenNetworkInfo[i].pu8ssid, request->ssids[i].ssid, request->ssids[i].ssid_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900652 strHiddenNetwork.pstrHiddenNetworkInfo[i].u8ssidlen = request->ssids[i].ssid_len;
653 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530654 PRINT_D(CFG80211_DBG, "Received one NULL SSID\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900655 strHiddenNetwork.u8ssidnum -= 1;
656 }
657 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530658 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100659 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900660 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900661 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900662 CfgScanResult, (void *)priv, &strHiddenNetwork);
663 } else {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530664 PRINT_D(CFG80211_DBG, "Trigger Scan Request\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100665 s32Error = wilc_scan(priv->hWILCWFIDrv, USER_SCAN, ACTIVE_SCAN,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900666 au8ScanChanList, request->n_channels,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900667 (const u8 *)request->ie, request->ie_len,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900668 CfgScanResult, (void *)priv, NULL);
669 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900670 } else {
671 PRINT_ER("Requested num of scanned channels is greater than the max, supported"
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530672 " channels\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900673 }
674
Leo Kime6e12662015-09-16 18:36:03 +0900675 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900676 s32Error = -EBUSY;
677 PRINT_WRN(CFG80211_DBG, "Device is busy: Error(%d)\n", s32Error);
678 }
679
680 return s32Error;
681}
682
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +0900683static int connect(struct wiphy *wiphy, struct net_device *dev,
684 struct cfg80211_connect_params *sme)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900685{
Leo Kime6e12662015-09-16 18:36:03 +0900686 s32 s32Error = 0;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900687 u32 i;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900688 u8 u8security = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +0900689 enum AUTHTYPE tenuAuth_type = ANY;
Dean Lee576917a2015-06-15 11:58:57 +0900690 char *pcgroup_encrypt_val = NULL;
691 char *pccipher_group = NULL;
692 char *pcwpa_version = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900693
Chaehyun Lim27268872015-09-15 14:06:13 +0900694 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +0900695 struct host_if_drv *pstrWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900696 tstrNetworkInfo *pstrNetworkInfo = NULL;
697
698
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100699 wilc_connecting = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900700 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +0900701 pstrWFIDrv = (struct host_if_drv *)(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900702
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100703 wilc_set_wfi_drv_handler(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900704
Johnny Kim8a143302015-06-10 17:06:46 +0900705 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 +0900706 if (!(strncmp(sme->ssid, "DIRECT-", 7))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900707 PRINT_D(CFG80211_DBG, "Connected to Direct network,OBSS disabled\n");
Leo Kimab16ec02015-10-29 12:05:40 +0900708 pstrWFIDrv->p2p_connect = 1;
709 } else {
710 pstrWFIDrv->p2p_connect = 0;
711 }
Chandra S Gorentla17aacd42015-08-08 17:41:35 +0530712 PRINT_INFO(CFG80211_DBG, "Required SSID = %s\n , AuthType = %d\n", sme->ssid, sme->auth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900713
Leo Kim771fbae2015-11-19 15:56:10 +0900714 for (i = 0; i < last_scanned_cnt; i++) {
Leo Kimf1ab1172015-11-19 15:56:11 +0900715 if ((sme->ssid_len == last_scanned_shadow[i].u8SsidLen) &&
716 memcmp(last_scanned_shadow[i].au8ssid,
717 sme->ssid,
718 sme->ssid_len) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900719 PRINT_INFO(CFG80211_DBG, "Network with required SSID is found %s\n", sme->ssid);
Leo Kim369a1d32015-12-21 14:18:23 +0900720 if (!sme->bssid) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900721 PRINT_INFO(CFG80211_DBG, "BSSID is not passed from the user\n");
722 break;
723 } else {
Leo Kimf1ab1172015-11-19 15:56:11 +0900724 if (memcmp(last_scanned_shadow[i].au8bssid,
725 sme->bssid,
726 ETH_ALEN) == 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900727 PRINT_INFO(CFG80211_DBG, "BSSID is passed from the user and matched\n");
728 break;
729 }
730 }
731 }
732 }
733
Leo Kim771fbae2015-11-19 15:56:10 +0900734 if (i < last_scanned_cnt) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900735 PRINT_D(CFG80211_DBG, "Required bss is in scan results\n");
736
Leo Kimf1ab1172015-11-19 15:56:11 +0900737 pstrNetworkInfo = &last_scanned_shadow[i];
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900738
739 PRINT_INFO(CFG80211_DBG, "network BSSID to be associated: %x%x%x%x%x%x\n",
740 pstrNetworkInfo->au8bssid[0], pstrNetworkInfo->au8bssid[1],
741 pstrNetworkInfo->au8bssid[2], pstrNetworkInfo->au8bssid[3],
742 pstrNetworkInfo->au8bssid[4], pstrNetworkInfo->au8bssid[5]);
743 } else {
744 s32Error = -ENOENT;
Leo Kim771fbae2015-11-19 15:56:10 +0900745 if (last_scanned_cnt == 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900746 PRINT_D(CFG80211_DBG, "No Scan results yet\n");
747 else
748 PRINT_D(CFG80211_DBG, "Required bss not in scan results: Error(%d)\n", s32Error);
749
750 goto done;
751 }
752
753 priv->WILC_WFI_wep_default = 0;
Chaehyun Lim2cc46832015-08-07 09:02:01 +0900754 memset(priv->WILC_WFI_wep_key, 0, sizeof(priv->WILC_WFI_wep_key));
755 memset(priv->WILC_WFI_wep_key_len, 0, sizeof(priv->WILC_WFI_wep_key_len));
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900756
757 PRINT_INFO(CFG80211_DBG, "sme->crypto.wpa_versions=%x\n", sme->crypto.wpa_versions);
758 PRINT_INFO(CFG80211_DBG, "sme->crypto.cipher_group=%x\n", sme->crypto.cipher_group);
759
760 PRINT_INFO(CFG80211_DBG, "sme->crypto.n_ciphers_pairwise=%d\n", sme->crypto.n_ciphers_pairwise);
761
762 if (INFO) {
763 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++)
764 PRINT_D(CORECONFIG_DBG, "sme->crypto.ciphers_pairwise[%d]=%x\n", i, sme->crypto.ciphers_pairwise[i]);
765 }
766
767 if (sme->crypto.cipher_group != NO_ENCRYPT) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900768 pcwpa_version = "Default";
769 PRINT_D(CORECONFIG_DBG, ">> sme->crypto.wpa_versions: %x\n", sme->crypto.wpa_versions);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900770 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900771 u8security = ENCRYPT_ENABLED | WEP;
772 pcgroup_encrypt_val = "WEP40";
773 pccipher_group = "WLAN_CIPHER_SUITE_WEP40";
774 PRINT_INFO(CFG80211_DBG, "WEP Default Key Idx = %d\n", sme->key_idx);
775
776 if (INFO) {
777 for (i = 0; i < sme->key_len; i++)
778 PRINT_D(CORECONFIG_DBG, "WEP Key Value[%d] = %d\n", i, sme->key[i]);
779 }
780 priv->WILC_WFI_wep_default = sme->key_idx;
781 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900782 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900783
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900784 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900785 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900786 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
787 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900788 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900789
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100790 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
791 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900792 } else if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900793 u8security = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
794 pcgroup_encrypt_val = "WEP104";
795 pccipher_group = "WLAN_CIPHER_SUITE_WEP104";
796
797 priv->WILC_WFI_wep_default = sme->key_idx;
798 priv->WILC_WFI_wep_key_len[sme->key_idx] = sme->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900799 memcpy(priv->WILC_WFI_wep_key[sme->key_idx], sme->key, sme->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900800
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900801 g_key_wep_params.key_len = sme->key_len;
Glen Leef3052582015-09-10 12:03:04 +0900802 g_key_wep_params.key = kmalloc(sme->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900803 memcpy(g_key_wep_params.key, sme->key, sme->key_len);
804 g_key_wep_params.key_idx = sme->key_idx;
Dean Lee72ed4dc2015-06-12 14:11:44 +0900805 g_wep_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900806
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100807 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, sme->key_idx);
808 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, sme->key, sme->key_len, sme->key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900809 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900810 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900811 u8security = ENCRYPT_ENABLED | WPA2 | TKIP;
812 pcgroup_encrypt_val = "WPA2_TKIP";
813 pccipher_group = "TKIP";
Leo Kima89f7c52015-11-25 11:59:41 +0900814 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900815 u8security = ENCRYPT_ENABLED | WPA2 | AES;
816 pcgroup_encrypt_val = "WPA2_AES";
817 pccipher_group = "AES";
818 }
819 pcwpa_version = "WPA_VERSION_2";
820 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
821 if (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900822 u8security = ENCRYPT_ENABLED | WPA | TKIP;
823 pcgroup_encrypt_val = "WPA_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 | WPA | AES;
827 pcgroup_encrypt_val = "WPA_AES";
828 pccipher_group = "AES";
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900829 }
830 pcwpa_version = "WPA_VERSION_1";
831
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900832 } else {
833 s32Error = -ENOTSUPP;
834 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
835
836 goto done;
837 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900838 }
839
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900840 if ((sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
841 || (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
842 for (i = 0; i < sme->crypto.n_ciphers_pairwise; i++) {
843 if (sme->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP) {
844 u8security = u8security | TKIP;
Leo Kima89f7c52015-11-25 11:59:41 +0900845 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900846 u8security = u8security | AES;
847 }
848 }
849 }
850
851 PRINT_D(CFG80211_DBG, "Adding key with cipher group = %x\n", sme->crypto.cipher_group);
852
853 PRINT_D(CFG80211_DBG, "Authentication Type = %d\n", sme->auth_type);
854 switch (sme->auth_type) {
855 case NL80211_AUTHTYPE_OPEN_SYSTEM:
856 PRINT_D(CFG80211_DBG, "In OPEN SYSTEM\n");
857 tenuAuth_type = OPEN_SYSTEM;
858 break;
859
860 case NL80211_AUTHTYPE_SHARED_KEY:
861 tenuAuth_type = SHARED_KEY;
862 PRINT_D(CFG80211_DBG, "In SHARED KEY\n");
863 break;
864
865 default:
866 PRINT_D(CFG80211_DBG, "Automatic Authentation type = %d\n", sme->auth_type);
867 }
868
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900869 if (sme->crypto.n_akm_suites) {
870 switch (sme->crypto.akm_suites[0]) {
871 case WLAN_AKM_SUITE_8021X:
872 tenuAuth_type = IEEE8021;
873 break;
874
875 default:
876 break;
877 }
878 }
879
880
881 PRINT_INFO(CFG80211_DBG, "Required Channel = %d\n", pstrNetworkInfo->u8channel);
882
883 PRINT_INFO(CFG80211_DBG, "Group encryption value = %s\n Cipher Group = %s\n WPA version = %s\n",
884 pcgroup_encrypt_val, pccipher_group, pcwpa_version);
885
Chaehyun Lim866a2c22015-10-02 16:41:21 +0900886 curr_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900887
Leo Kimab16ec02015-10-29 12:05:40 +0900888 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900889 wlan_channel = pstrNetworkInfo->u8channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900890
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100891 wilc_wlan_set_bssid(dev, pstrNetworkInfo->au8bssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900892
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100893 s32Error = wilc_set_join_req(priv->hWILCWFIDrv, pstrNetworkInfo->au8bssid, sme->ssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900894 sme->ssid_len, sme->ie, sme->ie_len,
895 CfgConnectResult, (void *)priv, u8security,
896 tenuAuth_type, pstrNetworkInfo->u8channel,
897 pstrNetworkInfo->pJoinParams);
Leo Kime6e12662015-09-16 18:36:03 +0900898 if (s32Error != 0) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100899 PRINT_ER("wilc_set_join_req(): Error(%d)\n", s32Error);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900900 s32Error = -ENOENT;
901 goto done;
902 }
903
904done:
905
906 return s32Error;
907}
908
Chaehyun Limb027cde2015-09-14 12:24:04 +0900909static int disconnect(struct wiphy *wiphy, struct net_device *dev, u16 reason_code)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900910{
Leo Kime6e12662015-09-16 18:36:03 +0900911 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +0900912 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +0900913 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim51e825f2015-09-15 14:06:14 +0900914 u8 NullBssid[ETH_ALEN] = {0};
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +0900915
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100916 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900917 priv = wiphy_priv(wiphy);
918
Leo Kim441dc602015-10-12 16:55:35 +0900919 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Leo Kimab16ec02015-10-29 12:05:40 +0900920 if (!pstrWFIDrv->p2p_connect)
Leo Kim0bd82742015-11-19 15:56:14 +0900921 wlan_channel = INVALID_CHANNEL;
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100922 wilc_wlan_set_bssid(priv->dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900923
924 PRINT_D(CFG80211_DBG, "Disconnecting with reason code(%d)\n", reason_code);
925
Leo Kim583d9722015-11-19 15:56:16 +0900926 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +0900927 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +0900928 wilc_ie = false;
Leo Kim1229b1a2015-10-29 12:05:39 +0900929 pstrWFIDrv->p2p_timeout = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900930
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100931 s32Error = wilc_disconnect(priv->hWILCWFIDrv, reason_code);
Leo Kime6e12662015-09-16 18:36:03 +0900932 if (s32Error != 0) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900933 PRINT_ER("Error in disconnecting: Error(%d)\n", s32Error);
934 s32Error = -EINVAL;
935 }
936
937 return s32Error;
938}
939
Chaehyun Lim953d4172015-09-14 12:24:05 +0900940static int add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
941 bool pairwise,
942 const u8 *mac_addr, struct key_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900943
944{
Leo Kime6e12662015-09-16 18:36:03 +0900945 s32 s32Error = 0, KeyLen = params->key_len;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +0900946 u32 i;
Chaehyun Lim27268872015-09-15 14:06:13 +0900947 struct wilc_priv *priv;
Arnd Bergmann057d1e92015-06-01 21:06:44 +0200948 const u8 *pu8RxMic = NULL;
949 const u8 *pu8TxMic = NULL;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900950 u8 u8mode = NO_ENCRYPT;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +0900951 u8 u8gmode = NO_ENCRYPT;
952 u8 u8pmode = NO_ENCRYPT;
Leo Kim841dfc42015-10-05 15:25:39 +0900953 enum AUTHTYPE tenuAuth_type = ANY;
Glen Lee76469202015-10-20 17:13:59 +0900954 struct wilc *wl;
955 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900956
957 priv = wiphy_priv(wiphy);
Glen Lee76469202015-10-20 17:13:59 +0900958 nic = netdev_priv(netdev);
959 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900960
961 PRINT_D(CFG80211_DBG, "Adding key with cipher suite = %x\n", params->cipher);
962
Johnny Kim8a143302015-06-10 17:06:46 +0900963 PRINT_D(CFG80211_DBG, "%p %p %d\n", wiphy, netdev, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900964
965 PRINT_D(CFG80211_DBG, "key %x %x %x\n", params->key[0],
966 params->key[1],
967 params->key[2]);
968
969
970 switch (params->cipher) {
971 case WLAN_CIPHER_SUITE_WEP40:
972 case WLAN_CIPHER_SUITE_WEP104:
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900973 if (priv->wdev->iftype == NL80211_IFTYPE_AP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900974 priv->WILC_WFI_wep_default = key_index;
975 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900976 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900977
978 PRINT_D(CFG80211_DBG, "Adding AP WEP Default key Idx = %d\n", key_index);
979 PRINT_D(CFG80211_DBG, "Adding AP WEP Key len= %d\n", params->key_len);
980
981 for (i = 0; i < params->key_len; i++)
982 PRINT_D(CFG80211_DBG, "WEP AP key val[%d] = %x\n", i, params->key[i]);
983
984 tenuAuth_type = OPEN_SYSTEM;
985
986 if (params->cipher == WLAN_CIPHER_SUITE_WEP40)
987 u8mode = ENCRYPT_ENABLED | WEP;
988 else
989 u8mode = ENCRYPT_ENABLED | WEP | WEP_EXTENDED;
990
Arnd Bergmann0e1af732015-11-16 15:04:54 +0100991 wilc_add_wep_key_bss_ap(priv->hWILCWFIDrv, params->key, params->key_len, key_index, u8mode, tenuAuth_type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900992 break;
993 }
Chaehyun Lim1a646e72015-08-07 09:02:03 +0900994 if (memcmp(params->key, priv->WILC_WFI_wep_key[key_index], params->key_len)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900995 priv->WILC_WFI_wep_default = key_index;
996 priv->WILC_WFI_wep_key_len[key_index] = params->key_len;
Chaehyun Limd00d2ba2015-08-10 11:33:19 +0900997 memcpy(priv->WILC_WFI_wep_key[key_index], params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +0900998
999 PRINT_D(CFG80211_DBG, "Adding WEP Default key Idx = %d\n", key_index);
1000 PRINT_D(CFG80211_DBG, "Adding WEP Key length = %d\n", params->key_len);
1001 if (INFO) {
1002 for (i = 0; i < params->key_len; i++)
1003 PRINT_INFO(CFG80211_DBG, "WEP key value[%d] = %d\n", i, params->key[i]);
1004 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001005 wilc_add_wep_key_bss_sta(priv->hWILCWFIDrv, params->key, params->key_len, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001006 }
1007
1008 break;
1009
1010 case WLAN_CIPHER_SUITE_TKIP:
1011 case WLAN_CIPHER_SUITE_CCMP:
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001012 if (priv->wdev->iftype == NL80211_IFTYPE_AP || priv->wdev->iftype == NL80211_IFTYPE_P2P_GO) {
Leo Kim369a1d32015-12-21 14:18:23 +09001013 if (!priv->wilc_gtk[key_index]) {
Glen Leef3052582015-09-10 12:03:04 +09001014 priv->wilc_gtk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001015 priv->wilc_gtk[key_index]->key = NULL;
1016 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001017 }
Leo Kim369a1d32015-12-21 14:18:23 +09001018 if (!priv->wilc_ptk[key_index]) {
Glen Leef3052582015-09-10 12:03:04 +09001019 priv->wilc_ptk[key_index] = kmalloc(sizeof(struct wilc_wfi_key), GFP_KERNEL);
Greg Kroah-Hartmanb1413b62015-06-02 14:11:12 +09001020 priv->wilc_ptk[key_index]->key = NULL;
1021 priv->wilc_ptk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001022 }
1023
1024
1025
Daniel Machon19132212015-08-05 08:18:31 +02001026 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001027 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1028 u8gmode = ENCRYPT_ENABLED | WPA | TKIP;
1029 else
1030 u8gmode = ENCRYPT_ENABLED | WPA2 | AES;
1031
1032 priv->wilc_groupkey = u8gmode;
1033
1034 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001035 pu8TxMic = params->key + 24;
1036 pu8RxMic = params->key + 16;
1037 KeyLen = params->key_len - 16;
1038 }
Shraddha Barkecccfc392015-10-12 20:49:19 +05301039 kfree(priv->wilc_gtk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001040
Glen Leef3052582015-09-10 12:03:04 +09001041 priv->wilc_gtk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001042 memcpy(priv->wilc_gtk[key_index]->key, params->key, params->key_len);
Shraddha Barkecccfc392015-10-12 20:49:19 +05301043 kfree(priv->wilc_gtk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001044
1045 if ((params->seq_len) > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001046 priv->wilc_gtk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001047 memcpy(priv->wilc_gtk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001048 }
1049
1050 priv->wilc_gtk[key_index]->cipher = params->cipher;
1051 priv->wilc_gtk[key_index]->key_len = params->key_len;
1052 priv->wilc_gtk[key_index]->seq_len = params->seq_len;
1053
1054 if (INFO) {
1055 for (i = 0; i < params->key_len; i++)
1056 PRINT_INFO(CFG80211_DBG, "Adding group key value[%d] = %x\n", i, params->key[i]);
1057 for (i = 0; i < params->seq_len; i++)
1058 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1059 }
1060
1061
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001062 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001063 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, AP_MODE, u8gmode);
1064
1065 } else {
1066 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]);
1067
1068 if (params->cipher == WLAN_CIPHER_SUITE_TKIP)
1069 u8pmode = ENCRYPT_ENABLED | WPA | TKIP;
1070 else
1071 u8pmode = priv->wilc_groupkey | AES;
1072
1073
1074 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001075 pu8TxMic = params->key + 24;
1076 pu8RxMic = params->key + 16;
1077 KeyLen = params->key_len - 16;
1078 }
1079
Shraddha Barkecccfc392015-10-12 20:49:19 +05301080 kfree(priv->wilc_ptk[key_index]->key);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001081
Glen Leef3052582015-09-10 12:03:04 +09001082 priv->wilc_ptk[key_index]->key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001083
Shraddha Barkecccfc392015-10-12 20:49:19 +05301084 kfree(priv->wilc_ptk[key_index]->seq);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001085
1086 if ((params->seq_len) > 0)
Glen Leef3052582015-09-10 12:03:04 +09001087 priv->wilc_ptk[key_index]->seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001088
1089 if (INFO) {
1090 for (i = 0; i < params->key_len; i++)
1091 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %x\n", i, params->key[i]);
1092
1093 for (i = 0; i < params->seq_len; i++)
1094 PRINT_INFO(CFG80211_DBG, "Adding group seq value[%d] = %x\n", i, params->seq[i]);
1095 }
1096
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001097 memcpy(priv->wilc_ptk[key_index]->key, params->key, params->key_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001098
1099 if ((params->seq_len) > 0)
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001100 memcpy(priv->wilc_ptk[key_index]->seq, params->seq, params->seq_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001101
1102 priv->wilc_ptk[key_index]->cipher = params->cipher;
1103 priv->wilc_ptk[key_index]->key_len = params->key_len;
1104 priv->wilc_ptk[key_index]->seq_len = params->seq_len;
1105
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001106 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001107 pu8RxMic, pu8TxMic, AP_MODE, u8pmode, key_index);
1108 }
1109 break;
1110 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001111
1112 {
1113 u8mode = 0;
Daniel Machon19132212015-08-05 08:18:31 +02001114 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001115 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001116 pu8RxMic = params->key + 24;
1117 pu8TxMic = params->key + 16;
1118 KeyLen = params->key_len - 16;
1119 }
1120
Glen Lee76469202015-10-20 17:13:59 +09001121 if (!g_gtk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001122 g_add_gtk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001123 g_add_gtk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001124 if (!mac_addr) {
1125 g_add_gtk_key_params.mac_addr = NULL;
1126 } else {
Glen Leef3052582015-09-10 12:03:04 +09001127 g_add_gtk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001128 memcpy(g_add_gtk_key_params.mac_addr, mac_addr, ETH_ALEN);
1129 }
1130 g_key_gtk_params.key_len = params->key_len;
1131 g_key_gtk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001132 g_key_gtk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001133 memcpy(g_key_gtk_params.key, params->key, params->key_len);
1134 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001135 g_key_gtk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001136 memcpy(g_key_gtk_params.seq, params->seq, params->seq_len);
1137 }
1138 g_key_gtk_params.cipher = params->cipher;
1139
1140 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_gtk_params.key[0],
1141 g_key_gtk_params.key[1],
1142 g_key_gtk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001143 g_gtk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001144 }
1145
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001146 wilc_add_rx_gtk(priv->hWILCWFIDrv, params->key, KeyLen,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001147 key_index, params->seq_len, params->seq, pu8RxMic, pu8TxMic, STATION_MODE, u8mode);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001148 } else {
1149 if (params->key_len > 16 && params->cipher == WLAN_CIPHER_SUITE_TKIP) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001150 pu8RxMic = params->key + 24;
1151 pu8TxMic = params->key + 16;
1152 KeyLen = params->key_len - 16;
1153 }
1154
Glen Lee76469202015-10-20 17:13:59 +09001155 if (!g_ptk_keys_saved && netdev == wl->vif[0].ndev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001156 g_add_ptk_key_params.key_idx = key_index;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001157 g_add_ptk_key_params.pairwise = pairwise;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001158 if (!mac_addr) {
1159 g_add_ptk_key_params.mac_addr = NULL;
1160 } else {
Glen Leef3052582015-09-10 12:03:04 +09001161 g_add_ptk_key_params.mac_addr = kmalloc(ETH_ALEN, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001162 memcpy(g_add_ptk_key_params.mac_addr, mac_addr, ETH_ALEN);
1163 }
1164 g_key_ptk_params.key_len = params->key_len;
1165 g_key_ptk_params.seq_len = params->seq_len;
Glen Leef3052582015-09-10 12:03:04 +09001166 g_key_ptk_params.key = kmalloc(params->key_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001167 memcpy(g_key_ptk_params.key, params->key, params->key_len);
1168 if (params->seq_len > 0) {
Glen Leef3052582015-09-10 12:03:04 +09001169 g_key_ptk_params.seq = kmalloc(params->seq_len, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001170 memcpy(g_key_ptk_params.seq, params->seq, params->seq_len);
1171 }
1172 g_key_ptk_params.cipher = params->cipher;
1173
1174 PRINT_D(CFG80211_DBG, "key %x %x %x\n", g_key_ptk_params.key[0],
1175 g_key_ptk_params.key[1],
1176 g_key_ptk_params.key[2]);
Dean Lee72ed4dc2015-06-12 14:11:44 +09001177 g_ptk_keys_saved = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001178 }
1179
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001180 wilc_add_ptk(priv->hWILCWFIDrv, params->key, KeyLen, mac_addr,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001181 pu8RxMic, pu8TxMic, STATION_MODE, u8mode, key_index);
1182 PRINT_D(CFG80211_DBG, "Adding pairwise key\n");
1183 if (INFO) {
1184 for (i = 0; i < params->key_len; i++)
1185 PRINT_INFO(CFG80211_DBG, "Adding pairwise key value[%d] = %d\n", i, params->key[i]);
1186 }
1187 }
1188 }
1189 break;
1190
1191 default:
1192 PRINT_ER("Not supported cipher: Error(%d)\n", s32Error);
1193 s32Error = -ENOTSUPP;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001194 }
1195
1196 return s32Error;
1197}
1198
Chaehyun Lim3044ba72015-09-14 12:24:06 +09001199static int del_key(struct wiphy *wiphy, struct net_device *netdev,
1200 u8 key_index,
1201 bool pairwise,
1202 const u8 *mac_addr)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001203{
Chaehyun Lim27268872015-09-15 14:06:13 +09001204 struct wilc_priv *priv;
Glen Lee692e2ac2015-10-20 17:14:00 +09001205 struct wilc *wl;
1206 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001207
1208 priv = wiphy_priv(wiphy);
Glen Lee692e2ac2015-10-20 17:14:00 +09001209 nic = netdev_priv(netdev);
1210 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001211
Glen Lee692e2ac2015-10-20 17:14:00 +09001212 if (netdev == wl->vif[0].ndev) {
Dean Lee72ed4dc2015-06-12 14:11:44 +09001213 g_ptk_keys_saved = false;
1214 g_gtk_keys_saved = false;
1215 g_wep_keys_saved = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001216
Shraddha Barkecccfc392015-10-12 20:49:19 +05301217 kfree(g_key_wep_params.key);
1218 g_key_wep_params.key = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001219
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001220 if ((priv->wilc_gtk[key_index]) != NULL) {
Shraddha Barkecccfc392015-10-12 20:49:19 +05301221 kfree(priv->wilc_gtk[key_index]->key);
1222 priv->wilc_gtk[key_index]->key = NULL;
1223 kfree(priv->wilc_gtk[key_index]->seq);
1224 priv->wilc_gtk[key_index]->seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001225
Chaehyun Lim49188af2015-08-11 10:32:41 +09001226 kfree(priv->wilc_gtk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001227 priv->wilc_gtk[key_index] = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001228 }
1229
1230 if ((priv->wilc_ptk[key_index]) != NULL) {
Shraddha Barkecccfc392015-10-12 20:49:19 +05301231 kfree(priv->wilc_ptk[key_index]->key);
1232 priv->wilc_ptk[key_index]->key = NULL;
1233 kfree(priv->wilc_ptk[key_index]->seq);
1234 priv->wilc_ptk[key_index]->seq = NULL;
Chaehyun Lim49188af2015-08-11 10:32:41 +09001235 kfree(priv->wilc_ptk[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001236 priv->wilc_ptk[key_index] = NULL;
1237 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001238
Shraddha Barkecccfc392015-10-12 20:49:19 +05301239 kfree(g_key_ptk_params.key);
1240 g_key_ptk_params.key = NULL;
1241 kfree(g_key_ptk_params.seq);
1242 g_key_ptk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001243
Shraddha Barkecccfc392015-10-12 20:49:19 +05301244 kfree(g_key_gtk_params.key);
1245 g_key_gtk_params.key = NULL;
1246 kfree(g_key_gtk_params.seq);
1247 g_key_gtk_params.seq = NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001248
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001249 wilc_set_machw_change_vir_if(netdev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001250 }
1251
1252 if (key_index >= 0 && key_index <= 3) {
Chaehyun Lim2cc46832015-08-07 09:02:01 +09001253 memset(priv->WILC_WFI_wep_key[key_index], 0, priv->WILC_WFI_wep_key_len[key_index]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001254 priv->WILC_WFI_wep_key_len[key_index] = 0;
1255
1256 PRINT_D(CFG80211_DBG, "Removing WEP key with index = %d\n", key_index);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001257 wilc_remove_wep_key(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001258 } else {
1259 PRINT_D(CFG80211_DBG, "Removing all installed keys\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001260 wilc_remove_key(priv->hWILCWFIDrv, mac_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001261 }
1262
Leo Kimaaed3292015-10-12 16:55:38 +09001263 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001264}
1265
Chaehyun Limf4893df2015-09-14 12:24:07 +09001266static int get_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1267 bool pairwise,
1268 const u8 *mac_addr, void *cookie, void (*callback)(void *cookie, struct key_params *))
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001269{
Chaehyun Lim27268872015-09-15 14:06:13 +09001270 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001271 struct key_params key_params;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001272 u32 i;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001273
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001274 priv = wiphy_priv(wiphy);
1275
1276
Alison Schofield3604af52015-10-12 13:22:44 -07001277 if (!pairwise) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001278 PRINT_D(CFG80211_DBG, "Getting group key idx: %x\n", key_index);
1279
1280 key_params.key = priv->wilc_gtk[key_index]->key;
1281 key_params.cipher = priv->wilc_gtk[key_index]->cipher;
1282 key_params.key_len = priv->wilc_gtk[key_index]->key_len;
1283 key_params.seq = priv->wilc_gtk[key_index]->seq;
1284 key_params.seq_len = priv->wilc_gtk[key_index]->seq_len;
1285 if (INFO) {
1286 for (i = 0; i < key_params.key_len; i++)
1287 PRINT_INFO(CFG80211_DBG, "Retrieved key value %x\n", key_params.key[i]);
1288 }
1289 } else {
1290 PRINT_D(CFG80211_DBG, "Getting pairwise key\n");
1291
1292 key_params.key = priv->wilc_ptk[key_index]->key;
1293 key_params.cipher = priv->wilc_ptk[key_index]->cipher;
1294 key_params.key_len = priv->wilc_ptk[key_index]->key_len;
1295 key_params.seq = priv->wilc_ptk[key_index]->seq;
1296 key_params.seq_len = priv->wilc_ptk[key_index]->seq_len;
1297 }
1298
1299 callback(cookie, &key_params);
1300
Leo Kima89f7c52015-11-25 11:59:41 +09001301 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001302}
1303
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09001304static int set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index,
1305 bool unicast, bool multicast)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001306{
Chaehyun Lim27268872015-09-15 14:06:13 +09001307 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001308
1309
1310 priv = wiphy_priv(wiphy);
1311
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301312 PRINT_D(CFG80211_DBG, "Setting default key with idx = %d\n", key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001313
1314 if (key_index != priv->WILC_WFI_wep_default) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001315 wilc_set_wep_default_keyid(priv->hWILCWFIDrv, key_index);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001316 }
1317
Leo Kimaaed3292015-10-12 16:55:38 +09001318 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001319}
1320
Chaehyun Limf06f5622015-09-14 12:24:18 +09001321static int get_station(struct wiphy *wiphy, struct net_device *dev,
1322 const u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001323{
Chaehyun Lim27268872015-09-15 14:06:13 +09001324 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001325 perInterface_wlan_t *nic;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001326 u32 i = 0;
1327 u32 associatedsta = 0;
1328 u32 inactive_time = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001329 priv = wiphy_priv(wiphy);
1330 nic = netdev_priv(dev);
1331
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001332 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
1333 PRINT_D(HOSTAPD_DBG, "Getting station parameters\n");
1334
1335 PRINT_INFO(HOSTAPD_DBG, ": %x%x%x%x%x\n", mac[0], mac[1], mac[2], mac[3], mac[4]);
1336
1337 for (i = 0; i < NUM_STA_ASSOCIATED; i++) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001338 if (!(memcmp(mac, priv->assoc_stainfo.au8Sta_AssociatedBss[i], ETH_ALEN))) {
1339 associatedsta = i;
1340 break;
1341 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001342 }
1343
1344 if (associatedsta == -1) {
Leo Kimaaed3292015-10-12 16:55:38 +09001345 PRINT_ER("Station required is not associated\n");
1346 return -ENOENT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001347 }
1348
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001349 sinfo->filled |= BIT(NL80211_STA_INFO_INACTIVE_TIME);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001350
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001351 wilc_get_inactive_time(priv->hWILCWFIDrv, mac, &(inactive_time));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001352 sinfo->inactive_time = 1000 * inactive_time;
1353 PRINT_D(CFG80211_DBG, "Inactive time %d\n", sinfo->inactive_time);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001354 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001355
1356 if (nic->iftype == STATION_MODE) {
Leo Kim03e7b9c2015-10-12 16:55:58 +09001357 struct rf_info strStatistics;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001358
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001359 wilc_get_statistics(priv->hWILCWFIDrv, &strStatistics);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001360
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001361 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL) |
Chandra S Gorentla62129902015-08-05 22:11:57 +05301362 BIT(NL80211_STA_INFO_RX_PACKETS) |
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001363 BIT(NL80211_STA_INFO_TX_PACKETS) |
1364 BIT(NL80211_STA_INFO_TX_FAILED) |
1365 BIT(NL80211_STA_INFO_TX_BITRATE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001366
Leo Kim00c8dfc2015-10-29 12:05:30 +09001367 sinfo->signal = strStatistics.rssi;
Leo Kim9b992742015-10-29 12:05:32 +09001368 sinfo->rx_packets = strStatistics.rx_cnt;
Leo Kim54160372015-10-29 12:05:33 +09001369 sinfo->tx_packets = strStatistics.tx_cnt + strStatistics.tx_fail_cnt;
1370 sinfo->tx_failed = strStatistics.tx_fail_cnt;
Leo Kim5babeec2015-10-29 12:05:29 +09001371 sinfo->txrate.legacy = strStatistics.link_speed * 10;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001372
Leo Kim5babeec2015-10-29 12:05:29 +09001373 if ((strStatistics.link_speed > TCP_ACK_FILTER_LINK_SPEED_THRESH) &&
1374 (strStatistics.link_speed != DEFAULT_LINK_SPEED))
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001375 wilc_enable_tcp_ack_filter(true);
Leo Kim5babeec2015-10-29 12:05:29 +09001376 else if (strStatistics.link_speed != DEFAULT_LINK_SPEED)
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001377 wilc_enable_tcp_ack_filter(false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001378
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001379 PRINT_D(CORECONFIG_DBG, "*** stats[%d][%d][%d][%d][%d]\n", sinfo->signal, sinfo->rx_packets, sinfo->tx_packets,
1380 sinfo->tx_failed, sinfo->txrate.legacy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001381 }
Leo Kimaaed3292015-10-12 16:55:38 +09001382 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001383}
1384
Chaehyun Lima5f7db62015-09-14 12:24:20 +09001385static int change_bss(struct wiphy *wiphy, struct net_device *dev,
1386 struct bss_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001387{
1388 PRINT_D(CFG80211_DBG, "Changing Bss parametrs\n");
1389 return 0;
1390}
1391
Chaehyun Lima76b63e2015-09-14 12:24:21 +09001392static int set_wiphy_params(struct wiphy *wiphy, u32 changed)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001393{
Leo Kime6e12662015-09-16 18:36:03 +09001394 s32 s32Error = 0;
Leo Kim95296502015-10-05 15:25:46 +09001395 struct cfg_param_val pstrCfgParamVal;
Chaehyun Lim27268872015-09-15 14:06:13 +09001396 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001397
1398 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001399
Tony Cho87c05b22015-10-12 16:56:07 +09001400 pstrCfgParamVal.flag = 0;
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301401 PRINT_D(CFG80211_DBG, "Setting Wiphy params\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001402
1403 if (changed & WIPHY_PARAM_RETRY_SHORT) {
1404 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RETRY_SHORT %d\n",
1405 priv->dev->ieee80211_ptr->wiphy->retry_short);
Tony Cho87c05b22015-10-12 16:56:07 +09001406 pstrCfgParamVal.flag |= RETRY_SHORT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001407 pstrCfgParamVal.short_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_short;
1408 }
1409 if (changed & WIPHY_PARAM_RETRY_LONG) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001410 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 +09001411 pstrCfgParamVal.flag |= RETRY_LONG;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001412 pstrCfgParamVal.long_retry_limit = priv->dev->ieee80211_ptr->wiphy->retry_long;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001413 }
1414 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
1415 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 +09001416 pstrCfgParamVal.flag |= FRAG_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001417 pstrCfgParamVal.frag_threshold = priv->dev->ieee80211_ptr->wiphy->frag_threshold;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001418 }
1419
1420 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1421 PRINT_D(CFG80211_DBG, "Setting WIPHY_PARAM_RTS_THRESHOLD %d\n", priv->dev->ieee80211_ptr->wiphy->rts_threshold);
1422
Tony Cho87c05b22015-10-12 16:56:07 +09001423 pstrCfgParamVal.flag |= RTS_THRESHOLD;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001424 pstrCfgParamVal.rts_threshold = priv->dev->ieee80211_ptr->wiphy->rts_threshold;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001425 }
1426
1427 PRINT_D(CFG80211_DBG, "Setting CFG params in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001428 s32Error = wilc_hif_set_cfg(priv->hWILCWFIDrv, &pstrCfgParamVal);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001429 if (s32Error)
1430 PRINT_ER("Error in setting WIPHY PARAMS\n");
1431
1432
1433 return s32Error;
1434}
Arnd Bergmanne5af0562015-05-29 22:52:12 +02001435
Chaehyun Lim4d466572015-09-14 12:24:22 +09001436static int set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1437 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001438{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001439 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001440 s32 s32Error = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001441 u8 flag = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001442
Chaehyun Lim27268872015-09-15 14:06:13 +09001443 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001444
1445 PRINT_D(CFG80211_DBG, "Setting PMKSA\n");
1446
1447
1448 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001449 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001450 ETH_ALEN)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001451 flag = PMKID_FOUND;
1452 PRINT_D(CFG80211_DBG, "PMKID already exists\n");
1453 break;
1454 }
1455 }
1456 if (i < WILC_MAX_NUM_PMKIDS) {
1457 PRINT_D(CFG80211_DBG, "Setting PMKID in private structure\n");
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001458 memcpy(priv->pmkid_list.pmkidlist[i].bssid, pmksa->bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001459 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001460 memcpy(priv->pmkid_list.pmkidlist[i].pmkid, pmksa->pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001461 PMKID_LEN);
1462 if (!(flag == PMKID_FOUND))
1463 priv->pmkid_list.numpmkid++;
1464 } else {
1465 PRINT_ER("Invalid PMKID index\n");
1466 s32Error = -EINVAL;
1467 }
1468
1469 if (!s32Error) {
1470 PRINT_D(CFG80211_DBG, "Setting pmkid in the host interface\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001471 s32Error = wilc_set_pmkid_info(priv->hWILCWFIDrv, &priv->pmkid_list);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001472 }
1473 return s32Error;
1474}
1475
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09001476static int del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1477 struct cfg80211_pmksa *pmksa)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001478{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001479 u32 i;
Leo Kime6e12662015-09-16 18:36:03 +09001480 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001481
Chaehyun Lim27268872015-09-15 14:06:13 +09001482 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001483
1484 PRINT_D(CFG80211_DBG, "Deleting PMKSA keys\n");
1485
1486 for (i = 0; i < priv->pmkid_list.numpmkid; i++) {
Chaehyun Lim1a646e72015-08-07 09:02:03 +09001487 if (!memcmp(pmksa->bssid, priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001488 ETH_ALEN)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001489 PRINT_D(CFG80211_DBG, "Reseting PMKID values\n");
Leo Kimcd1e6cb2015-10-05 15:25:45 +09001490 memset(&priv->pmkid_list.pmkidlist[i], 0, sizeof(struct host_if_pmkid));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001491 break;
1492 }
1493 }
1494
1495 if (i < priv->pmkid_list.numpmkid && priv->pmkid_list.numpmkid > 0) {
1496 for (; i < (priv->pmkid_list.numpmkid - 1); i++) {
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001497 memcpy(priv->pmkid_list.pmkidlist[i].bssid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001498 priv->pmkid_list.pmkidlist[i + 1].bssid,
1499 ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001500 memcpy(priv->pmkid_list.pmkidlist[i].pmkid,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001501 priv->pmkid_list.pmkidlist[i].pmkid,
1502 PMKID_LEN);
1503 }
1504 priv->pmkid_list.numpmkid--;
1505 } else {
1506 s32Error = -EINVAL;
1507 }
1508
1509 return s32Error;
1510}
1511
Chaehyun Limb33c39b2015-09-14 12:24:24 +09001512static int flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001513{
Chaehyun Lim27268872015-09-15 14:06:13 +09001514 struct wilc_priv *priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001515
1516 PRINT_D(CFG80211_DBG, "Flushing PMKID key values\n");
1517
Leo Kima949f902015-10-05 15:25:44 +09001518 memset(&priv->pmkid_list, 0, sizeof(struct host_if_pmkid_attr));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001519
1520 return 0;
1521}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001522
Arnd Bergmann1608c402015-11-16 15:04:53 +01001523static void WILC_WFI_CfgParseRxAction(u8 *buf, u32 len)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001524{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001525 u32 index = 0;
1526 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001527
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001528 u8 op_channel_attr_index = 0;
1529 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001530
1531 while (index < len) {
1532 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001533 buf[index + 3] = (buf[index + 3] & 0x01) | (0x00 << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001534 }
1535
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301536 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001537 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301538 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001539 op_channel_attr_index = index;
Leo Kima89f7c52015-11-25 11:59:41 +09001540 index += buf[index + 1] + 3;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001541 }
Leo Kim0bd82742015-11-19 15:56:14 +09001542 if (wlan_channel != INVALID_CHANNEL) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001543 if (channel_list_attr_index) {
1544 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1545 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1546 if (buf[i] == 0x51) {
1547 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
Leo Kim0bd82742015-11-19 15:56:14 +09001548 buf[j] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001549 }
1550 break;
1551 }
1552 }
1553 }
Leo Kima89f7c52015-11-25 11:59:41 +09001554
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001555 if (op_channel_attr_index) {
1556 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1557 buf[op_channel_attr_index + 6] = 0x51;
Leo Kim0bd82742015-11-19 15:56:14 +09001558 buf[op_channel_attr_index + 7] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001559 }
1560 }
1561}
1562
Arnd Bergmann1608c402015-11-16 15:04:53 +01001563static void WILC_WFI_CfgParseTxAction(u8 *buf, u32 len, bool bOperChan, u8 iftype)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001564{
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001565 u32 index = 0;
1566 u32 i = 0, j = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001567
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09001568 u8 op_channel_attr_index = 0;
1569 u8 channel_list_attr_index = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001570
1571 while (index < len) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001572 if (buf[index] == GO_INTENT_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001573 buf[index + 3] = (buf[index + 3] & 0x01) | (0x0f << 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001574
1575 break;
1576 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001577
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301578 if (buf[index] == CHANLIST_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001579 channel_list_attr_index = index;
Chandra S Gorentla78174ad2015-08-08 17:41:36 +05301580 else if (buf[index] == OPERCHAN_ATTR_ID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001581 op_channel_attr_index = index;
Leo Kima89f7c52015-11-25 11:59:41 +09001582 index += buf[index + 1] + 3;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001583 }
Leo Kim0bd82742015-11-19 15:56:14 +09001584 if (wlan_channel != INVALID_CHANNEL && bOperChan) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001585 if (channel_list_attr_index) {
1586 PRINT_D(GENERIC_DBG, "Modify channel list attribute\n");
1587 for (i = channel_list_attr_index + 3; i < ((channel_list_attr_index + 3) + buf[channel_list_attr_index + 1]); i++) {
1588 if (buf[i] == 0x51) {
1589 for (j = i + 2; j < ((i + 2) + buf[i + 1]); j++) {
Leo Kim0bd82742015-11-19 15:56:14 +09001590 buf[j] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001591 }
1592 break;
1593 }
1594 }
1595 }
Leo Kima89f7c52015-11-25 11:59:41 +09001596
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001597 if (op_channel_attr_index) {
1598 PRINT_D(GENERIC_DBG, "Modify operating channel attribute\n");
1599 buf[op_channel_attr_index + 6] = 0x51;
Leo Kim0bd82742015-11-19 15:56:14 +09001600 buf[op_channel_attr_index + 7] = wlan_channel;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001601 }
1602 }
1603}
1604
Chaehyun Limfbc2fe12015-09-15 14:06:16 +09001605void WILC_WFI_p2p_rx (struct net_device *dev, u8 *buff, u32 size)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001606{
Chaehyun Lim27268872015-09-15 14:06:13 +09001607 struct wilc_priv *priv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001608 u32 header, pkt_offset;
Leo Kim441dc602015-10-12 16:55:35 +09001609 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001610 u32 i = 0;
Chaehyun Limfb4ec9c2015-06-11 14:35:59 +09001611 s32 s32Freq;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001612
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001613 priv = wiphy_priv(dev->ieee80211_ptr->wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001614 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001615
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001616 memcpy(&header, (buff - HOST_HDR_OFFSET), HOST_HDR_OFFSET);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001617
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001618 pkt_offset = GET_PKT_OFFSET(header);
1619
1620 if (pkt_offset & IS_MANAGMEMENT_CALLBACK) {
1621 if (buff[FRAME_TYPE_ID] == IEEE80211_STYPE_PROBE_RESP) {
1622 PRINT_D(GENERIC_DBG, "Probe response ACK\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001623 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001624 return;
1625 } else {
1626 if (pkt_offset & IS_MGMT_STATUS_SUCCES) {
1627 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],
1628 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001629 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, true, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001630 } else {
1631 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],
1632 buff[ACTION_SUBTYPE_ID + 1], buff[P2P_PUB_ACTION_SUBTYPE + 1]);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001633 cfg80211_mgmt_tx_status(priv->wdev, priv->u64tx_cookie, buff, size, false, GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001634 }
1635 return;
1636 }
1637 } else {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001638 PRINT_D(GENERIC_DBG, "Rx Frame Type:%x\n", buff[FRAME_TYPE_ID]);
1639
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001640 s32Freq = ieee80211_channel_to_frequency(curr_channel, IEEE80211_BAND_2GHZ);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001641
1642 if (ieee80211_is_action(buff[FRAME_TYPE_ID])) {
1643 PRINT_D(GENERIC_DBG, "Rx Action Frame Type: %x %x\n", buff[ACTION_SUBTYPE_ID], buff[P2P_PUB_ACTION_SUBTYPE]);
1644
Leo Kim1229b1a2015-10-29 12:05:39 +09001645 if (priv->bCfgScanning && time_after_eq(jiffies, (unsigned long)pstrWFIDrv->p2p_timeout)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001646 PRINT_D(GENERIC_DBG, "Receiving action frames from wrong channels\n");
1647 return;
1648 }
1649 if (buff[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001650 switch (buff[ACTION_SUBTYPE_ID]) {
1651 case GAS_INTIAL_REQ:
1652 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buff[ACTION_SUBTYPE_ID]);
1653 break;
1654
1655 case GAS_INTIAL_RSP:
1656 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buff[ACTION_SUBTYPE_ID]);
1657 break;
1658
1659 case PUBLIC_ACT_VENDORSPEC:
Leo Kim881eb5d2015-11-19 15:56:15 +09001660 if (!memcmp(p2p_oui, &buff[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001661 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
Leo Kima25d5182015-11-19 15:56:19 +09001662 if (!wilc_ie) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001663 for (i = P2P_PUB_ACTION_SUBTYPE; i < size; i++) {
Leo Kim86685942015-11-19 15:56:18 +09001664 if (!memcmp(p2p_vendor_spec, &buff[i], 6)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09001665 p2p_recv_random = buff[i + 6];
Leo Kima25d5182015-11-19 15:56:19 +09001666 wilc_ie = true;
Leo Kimb84a3ac2015-11-19 15:56:17 +09001667 PRINT_D(GENERIC_DBG, "WILC Vendor specific IE:%02x\n", p2p_recv_random);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001668 break;
1669 }
1670 }
1671 }
1672 }
Leo Kimb84a3ac2015-11-19 15:56:17 +09001673 if (p2p_local_random > p2p_recv_random) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001674 if ((buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1675 || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buff[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
1676 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < size; i++) {
Leo Kim881eb5d2015-11-19 15:56:15 +09001677 if (buff[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buff[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001678 WILC_WFI_CfgParseRxAction(&buff[i + 6], size - (i + 6));
1679 break;
1680 }
1681 }
1682 }
Leo Kim583d9722015-11-19 15:56:16 +09001683 } else {
Leo Kimb84a3ac2015-11-19 15:56:17 +09001684 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 +09001685 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001686 }
1687
1688
Leo Kima25d5182015-11-19 15:56:19 +09001689 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 +09001690 PRINT_D(GENERIC_DBG, "Sending P2P to host without extra elemnt\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001691 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001692 return;
1693 }
1694 break;
1695
1696 default:
1697 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buff[ACTION_SUBTYPE_ID]);
1698 break;
1699 }
1700 }
1701 }
1702
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001703 cfg80211_rx_mgmt(priv->wdev, s32Freq, 0, buff, size - 7, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001704 }
1705}
1706
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001707static void WILC_WFI_mgmt_tx_complete(void *priv, int status)
1708{
1709 struct p2p_mgmt_data *pv_data = (struct p2p_mgmt_data *)priv;
1710
1711
1712 kfree(pv_data->buff);
1713 kfree(pv_data);
1714}
1715
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001716static void WILC_WFI_RemainOnChannelReady(void *pUserVoid)
1717{
Chaehyun Lim27268872015-09-15 14:06:13 +09001718 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001719
Chaehyun Lim27268872015-09-15 14:06:13 +09001720 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001721
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301722 PRINT_D(HOSTINF_DBG, "Remain on channel ready\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001723
Dean Lee72ed4dc2015-06-12 14:11:44 +09001724 priv->bInP2PlistenState = true;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001725
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001726 cfg80211_ready_on_channel(priv->wdev,
1727 priv->strRemainOnChanParams.u64ListenCookie,
1728 priv->strRemainOnChanParams.pstrListenChan,
1729 priv->strRemainOnChanParams.u32ListenDuration,
1730 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001731}
1732
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001733static void WILC_WFI_RemainOnChannelExpired(void *pUserVoid, u32 u32SessionID)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001734{
Chaehyun Lim27268872015-09-15 14:06:13 +09001735 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001736
Chaehyun Lim27268872015-09-15 14:06:13 +09001737 priv = (struct wilc_priv *)pUserVoid;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001738
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001739 if (u32SessionID == priv->strRemainOnChanParams.u32ListenSessionID) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05301740 PRINT_D(GENERIC_DBG, "Remain on channel expired\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001741
Dean Lee72ed4dc2015-06-12 14:11:44 +09001742 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001743
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001744 cfg80211_remain_on_channel_expired(priv->wdev,
1745 priv->strRemainOnChanParams.u64ListenCookie,
1746 priv->strRemainOnChanParams.pstrListenChan,
1747 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001748 } else {
1749 PRINT_D(GENERIC_DBG, "Received ID 0x%x Expected ID 0x%x (No match)\n", u32SessionID
1750 , priv->strRemainOnChanParams.u32ListenSessionID);
1751 }
1752}
1753
Chaehyun Lim6d19d692015-09-14 12:24:25 +09001754static int remain_on_channel(struct wiphy *wiphy,
1755 struct wireless_dev *wdev,
1756 struct ieee80211_channel *chan,
1757 unsigned int duration, u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001758{
Leo Kime6e12662015-09-16 18:36:03 +09001759 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09001760 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001761
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001762 priv = wiphy_priv(wiphy);
1763
1764 PRINT_D(GENERIC_DBG, "Remaining on channel %d\n", chan->hw_value);
1765
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001766
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001767 if (wdev->iftype == NL80211_IFTYPE_AP) {
1768 PRINT_D(GENERIC_DBG, "Required remain-on-channel while in AP mode");
1769 return s32Error;
1770 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001771
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001772 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001773
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001774 priv->strRemainOnChanParams.pstrListenChan = chan;
1775 priv->strRemainOnChanParams.u64ListenCookie = *cookie;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001776 priv->strRemainOnChanParams.u32ListenDuration = duration;
1777 priv->strRemainOnChanParams.u32ListenSessionID++;
1778
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001779 s32Error = wilc_remain_on_channel(priv->hWILCWFIDrv
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001780 , priv->strRemainOnChanParams.u32ListenSessionID
1781 , duration
1782 , chan->hw_value
1783 , WILC_WFI_RemainOnChannelExpired
1784 , WILC_WFI_RemainOnChannelReady
1785 , (void *)priv);
1786
1787 return s32Error;
1788}
1789
Chaehyun Lim1dd54402015-09-14 12:24:26 +09001790static int cancel_remain_on_channel(struct wiphy *wiphy,
1791 struct wireless_dev *wdev,
1792 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001793{
Leo Kime6e12662015-09-16 18:36:03 +09001794 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09001795 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001796
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001797 priv = wiphy_priv(wiphy);
1798
1799 PRINT_D(CFG80211_DBG, "Cancel remain on channel\n");
1800
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001801 s32Error = wilc_listen_state_expired(priv->hWILCWFIDrv, priv->strRemainOnChanParams.u32ListenSessionID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001802 return s32Error;
1803}
Leo Kima89f7c52015-11-25 11:59:41 +09001804
Chaehyun Limc1560322015-09-22 18:34:51 +09001805static int mgmt_tx(struct wiphy *wiphy,
1806 struct wireless_dev *wdev,
1807 struct cfg80211_mgmt_tx_params *params,
1808 u64 *cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001809{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001810 struct ieee80211_channel *chan = params->chan;
1811 unsigned int wait = params->wait;
1812 const u8 *buf = params->buf;
1813 size_t len = params->len;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001814 const struct ieee80211_mgmt *mgmt;
1815 struct p2p_mgmt_data *mgmt_tx;
Chaehyun Lim27268872015-09-15 14:06:13 +09001816 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09001817 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim4e4467f2015-06-11 14:35:55 +09001818 u32 i;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001819 perInterface_wlan_t *nic;
Leo Kim86685942015-11-19 15:56:18 +09001820 u32 buf_len = len + sizeof(p2p_vendor_spec) + sizeof(p2p_local_random);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001821
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001822 nic = netdev_priv(wdev->netdev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001823 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001824 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001825
1826 *cookie = (unsigned long)buf;
1827 priv->u64tx_cookie = *cookie;
1828 mgmt = (const struct ieee80211_mgmt *) buf;
1829
1830 if (ieee80211_is_mgmt(mgmt->frame_control)) {
Glen Leef3052582015-09-10 12:03:04 +09001831 mgmt_tx = kmalloc(sizeof(struct p2p_mgmt_data), GFP_KERNEL);
Leo Kim369a1d32015-12-21 14:18:23 +09001832 if (!mgmt_tx) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001833 PRINT_ER("Failed to allocate memory for mgmt_tx structure\n");
Leo Kime6e12662015-09-16 18:36:03 +09001834 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001835 }
Glen Leef3052582015-09-10 12:03:04 +09001836 mgmt_tx->buff = kmalloc(buf_len, GFP_KERNEL);
Leo Kim369a1d32015-12-21 14:18:23 +09001837 if (!mgmt_tx->buff) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001838 PRINT_ER("Failed to allocate memory for mgmt_tx buff\n");
Tony Chof638dd32015-09-07 19:09:31 +09001839 kfree(mgmt_tx);
Leo Kime6e12662015-09-16 18:36:03 +09001840 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001841 }
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09001842 memcpy(mgmt_tx->buff, buf, len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001843 mgmt_tx->size = len;
1844
1845
1846 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
1847 PRINT_D(GENERIC_DBG, "TX: Probe Response\n");
1848 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001849 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001850 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001851 } else if (ieee80211_is_action(mgmt->frame_control)) {
Chaehyun Limd85f5322015-06-11 14:35:54 +09001852 PRINT_D(GENERIC_DBG, "ACTION FRAME:%x\n", (u16)mgmt->frame_control);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001853
1854
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001855 if (buf[ACTION_CAT_ID] == PUB_ACTION_ATTR_ID) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001856 if (buf[ACTION_SUBTYPE_ID] != PUBLIC_ACT_VENDORSPEC ||
1857 buf[P2P_PUB_ACTION_SUBTYPE] != GO_NEG_CONF) {
1858 PRINT_D(GENERIC_DBG, "Setting channel: %d\n", chan->hw_value);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01001859 wilc_set_mac_chnl_num(priv->hWILCWFIDrv, chan->hw_value);
Chaehyun Lim866a2c22015-10-02 16:41:21 +09001860 curr_channel = chan->hw_value;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001861 }
1862 switch (buf[ACTION_SUBTYPE_ID]) {
1863 case GAS_INTIAL_REQ:
1864 {
1865 PRINT_D(GENERIC_DBG, "GAS INITIAL REQ %x\n", buf[ACTION_SUBTYPE_ID]);
1866 break;
1867 }
1868
1869 case GAS_INTIAL_RSP:
1870 {
1871 PRINT_D(GENERIC_DBG, "GAS INITIAL RSP %x\n", buf[ACTION_SUBTYPE_ID]);
1872 break;
1873 }
1874
1875 case PUBLIC_ACT_VENDORSPEC:
1876 {
Leo Kim881eb5d2015-11-19 15:56:15 +09001877 if (!memcmp(p2p_oui, &buf[ACTION_SUBTYPE_ID + 1], 4)) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001878 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09001879 if (p2p_local_random == 1 && p2p_recv_random < p2p_local_random) {
Leo Kim583d9722015-11-19 15:56:16 +09001880 get_random_bytes(&p2p_local_random, 1);
1881 p2p_local_random++;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001882 }
1883 }
1884
1885 if ((buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == GO_NEG_RSP
1886 || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)) {
Leo Kimb84a3ac2015-11-19 15:56:17 +09001887 if (p2p_local_random > p2p_recv_random) {
1888 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 +09001889
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001890 for (i = P2P_PUB_ACTION_SUBTYPE + 2; i < len; i++) {
Leo Kim881eb5d2015-11-19 15:56:15 +09001891 if (buf[i] == P2PELEM_ATTR_ID && !(memcmp(p2p_oui, &buf[i + 2], 4))) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001892 if (buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_REQ || buf[P2P_PUB_ACTION_SUBTYPE] == P2P_INV_RSP)
Dean Lee72ed4dc2015-06-12 14:11:44 +09001893 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), true, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001894 else
Dean Lee72ed4dc2015-06-12 14:11:44 +09001895 WILC_WFI_CfgParseTxAction(&mgmt_tx->buff[i + 6], len - (i + 6), false, nic->iftype);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001896 break;
1897 }
1898 }
1899
1900 if (buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_REQ && buf[P2P_PUB_ACTION_SUBTYPE] != P2P_INV_RSP) {
Leo Kim86685942015-11-19 15:56:18 +09001901 memcpy(&mgmt_tx->buff[len], p2p_vendor_spec, sizeof(p2p_vendor_spec));
1902 mgmt_tx->buff[len + sizeof(p2p_vendor_spec)] = p2p_local_random;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001903 mgmt_tx->size = buf_len;
1904 }
Leo Kim583d9722015-11-19 15:56:16 +09001905 } else {
Leo Kimb84a3ac2015-11-19 15:56:17 +09001906 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 +09001907 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001908 }
1909
1910 } else {
1911 PRINT_D(GENERIC_DBG, "Not a P2P public action frame\n");
1912 }
1913
1914 break;
1915 }
1916
1917 default:
1918 {
1919 PRINT_D(GENERIC_DBG, "NOT HANDLED PUBLIC ACTION FRAME TYPE:%x\n", buf[ACTION_SUBTYPE_ID]);
1920 break;
1921 }
1922 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001923 }
1924
1925 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 +09001926 pstrWFIDrv->p2p_timeout = (jiffies + msecs_to_jiffies(wait));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001927
Leo Kim1229b1a2015-10-29 12:05:39 +09001928 PRINT_D(GENERIC_DBG, "Current Jiffies: %lu Timeout:%llu\n",
1929 jiffies, pstrWFIDrv->p2p_timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001930 }
1931
Glen Lee829c4772015-10-29 12:18:44 +09001932 wilc_wlan_txq_add_mgmt_pkt(wdev->netdev, mgmt_tx,
1933 mgmt_tx->buff, mgmt_tx->size,
Glen Leec9d48342015-10-01 16:03:43 +09001934 WILC_WFI_mgmt_tx_complete);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001935 } else {
1936 PRINT_D(GENERIC_DBG, "This function transmits only management frames\n");
1937 }
Leo Kimaaed3292015-10-12 16:55:38 +09001938 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001939}
1940
Chaehyun Lim85c587a2015-09-22 18:34:50 +09001941static int mgmt_tx_cancel_wait(struct wiphy *wiphy,
1942 struct wireless_dev *wdev,
1943 u64 cookie)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001944{
Chaehyun Lim27268872015-09-15 14:06:13 +09001945 struct wilc_priv *priv;
Leo Kim441dc602015-10-12 16:55:35 +09001946 struct host_if_drv *pstrWFIDrv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09001947
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001948 priv = wiphy_priv(wiphy);
Leo Kim441dc602015-10-12 16:55:35 +09001949 pstrWFIDrv = (struct host_if_drv *)priv->hWILCWFIDrv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001950
1951
1952 PRINT_D(GENERIC_DBG, "Tx Cancel wait :%lu\n", jiffies);
Leo Kim1229b1a2015-10-29 12:05:39 +09001953 pstrWFIDrv->p2p_timeout = jiffies;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001954
Luis de Bethencourt7e4e87d2015-10-16 16:32:26 +01001955 if (!priv->bInP2PlistenState) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001956 cfg80211_remain_on_channel_expired(priv->wdev,
1957 priv->strRemainOnChanParams.u64ListenCookie,
1958 priv->strRemainOnChanParams.pstrListenChan,
1959 GFP_KERNEL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001960 }
1961
1962 return 0;
1963}
1964
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09001965void wilc_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev,
1966 u16 frame_type, bool reg)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001967{
Chaehyun Lim27268872015-09-15 14:06:13 +09001968 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001969 perInterface_wlan_t *nic;
Glen Lee1b869352015-10-20 17:14:01 +09001970 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001971
1972 priv = wiphy_priv(wiphy);
1973 nic = netdev_priv(priv->wdev->netdev);
Glen Lee1b869352015-10-20 17:14:01 +09001974 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001975
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001976 if (!frame_type)
1977 return;
1978
1979 PRINT_D(GENERIC_DBG, "Frame registering Frame Type: %x: Boolean: %d\n", frame_type, reg);
1980 switch (frame_type) {
1981 case PROBE_REQ:
1982 {
1983 nic->g_struct_frame_reg[0].frame_type = frame_type;
1984 nic->g_struct_frame_reg[0].reg = reg;
1985 }
1986 break;
1987
1988 case ACTION:
1989 {
1990 nic->g_struct_frame_reg[1].frame_type = frame_type;
1991 nic->g_struct_frame_reg[1].reg = reg;
1992 }
1993 break;
1994
1995 default:
1996 {
1997 break;
1998 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09001999 }
Leo Kima89f7c52015-11-25 11:59:41 +09002000
Glen Lee1b869352015-10-20 17:14:01 +09002001 if (!wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002002 PRINT_D(GENERIC_DBG, "Return since mac is closed\n");
2003 return;
2004 }
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002005 wilc_frame_register(priv->hWILCWFIDrv, frame_type, reg);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002006}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002007
Chaehyun Lima8047e22015-09-22 18:34:48 +09002008static int set_cqm_rssi_config(struct wiphy *wiphy, struct net_device *dev,
2009 s32 rssi_thold, u32 rssi_hyst)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002010{
2011 PRINT_D(CFG80211_DBG, "Setting CQM RSSi Function\n");
2012 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002013}
Leo Kima89f7c52015-11-25 11:59:41 +09002014
Chaehyun Limbdb63382015-09-14 12:24:19 +09002015static int dump_station(struct wiphy *wiphy, struct net_device *dev,
2016 int idx, u8 *mac, struct station_info *sinfo)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002017{
Chaehyun Lim27268872015-09-15 14:06:13 +09002018 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002019
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002020 PRINT_D(CFG80211_DBG, "Dumping station information\n");
2021
2022 if (idx != 0)
2023 return -ENOENT;
2024
2025 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002026
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002027 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002028
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002029 wilc_get_rssi(priv->hWILCWFIDrv, &(sinfo->signal));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002030
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002031 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002032}
2033
Chaehyun Lim46530672015-09-22 18:34:46 +09002034static int set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
2035 bool enabled, int timeout)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002036{
Chaehyun Lim27268872015-09-15 14:06:13 +09002037 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002038
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002039 PRINT_D(CFG80211_DBG, " Power save Enabled= %d , TimeOut = %d\n", enabled, timeout);
2040
Leo Kim369a1d32015-12-21 14:18:23 +09002041 if (!wiphy)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002042 return -ENOENT;
2043
2044 priv = wiphy_priv(wiphy);
Leo Kim369a1d32015-12-21 14:18:23 +09002045 if (!priv->hWILCWFIDrv) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002046 PRINT_ER("Driver is NULL\n");
2047 return -EIO;
2048 }
2049
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002050 if (wilc_enable_ps)
2051 wilc_set_power_mgmt(priv->hWILCWFIDrv, enabled, timeout);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002052
2053
Leo Kime6e12662015-09-16 18:36:03 +09002054 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002055}
Glen Lee108b3432015-09-16 18:53:20 +09002056
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002057static int change_virtual_intf(struct wiphy *wiphy, struct net_device *dev,
2058 enum nl80211_iftype type, u32 *flags, struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002059{
Chaehyun Lim27268872015-09-15 14:06:13 +09002060 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002061 perInterface_wlan_t *nic;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002062 u8 interface_type;
Chaehyun Limd85f5322015-06-11 14:35:54 +09002063 u16 TID = 0;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002064 u8 i;
Glen Lee299382c2015-10-20 17:13:56 +09002065 struct wilc *wl;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002066
2067 nic = netdev_priv(dev);
2068 priv = wiphy_priv(wiphy);
Glen Lee299382c2015-10-20 17:13:56 +09002069 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002070
2071 PRINT_D(HOSTAPD_DBG, "In Change virtual interface function\n");
2072 PRINT_D(HOSTAPD_DBG, "Wireless interface name =%s\n", dev->name);
Leo Kim583d9722015-11-19 15:56:16 +09002073 p2p_local_random = 0x01;
Leo Kimb84a3ac2015-11-19 15:56:17 +09002074 p2p_recv_random = 0x00;
Leo Kima25d5182015-11-19 15:56:19 +09002075 wilc_ie = false;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002076 wilc_optaining_ip = false;
2077 del_timer(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002078 PRINT_D(GENERIC_DBG, "Changing virtual interface, enable scan\n");
Leo Kima89f7c52015-11-25 11:59:41 +09002079
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002080 if (g_ptk_keys_saved && g_gtk_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002081 wilc_set_machw_change_vir_if(dev, true);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002082 }
2083
2084 switch (type) {
2085 case NL80211_IFTYPE_STATION:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002086 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002087 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_STATION\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002088
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002089 dev->ieee80211_ptr->iftype = type;
2090 priv->wdev->iftype = type;
2091 nic->monitor_flag = 0;
2092 nic->iftype = STATION_MODE;
2093
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002094 memset(priv->assoc_stainfo.au8Sta_AssociatedBss, 0, MAX_NUM_STA * ETH_ALEN);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002095 interface_type = nic->iftype;
2096 nic->iftype = STATION_MODE;
2097
Glen Lee299382c2015-10-20 17:13:56 +09002098 if (wl->initialized) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002099 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2100 wl->vif[0].bssid, TID);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002101 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002102
Glen Lee299382c2015-10-20 17:13:56 +09002103 up(&wl->cfg_event);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002104
Glen Lee53dc0cf2015-10-20 17:13:57 +09002105 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002106 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002107 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002108 nic->iftype = interface_type;
2109
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002110 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2111 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002112 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002113 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002114
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002115 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002116 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002117 g_key_wep_params.key_idx);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002118 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002119 g_key_wep_params.key,
2120 g_key_wep_params.key_len,
2121 g_key_wep_params.key_idx);
2122 }
2123
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002124 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002125
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002126 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2127 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2128 g_key_ptk_params.key[1],
2129 g_key_ptk_params.key[2]);
2130 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2131 g_key_gtk_params.key[1],
2132 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002133 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2134 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002135 g_add_ptk_key_params.key_idx,
2136 g_add_ptk_key_params.pairwise,
2137 g_add_ptk_key_params.mac_addr,
2138 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002139
Glen Lee299382c2015-10-20 17:13:56 +09002140 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2141 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002142 g_add_gtk_key_params.key_idx,
2143 g_add_gtk_key_params.pairwise,
2144 g_add_gtk_key_params.mac_addr,
2145 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002146 }
2147
Glen Lee299382c2015-10-20 17:13:56 +09002148 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002149 for (i = 0; i < num_reg_frame; i++) {
2150 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2151 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002152 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002153 nic->g_struct_frame_reg[i].frame_type,
2154 nic->g_struct_frame_reg[i].reg);
2155 }
2156 }
2157
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002158 wilc_enable_ps = true;
2159 wilc_set_power_mgmt(priv->hWILCWFIDrv, 1, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002160 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002161 break;
2162
2163 case NL80211_IFTYPE_P2P_CLIENT:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002164 wilc_enable_ps = false;
2165 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
2166 wilc_connecting = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002167 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_P2P_CLIENT\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002168
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002169 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2170 wl->vif[0].bssid, TID);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002171
2172 dev->ieee80211_ptr->iftype = type;
2173 priv->wdev->iftype = type;
2174 nic->monitor_flag = 0;
2175
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002176 PRINT_D(HOSTAPD_DBG, "Downloading P2P_CONCURRENCY_FIRMWARE\n");
2177 nic->iftype = CLIENT_MODE;
2178
2179
Glen Lee299382c2015-10-20 17:13:56 +09002180 if (wl->initialized) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002181 wilc_wait_msg_queue_idle();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002182
Glen Lee53dc0cf2015-10-20 17:13:57 +09002183 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002184 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002185 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002186
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002187 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2188 wilc_set_mac_address(wl->vif[0].hif_drv,
Glen Lee299382c2015-10-20 17:13:56 +09002189 wl->vif[0].src_addr);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002190 wilc_set_operation_mode(priv->hWILCWFIDrv, STATION_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002191
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002192 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002193 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2194 g_key_wep_params.key_idx);
2195 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
2196 g_key_wep_params.key,
2197 g_key_wep_params.key_len,
2198 g_key_wep_params.key_idx);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002199 }
2200
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002201 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002202
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002203 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2204 PRINT_D(CFG80211_DBG, "ptk %x %x %x\n", g_key_ptk_params.key[0],
2205 g_key_ptk_params.key[1],
2206 g_key_ptk_params.key[2]);
2207 PRINT_D(CFG80211_DBG, "gtk %x %x %x\n", g_key_gtk_params.key[0],
2208 g_key_gtk_params.key[1],
2209 g_key_gtk_params.key[2]);
Glen Lee299382c2015-10-20 17:13:56 +09002210 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2211 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002212 g_add_ptk_key_params.key_idx,
2213 g_add_ptk_key_params.pairwise,
2214 g_add_ptk_key_params.mac_addr,
2215 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002216
Glen Lee299382c2015-10-20 17:13:56 +09002217 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2218 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002219 g_add_gtk_key_params.key_idx,
2220 g_add_gtk_key_params.pairwise,
2221 g_add_gtk_key_params.mac_addr,
2222 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002223 }
2224
Dean Lee72ed4dc2015-06-12 14:11:44 +09002225 refresh_scan(priv, 1, true);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002226 wilc_set_machw_change_vir_if(dev, false);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002227
Glen Lee299382c2015-10-20 17:13:56 +09002228 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002229 for (i = 0; i < num_reg_frame; i++) {
2230 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2231 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002232 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002233 nic->g_struct_frame_reg[i].frame_type,
2234 nic->g_struct_frame_reg[i].reg);
2235 }
2236 }
2237 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002238 break;
2239
2240 case NL80211_IFTYPE_AP:
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002241 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002242 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_AP %d\n", type);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002243 dev->ieee80211_ptr->iftype = type;
2244 priv->wdev->iftype = type;
2245 nic->iftype = AP_MODE;
Johnny Kim8a143302015-06-10 17:06:46 +09002246 PRINT_D(CORECONFIG_DBG, "priv->hWILCWFIDrv[%p]\n", priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002247
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002248 PRINT_D(HOSTAPD_DBG, "Downloading AP firmware\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002249 wilc_wlan_get_firmware(dev);
Leo Kima89f7c52015-11-25 11:59:41 +09002250
Glen Lee299382c2015-10-20 17:13:56 +09002251 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002252 nic->iftype = AP_MODE;
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002253 wilc_mac_close(dev);
2254 wilc_mac_open(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002255
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002256 for (i = 0; i < num_reg_frame; i++) {
2257 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2258 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002259 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002260 nic->g_struct_frame_reg[i].frame_type,
2261 nic->g_struct_frame_reg[i].reg);
2262 }
2263 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002264 break;
2265
2266 case NL80211_IFTYPE_P2P_GO:
2267 PRINT_D(GENERIC_DBG, "start duringIP timer\n");
2268
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002269 wilc_optaining_ip = true;
Leo Kim7e872df2015-11-19 15:56:20 +09002270 mod_timer(&wilc_during_ip_timer,
2271 jiffies + msecs_to_jiffies(during_ip_time));
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002272 wilc_set_power_mgmt(priv->hWILCWFIDrv, 0, 0);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002273 wilc_del_all_rx_ba_session(priv->hWILCWFIDrv,
2274 wl->vif[0].bssid, TID);
2275 wilc_enable_ps = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002276 PRINT_D(HOSTAPD_DBG, "Interface type = NL80211_IFTYPE_GO\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002277 dev->ieee80211_ptr->iftype = type;
2278 priv->wdev->iftype = type;
2279
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 P2P_CONCURRENCY_FIRMWARE\n");
2283
2284
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002285 nic->iftype = GO_MODE;
2286
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002287 wilc_wait_msg_queue_idle();
Glen Lee53dc0cf2015-10-20 17:13:57 +09002288 wilc1000_wlan_deinit(dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002289 wilc1000_wlan_init(dev, nic);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002290 wilc_initialized = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002291
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002292 wilc_set_wfi_drv_handler(wl->vif[0].hif_drv);
2293 wilc_set_mac_address(wl->vif[0].hif_drv,
2294 wl->vif[0].src_addr);
2295 wilc_set_operation_mode(priv->hWILCWFIDrv, AP_MODE);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002296
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002297 if (g_wep_keys_saved) {
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002298 wilc_set_wep_default_keyid(wl->vif[0].hif_drv,
2299 g_key_wep_params.key_idx);
2300 wilc_add_wep_key_bss_sta(wl->vif[0].hif_drv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002301 g_key_wep_params.key,
2302 g_key_wep_params.key_len,
2303 g_key_wep_params.key_idx);
2304 }
2305
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002306 wilc_flush_join_req(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002307
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002308 if (g_ptk_keys_saved && g_gtk_keys_saved) {
2309 PRINT_D(CFG80211_DBG, "ptk %x %x %x cipher %x\n", g_key_ptk_params.key[0],
2310 g_key_ptk_params.key[1],
2311 g_key_ptk_params.key[2],
2312 g_key_ptk_params.cipher);
2313 PRINT_D(CFG80211_DBG, "gtk %x %x %x cipher %x\n", g_key_gtk_params.key[0],
2314 g_key_gtk_params.key[1],
2315 g_key_gtk_params.key[2],
2316 g_key_gtk_params.cipher);
Glen Lee299382c2015-10-20 17:13:56 +09002317 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2318 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002319 g_add_ptk_key_params.key_idx,
2320 g_add_ptk_key_params.pairwise,
2321 g_add_ptk_key_params.mac_addr,
2322 (struct key_params *)(&g_key_ptk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002323
Glen Lee299382c2015-10-20 17:13:56 +09002324 add_key(wl->vif[0].ndev->ieee80211_ptr->wiphy,
2325 wl->vif[0].ndev,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002326 g_add_gtk_key_params.key_idx,
2327 g_add_gtk_key_params.pairwise,
2328 g_add_gtk_key_params.mac_addr,
2329 (struct key_params *)(&g_key_gtk_params));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002330 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002331
Glen Lee299382c2015-10-20 17:13:56 +09002332 if (wl->initialized) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002333 for (i = 0; i < num_reg_frame; i++) {
2334 PRINT_D(INIT_DBG, "Frame registering Type: %x - Reg: %d\n", nic->g_struct_frame_reg[i].frame_type,
2335 nic->g_struct_frame_reg[i].reg);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002336 wilc_frame_register(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002337 nic->g_struct_frame_reg[i].frame_type,
2338 nic->g_struct_frame_reg[i].reg);
2339 }
2340 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002341 break;
2342
2343 default:
2344 PRINT_ER("Unknown interface type= %d\n", type);
Leo Kimaaed3292015-10-12 16:55:38 +09002345 return -EINVAL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002346 }
2347
Leo Kimaaed3292015-10-12 16:55:38 +09002348 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002349}
2350
Chaehyun Lima13168d2015-09-14 12:24:12 +09002351static int start_ap(struct wiphy *wiphy, struct net_device *dev,
2352 struct cfg80211_ap_settings *settings)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002353{
2354 struct cfg80211_beacon_data *beacon = &(settings->beacon);
Chaehyun Lim27268872015-09-15 14:06:13 +09002355 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002356 s32 s32Error = 0;
Glen Lee684dc182015-10-20 17:14:02 +09002357 struct wilc *wl;
2358 perInterface_wlan_t *nic;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002359
2360 priv = wiphy_priv(wiphy);
Glen Lee684dc182015-10-20 17:14:02 +09002361 nic = netdev_priv(dev);
2362 wl = nic->wilc;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002363 PRINT_D(HOSTAPD_DBG, "Starting ap\n");
2364
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302365 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 +09002366 settings->beacon_interval, settings->dtim_period, beacon->head_len, beacon->tail_len);
2367
Chaehyun Lim80785a92015-09-14 12:24:01 +09002368 s32Error = set_channel(wiphy, &settings->chandef);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002369
Leo Kime6e12662015-09-16 18:36:03 +09002370 if (s32Error != 0)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002371 PRINT_ER("Error in setting channel\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002372
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002373 wilc_wlan_set_bssid(dev, wl->vif[0].src_addr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002374
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002375 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002376 settings->beacon_interval,
2377 settings->dtim_period,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002378 beacon->head_len, (u8 *)beacon->head,
2379 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002380
2381 return s32Error;
2382}
2383
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002384static int change_beacon(struct wiphy *wiphy, struct net_device *dev,
2385 struct cfg80211_beacon_data *beacon)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002386{
Chaehyun Lim27268872015-09-15 14:06:13 +09002387 struct wilc_priv *priv;
Leo Kime6e12662015-09-16 18:36:03 +09002388 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002389
2390 priv = wiphy_priv(wiphy);
2391 PRINT_D(HOSTAPD_DBG, "Setting beacon\n");
2392
2393
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002394 s32Error = wilc_add_beacon(priv->hWILCWFIDrv,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002395 0,
2396 0,
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002397 beacon->head_len, (u8 *)beacon->head,
2398 beacon->tail_len, (u8 *)beacon->tail);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002399
2400 return s32Error;
2401}
2402
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002403static int stop_ap(struct wiphy *wiphy, struct net_device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002404{
Leo Kime6e12662015-09-16 18:36:03 +09002405 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002406 struct wilc_priv *priv;
Greg Kroah-Hartman63d03e42015-06-02 14:16:04 +09002407 u8 NullBssid[ETH_ALEN] = {0};
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002408
Leo Kim7ae43362015-09-16 18:35:59 +09002409 if (!wiphy)
2410 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002411
2412 priv = wiphy_priv(wiphy);
2413
2414 PRINT_D(HOSTAPD_DBG, "Deleting beacon\n");
2415
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002416 wilc_wlan_set_bssid(dev, NullBssid);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002417
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002418 s32Error = wilc_del_beacon(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002419
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002420 if (s32Error)
2421 PRINT_ER("Host delete beacon fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002422
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002423 return s32Error;
2424}
2425
Chaehyun Limed269552015-09-14 12:24:15 +09002426static int add_station(struct wiphy *wiphy, struct net_device *dev,
2427 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002428{
Leo Kime6e12662015-09-16 18:36:03 +09002429 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002430 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09002431 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002432 perInterface_wlan_t *nic;
2433
Leo Kim7ae43362015-09-16 18:35:59 +09002434 if (!wiphy)
2435 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002436
2437 priv = wiphy_priv(wiphy);
2438 nic = netdev_priv(dev);
2439
2440 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09002441 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Chaehyun Limd00d2ba2015-08-10 11:33:19 +09002442 memcpy(priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid], mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09002443 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09002444 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09002445 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002446
2447 PRINT_D(CFG80211_DBG, "Adding station parameters %d\n", params->aid);
2448
2449 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],
2450 priv->assoc_stainfo.au8Sta_AssociatedBss[params->aid][5]);
Leo Kim4101eb82015-10-29 12:05:42 +09002451 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09002452 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
2453 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002454
Leo Kim369a1d32015-12-21 14:18:23 +09002455 if (!params->ht_capa) {
Leo Kim22520122015-10-29 12:05:45 +09002456 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002457 } else {
Leo Kim22520122015-10-29 12:05:45 +09002458 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09002459 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09002460 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09002461 memcpy(strStaParams.ht_supp_mcs_set,
2462 &params->ht_capa->mcs,
2463 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09002464 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09002465 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09002466 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002467 }
2468
Leo Kimf676e172015-10-29 12:05:52 +09002469 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09002470 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002471
Leo Kim22520122015-10-29 12:05:45 +09002472 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
2473 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09002474 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
2475 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09002476 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
2477 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09002478 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
2479 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09002480 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
2481 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09002482 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
2483 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09002484 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
2485 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09002486 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
2487 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002488
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002489 s32Error = wilc_add_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002490 if (s32Error)
2491 PRINT_ER("Host add station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002492 }
2493
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002494 return s32Error;
2495}
2496
Chaehyun Lima0a8be92015-09-14 12:24:16 +09002497static int del_station(struct wiphy *wiphy, struct net_device *dev,
2498 struct station_del_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002499{
Arnd Bergmann057d1e92015-06-01 21:06:44 +02002500 const u8 *mac = params->mac;
Leo Kime6e12662015-09-16 18:36:03 +09002501 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002502 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002503 perInterface_wlan_t *nic;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002504
Leo Kim7ae43362015-09-16 18:35:59 +09002505 if (!wiphy)
2506 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002507
2508 priv = wiphy_priv(wiphy);
2509 nic = netdev_priv(dev);
2510
2511 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
2512 PRINT_D(HOSTAPD_DBG, "Deleting station\n");
2513
2514
Leo Kim369a1d32015-12-21 14:18:23 +09002515 if (!mac) {
Chandra S Gorentla17aacd42015-08-08 17:41:35 +05302516 PRINT_D(HOSTAPD_DBG, "All associated stations\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002517 s32Error = wilc_del_allstation(priv->hWILCWFIDrv, priv->assoc_stainfo.au8Sta_AssociatedBss);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002518 } else {
2519 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]);
2520 }
2521
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002522 s32Error = wilc_del_station(priv->hWILCWFIDrv, mac);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002523
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002524 if (s32Error)
2525 PRINT_ER("Host delete station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002526 }
2527 return s32Error;
2528}
2529
Chaehyun Lim14b42082015-09-14 12:24:17 +09002530static int change_station(struct wiphy *wiphy, struct net_device *dev,
2531 const u8 *mac, struct station_parameters *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002532{
Leo Kime6e12662015-09-16 18:36:03 +09002533 s32 s32Error = 0;
Chaehyun Lim27268872015-09-15 14:06:13 +09002534 struct wilc_priv *priv;
Tony Cho6a89ba92015-09-21 12:16:46 +09002535 struct add_sta_param strStaParams = { {0} };
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002536 perInterface_wlan_t *nic;
2537
2538
2539 PRINT_D(HOSTAPD_DBG, "Change station paramters\n");
2540
Leo Kim7ae43362015-09-16 18:35:59 +09002541 if (!wiphy)
2542 return -EFAULT;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002543
2544 priv = wiphy_priv(wiphy);
2545 nic = netdev_priv(dev);
2546
2547 if (nic->iftype == AP_MODE || nic->iftype == GO_MODE) {
Leo Kim2353c382015-10-29 12:05:41 +09002548 memcpy(strStaParams.bssid, mac, ETH_ALEN);
Leo Kim4101eb82015-10-29 12:05:42 +09002549 strStaParams.aid = params->aid;
Leo Kime7342232015-10-29 12:05:43 +09002550 strStaParams.rates_len = params->supported_rates_len;
Leo Kima622e012015-10-29 12:05:44 +09002551 strStaParams.rates = params->supported_rates;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002552
Leo Kim2353c382015-10-29 12:05:41 +09002553 PRINT_D(HOSTAPD_DBG, "BSSID = %x%x%x%x%x%x\n",
2554 strStaParams.bssid[0], strStaParams.bssid[1],
2555 strStaParams.bssid[2], strStaParams.bssid[3],
2556 strStaParams.bssid[4], strStaParams.bssid[5]);
Leo Kim4101eb82015-10-29 12:05:42 +09002557 PRINT_D(HOSTAPD_DBG, "ASSOC ID = %d\n", strStaParams.aid);
Leo Kime7342232015-10-29 12:05:43 +09002558 PRINT_D(HOSTAPD_DBG, "Number of supported rates = %d\n",
2559 strStaParams.rates_len);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002560
Leo Kim369a1d32015-12-21 14:18:23 +09002561 if (!params->ht_capa) {
Leo Kim22520122015-10-29 12:05:45 +09002562 strStaParams.ht_supported = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002563 } else {
Leo Kim22520122015-10-29 12:05:45 +09002564 strStaParams.ht_supported = true;
Leo Kim0d073f62015-10-29 12:05:46 +09002565 strStaParams.ht_capa_info = params->ht_capa->cap_info;
Leo Kimfba1f2d2015-10-29 12:05:47 +09002566 strStaParams.ht_ampdu_params = params->ht_capa->ampdu_params_info;
Leo Kim5ebbf4f2015-10-29 12:05:48 +09002567 memcpy(strStaParams.ht_supp_mcs_set,
2568 &params->ht_capa->mcs,
2569 WILC_SUPP_MCS_SET_SIZE);
Leo Kim223741d2015-10-29 12:05:49 +09002570 strStaParams.ht_ext_params = params->ht_capa->extended_ht_cap_info;
Leo Kim74fe73c2015-10-29 12:05:50 +09002571 strStaParams.ht_tx_bf_cap = params->ht_capa->tx_BF_cap_info;
Leo Kima486baf2015-10-29 12:05:51 +09002572 strStaParams.ht_ante_sel = params->ht_capa->antenna_selection_info;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002573 }
2574
Leo Kimf676e172015-10-29 12:05:52 +09002575 strStaParams.flags_mask = params->sta_flags_mask;
Leo Kim67ab64e2015-10-29 12:05:53 +09002576 strStaParams.flags_set = params->sta_flags_set;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002577
Leo Kim22520122015-10-29 12:05:45 +09002578 PRINT_D(HOSTAPD_DBG, "IS HT supported = %d\n",
2579 strStaParams.ht_supported);
Leo Kim0d073f62015-10-29 12:05:46 +09002580 PRINT_D(HOSTAPD_DBG, "Capability Info = %d\n",
2581 strStaParams.ht_capa_info);
Leo Kimfba1f2d2015-10-29 12:05:47 +09002582 PRINT_D(HOSTAPD_DBG, "AMPDU Params = %d\n",
2583 strStaParams.ht_ampdu_params);
Leo Kim223741d2015-10-29 12:05:49 +09002584 PRINT_D(HOSTAPD_DBG, "HT Extended params = %d\n",
2585 strStaParams.ht_ext_params);
Leo Kim74fe73c2015-10-29 12:05:50 +09002586 PRINT_D(HOSTAPD_DBG, "Tx Beamforming Cap = %d\n",
2587 strStaParams.ht_tx_bf_cap);
Leo Kima486baf2015-10-29 12:05:51 +09002588 PRINT_D(HOSTAPD_DBG, "Antenna selection info = %d\n",
2589 strStaParams.ht_ante_sel);
Leo Kimf676e172015-10-29 12:05:52 +09002590 PRINT_D(HOSTAPD_DBG, "Flag Mask = %d\n",
2591 strStaParams.flags_mask);
Leo Kim67ab64e2015-10-29 12:05:53 +09002592 PRINT_D(HOSTAPD_DBG, "Flag Set = %d\n",
2593 strStaParams.flags_set);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002594
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002595 s32Error = wilc_edit_station(priv->hWILCWFIDrv, &strStaParams);
Leo Kim7dc1d0c2015-09-16 18:36:00 +09002596 if (s32Error)
2597 PRINT_ER("Host edit station fail\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002598 }
2599 return s32Error;
2600}
2601
Chaehyun Lim37316e82015-09-22 18:34:52 +09002602static struct wireless_dev *add_virtual_intf(struct wiphy *wiphy,
2603 const char *name,
2604 unsigned char name_assign_type,
2605 enum nl80211_iftype type,
2606 u32 *flags,
2607 struct vif_params *params)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002608{
2609 perInterface_wlan_t *nic;
Chaehyun Lim27268872015-09-15 14:06:13 +09002610 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002611 struct net_device *new_ifc = NULL;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002612
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002613 priv = wiphy_priv(wiphy);
2614
2615
2616
2617 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", priv->wdev->netdev);
2618
2619 nic = netdev_priv(priv->wdev->netdev);
2620
2621
2622 if (type == NL80211_IFTYPE_MONITOR) {
2623 PRINT_D(HOSTAPD_DBG, "Monitor interface mode: Initializing mon interface virtual device driver\n");
2624 PRINT_D(HOSTAPD_DBG, "Adding monitor interface[%p]\n", nic->wilc_netdev);
2625 new_ifc = WILC_WFI_init_mon_interface(name, nic->wilc_netdev);
Leo Kim369a1d32015-12-21 14:18:23 +09002626 if (new_ifc) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002627 PRINT_D(HOSTAPD_DBG, "Setting monitor flag in private structure\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002628 nic = netdev_priv(priv->wdev->netdev);
2629 nic->monitor_flag = 1;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002630 } else
2631 PRINT_ER("Error in initializing monitor interface\n ");
2632 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002633 return priv->wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002634}
2635
Chaehyun Lim956d7212015-09-22 18:34:49 +09002636static int del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002637{
2638 PRINT_D(HOSTAPD_DBG, "Deleting virtual interface\n");
Leo Kime6e12662015-09-16 18:36:03 +09002639 return 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002640}
2641
Chaehyun Lim08241922015-09-15 14:06:12 +09002642static struct cfg80211_ops wilc_cfg80211_ops = {
Chaehyun Lim80785a92015-09-14 12:24:01 +09002643 .set_monitor_channel = set_channel,
Chaehyun Lim0e30d062015-09-14 12:24:02 +09002644 .scan = scan,
Chaehyun Lim4ffbcdb2015-09-14 12:24:03 +09002645 .connect = connect,
Chaehyun Limb027cde2015-09-14 12:24:04 +09002646 .disconnect = disconnect,
Chaehyun Lim953d4172015-09-14 12:24:05 +09002647 .add_key = add_key,
Chaehyun Lim3044ba72015-09-14 12:24:06 +09002648 .del_key = del_key,
Chaehyun Limf4893df2015-09-14 12:24:07 +09002649 .get_key = get_key,
Chaehyun Lim0f5b8ca2015-09-14 12:24:08 +09002650 .set_default_key = set_default_key,
Chaehyun Lim69deb4c2015-09-14 12:24:09 +09002651 .add_virtual_intf = add_virtual_intf,
Chaehyun Limb4a73352015-09-14 12:24:10 +09002652 .del_virtual_intf = del_virtual_intf,
Chaehyun Lim3615e9a2015-09-14 12:24:11 +09002653 .change_virtual_intf = change_virtual_intf,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002654
Chaehyun Lima13168d2015-09-14 12:24:12 +09002655 .start_ap = start_ap,
Chaehyun Lim2a4c84d2015-09-14 12:24:13 +09002656 .change_beacon = change_beacon,
Chaehyun Limc8cddd72015-09-14 12:24:14 +09002657 .stop_ap = stop_ap,
Chaehyun Limed269552015-09-14 12:24:15 +09002658 .add_station = add_station,
Chaehyun Lima0a8be92015-09-14 12:24:16 +09002659 .del_station = del_station,
Chaehyun Lim14b42082015-09-14 12:24:17 +09002660 .change_station = change_station,
Chaehyun Limf06f5622015-09-14 12:24:18 +09002661 .get_station = get_station,
Chaehyun Limbdb63382015-09-14 12:24:19 +09002662 .dump_station = dump_station,
Chaehyun Lima5f7db62015-09-14 12:24:20 +09002663 .change_bss = change_bss,
Chaehyun Lima76b63e2015-09-14 12:24:21 +09002664 .set_wiphy_params = set_wiphy_params,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002665
Chaehyun Lim4d466572015-09-14 12:24:22 +09002666 .set_pmksa = set_pmksa,
Chaehyun Lim1ff86d92015-09-14 12:24:23 +09002667 .del_pmksa = del_pmksa,
Chaehyun Limb33c39b2015-09-14 12:24:24 +09002668 .flush_pmksa = flush_pmksa,
Chaehyun Lim6d19d692015-09-14 12:24:25 +09002669 .remain_on_channel = remain_on_channel,
Chaehyun Lim1dd54402015-09-14 12:24:26 +09002670 .cancel_remain_on_channel = cancel_remain_on_channel,
Chaehyun Lim4a2f9b32015-09-14 12:24:27 +09002671 .mgmt_tx_cancel_wait = mgmt_tx_cancel_wait,
Chaehyun Lim12a26a32015-09-14 12:24:28 +09002672 .mgmt_tx = mgmt_tx,
Chaehyun Lim8e0735c2015-09-20 15:51:16 +09002673 .mgmt_frame_register = wilc_mgmt_frame_register,
Chaehyun Lim46530672015-09-22 18:34:46 +09002674 .set_power_mgmt = set_power_mgmt,
Chaehyun Lima8047e22015-09-22 18:34:48 +09002675 .set_cqm_rssi_config = set_cqm_rssi_config,
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002676
2677};
2678
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002679int WILC_WFI_update_stats(struct wiphy *wiphy, u32 pktlen, u8 changed)
2680{
Chaehyun Lim27268872015-09-15 14:06:13 +09002681 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002682
2683 priv = wiphy_priv(wiphy);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002684 switch (changed) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002685 case WILC_WFI_RX_PKT:
2686 {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002687 priv->netstats.rx_packets++;
2688 priv->netstats.rx_bytes += pktlen;
2689 priv->netstats.rx_time = get_jiffies_64();
2690 }
2691 break;
2692
2693 case WILC_WFI_TX_PKT:
2694 {
2695 priv->netstats.tx_packets++;
2696 priv->netstats.tx_bytes += pktlen;
2697 priv->netstats.tx_time = get_jiffies_64();
2698
2699 }
2700 break;
2701
2702 default:
2703 break;
2704 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002705 return 0;
2706}
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002707
Arnd Bergmann1608c402015-11-16 15:04:53 +01002708static struct wireless_dev *WILC_WFI_CfgAlloc(void)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002709{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002710 struct wireless_dev *wdev;
2711
2712
2713 PRINT_D(CFG80211_DBG, "Allocating wireless device\n");
Leo Kima89f7c52015-11-25 11:59:41 +09002714
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002715 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
2716 if (!wdev) {
2717 PRINT_ER("Cannot allocate wireless device\n");
2718 goto _fail_;
2719 }
2720
Chaehyun Lim27268872015-09-15 14:06:13 +09002721 wdev->wiphy = wiphy_new(&wilc_cfg80211_ops, sizeof(struct wilc_priv));
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002722 if (!wdev->wiphy) {
2723 PRINT_ER("Cannot allocate wiphy\n");
2724 goto _fail_mem_;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002725 }
2726
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002727 WILC_WFI_band_2ghz.ht_cap.ht_supported = 1;
2728 WILC_WFI_band_2ghz.ht_cap.cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
2729 WILC_WFI_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
2730 WILC_WFI_band_2ghz.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K;
2731 WILC_WFI_band_2ghz.ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002732
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002733 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &WILC_WFI_band_2ghz;
2734
2735 return wdev;
2736
2737_fail_mem_:
2738 kfree(wdev);
2739_fail_:
2740 return NULL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002741}
Leo Kima89f7c52015-11-25 11:59:41 +09002742
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01002743struct wireless_dev *wilc_create_wiphy(struct net_device *net, struct device *dev)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002744{
Chaehyun Lim27268872015-09-15 14:06:13 +09002745 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002746 struct wireless_dev *wdev;
Leo Kime6e12662015-09-16 18:36:03 +09002747 s32 s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002748
2749 PRINT_D(CFG80211_DBG, "Registering wifi device\n");
2750
2751 wdev = WILC_WFI_CfgAlloc();
Leo Kim369a1d32015-12-21 14:18:23 +09002752 if (!wdev) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002753 PRINT_ER("CfgAlloc Failed\n");
2754 return NULL;
2755 }
2756
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002757 priv = wdev_priv(wdev);
Arnd Bergmann83383ea2015-06-01 21:06:43 +02002758 sema_init(&(priv->SemHandleUpdateStats), 1);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002759 priv->wdev = wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002760 wdev->wiphy->max_scan_ssids = MAX_NUM_PROBED_SSID;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002761 wdev->wiphy->max_num_pmkids = WILC_MAX_NUM_PMKIDS;
2762 PRINT_INFO(CFG80211_DBG, "Max number of PMKIDs = %d\n", wdev->wiphy->max_num_pmkids);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002763
2764 wdev->wiphy->max_scan_ie_len = 1000;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002765 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002766 wdev->wiphy->cipher_suites = cipher_suites;
2767 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002768 wdev->wiphy->mgmt_stypes = wilc_wfi_cfg80211_mgmt_types;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002769
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002770 wdev->wiphy->max_remain_on_channel_duration = 500;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002771 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MONITOR) | BIT(NL80211_IFTYPE_P2P_GO) |
2772 BIT(NL80211_IFTYPE_P2P_CLIENT);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002773 wdev->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002774 wdev->iftype = NL80211_IFTYPE_STATION;
2775
2776
2777
2778 PRINT_INFO(CFG80211_DBG, "Max scan ids = %d,Max scan IE len = %d,Signal Type = %d,Interface Modes = %d,Interface Type = %d\n",
2779 wdev->wiphy->max_scan_ssids, wdev->wiphy->max_scan_ie_len, wdev->wiphy->signal_type,
2780 wdev->wiphy->interface_modes, wdev->iftype);
2781
Arnd Bergmann2e7d5372015-11-16 15:05:03 +01002782 set_wiphy_dev(wdev->wiphy, dev);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002783
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002784 s32Error = wiphy_register(wdev->wiphy);
2785 if (s32Error) {
2786 PRINT_ER("Cannot register wiphy device\n");
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002787 } else {
2788 PRINT_D(CFG80211_DBG, "Successful Registering\n");
2789 }
2790
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002791 priv->dev = net;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002792 return wdev;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002793}
Leo Kima89f7c52015-11-25 11:59:41 +09002794
Chaehyun Limdd4b6a82015-09-20 15:51:25 +09002795int wilc_init_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002796{
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09002797 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002798
Chaehyun Lim27268872015-09-15 14:06:13 +09002799 struct wilc_priv *priv;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002800
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002801 PRINT_D(INIT_DBG, "Host[%p][%p]\n", net, net->ieee80211_ptr);
2802 priv = wdev_priv(net->ieee80211_ptr);
2803 if (op_ifcs == 0) {
Greg Kroah-Hartman93dee8e2015-08-14 20:28:32 -07002804 setup_timer(&hAgingTimer, remove_network_from_shadow, 0);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002805 setup_timer(&wilc_during_ip_timer, clear_duringIP, 0);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002806 }
2807 op_ifcs++;
2808 if (s32Error < 0) {
2809 PRINT_ER("Failed to creat refresh Timer\n");
2810 return s32Error;
2811 }
2812
Dean Lee72ed4dc2015-06-12 14:11:44 +09002813 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002814
Dean Lee72ed4dc2015-06-12 14:11:44 +09002815 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002816
Arnd Bergmann83383ea2015-06-01 21:06:43 +02002817 sema_init(&(priv->hSemScanReq), 1);
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002818 s32Error = wilc_init(net, &priv->hWILCWFIDrv);
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09002819 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002820 PRINT_ER("Error while initializing hostinterface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09002821
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002822 return s32Error;
2823}
2824
Chaehyun Lima9a16822015-09-20 15:51:24 +09002825int wilc_deinit_host_int(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002826{
Chaehyun Lim1a8ccd82015-09-20 15:51:23 +09002827 int s32Error = 0;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002828
Chaehyun Lim27268872015-09-15 14:06:13 +09002829 struct wilc_priv *priv;
Chaehyun Lim8dfaafd2015-08-18 23:18:11 +09002830
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002831 priv = wdev_priv(net->ieee80211_ptr);
2832
Dean Lee72ed4dc2015-06-12 14:11:44 +09002833 priv->gbAutoRateAdjusted = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002834
Dean Lee72ed4dc2015-06-12 14:11:44 +09002835 priv->bInP2PlistenState = false;
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002836
2837 op_ifcs--;
2838
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002839 s32Error = wilc_deinit(priv->hWILCWFIDrv);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002840
Leo Kimd14991a2015-11-19 15:56:22 +09002841 clear_shadow_scan();
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002842 if (op_ifcs == 0) {
2843 PRINT_D(CORECONFIG_DBG, "destroy during ip\n");
Arnd Bergmann0e1af732015-11-16 15:04:54 +01002844 del_timer_sync(&wilc_during_ip_timer);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002845 }
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002846
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09002847 if (s32Error)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002848 PRINT_ER("Error while deintializing host interface\n");
Chaehyun Limf1fe9c42015-09-20 15:51:22 +09002849
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002850 return s32Error;
2851}
2852
Chaehyun Lim96da20a2015-09-20 15:51:08 +09002853void wilc_free_wiphy(struct net_device *net)
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002854{
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002855 PRINT_D(CFG80211_DBG, "Unregistering wiphy\n");
2856
Chaehyun Lim619837a2015-09-20 15:51:10 +09002857 if (!net) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002858 PRINT_D(INIT_DBG, "net_device is NULL\n");
2859 return;
2860 }
2861
Chaehyun Lim619837a2015-09-20 15:51:10 +09002862 if (!net->ieee80211_ptr) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002863 PRINT_D(INIT_DBG, "ieee80211_ptr is NULL\n");
2864 return;
2865 }
2866
Chaehyun Lim619837a2015-09-20 15:51:10 +09002867 if (!net->ieee80211_ptr->wiphy) {
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002868 PRINT_D(INIT_DBG, "wiphy is NULL\n");
2869 return;
2870 }
2871
2872 wiphy_unregister(net->ieee80211_ptr->wiphy);
2873
2874 PRINT_D(INIT_DBG, "Freeing wiphy\n");
2875 wiphy_free(net->ieee80211_ptr->wiphy);
2876 kfree(net->ieee80211_ptr);
Johnny Kimc5c77ba2015-05-11 14:30:56 +09002877}