[RAMEN9610-20413][9610] wlbt: SCSC Driver version 10.6.1.0
[GitHub/MotorolaMobilityLLC/kernel-slsi.git] / drivers / net / wireless / scsc / nl80211_vendor.c
1 /*****************************************************************************
2 *
3 * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved
4 *
5 ****************************************************************************/
6 #include <linux/version.h>
7 #include <net/cfg80211.h>
8 #include <net/ip.h>
9 #include <linux/etherdevice.h>
10 #include "dev.h"
11 #include "cfg80211_ops.h"
12 #include "debug.h"
13 #include "mgt.h"
14 #include "mlme.h"
15 #include "netif.h"
16 #include "unifiio.h"
17 #include "mib.h"
18 #include "nl80211_vendor.h"
19
20 #ifdef CONFIG_SCSC_WLAN_ENHANCED_LOGGING
21 #include "scsc_wifilogger.h"
22 #include "scsc_wifilogger_rings.h"
23 #include "scsc_wifilogger_types.h"
24 #endif
25 #define SLSI_WIFI_TAG_RSSI 21
26 #define SLSI_WIFI_TAG_REASON_CODE 14
27 #define SLSI_WIFI_TAG_VENDOR_SPECIFIC 0
28 #define SLSI_WIFI_TAG_EAPOL_MESSAGE_TYPE 29
29 #define SLSI_WIFI_TAG_STATUS 4
30
31 #define SLSI_GSCAN_INVALID_RSSI 0x7FFF
32 #define SLSI_EPNO_AUTH_FIELD_WEP_OPEN 1
33 #define SLSI_EPNO_AUTH_FIELD_WPA_PSK 2
34 #define SLSI_EPNO_AUTH_FIELD_WPA_EAP 4
35 #define WIFI_EVENT_FW_BTM_FRAME_REQUEST 56 // Request for a BTM frame is received
36 #define WIFI_EVENT_FW_BTM_FRAME_RESPONSE 57 // A BTM frame is transmitted.
37 #define WIFI_EVENT_FW_NR_FRAME_REQUEST 58
38 #define WIFI_EVENT_FW_RM_FRAME_RESPONSE 59
39
40 #define SLSI_WIFI_TAG_VD_CHANNEL_UTILISATION 0xf01a
41 #define SLSI_WIFI_TAG_VD_ROAMING_REASON 0xf019
42 #define SLSI_WIFI_TAG_VD_BTM_REQUEST_MODE 0xf01b
43 #define SLSI_WIFI_TAG_VD_BTM_RESPONSE_STATUS 0xf01c
44 #define SLSI_WIFI_TAG_VD_RETRY_COUNT 0xf00f
45 #define SLSI_WIFI_TAG_VD_EAPOL_KEY_TYPE 0xF008
46 #define SLSI_WIFI_EAPOL_KEY_TYPE_GTK 0x0000
47 #define SLSI_WIFI_EAPOL_KEY_TYPE_PTK 0x0001
48 #define SLSI_WIFI_ROAMING_SEARCH_REASON_RESERVED 0
49 #define SLSI_WIFI_ROAMING_SEARCH_REASON_LOW_RSSI 1
50 #define SLSI_WIFI_ROAMING_SEARCH_REASON_LINK_LOSS 2
51 #define SLSI_WIFI_ROAMING_SEARCH_REASON_BTM_REQ 3
52 #define SLSI_WIFI_ROAMING_SEARCH_REASON_CU_TRIGGER 4
53
54 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
55
56 #ifdef CONFIG_SCSC_WLAN_ENHANCED_LOGGING
57 static int mem_dump_buffer_size;
58 static char *mem_dump_buffer;
59 #endif
60 #ifdef CONFIG_SCSC_WLAN_DEBUG
61 char *slsi_print_event_name(int event_id)
62 {
63 switch (event_id) {
64 case SLSI_NL80211_SCAN_RESULTS_AVAILABLE_EVENT:
65 return "SCAN_RESULTS_AVAILABLE_EVENT";
66 case SLSI_NL80211_FULL_SCAN_RESULT_EVENT:
67 return "FULL_SCAN_RESULT_EVENT";
68 case SLSI_NL80211_SCAN_EVENT:
69 return "BUCKET_SCAN_DONE_EVENT";
70 #ifdef CONFIG_SCSC_WLAN_KEY_MGMT_OFFLOAD
71 case SLSI_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH:
72 return "KEY_MGMT_ROAM_AUTH";
73 #endif
74 case SLSI_NL80211_VENDOR_HANGED_EVENT:
75 return "SLSI_NL80211_VENDOR_HANGED_EVENT";
76 case SLSI_NL80211_EPNO_EVENT:
77 return "SLSI_NL80211_EPNO_EVENT";
78 case SLSI_NL80211_HOTSPOT_MATCH:
79 return "SLSI_NL80211_HOTSPOT_MATCH";
80 case SLSI_NL80211_RSSI_REPORT_EVENT:
81 return "SLSI_NL80211_RSSI_REPORT_EVENT";
82 #ifdef CONFIG_SCSC_WLAN_ENHANCED_LOGGING
83 case SLSI_NL80211_LOGGER_RING_EVENT:
84 return "SLSI_NL80211_LOGGER_RING_EVENT";
85 case SLSI_NL80211_LOGGER_FW_DUMP_EVENT:
86 return "SLSI_NL80211_LOGGER_FW_DUMP_EVENT";
87 #endif
88 case SLSI_NL80211_NAN_RESPONSE_EVENT:
89 return "SLSI_NL80211_NAN_RESPONSE_EVENT";
90 case SLSI_NL80211_NAN_PUBLISH_TERMINATED_EVENT:
91 return "SLSI_NL80211_NAN_PUBLISH_TERMINATED_EVENT";
92 case SLSI_NL80211_NAN_MATCH_EVENT:
93 return "SLSI_NL80211_NAN_MATCH_EVENT";
94 case SLSI_NL80211_NAN_MATCH_EXPIRED_EVENT:
95 return "SLSI_NL80211_NAN_MATCH_EXPIRED_EVENT";
96 case SLSI_NL80211_NAN_SUBSCRIBE_TERMINATED_EVENT:
97 return "SLSI_NL80211_NAN_SUBSCRIBE_TERMINATED_EVENT";
98 case SLSI_NL80211_NAN_FOLLOWUP_EVENT:
99 return "SLSI_NL80211_NAN_FOLLOWUP_EVENT";
100 case SLSI_NL80211_NAN_DISCOVERY_ENGINE_EVENT:
101 return "SLSI_NL80211_NAN_DISCOVERY_ENGINE_EVENT";
102 case SLSI_NL80211_RTT_RESULT_EVENT:
103 return "SLSI_NL80211_RTT_RESULT_EVENT";
104 case SLSI_NL80211_RTT_COMPLETE_EVENT:
105 return "SLSI_NL80211_RTT_COMPLETE_EVENT";
106 case SLSI_NL80211_VENDOR_ACS_EVENT:
107 return "SLSI_NL80211_VENDOR_ACS_EVENT";
108 case SLSI_NL80211_NAN_TRANSMIT_FOLLOWUP_STATUS:
109 return "SLSI_NL80211_NAN_TRANSMIT_FOLLOWUP_STATUS";
110 default:
111 return "UNKNOWN_EVENT";
112 }
113 }
114 #endif
115
116 int slsi_vendor_event(struct slsi_dev *sdev, int event_id, const void *data, int len)
117 {
118 struct sk_buff *skb;
119
120 #ifdef CONFIG_SCSC_WLAN_DEBUG
121 SLSI_DBG1_NODEV(SLSI_MLME, "Event: %s(%d), data = %p, len = %d\n",
122 slsi_print_event_name(event_id), event_id, data, len);
123 #endif
124
125 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
126 skb = cfg80211_vendor_event_alloc(sdev->wiphy, NULL, len, event_id, GFP_KERNEL);
127 #else
128 skb = cfg80211_vendor_event_alloc(sdev->wiphy, len, event_id, GFP_KERNEL);
129 #endif
130 if (!skb) {
131 SLSI_ERR_NODEV("Failed to allocate skb for vendor event: %d\n", event_id);
132 return -ENOMEM;
133 }
134
135 nla_put_nohdr(skb, len, data);
136
137 cfg80211_vendor_event(skb, GFP_KERNEL);
138
139 return 0;
140 }
141
142 static int slsi_vendor_cmd_reply(struct wiphy *wiphy, const void *data, int len)
143 {
144 struct sk_buff *skb;
145
146 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, len);
147 if (!skb) {
148 SLSI_ERR_NODEV("Failed to allocate skb\n");
149 return -ENOMEM;
150 }
151
152 nla_put_nohdr(skb, len, data);
153
154 return cfg80211_vendor_cmd_reply(skb);
155 }
156
157 static struct net_device *slsi_gscan_get_netdev(struct slsi_dev *sdev)
158 {
159 return slsi_get_netdev(sdev, SLSI_NET_INDEX_WLAN);
160 }
161
162 static struct netdev_vif *slsi_gscan_get_vif(struct slsi_dev *sdev)
163 {
164 struct net_device *dev;
165
166 dev = slsi_gscan_get_netdev(sdev);
167 if (!dev) {
168 SLSI_WARN_NODEV("Dev is NULL\n");
169 return NULL;
170 }
171
172 return netdev_priv(dev);
173 }
174
175 #ifdef CONFIG_SCSC_WLAN_DEBUG
176 static void slsi_gscan_add_dump_params(struct slsi_nl_gscan_param *nl_gscan_param)
177 {
178 int i;
179 int j;
180
181 SLSI_DBG2_NODEV(SLSI_GSCAN, "Parameters for SLSI_NL80211_VENDOR_SUBCMD_ADD_GSCAN sub-command:\n");
182 SLSI_DBG2_NODEV(SLSI_GSCAN, "base_period: %d max_ap_per_scan: %d report_threshold_percent: %d report_threshold_num_scans = %d num_buckets: %d\n",
183 nl_gscan_param->base_period, nl_gscan_param->max_ap_per_scan,
184 nl_gscan_param->report_threshold_percent, nl_gscan_param->report_threshold_num_scans,
185 nl_gscan_param->num_buckets);
186
187 for (i = 0; i < nl_gscan_param->num_buckets; i++) {
188 SLSI_DBG2_NODEV(SLSI_GSCAN, "Bucket: %d\n", i);
189 SLSI_DBG2_NODEV(SLSI_GSCAN, "\tbucket_index: %d band: %d period: %d report_events: %d num_channels: %d\n",
190 nl_gscan_param->nl_bucket[i].bucket_index, nl_gscan_param->nl_bucket[i].band,
191 nl_gscan_param->nl_bucket[i].period, nl_gscan_param->nl_bucket[i].report_events,
192 nl_gscan_param->nl_bucket[i].num_channels);
193
194 for (j = 0; j < nl_gscan_param->nl_bucket[i].num_channels; j++)
195 SLSI_DBG2_NODEV(SLSI_GSCAN, "\tchannel_list[%d]: %d\n",
196 j, nl_gscan_param->nl_bucket[i].channels[j].channel);
197 }
198 }
199
200 void slsi_gscan_scan_res_dump(struct slsi_gscan_result *scan_data)
201 {
202 struct slsi_nl_scan_result_param *nl_scan_res = &scan_data->nl_scan_res;
203
204 SLSI_DBG3_NODEV(SLSI_GSCAN, "TS:%llu SSID:%s BSSID:%pM Chan:%d RSSI:%d Bcn_Int:%d Capab:%#x IE_Len:%d\n",
205 nl_scan_res->ts, nl_scan_res->ssid, nl_scan_res->bssid, nl_scan_res->channel,
206 nl_scan_res->rssi, nl_scan_res->beacon_period, nl_scan_res->capability, nl_scan_res->ie_length);
207
208 SLSI_DBG_HEX_NODEV(SLSI_GSCAN, &nl_scan_res->ie_data[0], nl_scan_res->ie_length, "IE_Data:\n");
209 if (scan_data->anqp_length) {
210 SLSI_DBG3_NODEV(SLSI_GSCAN, "ANQP_LENGTH:%d\n", scan_data->anqp_length);
211 SLSI_DBG_HEX_NODEV(SLSI_GSCAN, nl_scan_res->ie_data + nl_scan_res->ie_length, scan_data->anqp_length, "ANQP_info:\n");
212 }
213 }
214 #endif
215
216 static int slsi_gscan_get_capabilities(struct wiphy *wiphy,
217 struct wireless_dev *wdev, const void *data, int len)
218 {
219 struct slsi_nl_gscan_capabilities nl_cap;
220 int ret = 0;
221 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
222
223 SLSI_DBG1_NODEV(SLSI_GSCAN, "SUBCMD_GET_GSCAN_CAPABILITIES\n");
224
225 memset(&nl_cap, 0, sizeof(struct slsi_nl_gscan_capabilities));
226
227 ret = slsi_mib_get_gscan_cap(sdev, &nl_cap);
228 if (ret != 0) {
229 SLSI_ERR(sdev, "Failed to read mib\n");
230 return ret;
231 }
232
233 nl_cap.max_scan_cache_size = SLSI_GSCAN_MAX_SCAN_CACHE_SIZE;
234 nl_cap.max_ap_cache_per_scan = SLSI_GSCAN_MAX_AP_CACHE_PER_SCAN;
235 nl_cap.max_scan_reporting_threshold = SLSI_GSCAN_MAX_SCAN_REPORTING_THRESHOLD;
236
237 ret = slsi_vendor_cmd_reply(wiphy, &nl_cap, sizeof(struct slsi_nl_gscan_capabilities));
238 if (ret)
239 SLSI_ERR_NODEV("gscan_get_capabilities vendor cmd reply failed (err = %d)\n", ret);
240
241 return ret;
242 }
243
244 static u32 slsi_gscan_put_channels(struct ieee80211_supported_band *chan_data, bool no_dfs, bool only_dfs, u32 *buf)
245 {
246 u32 chan_count = 0;
247 u32 chan_flags;
248 int i;
249
250 if (chan_data == NULL) {
251 SLSI_DBG3_NODEV(SLSI_GSCAN, "Band not supported\n");
252 return 0;
253 }
254 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)
255 chan_flags = (IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_OFDM | IEEE80211_CHAN_RADAR);
256 #else
257 chan_flags = (IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_OFDM | IEEE80211_CHAN_RADAR);
258 #endif
259
260 for (i = 0; i < chan_data->n_channels; i++) {
261 if (chan_data->channels[i].flags & IEEE80211_CHAN_DISABLED)
262 continue;
263 if (only_dfs) {
264 if (chan_data->channels[i].flags & chan_flags)
265 buf[chan_count++] = chan_data->channels[i].center_freq;
266 continue;
267 }
268 if (no_dfs && (chan_data->channels[i].flags & chan_flags))
269 continue;
270 buf[chan_count++] = chan_data->channels[i].center_freq;
271 }
272 return chan_count;
273 }
274
275 static int slsi_gscan_get_valid_channel(struct wiphy *wiphy,
276 struct wireless_dev *wdev, const void *data, int len)
277 {
278 int ret = 0, type, band;
279 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
280 u32 *chan_list;
281 u32 chan_count = 0, mem_len = 0;
282 struct sk_buff *reply;
283
284 if (len < SLSI_NL_VENDOR_DATA_OVERHEAD || !data)
285 return -EINVAL;
286
287 type = nla_type(data);
288
289 if (type == GSCAN_ATTRIBUTE_BAND) {
290 if (nla_len((struct nlattr *)data) != (SLSI_NL_ATTRIBUTE_U32_LEN - NLA_HDRLEN))
291 return -EINVAL;
292 band = nla_get_u32(data);
293 }
294 else
295 return -EINVAL;
296
297 if (band == 0) {
298 SLSI_WARN(sdev, "NO Bands. return 0 channel\n");
299 return ret;
300 }
301
302 SLSI_MUTEX_LOCK(sdev->netdev_add_remove_mutex);
303 SLSI_DBG3(sdev, SLSI_GSCAN, "band %d\n", band);
304 if (wiphy->bands[NL80211_BAND_2GHZ])
305 mem_len += wiphy->bands[NL80211_BAND_2GHZ]->n_channels * sizeof(u32);
306
307 if (wiphy->bands[NL80211_BAND_5GHZ])
308 mem_len += wiphy->bands[NL80211_BAND_5GHZ]->n_channels * sizeof(u32);
309
310 if (mem_len == 0) {
311 ret = -ENOTSUPP;
312 goto exit;
313 }
314
315 chan_list = kmalloc(mem_len, GFP_KERNEL);
316 if (chan_list == NULL) {
317 ret = -ENOMEM;
318 goto exit;
319 }
320 mem_len += SLSI_NL_VENDOR_REPLY_OVERHEAD + (SLSI_NL_ATTRIBUTE_U32_LEN * 2);
321 reply = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, mem_len);
322 if (reply == NULL) {
323 ret = -ENOMEM;
324 goto exit_with_chan_list;
325 }
326 switch (band) {
327 case WIFI_BAND_BG:
328 chan_count = slsi_gscan_put_channels(wiphy->bands[NL80211_BAND_2GHZ], false, false, chan_list);
329 break;
330 case WIFI_BAND_A:
331 chan_count = slsi_gscan_put_channels(wiphy->bands[NL80211_BAND_5GHZ], true, false, chan_list);
332 break;
333 case WIFI_BAND_A_DFS:
334 chan_count = slsi_gscan_put_channels(wiphy->bands[NL80211_BAND_5GHZ], false, true, chan_list);
335 break;
336 case WIFI_BAND_A_WITH_DFS:
337 chan_count = slsi_gscan_put_channels(wiphy->bands[NL80211_BAND_5GHZ], false, false, chan_list);
338 break;
339 case WIFI_BAND_ABG:
340 chan_count = slsi_gscan_put_channels(wiphy->bands[NL80211_BAND_2GHZ], true, false, chan_list);
341 chan_count += slsi_gscan_put_channels(wiphy->bands[NL80211_BAND_5GHZ], true, false, chan_list + chan_count);
342 break;
343 case WIFI_BAND_ABG_WITH_DFS:
344 chan_count = slsi_gscan_put_channels(wiphy->bands[NL80211_BAND_2GHZ], false, false, chan_list);
345 chan_count += slsi_gscan_put_channels(wiphy->bands[NL80211_BAND_5GHZ], false, false, chan_list + chan_count);
346 break;
347 default:
348 chan_count = 0;
349 SLSI_WARN(sdev, "Invalid Band %d\n", band);
350 }
351 nla_put_u32(reply, GSCAN_ATTRIBUTE_NUM_CHANNELS, chan_count);
352 nla_put(reply, GSCAN_ATTRIBUTE_CHANNEL_LIST, chan_count * sizeof(u32), chan_list);
353
354 ret = cfg80211_vendor_cmd_reply(reply);
355
356 if (ret)
357 SLSI_ERR(sdev, "FAILED to reply GET_VALID_CHANNELS\n");
358
359 exit_with_chan_list:
360 kfree(chan_list);
361 exit:
362 SLSI_MUTEX_UNLOCK(sdev->netdev_add_remove_mutex);
363 return ret;
364 }
365
366 struct slsi_gscan_result *slsi_prepare_scan_result(struct sk_buff *skb, u16 anqp_length, int hs2_id)
367 {
368 struct ieee80211_mgmt *mgmt = fapi_get_mgmt(skb);
369 struct slsi_gscan_result *scan_res;
370 struct timespec ts;
371 const u8 *ssid_ie;
372 int mem_reqd;
373 int ie_len;
374 u8 *ie;
375
376 ie = &mgmt->u.beacon.variable[0];
377 ie_len = fapi_get_datalen(skb) - (ie - (u8 *)mgmt) - anqp_length;
378
379 /* Exclude 1 byte for ie_data[1]. sizeof(u16) to include anqp_length, sizeof(int) for hs_id */
380 mem_reqd = (sizeof(struct slsi_gscan_result) - 1) + ie_len + anqp_length + sizeof(int) + sizeof(u16);
381
382 /* Allocate memory for scan result */
383 scan_res = kmalloc(mem_reqd, GFP_KERNEL);
384 if (scan_res == NULL) {
385 SLSI_ERR_NODEV("Failed to allocate memory for scan result\n");
386 return NULL;
387 }
388
389 /* Exclude 1 byte for ie_data[1] */
390 scan_res->scan_res_len = (sizeof(struct slsi_nl_scan_result_param) - 1) + ie_len;
391 scan_res->anqp_length = 0;
392
393 get_monotonic_boottime(&ts);
394 scan_res->nl_scan_res.ts = (u64)TIMESPEC_TO_US(ts);
395
396 ssid_ie = cfg80211_find_ie(WLAN_EID_SSID, &mgmt->u.beacon.variable[0], ie_len);
397 if ((ssid_ie != NULL) && (ssid_ie[1] > 0) && (ssid_ie[1] < IEEE80211_MAX_SSID_LEN)) {
398 memcpy(scan_res->nl_scan_res.ssid, &ssid_ie[2], ssid_ie[1]);
399 scan_res->nl_scan_res.ssid[ssid_ie[1]] = '\0';
400 } else {
401 scan_res->nl_scan_res.ssid[0] = '\0';
402 }
403
404 SLSI_ETHER_COPY(scan_res->nl_scan_res.bssid, mgmt->bssid);
405 scan_res->nl_scan_res.channel = fapi_get_u16(skb, u.mlme_scan_ind.channel_frequency) / 2;
406 scan_res->nl_scan_res.rssi = fapi_get_s16(skb, u.mlme_scan_ind.rssi);
407 scan_res->nl_scan_res.rtt = SLSI_GSCAN_RTT_UNSPECIFIED;
408 scan_res->nl_scan_res.rtt_sd = SLSI_GSCAN_RTT_UNSPECIFIED;
409 scan_res->nl_scan_res.beacon_period = mgmt->u.beacon.beacon_int;
410 scan_res->nl_scan_res.capability = mgmt->u.beacon.capab_info;
411 scan_res->nl_scan_res.ie_length = ie_len;
412 memcpy(scan_res->nl_scan_res.ie_data, ie, ie_len);
413 memcpy(scan_res->nl_scan_res.ie_data + ie_len, &hs2_id, sizeof(int));
414 memcpy(scan_res->nl_scan_res.ie_data + ie_len + sizeof(int), &anqp_length, sizeof(u16));
415 if (anqp_length) {
416 memcpy(scan_res->nl_scan_res.ie_data + ie_len + sizeof(u16) + sizeof(int), ie + ie_len, anqp_length);
417 scan_res->anqp_length = anqp_length + sizeof(u16) + sizeof(int);
418 }
419
420 #ifdef CONFIG_SCSC_WLAN_DEBUG
421 slsi_gscan_scan_res_dump(scan_res);
422 #endif
423
424 return scan_res;
425 }
426
427 static void slsi_gscan_hash_add(struct slsi_dev *sdev, struct slsi_gscan_result *scan_res)
428 {
429 u8 key = SLSI_GSCAN_GET_HASH_KEY(scan_res->nl_scan_res.bssid[5]);
430 struct netdev_vif *ndev_vif;
431
432 ndev_vif = slsi_gscan_get_vif(sdev);
433 if (!SLSI_MUTEX_IS_LOCKED(ndev_vif->scan_mutex))
434 SLSI_WARN_NODEV("ndev_vif->scan_mutex is not locked\n");
435
436 scan_res->hnext = sdev->gscan_hash_table[key];
437 sdev->gscan_hash_table[key] = scan_res;
438
439 /* Update the total buffer consumed and number of scan results */
440 sdev->buffer_consumed += scan_res->scan_res_len;
441 sdev->num_gscan_results++;
442 }
443
444 static struct slsi_gscan_result *slsi_gscan_hash_get(struct slsi_dev *sdev, u8 *mac)
445 {
446 struct slsi_gscan_result *temp;
447 struct netdev_vif *ndev_vif;
448 u8 key = SLSI_GSCAN_GET_HASH_KEY(mac[5]);
449
450 ndev_vif = slsi_gscan_get_vif(sdev);
451
452 if (!SLSI_MUTEX_IS_LOCKED(ndev_vif->scan_mutex))
453 SLSI_WARN_NODEV("ndev_vif->scan_mutex is not locked\n");
454
455 temp = sdev->gscan_hash_table[key];
456 while (temp != NULL) {
457 if (memcmp(temp->nl_scan_res.bssid, mac, ETH_ALEN) == 0)
458 return temp;
459 temp = temp->hnext;
460 }
461
462 return NULL;
463 }
464
465 void slsi_gscan_hash_remove(struct slsi_dev *sdev, u8 *mac)
466 {
467 u8 key = SLSI_GSCAN_GET_HASH_KEY(mac[5]);
468 struct slsi_gscan_result *curr;
469 struct slsi_gscan_result *prev;
470 struct netdev_vif *ndev_vif;
471 struct slsi_gscan_result *scan_res = NULL;
472
473 ndev_vif = slsi_gscan_get_vif(sdev);
474 if (!SLSI_MUTEX_IS_LOCKED(ndev_vif->scan_mutex))
475 SLSI_WARN_NODEV("ndev_vif->scan_mutex is not locked\n");
476
477 if (sdev->gscan_hash_table[key] == NULL)
478 return;
479
480 if (memcmp(sdev->gscan_hash_table[key]->nl_scan_res.bssid, mac, ETH_ALEN) == 0) {
481 scan_res = sdev->gscan_hash_table[key];
482 sdev->gscan_hash_table[key] = sdev->gscan_hash_table[key]->hnext;
483 } else {
484 prev = sdev->gscan_hash_table[key];
485 curr = prev->hnext;
486
487 while (curr != NULL) {
488 if (memcmp(curr->nl_scan_res.bssid, mac, ETH_ALEN) == 0) {
489 scan_res = curr;
490 prev->hnext = curr->hnext;
491 break;
492 }
493 prev = curr;
494 curr = curr->hnext;
495 }
496 }
497
498 if (scan_res) {
499 /* Update the total buffer consumed and number of scan results */
500 sdev->buffer_consumed -= scan_res->scan_res_len;
501 sdev->num_gscan_results--;
502 kfree(scan_res);
503 }
504
505 if (sdev->num_gscan_results < 0)
506 SLSI_ERR(sdev, "Wrong num_gscan_results: %d\n", sdev->num_gscan_results);
507 }
508
509 int slsi_check_scan_result(struct slsi_dev *sdev, struct slsi_bucket *bucket, struct slsi_gscan_result *new_scan_res)
510 {
511 struct slsi_gscan_result *scan_res;
512
513 /* Check if the scan result for the same BSS already exists in driver buffer */
514 scan_res = slsi_gscan_hash_get(sdev, new_scan_res->nl_scan_res.bssid);
515 if (scan_res == NULL) { /* New scan result */
516 if ((sdev->buffer_consumed + new_scan_res->scan_res_len) >= SLSI_GSCAN_MAX_SCAN_CACHE_SIZE) {
517 SLSI_DBG2(sdev, SLSI_GSCAN,
518 "Scan buffer full, discarding scan result, buffer_consumed = %d, buffer_threshold = %d\n",
519 sdev->buffer_consumed, sdev->buffer_threshold);
520
521 /* Scan buffer is full can't store anymore new results */
522 return SLSI_DISCARD_SCAN_RESULT;
523 }
524
525 return SLSI_KEEP_SCAN_RESULT;
526 }
527
528 /* Even if scan buffer is full existing results can be replaced with the latest one */
529 if (scan_res->scan_cycle == bucket->scan_cycle)
530 /* For the same scan cycle the result will be replaced only if the RSSI is better */
531 if (new_scan_res->nl_scan_res.rssi < scan_res->nl_scan_res.rssi)
532 return SLSI_DISCARD_SCAN_RESULT;
533
534 /* Remove the existing scan result */
535 slsi_gscan_hash_remove(sdev, scan_res->nl_scan_res.bssid);
536
537 return SLSI_KEEP_SCAN_RESULT;
538 }
539
540 void slsi_gscan_handle_scan_result(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb, u16 scan_id, bool scan_done)
541 {
542 struct slsi_gscan_result *scan_res = NULL;
543 struct netdev_vif *ndev_vif = netdev_priv(dev);
544 struct slsi_bucket *bucket;
545 u16 bucket_index;
546 int event_type = WIFI_SCAN_FAILED;
547 u16 anqp_length;
548 int hs2_network_id;
549
550 if (!SLSI_MUTEX_IS_LOCKED(ndev_vif->scan_mutex))
551 SLSI_WARN_NODEV("ndev_vif->scan_mutex is not locked\n");
552
553 SLSI_NET_DBG_HEX(dev, SLSI_GSCAN, skb->data, skb->len, "mlme_scan_ind skb->len: %d\n", skb->len);
554
555 bucket_index = scan_id - SLSI_GSCAN_SCAN_ID_START;
556 if (bucket_index >= SLSI_GSCAN_MAX_BUCKETS) {
557 SLSI_NET_ERR(dev, "Invalid bucket index: %d (scan_id = %#x)\n", bucket_index, scan_id);
558 goto out;
559 }
560
561 bucket = &sdev->bucket[bucket_index];
562 if (!bucket->used) {
563 SLSI_NET_DBG1(dev, SLSI_GSCAN, "Bucket is not active, index: %d (scan_id = %#x)\n", bucket_index, scan_id);
564 goto out;
565 }
566
567 /* For scan_done indication - no need to store the results */
568 if (scan_done) {
569 bucket->scan_cycle++;
570 bucket->gscan->num_scans++;
571
572 SLSI_NET_DBG3(dev, SLSI_GSCAN, "scan done, scan_cycle = %d, num_scans = %d\n",
573 bucket->scan_cycle, bucket->gscan->num_scans);
574
575 if (bucket->report_events & SLSI_REPORT_EVENTS_EACH_SCAN)
576 event_type = WIFI_SCAN_RESULTS_AVAILABLE;
577 if (bucket->gscan->num_scans % bucket->gscan->report_threshold_num_scans == 0)
578 event_type = WIFI_SCAN_THRESHOLD_NUM_SCANS;
579 if (sdev->buffer_consumed >= sdev->buffer_threshold)
580 event_type = WIFI_SCAN_THRESHOLD_PERCENT;
581
582 if (event_type != WIFI_SCAN_FAILED)
583 slsi_vendor_event(sdev, SLSI_NL80211_SCAN_EVENT, &event_type, sizeof(event_type));
584
585 goto out;
586 }
587
588 anqp_length = fapi_get_u16(skb, u.mlme_scan_ind.anqp_elements_length);
589 /* TODO new FAPI 3.c has mlme_scan_ind.network_block_id, use that when fapi is updated. */
590 hs2_network_id = 1;
591
592 scan_res = slsi_prepare_scan_result(skb, anqp_length, hs2_network_id);
593 if (scan_res == NULL) {
594 SLSI_NET_ERR(dev, "Failed to prepare scan result\n");
595 goto out;
596 }
597
598 /* Check for ePNO networks */
599 if (fapi_get_u16(skb, u.mlme_scan_ind.preferrednetwork_ap)) {
600 if (anqp_length == 0)
601 slsi_vendor_event(sdev, SLSI_NL80211_EPNO_EVENT,
602 &scan_res->nl_scan_res, scan_res->scan_res_len);
603 else
604 slsi_vendor_event(sdev, SLSI_NL80211_HOTSPOT_MATCH,
605 &scan_res->nl_scan_res, scan_res->scan_res_len + scan_res->anqp_length);
606 }
607
608 if (bucket->report_events & SLSI_REPORT_EVENTS_FULL_RESULTS) {
609 struct sk_buff *nlevent;
610
611 SLSI_NET_DBG3(dev, SLSI_GSCAN, "report_events: SLSI_REPORT_EVENTS_FULL_RESULTS\n");
612 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
613 nlevent = cfg80211_vendor_event_alloc(sdev->wiphy, NULL, scan_res->scan_res_len + 4, SLSI_NL80211_FULL_SCAN_RESULT_EVENT, GFP_KERNEL);
614 #else
615 nlevent = cfg80211_vendor_event_alloc(sdev->wiphy, scan_res->scan_res_len + 4, SLSI_NL80211_FULL_SCAN_RESULT_EVENT, GFP_KERNEL);
616 #endif
617 if (!nlevent) {
618 SLSI_ERR(sdev, "failed to allocate sbk of size:%d\n", scan_res->scan_res_len + 4);
619 kfree(scan_res);
620 goto out;
621 }
622 if (nla_put_u32(nlevent, GSCAN_ATTRIBUTE_SCAN_BUCKET_BIT, (1 << bucket_index)) ||
623 nla_put(nlevent, GSCAN_ATTRIBUTE_SCAN_RESULTS, scan_res->scan_res_len, &scan_res->nl_scan_res)) {
624 SLSI_ERR(sdev, "failed to put data\n");
625 kfree_skb(nlevent);
626 kfree(scan_res);
627 goto out;
628 }
629 cfg80211_vendor_event(nlevent, GFP_KERNEL);
630 }
631
632 if (slsi_check_scan_result(sdev, bucket, scan_res) == SLSI_DISCARD_SCAN_RESULT) {
633 kfree(scan_res);
634 goto out;
635 }
636 slsi_gscan_hash_add(sdev, scan_res);
637
638 out:
639 slsi_kfree_skb(skb);
640 }
641
642 u8 slsi_gscan_get_scan_policy(enum wifi_band band)
643 {
644 u8 scan_policy;
645
646 switch (band) {
647 case WIFI_BAND_UNSPECIFIED:
648 scan_policy = FAPI_SCANPOLICY_ANY_RA;
649 break;
650 case WIFI_BAND_BG:
651 scan_policy = FAPI_SCANPOLICY_2_4GHZ;
652 break;
653 case WIFI_BAND_A:
654 scan_policy = (FAPI_SCANPOLICY_5GHZ |
655 FAPI_SCANPOLICY_NON_DFS);
656 break;
657 case WIFI_BAND_A_DFS:
658 scan_policy = (FAPI_SCANPOLICY_5GHZ |
659 FAPI_SCANPOLICY_DFS);
660 break;
661 case WIFI_BAND_A_WITH_DFS:
662 scan_policy = (FAPI_SCANPOLICY_5GHZ |
663 FAPI_SCANPOLICY_NON_DFS |
664 FAPI_SCANPOLICY_DFS);
665 break;
666 case WIFI_BAND_ABG:
667 scan_policy = (FAPI_SCANPOLICY_5GHZ |
668 FAPI_SCANPOLICY_NON_DFS |
669 FAPI_SCANPOLICY_2_4GHZ);
670 break;
671 case WIFI_BAND_ABG_WITH_DFS:
672 scan_policy = (FAPI_SCANPOLICY_5GHZ |
673 FAPI_SCANPOLICY_NON_DFS |
674 FAPI_SCANPOLICY_DFS |
675 FAPI_SCANPOLICY_2_4GHZ);
676 break;
677 default:
678 scan_policy = FAPI_SCANPOLICY_ANY_RA;
679 break;
680 }
681
682 SLSI_DBG2_NODEV(SLSI_GSCAN, "Scan Policy: %#x\n", scan_policy);
683
684 return scan_policy;
685 }
686
687 static int slsi_gscan_add_read_params(struct slsi_nl_gscan_param *nl_gscan_param, const void *data, int len)
688 {
689 int j = 0;
690 int type, tmp, tmp1, tmp2, k = 0;
691 const struct nlattr *iter, *iter1, *iter2;
692 struct slsi_nl_bucket_param *nl_bucket;
693
694 nla_for_each_attr(iter, data, len, tmp) {
695 if (!iter)
696 return -EINVAL;
697
698 type = nla_type(iter);
699
700 if (j >= SLSI_GSCAN_MAX_BUCKETS)
701 break;
702
703 switch (type) {
704 case GSCAN_ATTRIBUTE_BASE_PERIOD:
705 if (nla_len(iter) != SLSI_NL_ATTRIBUTE_U32_LEN)
706 return -EINVAL;
707 nl_gscan_param->base_period = nla_get_u32(iter);
708 break;
709 case GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN:
710 if (nla_len(iter) != SLSI_NL_ATTRIBUTE_U32_LEN)
711 return -EINVAL;
712 nl_gscan_param->max_ap_per_scan = nla_get_u32(iter);
713 break;
714 case GSCAN_ATTRIBUTE_REPORT_THRESHOLD:
715 if (nla_len(iter) != SLSI_NL_ATTRIBUTE_U32_LEN)
716 return -EINVAL;
717 nl_gscan_param->report_threshold_percent = nla_get_u32(iter);
718 break;
719 case GSCAN_ATTRIBUTE_REPORT_THRESHOLD_NUM_SCANS:
720 if (nla_len(iter) != SLSI_NL_ATTRIBUTE_U32_LEN)
721 return -EINVAL;
722 nl_gscan_param->report_threshold_num_scans = nla_get_u32(iter);
723 break;
724 case GSCAN_ATTRIBUTE_NUM_BUCKETS:
725 if (nla_len(iter) != SLSI_NL_ATTRIBUTE_U32_LEN)
726 return -EINVAL;
727 nl_gscan_param->num_buckets = nla_get_u32(iter);
728 break;
729 case GSCAN_ATTRIBUTE_CH_BUCKET_1:
730 case GSCAN_ATTRIBUTE_CH_BUCKET_2:
731 case GSCAN_ATTRIBUTE_CH_BUCKET_3:
732 case GSCAN_ATTRIBUTE_CH_BUCKET_4:
733 case GSCAN_ATTRIBUTE_CH_BUCKET_5:
734 case GSCAN_ATTRIBUTE_CH_BUCKET_6:
735 case GSCAN_ATTRIBUTE_CH_BUCKET_7:
736 case GSCAN_ATTRIBUTE_CH_BUCKET_8:
737 nla_for_each_nested(iter1, iter, tmp1) {
738 if (!iter1)
739 return -EINVAL;
740
741 type = nla_type(iter1);
742
743 nl_bucket = nl_gscan_param->nl_bucket;
744
745 switch (type) {
746 case GSCAN_ATTRIBUTE_BUCKET_ID:
747 if (nla_len(iter1) != (SLSI_NL_ATTRIBUTE_U32_LEN - NLA_HDRLEN))
748 return -EINVAL;
749 nl_bucket[j].bucket_index = nla_get_u32(iter1);
750 break;
751 case GSCAN_ATTRIBUTE_BUCKET_PERIOD:
752 if (nla_len(iter1) != (SLSI_NL_ATTRIBUTE_U32_LEN - NLA_HDRLEN))
753 return -EINVAL;
754 nl_bucket[j].period = nla_get_u32(iter1);
755 break;
756 case GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS:
757 if (nla_len(iter1) != (SLSI_NL_ATTRIBUTE_U32_LEN - NLA_HDRLEN))
758 return -EINVAL;
759 nl_bucket[j].num_channels = nla_get_u32(iter1);
760 break;
761 case GSCAN_ATTRIBUTE_BUCKET_CHANNELS:
762 nla_for_each_nested(iter2, iter1, tmp2) {
763 if (k >= SLSI_GSCAN_MAX_CHANNELS)
764 break;
765
766 if (nla_len(iter2) != (SLSI_NL_ATTRIBUTE_U32_LEN - NLA_HDRLEN))
767 return -EINVAL;
768
769 nl_bucket[j].channels[k].channel = nla_get_u32(iter2);
770 k++;
771 }
772 k = 0;
773 break;
774 case GSCAN_ATTRIBUTE_BUCKETS_BAND:
775 if (nla_len(iter1) != (SLSI_NL_ATTRIBUTE_U32_LEN - NLA_HDRLEN))
776 return -EINVAL;
777 nl_bucket[j].band = nla_get_u32(iter1);
778 break;
779 case GSCAN_ATTRIBUTE_REPORT_EVENTS:
780 if (nla_len(iter1) != (SLSI_NL_ATTRIBUTE_U32_LEN - NLA_HDRLEN))
781 return -EINVAL;
782 nl_bucket[j].report_events = nla_get_u32(iter1);
783 break;
784 case GSCAN_ATTRIBUTE_BUCKET_EXPONENT:
785 if (nla_len(iter1) != (SLSI_NL_ATTRIBUTE_U32_LEN - NLA_HDRLEN))
786 return -EINVAL;
787 nl_bucket[j].exponent = nla_get_u32(iter1);
788 break;
789 case GSCAN_ATTRIBUTE_BUCKET_STEP_COUNT:
790 if (nla_len(iter1) != (SLSI_NL_ATTRIBUTE_U32_LEN - NLA_HDRLEN))
791 return -EINVAL;
792 nl_bucket[j].step_count = nla_get_u32(iter1);
793 break;
794 case GSCAN_ATTRIBUTE_BUCKET_MAX_PERIOD:
795 if (nla_len(iter1) != (SLSI_NL_ATTRIBUTE_U32_LEN - NLA_HDRLEN))
796 return -EINVAL;
797 nl_bucket[j].max_period = nla_get_u32(iter1);
798 break;
799 default:
800 SLSI_ERR_NODEV("No ATTR_BUKTS_type - %x\n", type);
801 break;
802 }
803 }
804 j++;
805 break;
806 default:
807 SLSI_ERR_NODEV("No GSCAN_ATTR_CH_BUKT_type - %x\n", type);
808 break;
809 }
810 }
811
812 return 0;
813 }
814
815 int slsi_gscan_add_verify_params(struct slsi_nl_gscan_param *nl_gscan_param)
816 {
817 int i;
818
819 if ((nl_gscan_param->max_ap_per_scan < 0) || (nl_gscan_param->max_ap_per_scan > SLSI_GSCAN_MAX_AP_CACHE_PER_SCAN)) {
820 SLSI_ERR_NODEV("Invalid max_ap_per_scan: %d\n", nl_gscan_param->max_ap_per_scan);
821 return -EINVAL;
822 }
823
824 if ((nl_gscan_param->report_threshold_percent < 0) || (nl_gscan_param->report_threshold_percent > SLSI_GSCAN_MAX_SCAN_REPORTING_THRESHOLD)) {
825 SLSI_ERR_NODEV("Invalid report_threshold_percent: %d\n", nl_gscan_param->report_threshold_percent);
826 return -EINVAL;
827 }
828
829 if ((nl_gscan_param->num_buckets <= 0) || (nl_gscan_param->num_buckets > SLSI_GSCAN_MAX_BUCKETS)) {
830 SLSI_ERR_NODEV("Invalid num_buckets: %d\n", nl_gscan_param->num_buckets);
831 return -EINVAL;
832 }
833
834 for (i = 0; i < nl_gscan_param->num_buckets; i++) {
835 if ((nl_gscan_param->nl_bucket[i].band == WIFI_BAND_UNSPECIFIED) && (nl_gscan_param->nl_bucket[i].num_channels == 0)) {
836 SLSI_ERR_NODEV("No band/channels provided for gscan: band = %d, num_channel = %d\n",
837 nl_gscan_param->nl_bucket[i].band, nl_gscan_param->nl_bucket[i].num_channels);
838 return -EINVAL;
839 }
840
841 if (nl_gscan_param->nl_bucket[i].report_events > 4) {
842 SLSI_ERR_NODEV("Unsupported report event: report_event = %d\n", nl_gscan_param->nl_bucket[i].report_events);
843 return -EINVAL;
844 }
845 }
846
847 return 0;
848 }
849
850 void slsi_gscan_add_to_list(struct slsi_gscan **sdev_gscan, struct slsi_gscan *gscan)
851 {
852 gscan->next = *sdev_gscan;
853 *sdev_gscan = gscan;
854 }
855
856 int slsi_gscan_alloc_buckets(struct slsi_dev *sdev, struct slsi_gscan *gscan, int num_buckets)
857 {
858 int i;
859 int bucket_index = 0;
860 int free_buckets = 0;
861
862 for (i = 0; i < SLSI_GSCAN_MAX_BUCKETS; i++)
863 if (!sdev->bucket[i].used)
864 free_buckets++;
865
866 if (num_buckets > free_buckets) {
867 SLSI_ERR_NODEV("Not enough free buckets, num_buckets = %d, free_buckets = %d\n",
868 num_buckets, free_buckets);
869 return -EINVAL;
870 }
871
872 /* Allocate free buckets for the current gscan */
873 for (i = 0; i < SLSI_GSCAN_MAX_BUCKETS; i++)
874 if (!sdev->bucket[i].used) {
875 sdev->bucket[i].used = true;
876 sdev->bucket[i].gscan = gscan;
877 gscan->bucket[bucket_index] = &sdev->bucket[i];
878 bucket_index++;
879 if (bucket_index == num_buckets)
880 break;
881 }
882
883 return 0;
884 }
885
886 static void slsi_gscan_free_buckets(struct slsi_gscan *gscan)
887 {
888 struct slsi_bucket *bucket;
889 int i;
890
891 SLSI_DBG1_NODEV(SLSI_GSCAN, "gscan = %p, num_buckets = %d\n", gscan, gscan->num_buckets);
892
893 for (i = 0; i < gscan->num_buckets; i++) {
894 bucket = gscan->bucket[i];
895
896 SLSI_DBG2_NODEV(SLSI_GSCAN, "bucket = %p, used = %d, report_events = %d, scan_id = %#x, gscan = %p\n",
897 bucket, bucket->used, bucket->report_events, bucket->scan_id, bucket->gscan);
898 if (bucket->used) {
899 bucket->used = false;
900 bucket->report_events = 0;
901 bucket->gscan = NULL;
902 }
903 }
904 }
905
906 void slsi_gscan_flush_scan_results(struct slsi_dev *sdev)
907 {
908 struct netdev_vif *ndev_vif;
909 struct slsi_gscan_result *temp;
910 int i;
911
912 ndev_vif = slsi_gscan_get_vif(sdev);
913 if (!ndev_vif) {
914 SLSI_WARN_NODEV("ndev_vif is NULL");
915 return;
916 }
917
918 SLSI_MUTEX_LOCK(ndev_vif->scan_mutex);
919 for (i = 0; i < SLSI_GSCAN_HASH_TABLE_SIZE; i++)
920 while (sdev->gscan_hash_table[i]) {
921 temp = sdev->gscan_hash_table[i];
922 sdev->gscan_hash_table[i] = sdev->gscan_hash_table[i]->hnext;
923 sdev->num_gscan_results--;
924 sdev->buffer_consumed -= temp->scan_res_len;
925 kfree(temp);
926 }
927
928 SLSI_DBG2(sdev, SLSI_GSCAN, "num_gscan_results: %d, buffer_consumed = %d\n",
929 sdev->num_gscan_results, sdev->buffer_consumed);
930
931 if (sdev->num_gscan_results != 0)
932 SLSI_WARN_NODEV("sdev->num_gscan_results is not zero\n");
933
934 if (sdev->buffer_consumed != 0)
935 SLSI_WARN_NODEV("sdev->buffer_consumedis not zero\n");
936
937 SLSI_MUTEX_UNLOCK(ndev_vif->scan_mutex);
938 }
939
940 static int slsi_gscan_add_mlme(struct slsi_dev *sdev, struct slsi_nl_gscan_param *nl_gscan_param, struct slsi_gscan *gscan)
941 {
942 struct slsi_gscan_param gscan_param;
943 struct net_device *dev;
944 int ret = 0;
945 int i;
946 #ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION
947 u8 mac_addr_mask[ETH_ALEN];
948 #endif
949
950 dev = slsi_gscan_get_netdev(sdev);
951
952 if (!dev) {
953 SLSI_WARN_NODEV("dev is NULL\n");
954 return -EINVAL;
955 }
956
957 for (i = 0; i < nl_gscan_param->num_buckets; i++) {
958 u16 report_mode = 0;
959
960 gscan_param.nl_bucket = &nl_gscan_param->nl_bucket[i]; /* current bucket */
961 gscan_param.bucket = gscan->bucket[i];
962
963 if (gscan_param.bucket->report_events) {
964 if (gscan_param.bucket->report_events & SLSI_REPORT_EVENTS_EACH_SCAN)
965 report_mode |= FAPI_REPORTMODE_END_OF_SCAN_CYCLE;
966 if (gscan_param.bucket->report_events & SLSI_REPORT_EVENTS_FULL_RESULTS)
967 report_mode |= FAPI_REPORTMODE_REAL_TIME;
968 if (gscan_param.bucket->report_events & SLSI_REPORT_EVENTS_NO_BATCH)
969 report_mode |= FAPI_REPORTMODE_NO_BATCH;
970 } else {
971 report_mode = FAPI_REPORTMODE_RESERVED;
972 }
973
974 if (report_mode == 0) {
975 SLSI_NET_ERR(dev, "Invalid report event value: %d\n", gscan_param.bucket->report_events);
976 return -EINVAL;
977 }
978
979 /* In case of epno no_batch mode should be set. */
980 if (sdev->epno_active)
981 report_mode |= FAPI_REPORTMODE_NO_BATCH;
982
983 #ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION
984 memset(mac_addr_mask, 0xFF, ETH_ALEN);
985 if (sdev->scan_addr_set == 1) {
986 for (i = 3; i < ETH_ALEN; i++)
987 mac_addr_mask[i] = 0x00;
988 ret = slsi_set_mac_randomisation_mask(sdev, mac_addr_mask);
989 if (ret)
990 sdev->scan_addr_set = 0;
991 } else
992 slsi_set_mac_randomisation_mask(sdev, mac_addr_mask);
993 #endif
994 ret = slsi_mlme_add_scan(sdev,
995 dev,
996 FAPI_SCANTYPE_GSCAN,
997 report_mode,
998 0, /* n_ssids */
999 NULL, /* ssids */
1000 nl_gscan_param->nl_bucket[i].num_channels,
1001 NULL, /* ieee80211_channel */
1002 &gscan_param,
1003 NULL, /* ies */
1004 0, /* ies_len */
1005 false /* wait_for_ind */);
1006
1007 if (ret != 0) {
1008 SLSI_NET_ERR(dev, "Failed to add bucket: %d\n", i);
1009
1010 /* Delete the scan those are already added */
1011 for (i = (i - 1); i >= 0; i--)
1012 slsi_mlme_del_scan(sdev, dev, gscan->bucket[i]->scan_id, false);
1013 break;
1014 }
1015 }
1016
1017 return ret;
1018 }
1019
1020 static int slsi_gscan_add(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
1021 {
1022 int ret = 0;
1023 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1024 struct slsi_nl_gscan_param *nl_gscan_param = NULL;
1025 struct slsi_gscan *gscan;
1026 struct netdev_vif *ndev_vif;
1027 int buffer_threshold;
1028 int i;
1029
1030 SLSI_DBG1_NODEV(SLSI_GSCAN, "SUBCMD_ADD_GSCAN\n");
1031
1032 if (!sdev) {
1033 SLSI_WARN_NODEV("sdev is NULL\n");
1034 return -EINVAL;
1035 }
1036
1037 if (!slsi_dev_gscan_supported())
1038 return -ENOTSUPP;
1039
1040 ndev_vif = slsi_gscan_get_vif(sdev);
1041
1042 SLSI_MUTEX_LOCK(ndev_vif->scan_mutex);
1043 /* Allocate memory for the received scan params */
1044 nl_gscan_param = kzalloc(sizeof(*nl_gscan_param), GFP_KERNEL);
1045 if (nl_gscan_param == NULL) {
1046 SLSI_ERR_NODEV("Failed for allocate memory for gscan params\n");
1047 ret = -ENOMEM;
1048 goto exit;
1049 }
1050
1051 slsi_gscan_add_read_params(nl_gscan_param, data, len);
1052
1053 #ifdef CONFIG_SCSC_WLAN_DEBUG
1054 slsi_gscan_add_dump_params(nl_gscan_param);
1055 #endif
1056
1057 ret = slsi_gscan_add_verify_params(nl_gscan_param);
1058 if (ret) {
1059 /* After adding a hotlist a new gscan is added with 0 buckets - return success */
1060 if (nl_gscan_param->num_buckets == 0) {
1061 kfree(nl_gscan_param);
1062 SLSI_MUTEX_UNLOCK(ndev_vif->scan_mutex);
1063 return 0;
1064 }
1065
1066 goto exit;
1067 }
1068
1069 /* Allocate Memory for the new gscan */
1070 gscan = kzalloc(sizeof(*gscan), GFP_KERNEL);
1071 if (gscan == NULL) {
1072 SLSI_ERR_NODEV("Failed to allocate memory for gscan\n");
1073 ret = -ENOMEM;
1074 goto exit;
1075 }
1076
1077 gscan->num_buckets = nl_gscan_param->num_buckets;
1078 gscan->report_threshold_percent = nl_gscan_param->report_threshold_percent;
1079 gscan->report_threshold_num_scans = nl_gscan_param->report_threshold_num_scans;
1080 gscan->nl_bucket = nl_gscan_param->nl_bucket[0];
1081
1082 /* If multiple gscan is added; consider the lowest report_threshold_percent */
1083 buffer_threshold = (SLSI_GSCAN_MAX_SCAN_CACHE_SIZE * nl_gscan_param->report_threshold_percent) / 100;
1084 if ((sdev->buffer_threshold == 0) || (buffer_threshold < sdev->buffer_threshold))
1085 sdev->buffer_threshold = buffer_threshold;
1086
1087 ret = slsi_gscan_alloc_buckets(sdev, gscan, nl_gscan_param->num_buckets);
1088 if (ret)
1089 goto exit_with_gscan_free;
1090
1091 for (i = 0; i < nl_gscan_param->num_buckets; i++)
1092 gscan->bucket[i]->report_events = nl_gscan_param->nl_bucket[i].report_events;
1093
1094 ret = slsi_gscan_add_mlme(sdev, nl_gscan_param, gscan);
1095 if (ret) {
1096 /* Free the buckets */
1097 slsi_gscan_free_buckets(gscan);
1098
1099 goto exit_with_gscan_free;
1100 }
1101
1102 slsi_gscan_add_to_list(&sdev->gscan, gscan);
1103
1104 goto exit;
1105
1106 exit_with_gscan_free:
1107 kfree(gscan);
1108 exit:
1109 kfree(nl_gscan_param);
1110
1111 SLSI_MUTEX_UNLOCK(ndev_vif->scan_mutex);
1112 return ret;
1113 }
1114
1115 static int slsi_gscan_del(struct wiphy *wiphy,
1116 struct wireless_dev *wdev, const void *data, int len)
1117 {
1118 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1119 struct net_device *dev;
1120 struct netdev_vif *ndev_vif;
1121 struct slsi_gscan *gscan;
1122 int ret = 0;
1123 int i;
1124
1125 SLSI_DBG1_NODEV(SLSI_GSCAN, "SUBCMD_DEL_GSCAN\n");
1126
1127 dev = slsi_gscan_get_netdev(sdev);
1128 if (!dev) {
1129 SLSI_WARN_NODEV("dev is NULL\n");
1130 return -EINVAL;
1131 }
1132
1133 ndev_vif = netdev_priv(dev);
1134
1135 SLSI_MUTEX_LOCK(ndev_vif->scan_mutex);
1136 while (sdev->gscan != NULL) {
1137 gscan = sdev->gscan;
1138
1139 SLSI_DBG3(sdev, SLSI_GSCAN, "gscan = %p, num_buckets = %d\n", gscan, gscan->num_buckets);
1140
1141 for (i = 0; i < gscan->num_buckets; i++)
1142 if (gscan->bucket[i]->used)
1143 slsi_mlme_del_scan(sdev, dev, gscan->bucket[i]->scan_id, false);
1144 slsi_gscan_free_buckets(gscan);
1145 sdev->gscan = gscan->next;
1146 kfree(gscan);
1147 }
1148 SLSI_MUTEX_UNLOCK(ndev_vif->scan_mutex);
1149
1150 slsi_gscan_flush_scan_results(sdev);
1151
1152 sdev->buffer_threshold = 0;
1153
1154 return ret;
1155 }
1156
1157 static int slsi_gscan_get_scan_results(struct wiphy *wiphy,
1158 struct wireless_dev *wdev, const void *data, int len)
1159 {
1160 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1161 struct sk_buff *skb;
1162 struct slsi_gscan_result *scan_res;
1163 struct nlattr *scan_hdr;
1164 struct netdev_vif *ndev_vif;
1165 int num_results = 0;
1166 int mem_needed;
1167 const struct nlattr *attr;
1168 int nl_num_results = 0;
1169 int ret = 0;
1170 int temp;
1171 int type;
1172 int i;
1173
1174 SLSI_DBG1_NODEV(SLSI_GSCAN, "SUBCMD_GET_SCAN_RESULTS\n");
1175
1176 /* Read the number of scan results need to be given */
1177 nla_for_each_attr(attr, data, len, temp) {
1178 type = nla_type(attr);
1179
1180 switch (type) {
1181 case GSCAN_ATTRIBUTE_NUM_OF_RESULTS:
1182 if (nla_len(attr) != SLSI_NL_ATTRIBUTE_U32_LEN)
1183 return -EINVAL;
1184 nl_num_results = nla_get_u32(attr);
1185 break;
1186 default:
1187 SLSI_ERR_NODEV("Unknown attribute: %d\n", type);
1188 break;
1189 }
1190 }
1191
1192 ndev_vif = slsi_gscan_get_vif(sdev);
1193 if (!ndev_vif) {
1194 SLSI_WARN_NODEV("ndev_vif is NULL\n");
1195 return -EINVAL;
1196 }
1197
1198 SLSI_MUTEX_LOCK(ndev_vif->scan_mutex);
1199
1200 num_results = sdev->num_gscan_results;
1201
1202 SLSI_DBG3(sdev, SLSI_GSCAN, "nl_num_results: %d, num_results = %d\n", nl_num_results, sdev->num_gscan_results);
1203
1204 if (num_results == 0) {
1205 SLSI_DBG1(sdev, SLSI_GSCAN, "No scan results available\n");
1206 /* Return value should be 0 for this scenario */
1207 goto exit;
1208 }
1209
1210 /* Find the number of results to return */
1211 if (num_results > nl_num_results)
1212 num_results = nl_num_results;
1213
1214 /* 12 bytes additional for scan_id, flags and num_resuls */
1215 mem_needed = num_results * sizeof(struct slsi_nl_scan_result_param) + 12;
1216
1217 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, mem_needed);
1218 if (skb == NULL) {
1219 SLSI_ERR_NODEV("skb alloc failed");
1220 ret = -ENOMEM;
1221 goto exit;
1222 }
1223
1224 scan_hdr = nla_nest_start(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS);
1225 if (scan_hdr == NULL) {
1226 kfree_skb(skb);
1227 SLSI_ERR_NODEV("scan_hdr is NULL.\n");
1228 ret = -ENOMEM;
1229 goto exit;
1230 }
1231
1232 nla_put_u32(skb, GSCAN_ATTRIBUTE_SCAN_ID, 0);
1233 nla_put_u8(skb, GSCAN_ATTRIBUTE_SCAN_FLAGS, 0);
1234 nla_put_u32(skb, GSCAN_ATTRIBUTE_NUM_OF_RESULTS, num_results);
1235
1236 for (i = 0; i < SLSI_GSCAN_HASH_TABLE_SIZE; i++)
1237 while (sdev->gscan_hash_table[i]) {
1238 scan_res = sdev->gscan_hash_table[i];
1239 sdev->gscan_hash_table[i] = sdev->gscan_hash_table[i]->hnext;
1240 sdev->num_gscan_results--;
1241 sdev->buffer_consumed -= scan_res->scan_res_len;
1242 /* TODO: If IE is included then HAL is not able to parse the results */
1243 nla_put(skb, GSCAN_ATTRIBUTE_SCAN_RESULTS, sizeof(struct slsi_nl_scan_result_param), &scan_res->nl_scan_res);
1244 kfree(scan_res);
1245 num_results--;
1246 if (num_results == 0)
1247 goto out;
1248 }
1249 out:
1250 nla_nest_end(skb, scan_hdr);
1251
1252 ret = cfg80211_vendor_cmd_reply(skb);
1253 exit:
1254 SLSI_MUTEX_UNLOCK(ndev_vif->scan_mutex);
1255 return ret;
1256 }
1257
1258 void slsi_rx_rssi_report_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb)
1259 {
1260 struct netdev_vif *ndev_vif = netdev_priv(dev);
1261 struct slsi_rssi_monitor_evt event_data;
1262
1263 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1264 SLSI_ETHER_COPY(event_data.bssid, fapi_get_buff(skb, u.mlme_rssi_report_ind.bssid));
1265 event_data.rssi = fapi_get_s16(skb, u.mlme_rssi_report_ind.rssi);
1266 SLSI_DBG3(sdev, SLSI_GSCAN, "RSSI threshold breached, Current RSSI for %pM= %d\n", event_data.bssid, event_data.rssi);
1267 slsi_vendor_event(sdev, SLSI_NL80211_RSSI_REPORT_EVENT, &event_data, sizeof(event_data));
1268 slsi_kfree_skb(skb);
1269 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1270 }
1271
1272 #ifdef CONFIG_SCSC_WLAN_KEY_MGMT_OFFLOAD
1273 static int slsi_key_mgmt_set_pmk(struct wiphy *wiphy,
1274 struct wireless_dev *wdev, const void *pmk, int pmklen)
1275 {
1276 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1277 struct net_device *net_dev;
1278 struct netdev_vif *ndev_vif;
1279 int r = 0;
1280
1281 if (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) {
1282 SLSI_DBG3(sdev, SLSI_GSCAN, "Not required to set PMK for P2P client\n");
1283 return r;
1284 }
1285 SLSI_DBG3(sdev, SLSI_GSCAN, "SUBCMD_SET_PMK Received\n");
1286
1287 net_dev = slsi_get_netdev(sdev, SLSI_NET_INDEX_WLAN);
1288 ndev_vif = netdev_priv(net_dev);
1289
1290 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1291
1292 r = slsi_mlme_set_pmk(sdev, net_dev, pmk, (u16)pmklen);
1293
1294 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1295 return r;
1296 }
1297 #endif
1298
1299 static int slsi_set_bssid_blacklist(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
1300 {
1301 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1302 struct net_device *net_dev;
1303 struct netdev_vif *ndev_vif;
1304 int temp1;
1305 int type;
1306 const struct nlattr *attr;
1307 u32 num_bssids = 0;
1308 u8 i = 0;
1309 int ret;
1310 u8 *bssid = NULL;
1311 struct cfg80211_acl_data *acl_data = NULL;
1312
1313 SLSI_DBG1_NODEV(SLSI_GSCAN, "SUBCMD_SET_BSSID_BLACK_LIST\n");
1314
1315 net_dev = slsi_get_netdev(sdev, SLSI_NET_INDEX_WLAN);
1316 if (!net_dev) {
1317 SLSI_WARN_NODEV("net_dev is NULL\n");
1318 return -EINVAL;
1319 }
1320
1321 ndev_vif = netdev_priv(net_dev);
1322 /*This subcmd can be issued in either connected or disconnected state.
1323 * Hence using scan_mutex and not vif_mutex
1324 */
1325 SLSI_MUTEX_LOCK(ndev_vif->scan_mutex);
1326 nla_for_each_attr(attr, data, len, temp1) {
1327 if (!attr) {
1328 ret = -EINVAL;
1329 break;
1330 }
1331
1332 type = nla_type(attr);
1333
1334 switch (type) {
1335 case GSCAN_ATTRIBUTE_NUM_BSSID:
1336 if (acl_data)
1337 break;
1338
1339 if (nla_len(attr) != (SLSI_NL_ATTRIBUTE_U32_LEN - NLA_HDRLEN)) {
1340 ret = -EINVAL;
1341 goto exit;
1342 }
1343 num_bssids = nla_get_u32(attr);
1344 if (num_bssids == 0 || (num_bssids > (u32)(0xFFFFFFFF / (sizeof(*acl_data) + sizeof(struct mac_address))))) {
1345 ret = -EINVAL;
1346 goto exit;
1347 }
1348 acl_data = kmalloc(sizeof(*acl_data) + (sizeof(struct mac_address) * num_bssids), GFP_KERNEL);
1349 if (!acl_data) {
1350 ret = -ENOMEM;
1351 goto exit;
1352 }
1353 acl_data->n_acl_entries = num_bssids;
1354 break;
1355
1356 case GSCAN_ATTRIBUTE_BLACKLIST_BSSID:
1357 if (!acl_data) {
1358 ret = -EINVAL;
1359 goto exit;
1360 }
1361
1362 if (nla_len(attr) != (SLSI_NL_ATTRIBUTE_U8_LEN - NLA_HDRLEN)) {
1363 ret = -EINVAL;
1364 goto exit;
1365 }
1366
1367 if (i >= num_bssids) {
1368 ret = -EINVAL;
1369 goto exit;
1370 }
1371
1372 bssid = (u8 *)nla_data(attr);
1373
1374 SLSI_ETHER_COPY(acl_data->mac_addrs[i].addr, bssid);
1375 SLSI_DBG3_NODEV(SLSI_GSCAN, "mac_addrs[%d]:%pM)\n", i, acl_data->mac_addrs[i].addr);
1376 i++;
1377 break;
1378 default:
1379 SLSI_ERR_NODEV("Unknown attribute: %d\n", type);
1380 ret = -EINVAL;
1381 goto exit;
1382 }
1383 }
1384
1385 if (acl_data) {
1386 acl_data->acl_policy = FAPI_ACLPOLICY_BLACKLIST;
1387 ret = slsi_mlme_set_acl(sdev, net_dev, 0, acl_data);
1388 if (ret)
1389 SLSI_ERR_NODEV("Failed to set bssid blacklist\n");
1390 } else {
1391 ret = -EINVAL;
1392 }
1393 exit:
1394 SLSI_MUTEX_UNLOCK(ndev_vif->scan_mutex);
1395 kfree(acl_data);
1396 return ret;
1397 }
1398
1399 static int slsi_start_keepalive_offload(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
1400 {
1401 #ifndef CONFIG_SCSC_WLAN_NAT_KEEPALIVE_DISABLE
1402 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1403 struct net_device *net_dev;
1404 struct netdev_vif *ndev_vif;
1405
1406 int temp;
1407 int type;
1408 const struct nlattr *attr;
1409 u16 ip_pkt_len = 0;
1410 u8 *ip_pkt = NULL, *src_mac_addr = NULL, *dst_mac_addr = NULL;
1411 u32 period = 0;
1412 struct slsi_peer *peer;
1413 struct sk_buff *skb;
1414 struct ethhdr *ehdr;
1415 int r = 0;
1416 u16 host_tag = 0;
1417 u8 index = 0;
1418
1419 SLSI_DBG3(sdev, SLSI_MLME, "SUBCMD_START_KEEPALIVE_OFFLOAD received\n");
1420 net_dev = slsi_get_netdev(sdev, SLSI_NET_INDEX_WLAN);
1421 ndev_vif = netdev_priv(net_dev);
1422
1423 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1424 if (!ndev_vif->activated) {
1425 SLSI_WARN_NODEV("ndev_vif is not activated\n");
1426 r = -EINVAL;
1427 goto exit;
1428 }
1429 if (ndev_vif->vif_type != FAPI_VIFTYPE_STATION) {
1430 SLSI_WARN_NODEV("ndev_vif->vif_type is not FAPI_VIFTYPE_STATION\n");
1431 r = -EINVAL;
1432 goto exit;
1433 }
1434 if (ndev_vif->sta.vif_status != SLSI_VIF_STATUS_CONNECTED) {
1435 SLSI_WARN_NODEV("ndev_vif->sta.vif_status is not SLSI_VIF_STATUS_CONNECTED\n");
1436 r = -EINVAL;
1437 goto exit;
1438 }
1439
1440 peer = slsi_get_peer_from_qs(sdev, net_dev, SLSI_STA_PEER_QUEUESET);
1441 if (!peer) {
1442 SLSI_WARN_NODEV("peer is NULL\n");
1443 r = -EINVAL;
1444 goto exit;
1445 }
1446
1447 nla_for_each_attr(attr, data, len, temp) {
1448 type = nla_type(attr);
1449
1450 switch (type) {
1451 case MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN:
1452 ip_pkt_len = nla_get_u16(attr);
1453 break;
1454
1455 case MKEEP_ALIVE_ATTRIBUTE_IP_PKT:
1456 ip_pkt = (u8 *)nla_data(attr);
1457 break;
1458
1459 case MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC:
1460 period = nla_get_u32(attr);
1461 break;
1462
1463 case MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR:
1464 dst_mac_addr = (u8 *)nla_data(attr);
1465 break;
1466
1467 case MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR:
1468 src_mac_addr = (u8 *)nla_data(attr);
1469 break;
1470
1471 case MKEEP_ALIVE_ATTRIBUTE_ID:
1472 index = nla_get_u8(attr);
1473 break;
1474
1475 default:
1476 SLSI_ERR_NODEV("Unknown attribute: %d\n", type);
1477 r = -EINVAL;
1478 goto exit;
1479 }
1480 }
1481
1482 /* Stop any existing request. This may fail if no request exists
1483 * so ignore the return value
1484 */
1485 slsi_mlme_send_frame_mgmt(sdev, net_dev, NULL, 0,
1486 FAPI_DATAUNITDESCRIPTOR_IEEE802_3_FRAME,
1487 FAPI_MESSAGETYPE_ANY_OTHER,
1488 ndev_vif->sta.keepalive_host_tag[index - 1], 0, 0, 0);
1489
1490 skb = slsi_alloc_skb_headroom(sizeof(struct ethhdr) + ip_pkt_len, GFP_KERNEL);
1491 if (!skb) {
1492 SLSI_WARN_NODEV("Memory allocation failed for skb\n");
1493 r = -ENOMEM;
1494 goto exit;
1495 }
1496
1497 skb_reset_mac_header(skb);
1498 skb_set_network_header(skb, sizeof(struct ethhdr));
1499
1500 /* Ethernet Header */
1501 ehdr = (struct ethhdr *)skb_put(skb, sizeof(struct ethhdr));
1502
1503 if (dst_mac_addr)
1504 SLSI_ETHER_COPY(ehdr->h_dest, dst_mac_addr);
1505 if (src_mac_addr)
1506 SLSI_ETHER_COPY(ehdr->h_source, src_mac_addr);
1507 ehdr->h_proto = cpu_to_be16(ETH_P_IP);
1508 if (ip_pkt)
1509 memcpy(skb_put(skb, ip_pkt_len), ip_pkt, ip_pkt_len);
1510
1511 skb->dev = net_dev;
1512 skb->protocol = ETH_P_IP;
1513 skb->ip_summed = CHECKSUM_UNNECESSARY;
1514
1515 /* Queueset 0 AC 0 */
1516 skb->queue_mapping = slsi_netif_get_peer_queue(0, 0);
1517
1518 /* Enabling the "Don't Fragment" Flag in the IP Header */
1519 ip_hdr(skb)->frag_off |= htons(IP_DF);
1520
1521 /* Calculation of IP header checksum */
1522 ip_hdr(skb)->check = 0;
1523 ip_send_check(ip_hdr(skb));
1524
1525 host_tag = slsi_tx_mgmt_host_tag(sdev);
1526 r = slsi_mlme_send_frame_data(sdev, net_dev, skb, FAPI_MESSAGETYPE_ANY_OTHER, host_tag,
1527 0, (period * 1000));
1528 if (r == 0)
1529 ndev_vif->sta.keepalive_host_tag[index - 1] = host_tag;
1530 else
1531 slsi_kfree_skb(skb);
1532
1533 exit:
1534 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1535 return r;
1536 #else
1537 SLSI_DBG3_NODEV(SLSI_MLME, "SUBCMD_START_KEEPALIVE_OFFLOAD received\n");
1538 SLSI_DBG3_NODEV(SLSI_MLME, "NAT Keep Alive Feature is disabled\n");
1539 return -EOPNOTSUPP;
1540
1541 #endif
1542 }
1543
1544 static int slsi_stop_keepalive_offload(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
1545 {
1546 #ifndef CONFIG_SCSC_WLAN_NAT_KEEPALIVE_DISABLE
1547 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1548 struct net_device *net_dev;
1549 struct netdev_vif *ndev_vif;
1550 int r = 0;
1551 int temp;
1552 int type;
1553 const struct nlattr *attr;
1554 u8 index = 0;
1555
1556 SLSI_DBG3(sdev, SLSI_MLME, "SUBCMD_STOP_KEEPALIVE_OFFLOAD received\n");
1557 net_dev = slsi_get_netdev(sdev, SLSI_NET_INDEX_WLAN);
1558 ndev_vif = netdev_priv(net_dev);
1559
1560 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1561 if (!ndev_vif->activated) {
1562 SLSI_WARN(sdev, "VIF is not activated\n");
1563 r = -EINVAL;
1564 goto exit;
1565 }
1566 if (ndev_vif->vif_type != FAPI_VIFTYPE_STATION) {
1567 SLSI_WARN(sdev, "Not a STA VIF\n");
1568 r = -EINVAL;
1569 goto exit;
1570 }
1571 if (ndev_vif->sta.vif_status != SLSI_VIF_STATUS_CONNECTED) {
1572 SLSI_WARN(sdev, "VIF is not connected\n");
1573 r = -EINVAL;
1574 goto exit;
1575 }
1576
1577 nla_for_each_attr(attr, data, len, temp) {
1578 type = nla_type(attr);
1579
1580 switch (type) {
1581 case MKEEP_ALIVE_ATTRIBUTE_ID:
1582 index = nla_get_u8(attr);
1583 break;
1584
1585 default:
1586 SLSI_ERR_NODEV("Unknown attribute: %d\n", type);
1587 r = -EINVAL;
1588 goto exit;
1589 }
1590 }
1591
1592 r = slsi_mlme_send_frame_mgmt(sdev, net_dev, NULL, 0, FAPI_DATAUNITDESCRIPTOR_IEEE802_3_FRAME,
1593 FAPI_MESSAGETYPE_ANY_OTHER, ndev_vif->sta.keepalive_host_tag[index - 1], 0, 0, 0);
1594 ndev_vif->sta.keepalive_host_tag[index - 1] = 0;
1595
1596 exit:
1597 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1598 return r;
1599 #else
1600 SLSI_DBG3_NODEV(SLSI_MLME, "SUBCMD_STOP_KEEPALIVE_OFFLOAD received\n");
1601 SLSI_DBG3_NODEV(SLSI_MLME, "NAT Keep Alive Feature is disabled\n");
1602 return -EOPNOTSUPP;
1603
1604 #endif
1605 }
1606
1607 static inline int slsi_epno_ssid_list_get(struct slsi_dev *sdev,
1608 struct slsi_epno_ssid_param *epno_ssid_params, const struct nlattr *outer)
1609 {
1610 int type, tmp;
1611 u8 epno_auth;
1612 u8 len = 0;
1613 const struct nlattr *inner;
1614
1615 nla_for_each_nested(inner, outer, tmp) {
1616 type = nla_type(inner);
1617 switch (type) {
1618 case SLSI_ATTRIBUTE_EPNO_FLAGS:
1619 epno_ssid_params->flags |= nla_get_u16(inner);
1620 break;
1621 case SLSI_ATTRIBUTE_EPNO_AUTH:
1622 epno_auth = nla_get_u8(inner);
1623 if (epno_auth & SLSI_EPNO_AUTH_FIELD_WEP_OPEN)
1624 epno_ssid_params->flags |= FAPI_EPNOPOLICY_AUTH_OPEN;
1625 else if (epno_auth & SLSI_EPNO_AUTH_FIELD_WPA_PSK)
1626 epno_ssid_params->flags |= FAPI_EPNOPOLICY_AUTH_PSK;
1627 else if (epno_auth & SLSI_EPNO_AUTH_FIELD_WPA_EAP)
1628 epno_ssid_params->flags |= FAPI_EPNOPOLICY_AUTH_EAPOL;
1629 break;
1630 case SLSI_ATTRIBUTE_EPNO_SSID_LEN:
1631 len = nla_get_u8(inner);
1632 if (len <= 32) {
1633 epno_ssid_params->ssid_len = len;
1634 } else {
1635 SLSI_ERR(sdev, "SSID too long %d\n", len);
1636 return -EINVAL;
1637 }
1638 break;
1639 case SLSI_ATTRIBUTE_EPNO_SSID:
1640 memcpy(epno_ssid_params->ssid, nla_data(inner), len);
1641 break;
1642 default:
1643 SLSI_WARN(sdev, "Ignoring unknown type:%d\n", type);
1644 }
1645 }
1646 return 0;
1647 }
1648
1649 static int slsi_set_epno_ssid(struct wiphy *wiphy,
1650 struct wireless_dev *wdev, const void *data, int len)
1651 {
1652 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1653 struct net_device *net_dev;
1654 struct netdev_vif *ndev_vif;
1655 int r = 0;
1656 int tmp, tmp1, type, num = 0;
1657 const struct nlattr *outer, *iter;
1658 u8 i = 0;
1659 struct slsi_epno_ssid_param *epno_ssid_params;
1660 struct slsi_epno_param *epno_params;
1661
1662 SLSI_DBG3(sdev, SLSI_GSCAN, "SUBCMD_SET_EPNO_LIST Received\n");
1663
1664 if (!slsi_dev_epno_supported())
1665 return -EOPNOTSUPP;
1666
1667 epno_params = kmalloc((sizeof(*epno_params) + (sizeof(*epno_ssid_params) * SLSI_GSCAN_MAX_EPNO_SSIDS)),
1668 GFP_KERNEL);
1669 if (!epno_params) {
1670 SLSI_ERR(sdev, "Mem alloc fail\n");
1671 return -ENOMEM;
1672 }
1673 net_dev = slsi_get_netdev(sdev, SLSI_NET_INDEX_WLAN);
1674 ndev_vif = netdev_priv(net_dev);
1675 nla_for_each_attr(iter, data, len, tmp1) {
1676 type = nla_type(iter);
1677 switch (type) {
1678 case SLSI_ATTRIBUTE_EPNO_MINIMUM_5G_RSSI:
1679 epno_params->min_5g_rssi = nla_get_u16(iter);
1680 break;
1681 case SLSI_ATTRIBUTE_EPNO_MINIMUM_2G_RSSI:
1682 epno_params->min_2g_rssi = nla_get_u16(iter);
1683 break;
1684 case SLSI_ATTRIBUTE_EPNO_INITIAL_SCORE_MAX:
1685 epno_params->initial_score_max = nla_get_u16(iter);
1686 break;
1687 case SLSI_ATTRIBUTE_EPNO_CUR_CONN_BONUS:
1688 epno_params->current_connection_bonus = nla_get_u8(iter);
1689 break;
1690 case SLSI_ATTRIBUTE_EPNO_SAME_NETWORK_BONUS:
1691 epno_params->same_network_bonus = nla_get_u8(iter);
1692 break;
1693 case SLSI_ATTRIBUTE_EPNO_SECURE_BONUS:
1694 epno_params->secure_bonus = nla_get_u8(iter);
1695 break;
1696 case SLSI_ATTRIBUTE_EPNO_5G_BONUS:
1697 epno_params->band_5g_bonus = nla_get_u8(iter);
1698 break;
1699 case SLSI_ATTRIBUTE_EPNO_SSID_LIST:
1700 nla_for_each_nested(outer, iter, tmp) {
1701 epno_ssid_params = &epno_params->epno_ssid[i];
1702 epno_ssid_params->flags = 0;
1703 r = slsi_epno_ssid_list_get(sdev, epno_ssid_params, outer);
1704 if (r)
1705 goto exit;
1706 i++;
1707 }
1708 break;
1709 case SLSI_ATTRIBUTE_EPNO_SSID_NUM:
1710 num = nla_get_u8(iter);
1711 if (num > SLSI_GSCAN_MAX_EPNO_SSIDS) {
1712 SLSI_ERR(sdev, "Cannot support %d SSIDs. max %d\n", num, SLSI_GSCAN_MAX_EPNO_SSIDS);
1713 r = -EINVAL;
1714 goto exit;
1715 }
1716 epno_params->num_networks = num;
1717 break;
1718 default:
1719 SLSI_ERR(sdev, "Invalid attribute %d\n", type);
1720 r = -EINVAL;
1721 goto exit;
1722 }
1723 }
1724
1725 if (i != num) {
1726 SLSI_ERR(sdev, "num_ssid %d does not match ssids sent %d\n", num, i);
1727 r = -EINVAL;
1728 goto exit;
1729 }
1730 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1731 r = slsi_mlme_set_pno_list(sdev, num, epno_params, NULL);
1732 if (r == 0)
1733 sdev->epno_active = (num != 0);
1734 else
1735 sdev->epno_active = false;
1736 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1737 exit:
1738 kfree(epno_params);
1739 return r;
1740 }
1741
1742 static int slsi_set_hs_params(struct wiphy *wiphy,
1743 struct wireless_dev *wdev, const void *data, int len)
1744 {
1745 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1746 struct net_device *net_dev;
1747 struct netdev_vif *ndev_vif;
1748 int r = 0;
1749 int tmp, tmp1, tmp2, type, num = 0;
1750 const struct nlattr *outer, *inner, *iter;
1751 u8 i = 0;
1752 struct slsi_epno_hs2_param *epno_hs2_params_array;
1753 struct slsi_epno_hs2_param *epno_hs2_params;
1754
1755 SLSI_DBG3(sdev, SLSI_GSCAN, "SUBCMD_SET_HS_LIST Received\n");
1756
1757 if (!slsi_dev_epno_supported())
1758 return -EOPNOTSUPP;
1759
1760 epno_hs2_params_array = kmalloc(sizeof(*epno_hs2_params_array) * SLSI_GSCAN_MAX_EPNO_HS2_PARAM, GFP_KERNEL);
1761 if (!epno_hs2_params_array) {
1762 SLSI_ERR(sdev, "Mem alloc fail\n");
1763 return -ENOMEM;
1764 }
1765
1766 net_dev = slsi_get_netdev(sdev, SLSI_NET_INDEX_WLAN);
1767 ndev_vif = netdev_priv(net_dev);
1768
1769 nla_for_each_attr(iter, data, len, tmp2) {
1770 type = nla_type(iter);
1771 switch (type) {
1772 case SLSI_ATTRIBUTE_EPNO_HS_PARAM_LIST:
1773 nla_for_each_nested(outer, iter, tmp) {
1774 epno_hs2_params = &epno_hs2_params_array[i];
1775 i++;
1776 nla_for_each_nested(inner, outer, tmp1) {
1777 type = nla_type(inner);
1778
1779 switch (type) {
1780 case SLSI_ATTRIBUTE_EPNO_HS_ID:
1781 epno_hs2_params->id = (u32)nla_get_u32(inner);
1782 break;
1783 case SLSI_ATTRIBUTE_EPNO_HS_REALM:
1784 memcpy(epno_hs2_params->realm, nla_data(inner), 256);
1785 break;
1786 case SLSI_ATTRIBUTE_EPNO_HS_CONSORTIUM_IDS:
1787 memcpy(epno_hs2_params->roaming_consortium_ids, nla_data(inner), 16 * 8);
1788 break;
1789 case SLSI_ATTRIBUTE_EPNO_HS_PLMN:
1790 memcpy(epno_hs2_params->plmn, nla_data(inner), 3);
1791 break;
1792 default:
1793 SLSI_WARN(sdev, "Ignoring unknown type:%d\n", type);
1794 }
1795 }
1796 }
1797 break;
1798 case SLSI_ATTRIBUTE_EPNO_HS_NUM:
1799 num = nla_get_u8(iter);
1800 if (num > SLSI_GSCAN_MAX_EPNO_HS2_PARAM) {
1801 SLSI_ERR(sdev, "Cannot support %d SSIDs. max %d\n", num, SLSI_GSCAN_MAX_EPNO_SSIDS);
1802 r = -EINVAL;
1803 goto exit;
1804 }
1805 break;
1806 default:
1807 SLSI_ERR(sdev, "Invalid attribute %d\n", type);
1808 r = -EINVAL;
1809 goto exit;
1810 }
1811 }
1812 if (i != num) {
1813 SLSI_ERR(sdev, "num_ssid %d does not match ssids sent %d\n", num, i);
1814 r = -EINVAL;
1815 goto exit;
1816 }
1817
1818 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1819 r = slsi_mlme_set_pno_list(sdev, num, NULL, epno_hs2_params_array);
1820 if (r == 0)
1821 sdev->epno_active = true;
1822 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1823 exit:
1824 kfree(epno_hs2_params_array);
1825 return r;
1826 }
1827
1828 static int slsi_reset_hs_params(struct wiphy *wiphy,
1829 struct wireless_dev *wdev, const void *data, int len)
1830 {
1831 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1832 struct net_device *net_dev;
1833 struct netdev_vif *ndev_vif;
1834 int r;
1835
1836 SLSI_DBG3(sdev, SLSI_GSCAN, "SUBCMD_RESET_HS_LIST Received\n");
1837
1838 if (!slsi_dev_epno_supported())
1839 return -EOPNOTSUPP;
1840
1841 net_dev = slsi_get_netdev(sdev, SLSI_NET_INDEX_WLAN);
1842 ndev_vif = netdev_priv(net_dev);
1843
1844 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1845 r = slsi_mlme_set_pno_list(sdev, 0, NULL, NULL);
1846 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1847 sdev->epno_active = false;
1848 return r;
1849 }
1850
1851 static int slsi_set_rssi_monitor(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
1852 {
1853 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1854 struct net_device *net_dev;
1855 struct netdev_vif *ndev_vif;
1856 int r = 0;
1857 int temp;
1858 int type;
1859 const struct nlattr *attr;
1860 s8 min_rssi = 0, max_rssi = 0;
1861 u16 enable = 0;
1862
1863 SLSI_DBG3(sdev, SLSI_GSCAN, "Recd RSSI monitor command\n");
1864
1865 net_dev = slsi_get_netdev(sdev, SLSI_NET_INDEX_WLAN);
1866 if (net_dev == NULL) {
1867 SLSI_ERR(sdev, "netdev is NULL!!\n");
1868 return -ENODEV;
1869 }
1870
1871 ndev_vif = netdev_priv(net_dev);
1872 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
1873
1874 if (!ndev_vif->activated) {
1875 SLSI_ERR(sdev, "Vif not activated\n");
1876 r = -EINVAL;
1877 goto exit;
1878 }
1879 if (ndev_vif->vif_type != FAPI_VIFTYPE_STATION) {
1880 SLSI_ERR(sdev, "Not a STA vif\n");
1881 r = -EINVAL;
1882 goto exit;
1883 }
1884 if (ndev_vif->sta.vif_status != SLSI_VIF_STATUS_CONNECTED) {
1885 SLSI_ERR(sdev, "STA vif not connected\n");
1886 r = -EINVAL;
1887 goto exit;
1888 }
1889
1890 nla_for_each_attr(attr, data, len, temp) {
1891 type = nla_type(attr);
1892 switch (type) {
1893 case SLSI_RSSI_MONITOR_ATTRIBUTE_START:
1894 enable = (u16)nla_get_u8(attr);
1895 break;
1896 case SLSI_RSSI_MONITOR_ATTRIBUTE_MIN_RSSI:
1897 min_rssi = nla_get_s8(attr);
1898 break;
1899 case SLSI_RSSI_MONITOR_ATTRIBUTE_MAX_RSSI:
1900 max_rssi = nla_get_s8(attr);
1901 break;
1902 default:
1903 r = -EINVAL;
1904 goto exit;
1905 }
1906 }
1907 if (min_rssi > max_rssi) {
1908 SLSI_ERR(sdev, "Invalid params, min_rssi= %d ,max_rssi = %d\n", min_rssi, max_rssi);
1909 r = -EINVAL;
1910 goto exit;
1911 }
1912 r = slsi_mlme_set_rssi_monitor(sdev, net_dev, enable, min_rssi, max_rssi);
1913 exit:
1914 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
1915 return r;
1916 }
1917
1918 #ifdef CONFIG_SCSC_WLAN_DEBUG
1919 void slsi_lls_debug_dump_stats(struct slsi_dev *sdev, struct slsi_lls_radio_stat *radio_stat,
1920 struct slsi_lls_iface_stat *iface_stat, u8 *buf, int buf_len, int num_of_radios)
1921 {
1922 int i, j;
1923
1924 for (j = 0; j < num_of_radios; j++) {
1925 SLSI_DBG3(sdev, SLSI_GSCAN, "radio_stat====\n");
1926 SLSI_DBG3(sdev, SLSI_GSCAN, "\tradio_id : %d, on_time : %d, tx_time : %d, rx_time : %d,"
1927 "on_time_scan : %d, num_channels : %d\n", radio_stat->radio, radio_stat->on_time,
1928 radio_stat->tx_time, radio_stat->rx_time, radio_stat->on_time_scan,
1929 radio_stat->num_channels);
1930
1931 radio_stat = (struct slsi_lls_radio_stat *)((u8 *)radio_stat + sizeof(struct slsi_lls_radio_stat) +
1932 (sizeof(struct slsi_lls_channel_stat) * radio_stat->num_channels));
1933 }
1934 SLSI_DBG3(sdev, SLSI_GSCAN, "iface_stat====\n");
1935 SLSI_DBG3(sdev, SLSI_GSCAN, "\tiface %p info : (mode : %d, mac_addr : %pM, state : %d, roaming : %d,"
1936 " capabilities : %d, ssid : %s, bssid : %pM, ap_country_str : [%d%d%d])\trssi_data : %d\n",
1937 iface_stat->iface, iface_stat->info.mode, iface_stat->info.mac_addr, iface_stat->info.state,
1938 iface_stat->info.roaming, iface_stat->info.capabilities, iface_stat->info.ssid,
1939 iface_stat->info.bssid, iface_stat->info.ap_country_str[0], iface_stat->info.ap_country_str[1],
1940 iface_stat->info.ap_country_str[2], iface_stat->rssi_data);
1941
1942 SLSI_DBG3(sdev, SLSI_GSCAN, "\tnum_peers %d\n", iface_stat->num_peers);
1943 for (i = 0; i < iface_stat->num_peers; i++) {
1944 SLSI_DBG3(sdev, SLSI_GSCAN, "\t\tpeer_mac_address %pM\n", iface_stat->peer_info[i].peer_mac_address);
1945 }
1946
1947 SLSI_DBG_HEX(sdev, SLSI_GSCAN, buf, buf_len, "return buffer\n");
1948 }
1949 #endif
1950
1951 static int slsi_lls_set_stats(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
1952 {
1953 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
1954 struct net_device *net_dev = NULL;
1955 struct netdev_vif *ndev_vif = NULL;
1956 int temp;
1957 int type;
1958 const struct nlattr *attr;
1959 u32 mpdu_size_threshold = 0;
1960 u32 aggr_stat_gathering = 0;
1961 int r = 0, i;
1962
1963 if (!slsi_dev_lls_supported())
1964 return -EOPNOTSUPP;
1965
1966 if (slsi_is_test_mode_enabled()) {
1967 SLSI_WARN(sdev, "not supported in WlanLite mode\n");
1968 return -EOPNOTSUPP;
1969 }
1970
1971 nla_for_each_attr(attr, data, len, temp) {
1972 type = nla_type(attr);
1973
1974 switch (type) {
1975 case LLS_ATTRIBUTE_SET_MPDU_SIZE_THRESHOLD:
1976 mpdu_size_threshold = nla_get_u32(attr);
1977 break;
1978
1979 case LLS_ATTRIBUTE_SET_AGGR_STATISTICS_GATHERING:
1980 aggr_stat_gathering = nla_get_u32(attr);
1981 break;
1982
1983 default:
1984 SLSI_ERR_NODEV("Unknown attribute: %d\n", type);
1985 r = -EINVAL;
1986 }
1987 }
1988
1989 SLSI_MUTEX_LOCK(sdev->device_config_mutex);
1990 /* start Statistics measurements in Firmware */
1991 (void)slsi_mlme_start_link_stats_req(sdev, mpdu_size_threshold, aggr_stat_gathering);
1992
1993 net_dev = slsi_get_netdev(sdev, SLSI_NET_INDEX_WLAN);
1994 if (net_dev) {
1995 ndev_vif = netdev_priv(net_dev);
1996 for (i = 0; i < SLSI_LLS_AC_MAX; i++) {
1997 ndev_vif->rx_packets[i] = 0;
1998 ndev_vif->tx_packets[i] = 0;
1999 ndev_vif->tx_no_ack[i] = 0;
2000 }
2001 }
2002 SLSI_MUTEX_UNLOCK(sdev->device_config_mutex);
2003 return 0;
2004 }
2005
2006 static int slsi_lls_clear_stats(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
2007 {
2008 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
2009 int temp;
2010 int type;
2011 const struct nlattr *attr;
2012 u32 stats_clear_req_mask = 0;
2013 u32 stop_req = 0;
2014 int r = 0, i;
2015 struct net_device *net_dev = NULL;
2016 struct netdev_vif *ndev_vif = NULL;
2017
2018 SLSI_DBG3(sdev, SLSI_GSCAN, "\n");
2019
2020 nla_for_each_attr(attr, data, len, temp) {
2021 type = nla_type(attr);
2022
2023 switch (type) {
2024 case LLS_ATTRIBUTE_CLEAR_STOP_REQUEST_MASK:
2025 stats_clear_req_mask = nla_get_u32(attr);
2026 SLSI_DBG3(sdev, SLSI_GSCAN, "stats_clear_req_mask:%u\n", stats_clear_req_mask);
2027 break;
2028
2029 case LLS_ATTRIBUTE_CLEAR_STOP_REQUEST:
2030 stop_req = nla_get_u32(attr);
2031 SLSI_DBG3(sdev, SLSI_GSCAN, "stop_req:%u\n", stop_req);
2032 break;
2033
2034 default:
2035 SLSI_ERR(sdev, "Unknown attribute:%d\n", type);
2036 r = -EINVAL;
2037 }
2038 }
2039
2040 /* stop_req = 0 : clear the stats which are flaged 0
2041 * stop_req = 1 : clear the stats which are flaged 1
2042 */
2043 if (!stop_req)
2044 stats_clear_req_mask = ~stats_clear_req_mask;
2045
2046 SLSI_MUTEX_LOCK(sdev->device_config_mutex);
2047 (void)slsi_mlme_stop_link_stats_req(sdev, stats_clear_req_mask);
2048 net_dev = slsi_get_netdev(sdev, SLSI_NET_INDEX_WLAN);
2049 if (net_dev) {
2050 ndev_vif = netdev_priv(net_dev);
2051 for (i = 0; i < SLSI_LLS_AC_MAX; i++) {
2052 ndev_vif->rx_packets[i] = 0;
2053 ndev_vif->tx_packets[i] = 0;
2054 ndev_vif->tx_no_ack[i] = 0;
2055 }
2056 }
2057 SLSI_MUTEX_UNLOCK(sdev->device_config_mutex);
2058 return 0;
2059 }
2060
2061 static u32 slsi_lls_ie_to_cap(const u8 *ies, int ies_len)
2062 {
2063 u32 capabilities = 0;
2064 const u8 *ie_data;
2065 const u8 *ie;
2066 int ie_len;
2067
2068 if (!ies || ies_len == 0) {
2069 SLSI_ERR_NODEV("no ie[&%p %d]\n", ies, ies_len);
2070 return 0;
2071 }
2072 ie = cfg80211_find_ie(WLAN_EID_EXT_CAPABILITY, ies, ies_len);
2073 if (ie) {
2074 ie_len = ie[1];
2075 ie_data = &ie[2];
2076 if ((ie_len >= 4) && (ie_data[3] & SLSI_WLAN_EXT_CAPA3_INTERWORKING_ENABLED))
2077 capabilities |= SLSI_LLS_CAPABILITY_INTERWORKING;
2078 if ((ie_len >= 7) && (ie_data[6] & 0x01)) /* Bit48: UTF-8 ssid */
2079 capabilities |= SLSI_LLS_CAPABILITY_SSID_UTF8;
2080 }
2081
2082 ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, SLSI_WLAN_OUI_TYPE_WFA_HS20_IND, ies, ies_len);
2083 if (ie)
2084 capabilities |= SLSI_LLS_CAPABILITY_HS20;
2085 return capabilities;
2086 }
2087
2088 static void slsi_lls_iface_sta_stats(struct slsi_dev *sdev, struct netdev_vif *ndev_vif,
2089 struct slsi_lls_iface_stat *iface_stat)
2090 {
2091 int i;
2092 struct slsi_lls_interface_link_layer_info *lls_info = &iface_stat->info;
2093 enum slsi_lls_peer_type peer_type;
2094 struct slsi_peer *peer;
2095 const u8 *ie_data, *ie;
2096 u8 ie_len;
2097
2098 SLSI_DBG3(sdev, SLSI_GSCAN, "\n");
2099
2100 if (ndev_vif->ifnum == SLSI_NET_INDEX_WLAN) {
2101 lls_info->mode = SLSI_LLS_INTERFACE_STA;
2102 peer_type = SLSI_LLS_PEER_AP;
2103 } else {
2104 lls_info->mode = SLSI_LLS_INTERFACE_P2P_CLIENT;
2105 peer_type = SLSI_LLS_PEER_P2P_GO;
2106 }
2107
2108 switch (ndev_vif->sta.vif_status) {
2109 case SLSI_VIF_STATUS_CONNECTING:
2110 lls_info->state = SLSI_LLS_AUTHENTICATING;
2111 break;
2112 case SLSI_VIF_STATUS_CONNECTED:
2113 lls_info->state = SLSI_LLS_ASSOCIATED;
2114 break;
2115 default:
2116 lls_info->state = SLSI_LLS_DISCONNECTED;
2117 }
2118 lls_info->roaming = ndev_vif->sta.roam_in_progress ?
2119 SLSI_LLS_ROAMING_ACTIVE : SLSI_LLS_ROAMING_IDLE;
2120
2121 iface_stat->info.capabilities = 0;
2122 lls_info->ssid[0] = 0;
2123 if (ndev_vif->sta.sta_bss) {
2124 ie = cfg80211_find_ie(WLAN_EID_SSID, ndev_vif->sta.sta_bss->ies->data,
2125 ndev_vif->sta.sta_bss->ies->len);
2126 if (ie) {
2127 ie_len = ie[1];
2128 ie_data = &ie[2];
2129 memcpy(lls_info->ssid, ie_data, ie_len);
2130 lls_info->ssid[ie_len] = 0;
2131 }
2132 SLSI_ETHER_COPY(lls_info->bssid, ndev_vif->sta.sta_bss->bssid);
2133 ie = cfg80211_find_ie(WLAN_EID_COUNTRY, ndev_vif->sta.sta_bss->ies->data,
2134 ndev_vif->sta.sta_bss->ies->len);
2135 if (ie) {
2136 ie_data = &ie[2];
2137 memcpy(lls_info->ap_country_str, ie_data, 3);
2138 iface_stat->peer_info[0].capabilities |= SLSI_LLS_CAPABILITY_COUNTRY;
2139 }
2140 }
2141
2142 peer = ndev_vif->peer_sta_record[SLSI_STA_PEER_QUEUESET]; /* connected AP */
2143 if (peer && peer->valid && peer->assoc_ie && peer->assoc_resp_ie) {
2144 iface_stat->info.capabilities |= slsi_lls_ie_to_cap(peer->assoc_ie->data, peer->assoc_ie->len);
2145 if (peer->capabilities & WLAN_CAPABILITY_PRIVACY) {
2146 iface_stat->peer_info[0].capabilities |= SLSI_LLS_CAPABILITY_PROTECTED;
2147 iface_stat->info.capabilities |= SLSI_LLS_CAPABILITY_PROTECTED;
2148 }
2149 if (peer->qos_enabled) {
2150 iface_stat->peer_info[0].capabilities |= SLSI_LLS_CAPABILITY_QOS;
2151 iface_stat->info.capabilities |= SLSI_LLS_CAPABILITY_QOS;
2152 }
2153 iface_stat->peer_info[0].capabilities |= slsi_lls_ie_to_cap(peer->assoc_resp_ie->data, peer->assoc_resp_ie->len);
2154
2155 SLSI_ETHER_COPY(iface_stat->peer_info[0].peer_mac_address, peer->address);
2156 iface_stat->peer_info[0].type = peer_type;
2157 iface_stat->num_peers = 1;
2158 }
2159
2160 for (i = MAP_AID_TO_QS(SLSI_TDLS_PEER_INDEX_MIN); i <= MAP_AID_TO_QS(SLSI_TDLS_PEER_INDEX_MAX); i++) {
2161 peer = ndev_vif->peer_sta_record[i];
2162 if (peer && peer->valid) {
2163 SLSI_ETHER_COPY(iface_stat->peer_info[iface_stat->num_peers].peer_mac_address, peer->address);
2164 iface_stat->peer_info[iface_stat->num_peers].type = SLSI_LLS_PEER_TDLS;
2165 if (peer->qos_enabled)
2166 iface_stat->peer_info[iface_stat->num_peers].capabilities |= SLSI_LLS_CAPABILITY_QOS;
2167 iface_stat->peer_info[iface_stat->num_peers].num_rate = 0;
2168 iface_stat->num_peers++;
2169 }
2170 }
2171 }
2172
2173 static void slsi_lls_iface_ap_stats(struct slsi_dev *sdev, struct netdev_vif *ndev_vif, struct slsi_lls_iface_stat *iface_stat)
2174 {
2175 enum slsi_lls_peer_type peer_type = SLSI_LLS_PEER_INVALID;
2176 struct slsi_peer *peer;
2177 int i;
2178 struct net_device *dev;
2179
2180 SLSI_DBG3(sdev, SLSI_GSCAN, "\n");
2181
2182 /* We are AP/GO, so we advertize our own country. */
2183 memcpy(iface_stat->info.ap_country_str, iface_stat->info.country_str, 3);
2184
2185 if (ndev_vif->ifnum == SLSI_NET_INDEX_WLAN) {
2186 iface_stat->info.mode = SLSI_LLS_INTERFACE_SOFTAP;
2187 peer_type = SLSI_LLS_PEER_STA;
2188 } else if (ndev_vif->ifnum == SLSI_NET_INDEX_P2PX_SWLAN) {
2189 dev = sdev->netdev[SLSI_NET_INDEX_P2PX_SWLAN];
2190 if (SLSI_IS_VIF_INDEX_P2P_GROUP(sdev, ndev_vif)) {
2191 iface_stat->info.mode = SLSI_LLS_INTERFACE_P2P_GO;
2192 peer_type = SLSI_LLS_PEER_P2P_CLIENT;
2193 }
2194 }
2195
2196 for (i = MAP_AID_TO_QS(SLSI_PEER_INDEX_MIN); i <= MAP_AID_TO_QS(SLSI_PEER_INDEX_MAX); i++) {
2197 peer = ndev_vif->peer_sta_record[i];
2198 if (peer && peer->valid) {
2199 SLSI_ETHER_COPY(iface_stat->peer_info[iface_stat->num_peers].peer_mac_address, peer->address);
2200 iface_stat->peer_info[iface_stat->num_peers].type = peer_type;
2201 iface_stat->peer_info[iface_stat->num_peers].num_rate = 0;
2202 if (peer->qos_enabled)
2203 iface_stat->peer_info[iface_stat->num_peers].capabilities = SLSI_LLS_CAPABILITY_QOS;
2204 iface_stat->num_peers++;
2205 }
2206 }
2207
2208 memcpy(iface_stat->info.ssid, ndev_vif->ap.ssid, ndev_vif->ap.ssid_len);
2209 iface_stat->info.ssid[ndev_vif->ap.ssid_len] = 0;
2210 if (ndev_vif->ap.privacy)
2211 iface_stat->info.capabilities |= SLSI_LLS_CAPABILITY_PROTECTED;
2212 if (ndev_vif->ap.qos_enabled)
2213 iface_stat->info.capabilities |= SLSI_LLS_CAPABILITY_QOS;
2214 }
2215
2216 static void slsi_lls_iface_stat_fill(struct slsi_dev *sdev,
2217 struct net_device *net_dev,
2218 struct slsi_lls_iface_stat *iface_stat)
2219 {
2220 int i;
2221 struct netdev_vif *ndev_vif;
2222 struct slsi_mib_data mibrsp = { 0, NULL };
2223 struct slsi_mib_value *values = NULL;
2224 struct slsi_mib_get_entry get_values[] = {{ SLSI_PSID_UNIFI_AC_RETRIES, { SLSI_TRAFFIC_Q_BE + 1, 0 } },
2225 { SLSI_PSID_UNIFI_AC_RETRIES, { SLSI_TRAFFIC_Q_BK + 1, 0 } },
2226 { SLSI_PSID_UNIFI_AC_RETRIES, { SLSI_TRAFFIC_Q_VI + 1, 0 } },
2227 { SLSI_PSID_UNIFI_AC_RETRIES, { SLSI_TRAFFIC_Q_VO + 1, 0 } },
2228 { SLSI_PSID_UNIFI_BEACON_RECEIVED, {0, 0} },
2229 { SLSI_PSID_UNIFI_PS_LEAKY_AP, {0, 0} },
2230 { SLSI_PSID_UNIFI_RSSI, {0, 0} } };
2231
2232 iface_stat->iface = NULL;
2233 iface_stat->info.mode = SLSI_LLS_INTERFACE_UNKNOWN;
2234 iface_stat->info.country_str[0] = sdev->device_config.domain_info.regdomain->alpha2[0];
2235 iface_stat->info.country_str[1] = sdev->device_config.domain_info.regdomain->alpha2[1];
2236 iface_stat->info.country_str[2] = ' '; /* 3rd char of our country code is ASCII<space> */
2237
2238 for (i = 0; i < SLSI_LLS_AC_MAX; i++)
2239 iface_stat->ac[i].ac = SLSI_LLS_AC_MAX;
2240
2241 if (!net_dev)
2242 return;
2243
2244 ndev_vif = netdev_priv(net_dev);
2245 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
2246
2247 if (!ndev_vif->activated)
2248 goto exit;
2249
2250 if (ndev_vif->vif_type == FAPI_VIFTYPE_STATION) {
2251 slsi_lls_iface_sta_stats(sdev, ndev_vif, iface_stat);
2252 } else if (ndev_vif->vif_type == FAPI_VIFTYPE_AP) {
2253 slsi_lls_iface_ap_stats(sdev, ndev_vif, iface_stat);
2254 SLSI_ETHER_COPY(iface_stat->info.bssid, net_dev->dev_addr);
2255 }
2256 SLSI_ETHER_COPY(iface_stat->info.mac_addr, net_dev->dev_addr);
2257
2258 mibrsp.dataLength = 10 * sizeof(get_values) / sizeof(get_values[0]);
2259 mibrsp.data = kmalloc(mibrsp.dataLength, GFP_KERNEL);
2260 if (!mibrsp.data) {
2261 SLSI_ERR(sdev, "Cannot kmalloc %d bytes for interface MIBs\n", mibrsp.dataLength);
2262 goto exit;
2263 }
2264
2265 values = slsi_read_mibs(sdev, net_dev, get_values, sizeof(get_values) / sizeof(get_values[0]), &mibrsp);
2266 if (!values)
2267 goto exit;
2268
2269 for (i = 0; i < SLSI_LLS_AC_MAX; i++) {
2270 if (values[i].type == SLSI_MIB_TYPE_UINT) {
2271 iface_stat->ac[i].ac = slsi_fapi_to_android_traffic_q(i);
2272 iface_stat->ac[i].retries = values[i].u.uintValue;
2273 iface_stat->ac[i].rx_mpdu = ndev_vif->rx_packets[i];
2274 iface_stat->ac[i].tx_mpdu = ndev_vif->tx_packets[i];
2275 iface_stat->ac[i].mpdu_lost = ndev_vif->tx_no_ack[i];
2276 } else {
2277 SLSI_WARN(sdev, "LLS: expected datatype 1 but received %d\n", values[i].type);
2278 }
2279 }
2280
2281 if (values[4].type == SLSI_MIB_TYPE_UINT)
2282 iface_stat->beacon_rx = values[4].u.uintValue;
2283
2284 if (values[5].type == SLSI_MIB_TYPE_UINT) {
2285 iface_stat->leaky_ap_detected = values[5].u.uintValue;
2286 iface_stat->leaky_ap_guard_time = 5; /* 5 milli sec. As mentioned in lls document */
2287 }
2288
2289 if (values[6].type == SLSI_MIB_TYPE_INT)
2290 iface_stat->rssi_data = values[6].u.intValue;
2291
2292 exit:
2293 kfree(values);
2294 kfree(mibrsp.data);
2295 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
2296 }
2297
2298 void slsi_check_num_radios(struct slsi_dev *sdev)
2299 {
2300 struct slsi_mib_data mibrsp = { 0, NULL };
2301 struct slsi_mib_value *values = NULL;
2302 struct slsi_mib_get_entry get_values[] = {{ SLSI_PSID_UNIFI_RADIO_SCAN_TIME, { 1, 0 } } };
2303
2304 if (slsi_is_test_mode_enabled()) {
2305 SLSI_WARN(sdev, "not supported in WlanLite mode\n");
2306 return;
2307 }
2308
2309 /* Expect each mib length in response is <= 15 So assume 15 bytes for each MIB */
2310 mibrsp.dataLength = 15 * ARRAY_SIZE(get_values);
2311 mibrsp.data = kmalloc(mibrsp.dataLength, GFP_KERNEL);
2312 if (!mibrsp.data) {
2313 SLSI_ERR(sdev, "Cannot kmalloc %d bytes\n", mibrsp.dataLength);
2314 sdev->lls_num_radio = 0;
2315 return;
2316 }
2317
2318 values = slsi_read_mibs(sdev, NULL, get_values, ARRAY_SIZE(get_values), &mibrsp);
2319 if (!values) {
2320 sdev->lls_num_radio = 0;
2321 } else {
2322 sdev->lls_num_radio = values[0].type == SLSI_MIB_TYPE_NONE ? 1 : 2;
2323 kfree(values);
2324 }
2325
2326 kfree(mibrsp.data);
2327 }
2328
2329 static void slsi_lls_radio_stat_fill(struct slsi_dev *sdev, struct net_device *dev,
2330 struct slsi_lls_radio_stat *radio_stat,
2331 int max_chan_count, int radio_index, int twoorfive)
2332 {
2333 struct slsi_mib_data mibrsp = { 0, NULL };
2334 struct slsi_mib_data supported_chan_mib = { 0, NULL };
2335 struct slsi_mib_value *values = NULL;
2336 struct slsi_mib_get_entry get_values[] = {{ SLSI_PSID_UNIFI_RADIO_SCAN_TIME, { radio_index, 0 } },
2337 { SLSI_PSID_UNIFI_RADIO_RX_TIME, { radio_index, 0 } },
2338 { SLSI_PSID_UNIFI_RADIO_TX_TIME, { radio_index, 0 } },
2339 { SLSI_PSID_UNIFI_RADIO_ON_TIME, { radio_index, 0 } },
2340 { SLSI_PSID_UNIFI_SUPPORTED_CHANNELS, { 0, 0 } } };
2341 u32 *radio_data[] = {&radio_stat->on_time_scan, &radio_stat->rx_time,
2342 &radio_stat->tx_time, &radio_stat->on_time};
2343 int i, j, chan_count, chan_start, k;
2344
2345 radio_stat->radio = radio_index;
2346
2347 /* Expect each mib length in response is <= 15 So assume 15 bytes for each MIB */
2348 mibrsp.dataLength = 15 * sizeof(get_values) / sizeof(get_values[0]);
2349 mibrsp.data = kmalloc(mibrsp.dataLength, GFP_KERNEL);
2350 if (mibrsp.data == NULL) {
2351 SLSI_ERR(sdev, "Cannot kmalloc %d bytes\n", mibrsp.dataLength);
2352 return;
2353 }
2354 values = slsi_read_mibs(sdev, NULL, get_values, sizeof(get_values) / sizeof(get_values[0]), &mibrsp);
2355 if (!values)
2356 goto exit_with_mibrsp;
2357
2358 for (i = 0; i < (sizeof(get_values) / sizeof(get_values[0])) - 1; i++) {
2359 if (values[i].type == SLSI_MIB_TYPE_UINT) {
2360 *radio_data[i] = values[i].u.uintValue;
2361 } else {
2362 SLSI_ERR(sdev, "invalid type. iter:%d", i);
2363 }
2364 }
2365 if (values[4].type != SLSI_MIB_TYPE_OCTET) {
2366 SLSI_ERR(sdev, "Supported_Chan invalid type.");
2367 goto exit_with_values;
2368 }
2369
2370 supported_chan_mib = values[4].u.octetValue;
2371 for (j = 0; j < supported_chan_mib.dataLength / 2; j++) {
2372 struct slsi_lls_channel_info *radio_chan;
2373
2374 chan_start = supported_chan_mib.data[j * 2];
2375 chan_count = supported_chan_mib.data[j * 2 + 1];
2376 if (radio_stat->num_channels + chan_count > max_chan_count)
2377 chan_count = max_chan_count - radio_stat->num_channels;
2378 if (chan_start == 1 && (twoorfive & BIT(0))) { /* for 2.4GHz */
2379 for (k = 0; k < chan_count; k++) {
2380 radio_chan = &radio_stat->channels[radio_stat->num_channels + k].channel;
2381 if (k + chan_start == 14)
2382 radio_chan->center_freq = 2484;
2383 else
2384 radio_chan->center_freq = 2407 + (chan_start + k) * 5;
2385 radio_chan->width = SLSI_LLS_CHAN_WIDTH_20;
2386 }
2387 radio_stat->num_channels += chan_count;
2388 } else if (chan_start != 1 && (twoorfive & BIT(1))) {
2389 /* for 5GHz */
2390 for (k = 0; k < chan_count; k++) {
2391 radio_chan = &radio_stat->channels[radio_stat->num_channels + k].channel;
2392 radio_chan->center_freq = 5000 + (chan_start + (k * 4)) * 5;
2393 radio_chan->width = SLSI_LLS_CHAN_WIDTH_20;
2394 }
2395 radio_stat->num_channels += chan_count;
2396 }
2397 }
2398 exit_with_values:
2399 kfree(values);
2400 exit_with_mibrsp:
2401 kfree(mibrsp.data);
2402 }
2403
2404 static int slsi_lls_fill(struct slsi_dev *sdev, u8 **src_buf)
2405 {
2406 struct net_device *net_dev = NULL;
2407 struct slsi_lls_radio_stat *radio_stat;
2408 struct slsi_lls_radio_stat *radio_stat_temp;
2409 struct slsi_lls_iface_stat *iface_stat;
2410 int buf_len = 0;
2411 int max_chan_count = 0;
2412 u8 *buf;
2413 int num_of_radios_supported;
2414 int i = 0;
2415 int radio_type[2] = {BIT(0), BIT(1)};
2416
2417 if (sdev->lls_num_radio == 0) {
2418 slsi_check_num_radios(sdev);
2419 if (sdev->lls_num_radio == 0)
2420 return -EIO;
2421 }
2422
2423 num_of_radios_supported = sdev->lls_num_radio;
2424 net_dev = slsi_get_netdev(sdev, SLSI_NET_INDEX_WLAN);
2425
2426 if (sdev->wiphy->bands[NL80211_BAND_2GHZ])
2427 max_chan_count = sdev->wiphy->bands[NL80211_BAND_2GHZ]->n_channels;
2428 if (sdev->wiphy->bands[NL80211_BAND_5GHZ])
2429 max_chan_count += sdev->wiphy->bands[NL80211_BAND_5GHZ]->n_channels;
2430 buf_len = (int)((num_of_radios_supported * sizeof(struct slsi_lls_radio_stat))
2431 + sizeof(struct slsi_lls_iface_stat)
2432 + sizeof(u8)
2433 + (sizeof(struct slsi_lls_peer_info) * SLSI_ADHOC_PEER_CONNECTIONS_MAX)
2434 + (sizeof(struct slsi_lls_channel_stat) * max_chan_count));
2435 buf = kzalloc(buf_len, GFP_KERNEL);
2436 if (!buf) {
2437 SLSI_ERR(sdev, "No mem. Size:%d\n", buf_len);
2438 return -ENOMEM;
2439 }
2440 buf[0] = num_of_radios_supported;
2441 *src_buf = buf;
2442 iface_stat = (struct slsi_lls_iface_stat *)(buf + sizeof(u8));
2443 slsi_lls_iface_stat_fill(sdev, net_dev, iface_stat);
2444
2445 radio_stat = (struct slsi_lls_radio_stat *)(buf + sizeof(u8) + sizeof(struct slsi_lls_iface_stat) +
2446 (sizeof(struct slsi_lls_peer_info) * iface_stat->num_peers));
2447 radio_stat_temp = radio_stat;
2448 if (num_of_radios_supported == 1) {
2449 radio_type[0] = BIT(0) | BIT(1);
2450 slsi_lls_radio_stat_fill(sdev, net_dev, radio_stat, max_chan_count, 0, radio_type[0]);
2451 radio_stat = (struct slsi_lls_radio_stat *)((u8 *)radio_stat + sizeof(struct slsi_lls_radio_stat) +
2452 (sizeof(struct slsi_lls_channel_stat) * radio_stat->num_channels));
2453 } else {
2454 for (i = 1; i <= num_of_radios_supported ; i++) {
2455 slsi_lls_radio_stat_fill(sdev, net_dev, radio_stat, max_chan_count, i, radio_type[i - 1]);
2456 radio_stat = (struct slsi_lls_radio_stat *)((u8 *)radio_stat +
2457 sizeof(struct slsi_lls_radio_stat) + (sizeof(struct slsi_lls_channel_stat)
2458 * radio_stat->num_channels));
2459 }
2460 }
2461 #ifdef CONFIG_SCSC_WLAN_DEBUG
2462 if (slsi_dev_llslogs_supported())
2463 slsi_lls_debug_dump_stats(sdev, radio_stat_temp, iface_stat, buf, buf_len, num_of_radios_supported);
2464 #endif
2465 return buf_len;
2466 }
2467
2468 static int slsi_lls_get_stats(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
2469 {
2470 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
2471 int ret;
2472 u8 *buf = NULL;
2473 int buf_len;
2474
2475 if (!slsi_dev_lls_supported())
2476 return -EOPNOTSUPP;
2477
2478 if (slsi_is_test_mode_enabled()) {
2479 SLSI_WARN(sdev, "not supported in WlanLite mode\n");
2480 return -EOPNOTSUPP;
2481 }
2482
2483 if (!sdev) {
2484 SLSI_ERR(sdev, "sdev is Null\n");
2485 return -EINVAL;
2486 }
2487
2488 SLSI_MUTEX_LOCK(sdev->device_config_mutex);
2489 /* In case of lower layer failure do not read LLS MIBs */
2490 if (sdev->mlme_blocked)
2491 buf_len = -EIO;
2492 else
2493 buf_len = slsi_lls_fill(sdev, &buf);
2494 SLSI_MUTEX_UNLOCK(sdev->device_config_mutex);
2495
2496 if (buf_len > 0) {
2497 ret = slsi_vendor_cmd_reply(wiphy, buf, buf_len);
2498 if (ret)
2499 SLSI_ERR_NODEV("vendor cmd reply failed (err:%d)\n", ret);
2500 } else {
2501 ret = buf_len;
2502 }
2503 kfree(buf);
2504 return ret;
2505 }
2506
2507 static int slsi_gscan_set_oui(struct wiphy *wiphy,
2508 struct wireless_dev *wdev, const void *data, int len)
2509 {
2510 int ret = 0;
2511
2512 #ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION
2513
2514 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
2515 struct net_device *dev = wdev->netdev;
2516 struct netdev_vif *ndev_vif;
2517 int temp;
2518 int type;
2519 const struct nlattr *attr;
2520 u8 scan_oui[6];
2521
2522 memset(&scan_oui, 0, 6);
2523
2524 if (!dev) {
2525 SLSI_ERR(sdev, "dev is NULL!!\n");
2526 return -EINVAL;
2527 }
2528
2529 ndev_vif = netdev_priv(dev);
2530 SLSI_MUTEX_LOCK(ndev_vif->scan_mutex);
2531 sdev->scan_addr_set = 0;
2532
2533 nla_for_each_attr(attr, data, len, temp) {
2534 if (!attr) {
2535 ret = -EINVAL;
2536 break;
2537 }
2538
2539 type = nla_type(attr);
2540 switch (type) {
2541 case SLSI_NL_ATTRIBUTE_PNO_RANDOM_MAC_OUI:
2542 {
2543 if (nla_len(attr) != 3) {
2544 ret = -EINVAL;
2545 break;
2546 }
2547 memcpy(&scan_oui, nla_data(attr), 3);
2548 memcpy(sdev->scan_mac_addr, scan_oui, 6);
2549 sdev->scan_addr_set = 1;
2550 break;
2551 }
2552 default:
2553 ret = -EINVAL;
2554 SLSI_ERR(sdev, "Invalid type : %d\n", type);
2555 break;
2556 }
2557 }
2558 SLSI_MUTEX_UNLOCK(ndev_vif->scan_mutex);
2559 #endif
2560 return ret;
2561 }
2562
2563 static int slsi_get_feature_set(struct wiphy *wiphy,
2564 struct wireless_dev *wdev, const void *data, int len)
2565 {
2566 u32 feature_set = 0;
2567 int ret = 0;
2568
2569 SLSI_DBG3_NODEV(SLSI_GSCAN, "\n");
2570
2571 feature_set |= SLSI_WIFI_HAL_FEATURE_RSSI_MONITOR;
2572 feature_set |= SLSI_WIFI_HAL_FEATURE_CONTROL_ROAMING;
2573 feature_set |= SLSI_WIFI_HAL_FEATURE_TDLS | SLSI_WIFI_HAL_FEATURE_TDLS_OFFCHANNEL;
2574 #ifndef CONFIG_SCSC_WLAN_NAT_KEEPALIVE_DISABLE
2575 feature_set |= SLSI_WIFI_HAL_FEATURE_MKEEP_ALIVE;
2576 #endif
2577 #ifdef CONFIG_SCSC_WLAN_ENHANCED_LOGGING
2578 feature_set |= SLSI_WIFI_HAL_FEATURE_LOGGER;
2579 #endif
2580 if (slsi_dev_gscan_supported())
2581 feature_set |= SLSI_WIFI_HAL_FEATURE_GSCAN;
2582 if (slsi_dev_lls_supported())
2583 feature_set |= SLSI_WIFI_HAL_FEATURE_LINK_LAYER_STATS;
2584 if (slsi_dev_epno_supported())
2585 feature_set |= SLSI_WIFI_HAL_FEATURE_HAL_EPNO;
2586 if (slsi_dev_nan_supported(SDEV_FROM_WIPHY(wiphy)))
2587 feature_set |= SLSI_WIFI_HAL_FEATURE_NAN;
2588 if (slsi_dev_rtt_supported()) {
2589 feature_set |= SLSI_WIFI_HAL_FEATURE_D2D_RTT;
2590 feature_set |= SLSI_WIFI_HAL_FEATURE_D2AP_RTT;
2591 }
2592
2593 ret = slsi_vendor_cmd_reply(wiphy, &feature_set, sizeof(feature_set));
2594
2595 return ret;
2596 }
2597
2598 static int slsi_set_country_code(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
2599 {
2600 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
2601 int ret = 0;
2602 int temp;
2603 int type;
2604 const struct nlattr *attr;
2605 char country_code[SLSI_COUNTRY_CODE_LEN];
2606
2607 SLSI_DBG3(sdev, SLSI_GSCAN, "Received country code command\n");
2608
2609 nla_for_each_attr(attr, data, len, temp) {
2610 type = nla_type(attr);
2611 switch (type) {
2612 case SLSI_NL_ATTRIBUTE_COUNTRY_CODE:
2613 {
2614 if (nla_len(attr) < (SLSI_COUNTRY_CODE_LEN - 1)) {
2615 ret = -EINVAL;
2616 SLSI_ERR(sdev, "Insufficient Country Code Length : %d\n", nla_len(attr));
2617 return ret;
2618 }
2619 memcpy(country_code, nla_data(attr), (SLSI_COUNTRY_CODE_LEN - 1));
2620 break;
2621 }
2622 default:
2623 ret = -EINVAL;
2624 SLSI_ERR(sdev, "Invalid type : %d\n", type);
2625 return ret;
2626 }
2627 }
2628 ret = slsi_set_country_update_regd(sdev, country_code, SLSI_COUNTRY_CODE_LEN);
2629 if (ret < 0)
2630 SLSI_ERR(sdev, "Set country failed ret:%d\n", ret);
2631 return ret;
2632 }
2633
2634 static int slsi_apf_read_filter(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
2635 {
2636 int ret = 0;
2637 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
2638 struct net_device *dev = wdev->netdev;
2639 u8 *host_dst;
2640 int datalen;
2641
2642 SLSI_DBG1_NODEV(SLSI_GSCAN, "SUBCMD_APF_READ_FILTER\n");
2643 SLSI_MUTEX_LOCK(sdev->device_config_mutex);
2644 if (!sdev->device_config.fw_apf_supported) {
2645 SLSI_WARN(sdev, "APF not supported by the firmware.\n");
2646 SLSI_MUTEX_UNLOCK(sdev->device_config_mutex);
2647 return -ENOTSUPP;
2648 }
2649
2650 ret = slsi_mlme_read_apf_request(sdev, dev, &host_dst, &datalen);
2651 if (!ret)
2652 ret = slsi_vendor_cmd_reply(wiphy, host_dst, datalen);
2653
2654 SLSI_MUTEX_UNLOCK(sdev->device_config_mutex);
2655 return ret;
2656 }
2657
2658 static int slsi_apf_get_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
2659 {
2660 int ret = 0;
2661 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
2662 struct net_device *dev = wdev->netdev;
2663 struct sk_buff *nl_skb;
2664 struct nlattr *nlattr_start;
2665
2666 SLSI_DBG1_NODEV(SLSI_GSCAN, "SUBCMD_APF_GET_CAPABILITIES\n");
2667 SLSI_MUTEX_LOCK(sdev->device_config_mutex);
2668 if (!sdev->device_config.fw_apf_supported) {
2669 SLSI_WARN(sdev, "APF not supported by the firmware.\n");
2670 ret = -ENOTSUPP;
2671 goto exit;
2672 }
2673 memset(&sdev->device_config.apf_cap, 0, sizeof(struct slsi_apf_capabilities));
2674
2675 ret = slsi_mib_get_apf_cap(sdev, dev);
2676 if (ret != 0) {
2677 SLSI_ERR(sdev, "Failed to read mib\n");
2678 goto exit;
2679 }
2680 SLSI_DBG3(sdev, SLSI_GSCAN, "APF version: %d Max_Length:%d\n", sdev->device_config.apf_cap.version,
2681 sdev->device_config.apf_cap.max_length);
2682 nl_skb = cfg80211_vendor_cmd_alloc_reply_skb(sdev->wiphy, NLMSG_DEFAULT_SIZE);
2683 if (!nl_skb) {
2684 SLSI_ERR(sdev, "NO MEM for nl_skb!!!\n");
2685 ret = -ENOMEM;
2686 goto exit;
2687 }
2688
2689 nlattr_start = nla_nest_start(nl_skb, NL80211_ATTR_VENDOR_DATA);
2690 if (!nlattr_start) {
2691 SLSI_ERR(sdev, "failed to put NL80211_ATTR_VENDOR_DATA\n");
2692 /* Dont use slsi skb wrapper for this free */
2693 kfree_skb(nl_skb);
2694 ret = -EINVAL;
2695 goto exit;
2696 }
2697
2698 ret = nla_put_u16(nl_skb, SLSI_APF_ATTR_VERSION, sdev->device_config.apf_cap.version);
2699 ret |= nla_put_u16(nl_skb, SLSI_APF_ATTR_MAX_LEN, sdev->device_config.apf_cap.max_length);
2700 if (ret) {
2701 SLSI_ERR(sdev, "Error in nla_put*:%x\n", ret);
2702 /* Dont use slsi skb wrapper for this free */
2703 kfree_skb(nl_skb);
2704 goto exit;
2705 }
2706
2707 ret = cfg80211_vendor_cmd_reply(nl_skb);
2708 if (ret)
2709 SLSI_ERR(sdev, "apf_get_capabilities cfg80211_vendor_cmd_reply failed :%d\n", ret);
2710 exit:
2711 SLSI_MUTEX_UNLOCK(sdev->device_config_mutex);
2712 return ret;
2713 }
2714
2715 static int slsi_apf_set_filter(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
2716 {
2717 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
2718 struct net_device *dev = wdev->netdev;
2719 int ret = 0;
2720 int temp;
2721 int type;
2722 const struct nlattr *attr;
2723 u32 program_len = 0;
2724 u8 *program = NULL;
2725
2726 SLSI_DBG3(sdev, SLSI_GSCAN, "Received apf_set_filter command\n");
2727 SLSI_MUTEX_LOCK(sdev->device_config_mutex);
2728 if (!sdev->device_config.fw_apf_supported) {
2729 SLSI_WARN(sdev, "APF not supported by the firmware.\n");
2730 ret = -ENOTSUPP;
2731 goto exit;
2732 }
2733
2734 if (!dev) {
2735 SLSI_ERR(sdev, "dev is NULL!!\n");
2736 ret = -EINVAL;
2737 goto exit;
2738 }
2739
2740 nla_for_each_attr(attr, data, len, temp) {
2741 type = nla_type(attr);
2742 switch (type) {
2743 case SLSI_APF_ATTR_PROGRAM_LEN:
2744 {
2745 program_len = nla_get_u32(attr);
2746 kfree(program);
2747 program = kmalloc(program_len, GFP_KERNEL);
2748 if (!program) {
2749 ret = -ENOMEM;
2750 goto exit;
2751 }
2752 break;
2753 }
2754 case SLSI_APF_ATTR_PROGRAM:
2755 {
2756 memcpy(program, (u8 *)nla_data(attr), program_len);
2757 break;
2758 }
2759 default:
2760 SLSI_ERR(sdev, "Invalid type : %d\n", type);
2761 ret = -EINVAL;
2762 goto exit;
2763 }
2764 }
2765
2766 ret = slsi_mlme_install_apf_request(sdev, dev, program, program_len);
2767 if (ret < 0) {
2768 SLSI_ERR(sdev, "apf_set_filter failed ret:%d\n", ret);
2769 ret = -EINVAL;
2770 goto exit;
2771 }
2772 exit:
2773 kfree(program);
2774 SLSI_MUTEX_UNLOCK(sdev->device_config_mutex);
2775 return ret;
2776 }
2777
2778 static int slsi_rtt_get_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
2779 {
2780 struct slsi_rtt_capabilities rtt_cap;
2781 int ret = 0;
2782 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
2783 struct net_device *dev = wdev->netdev;
2784
2785 SLSI_DBG1_NODEV(SLSI_GSCAN, "SUBCMD_GET_RTT_CAPABILITIES\n");
2786 if (!slsi_dev_rtt_supported()) {
2787 SLSI_WARN(sdev, "RTT not supported.\n");
2788 return -ENOTSUPP;
2789 }
2790 memset(&rtt_cap, 0, sizeof(struct slsi_rtt_capabilities));
2791
2792 ret = slsi_mib_get_rtt_cap(sdev, dev, &rtt_cap);
2793 if (ret != 0) {
2794 SLSI_ERR(sdev, "Failed to read mib\n");
2795 return ret;
2796 }
2797 ret = slsi_vendor_cmd_reply(wiphy, &rtt_cap, sizeof(struct slsi_rtt_capabilities));
2798 if (ret)
2799 SLSI_ERR_NODEV("rtt_get_capabilities vendor cmd reply failed (err = %d)\n", ret);
2800 return ret;
2801 }
2802
2803 static int slsi_rtt_set_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
2804 {
2805 int r, type, j = 0;
2806 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
2807 #ifdef CONFIG_SCSC_WIFI_NAN_ENABLE
2808 struct netdev_vif *ndev_vif;
2809 #endif
2810 struct net_device *dev = wdev->netdev;
2811 struct slsi_rtt_config *nl_rtt_params;
2812 const struct nlattr *iter, *outer, *inner;
2813 u8 source_addr[ETH_ALEN];
2814 int tmp, tmp1, tmp2;
2815 u16 rtt_id = 0;
2816 u8 num_devices = 0;
2817 u16 rtt_peer = SLSI_RTT_PEER_AP;
2818 u16 vif_idx = 0;
2819 u16 channel_freq = 0;
2820
2821 SLSI_DBG1_NODEV(SLSI_GSCAN, "SUBCMD_RTT_RANGE_START\n");
2822 if (!slsi_dev_rtt_supported()) {
2823 SLSI_ERR(sdev, "RTT not supported.\n");
2824 return WIFI_HAL_ERROR_NOT_SUPPORTED;
2825 }
2826 nla_for_each_attr(iter, data, len, tmp) {
2827 type = nla_type(iter);
2828 switch (type) {
2829 case SLSI_RTT_ATTRIBUTE_TARGET_CNT:
2830 num_devices = nla_get_u8(iter);
2831 SLSI_DBG1_NODEV(SLSI_GSCAN, "Target cnt %d\n", num_devices);
2832 break;
2833 case SLSI_RTT_ATTRIBUTE_TARGET_ID:
2834 rtt_id = nla_get_u16(iter);
2835 SLSI_DBG1_NODEV(SLSI_GSCAN, "Target id %d\n", rtt_id);
2836 break;
2837 default:
2838 SLSI_ERR_NODEV("Unexpected RTT attribute:type - %d\n", type);
2839 break;
2840 }
2841 }
2842 if (!num_devices) {
2843 SLSI_ERR_NODEV("No device found for rtt configuration!\n");
2844 return -EINVAL;
2845 }
2846 /* Allocate memory for the received config params */
2847 nl_rtt_params = kcalloc(num_devices, sizeof(*nl_rtt_params), GFP_KERNEL);
2848 if (!nl_rtt_params) {
2849 SLSI_ERR_NODEV("Failed for allocate memory for config rtt_param\n");
2850 return -ENOMEM;
2851 }
2852 nla_for_each_attr(iter, data, len, tmp) {
2853 type = nla_type(iter);
2854 switch (type) {
2855 case SLSI_RTT_ATTRIBUTE_TARGET_INFO:
2856 nla_for_each_nested(outer, iter, tmp1) {
2857 nla_for_each_nested(inner, outer, tmp2) {
2858 switch (nla_type(inner)) {
2859 case SLSI_RTT_ATTRIBUTE_TARGET_MAC:
2860 memcpy(nl_rtt_params[j].peer_addr, nla_data(inner), ETH_ALEN);
2861 break;
2862 case SLSI_RTT_ATTRIBUTE_TARGET_TYPE:
2863 nl_rtt_params[j].type = nla_get_u16(inner);
2864 break;
2865 case SLSI_RTT_ATTRIBUTE_TARGET_PEER:
2866 rtt_peer = nla_get_u16(inner);
2867 break;
2868 case SLSI_RTT_ATTRIBUTE_TARGET_CHAN_FREQ:
2869 channel_freq = nla_get_u16(inner);
2870 nl_rtt_params[j].channel_freq = channel_freq * 2;
2871 break;
2872 case SLSI_RTT_ATTRIBUTE_TARGET_PERIOD:
2873 nl_rtt_params[j].burst_period = nla_get_u8(inner);
2874 break;
2875 case SLSI_RTT_ATTRIBUTE_TARGET_NUM_BURST:
2876 nl_rtt_params[j].num_burst = nla_get_u8(inner);
2877 break;
2878 case SLSI_RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST:
2879 nl_rtt_params[j].num_frames_per_burst = nla_get_u8(inner);
2880 break;
2881 case SLSI_RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR:
2882 nl_rtt_params[j].num_retries_per_ftmr = nla_get_u8(inner);
2883 break;
2884 case SLSI_RTT_ATTRIBUTE_TARGET_BURST_DURATION:
2885 nl_rtt_params[j].burst_duration = nla_get_u8(inner);
2886 break;
2887 case SLSI_RTT_ATTRIBUTE_TARGET_PREAMBLE:
2888 nl_rtt_params[j].preamble = nla_get_u16(inner);
2889 break;
2890 case SLSI_RTT_ATTRIBUTE_TARGET_BW:
2891 nl_rtt_params[j].bw = nla_get_u16(inner);
2892 break;
2893 case SLSI_RTT_ATTRIBUTE_TARGET_LCI:
2894 nl_rtt_params[j].LCI_request = nla_get_u16(inner);
2895 break;
2896 case SLSI_RTT_ATTRIBUTE_TARGET_LCR:
2897 nl_rtt_params[j].LCR_request = nla_get_u16(inner);
2898 break;
2899 default:
2900 SLSI_ERR_NODEV("Unknown RTT INFO ATTRIBUTE type: %d\n", type);
2901 break;
2902 }
2903 }
2904 j++;
2905 }
2906 break;
2907 default:
2908 SLSI_ERR_NODEV("No ATTRIBUTE_Target cnt - %d\n", type);
2909 break;
2910 }
2911 }
2912
2913 SLSI_ETHER_COPY(source_addr, dev->dev_addr);
2914
2915 if (rtt_peer == SLSI_RTT_PEER_NAN) {
2916 #ifdef CONFIG_SCSC_WIFI_NAN_ENABLE
2917 if (!slsi_dev_nan_supported(sdev)) {
2918 SLSI_ERR(sdev, "NAN not supported(mib:%d)\n", sdev->nan_enabled);
2919 kfree(nl_rtt_params);
2920 return WIFI_HAL_ERROR_NOT_SUPPORTED;
2921 }
2922 ndev_vif = netdev_priv(dev);
2923 if (ndev_vif->activated) {
2924 vif_idx = ndev_vif->vif_type;
2925 } else {
2926 SLSI_ERR(sdev, "NAN vif not activated\n");
2927 kfree(nl_rtt_params);
2928 return -EINVAL;
2929 }
2930 #else
2931 SLSI_ERR(sdev, "NAN not enabled\n");
2932 return -ENOTSUPP;
2933 #endif
2934 }
2935 r = slsi_mlme_add_range_req(sdev, num_devices, nl_rtt_params, rtt_id, vif_idx, source_addr);
2936 if (r) {
2937 r = -EINVAL;
2938 SLSI_ERR_NODEV("Failed to set rtt config\n");
2939 } else {
2940 sdev->rtt_vif[rtt_id] = vif_idx;
2941 SLSI_DBG1_NODEV(SLSI_GSCAN, "Successfully set rtt config\n");
2942 }
2943 kfree(nl_rtt_params);
2944 return r;
2945 }
2946
2947 int slsi_tx_rate_calc(struct sk_buff *nl_skb, u16 fw_rate, int res, bool tx_rate)
2948 {
2949 u8 preamble;
2950 const u32 fw_rate_idx_to_80211_rate[] = { 0, 10, 20, 55, 60, 90, 110, 120, 180, 240, 360, 480, 540 };
2951 u32 data_rate = 0;
2952 u32 mcs = 0, nss = 0;
2953 u32 chan_bw_idx = 0;
2954 int gi_idx;
2955
2956 preamble = (fw_rate & SLSI_FW_API_RATE_HT_SELECTOR_FIELD) >> 14;
2957 if ((fw_rate & SLSI_FW_API_RATE_HT_SELECTOR_FIELD) == SLSI_FW_API_RATE_NON_HT_SELECTED) {
2958 u16 fw_rate_idx = fw_rate & SLSI_FW_API_RATE_INDEX_FIELD;
2959
2960 if (fw_rate > 0 && fw_rate_idx < ARRAY_SIZE(fw_rate_idx_to_80211_rate))
2961 data_rate = fw_rate_idx_to_80211_rate[fw_rate_idx];
2962 } else if ((fw_rate & SLSI_FW_API_RATE_HT_SELECTOR_FIELD) == SLSI_FW_API_RATE_HT_SELECTED) {
2963 nss = (SLSI_FW_API_RATE_HT_NSS_FIELD & fw_rate) >> 6;
2964 chan_bw_idx = (fw_rate & SLSI_FW_API_RATE_BW_FIELD) >> 9;
2965 gi_idx = ((fw_rate & SLSI_FW_API_RATE_SGI) == SLSI_FW_API_RATE_SGI) ? 1 : 0;
2966 mcs = SLSI_FW_API_RATE_HT_MCS_FIELD & fw_rate;
2967 if ((chan_bw_idx < 2) && (mcs <= 7)) {
2968 data_rate = (nss + 1) * slsi_rates_table[chan_bw_idx][gi_idx][mcs];
2969 } else if (mcs == 32 && chan_bw_idx == 1) {
2970 if (gi_idx == 1)
2971 data_rate = (nss + 1) * 67;
2972 else
2973 data_rate = (nss + 1) * 60;
2974 } else {
2975 SLSI_WARN_NODEV("FW DATA RATE decode error fw_rate:%x, bw:%x, mcs_idx:%x, nss : %d\n",
2976 fw_rate, chan_bw_idx, mcs, nss);
2977 }
2978 } else if ((fw_rate & SLSI_FW_API_RATE_HT_SELECTOR_FIELD) == SLSI_FW_API_RATE_VHT_SELECTED) {
2979 /* report vht rate in legacy units and not as mcs index. reason: upper layers may still be not
2980 * updated with vht msc table.
2981 */
2982 chan_bw_idx = (fw_rate & SLSI_FW_API_RATE_BW_FIELD) >> 9;
2983 gi_idx = ((fw_rate & SLSI_FW_API_RATE_SGI) == SLSI_FW_API_RATE_SGI) ? 1 : 0;
2984 /* Calculate NSS --> bits 6 to 4*/
2985 nss = (SLSI_FW_API_RATE_VHT_NSS_FIELD & fw_rate) >> 4;
2986 mcs = SLSI_FW_API_RATE_VHT_MCS_FIELD & fw_rate;
2987 /* Bandwidth (BW): 0x0= 20 MHz, 0x1= 40 MHz, 0x2= 80 MHz, 0x3= 160/ 80+80 MHz. 0x3 is not supported */
2988 if ((chan_bw_idx <= 2) && (mcs <= 9))
2989 data_rate = (nss + 1) * slsi_rates_table[chan_bw_idx][gi_idx][mcs];
2990 else
2991 SLSI_WARN_NODEV("FW DATA RATE decode error fw_rate:%x, bw:%x, mcs_idx:%x,nss : %d\n",
2992 fw_rate, chan_bw_idx, mcs, nss);
2993 if (nss > 1)
2994 nss += 1;
2995 }
2996
2997 if (tx_rate) {
2998 res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_TX_PREAMBLE, preamble);
2999 res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_TX_NSS, nss);
3000 res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_TX_BW, chan_bw_idx);
3001 res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_TX_MCS, mcs);
3002 res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_TX_RATE, data_rate);
3003 } else {
3004 res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_RX_PREAMBLE, preamble);
3005 res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_RX_NSS, nss);
3006 res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_RX_BW, chan_bw_idx);
3007 res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_RX_MCS, mcs);
3008 res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_RX_RATE, data_rate);
3009 }
3010 return res;
3011 }
3012
3013 void slsi_rx_range_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb)
3014 {
3015 struct netdev_vif *ndev_vif = netdev_priv(dev);
3016 u32 i, tm;
3017 u16 rtt_entry_count = fapi_get_u16(skb, u.mlme_range_ind.entries);
3018 u16 rtt_id = fapi_get_u16(skb, u.mlme_range_ind.rtt_id);
3019 u32 tmac = fapi_get_u32(skb, u.mlme_range_ind.spare_3);
3020 int data_len = fapi_get_datalen(skb);
3021 u8 *ip_ptr, *start_ptr;
3022 u16 tx_data, rx_data;
3023 struct sk_buff *nl_skb;
3024 int res = 0;
3025 struct nlattr *nlattr_nested;
3026 struct timespec ts;
3027 u64 tkernel;
3028 u8 rep_cnt = 0;
3029
3030 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
3031 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
3032 nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NULL, NLMSG_DEFAULT_SIZE,
3033 SLSI_NL80211_RTT_RESULT_EVENT, GFP_KERNEL);
3034 #else
3035 nl_skb = cfg80211_vendor_event_alloc(sdev->wiphy, NLMSG_DEFAULT_SIZE, SLSI_NL80211_RTT_RESULT_EVENT,
3036 GFP_KERNEL);
3037 #endif
3038 #ifdef CONFIG_SCSC_WLAN_DEBUG
3039 SLSI_DBG1_NODEV(SLSI_GSCAN, "Event: %s(%d)\n",
3040 slsi_print_event_name(SLSI_NL80211_RTT_RESULT_EVENT), SLSI_NL80211_RTT_RESULT_EVENT);
3041 #endif
3042
3043 if (!nl_skb) {
3044 SLSI_ERR(sdev, "NO MEM for nl_skb!!!\n");
3045 goto exit;
3046 }
3047
3048 ip_ptr = fapi_get_data(skb);
3049 start_ptr = fapi_get_data(skb);
3050 res |= nla_put_u16(nl_skb, SLSI_RTT_ATTRIBUTE_RESULT_CNT, rtt_entry_count);
3051 res |= nla_put_u16(nl_skb, SLSI_RTT_ATTRIBUTE_TARGET_ID, rtt_id);
3052 res |= nla_put_u8(nl_skb, SLSI_RTT_ATTRIBUTE_RESULTS_PER_TARGET, 1);
3053 for (i = 0; i < rtt_entry_count; i++) {
3054 nlattr_nested = nla_nest_start(nl_skb, SLSI_RTT_ATTRIBUTE_RESULT);
3055 if (!nlattr_nested) {
3056 SLSI_ERR(sdev, "Error in nla_nest_start\n");
3057 /* Dont use slsi skb wrapper for this free */
3058 kfree_skb(nl_skb);
3059 goto exit;
3060 }
3061 ip_ptr += 7; /*skip first 7 bytes for fapi_ie_generic */
3062 res |= nla_put(nl_skb, SLSI_RTT_EVENT_ATTR_ADDR, ETH_ALEN, ip_ptr);
3063 ip_ptr += 6;
3064 res |= nla_put_u16(nl_skb, SLSI_RTT_EVENT_ATTR_BURST_NUM, *ip_ptr);
3065 ip_ptr += 2;
3066 res |= nla_put_u8(nl_skb, SLSI_RTT_EVENT_ATTR_MEASUREMENT_NUM, *ip_ptr++);
3067 res |= nla_put_u8(nl_skb, SLSI_RTT_EVENT_ATTR_SUCCESS_NUM, *ip_ptr++);
3068 res |= nla_put_u8(nl_skb, SLSI_RTT_EVENT_ATTR_NUM_PER_BURST_PEER, *ip_ptr++);
3069 res |= nla_put_u16(nl_skb, SLSI_RTT_EVENT_ATTR_STATUS, *ip_ptr);
3070 ip_ptr += 2;
3071 res |= nla_put_u8(nl_skb, SLSI_RTT_EVENT_ATTR_RETRY_AFTER_DURATION, *ip_ptr++);
3072 res |= nla_put_u16(nl_skb, SLSI_RTT_EVENT_ATTR_TYPE, *ip_ptr);
3073 ip_ptr += 2;
3074 res |= nla_put_u16(nl_skb, SLSI_RTT_EVENT_ATTR_RSSI, *ip_ptr);
3075 ip_ptr += 2;
3076 res |= nla_put_u16(nl_skb, SLSI_RTT_EVENT_ATTR_RSSI_SPREAD, *ip_ptr);
3077 ip_ptr += 2;
3078 memcpy(&tx_data, ip_ptr, 2);
3079 res = slsi_tx_rate_calc(nl_skb, tx_data, res, 1);
3080 ip_ptr += 2;
3081 memcpy(&rx_data, ip_ptr, 2);
3082 res = slsi_tx_rate_calc(nl_skb, rx_data, res, 0);
3083 ip_ptr += 2;
3084 res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_RTT, *ip_ptr);
3085 ip_ptr += 4;
3086 res |= nla_put_u16(nl_skb, SLSI_RTT_EVENT_ATTR_RTT_SD, *ip_ptr);
3087 ip_ptr += 2;
3088 res |= nla_put_u16(nl_skb, SLSI_RTT_EVENT_ATTR_RTT_SPREAD, *ip_ptr);
3089 ip_ptr += 2;
3090 get_monotonic_boottime(&ts);
3091 tkernel = (u64)TIMESPEC_TO_US(ts);
3092 tm = *ip_ptr;
3093 res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_TIMESTAMP_US, tkernel - (tmac - tm));
3094 ip_ptr += 4;
3095 res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_DISTANCE_MM, *ip_ptr);
3096 ip_ptr += 4;
3097 res |= nla_put_u32(nl_skb, SLSI_RTT_EVENT_ATTR_DISTANCE_SD_MM, *ip_ptr);
3098 ip_ptr += 4;
3099 res |= nla_put_u8(nl_skb, SLSI_RTT_EVENT_ATTR_BURST_DURATION_MSN, *ip_ptr++);
3100 res |= nla_put_u8(nl_skb, SLSI_RTT_EVENT_ATTR_NEGOTIATED_BURST_NUM, *ip_ptr++);
3101 for (rep_cnt = 0; rep_cnt < 2; rep_cnt++) {
3102 if (ip_ptr - start_ptr < data_len && ip_ptr[0] == WLAN_EID_MEASURE_REPORT) {
3103 if (ip_ptr[4] == 8) /*LCI Element*/
3104 res |= nla_put(nl_skb, SLSI_RTT_EVENT_ATTR_LCI,
3105 ip_ptr[1] + 2, ip_ptr);
3106 else if (ip_ptr[4] == 11) /*LCR element */
3107 res |= nla_put(nl_skb, SLSI_RTT_EVENT_ATTR_LCR,
3108 ip_ptr[1] + 2, ip_ptr);
3109 ip_ptr += ip_ptr[1] + 2;
3110 }
3111 }
3112 nla_nest_end(nl_skb, nlattr_nested);
3113 }
3114 SLSI_DBG_HEX(sdev, SLSI_GSCAN, fapi_get_data(skb), fapi_get_datalen(skb), "range indication skb buffer:\n");
3115 if (res) {
3116 SLSI_ERR(sdev, "Error in nla_put*:%x\n", res);
3117 kfree_skb(nl_skb);
3118 goto exit;
3119 }
3120 cfg80211_vendor_event(nl_skb, GFP_KERNEL);
3121 exit:
3122 slsi_kfree_skb(skb);
3123 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
3124 }
3125
3126 void slsi_rx_range_done_ind(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb)
3127 {
3128 struct netdev_vif *ndev_vif = netdev_priv(dev);
3129 u16 rtt_id = fapi_get_u16(skb, u.mlme_range_ind.rtt_id);
3130 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
3131 #ifdef CONFIG_SCSC_WLAN_DEBUG
3132 SLSI_DBG1_NODEV(SLSI_GSCAN, "Event: %s(%d)\n",
3133 slsi_print_event_name(SLSI_NL80211_RTT_COMPLETE_EVENT), SLSI_NL80211_RTT_COMPLETE_EVENT);
3134 #endif
3135 slsi_vendor_event(sdev, SLSI_NL80211_RTT_COMPLETE_EVENT, &rtt_id, sizeof(rtt_id));
3136 slsi_kfree_skb(skb);
3137 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
3138 }
3139
3140 static int slsi_rtt_cancel_config(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
3141 {
3142 int temp, ret, r = 1, j = 0, type;
3143 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
3144 struct net_device *dev = wdev->netdev;
3145 u8 *addr;
3146 const struct nlattr *iter;
3147 u16 num_devices = 0, rtt_id = 0;
3148
3149 SLSI_DBG1_NODEV(SLSI_GSCAN, "RTT_SUBCMD_CANCEL_CONFIG\n");
3150 if (!slsi_dev_rtt_supported()) {
3151 SLSI_WARN(sdev, "RTT not supported.\n");
3152 return -ENOTSUPP;
3153 }
3154 nla_for_each_attr(iter, data, len, temp) {
3155 type = nla_type(iter);
3156 switch (type) {
3157 case SLSI_RTT_ATTRIBUTE_TARGET_CNT:
3158 num_devices = nla_get_u16(iter);
3159 SLSI_DBG1_NODEV(SLSI_GSCAN, "Target cnt %d\n", num_devices);
3160 break;
3161 case SLSI_RTT_ATTRIBUTE_TARGET_ID:
3162 rtt_id = nla_get_u16(iter);
3163 SLSI_DBG1_NODEV(SLSI_GSCAN, "Target id %d\n", rtt_id);
3164 break;
3165 default:
3166 SLSI_ERR_NODEV("No ATTRIBUTE_Target cnt - %d\n", type);
3167 break;
3168 }
3169 }
3170 /* Allocate memory for the received mac addresses */
3171 if (num_devices) {
3172 addr = kzalloc(ETH_ALEN * num_devices, GFP_KERNEL);
3173 if (!addr) {
3174 SLSI_ERR_NODEV("Failed for allocate memory for mac addresses\n");
3175 ret = -ENOMEM;
3176 return ret;
3177 }
3178 nla_for_each_attr(iter, data, len, temp) {
3179 type = nla_type(iter);
3180 if (type == SLSI_RTT_ATTRIBUTE_TARGET_MAC) {
3181 memcpy(&addr[j], nla_data(iter), ETH_ALEN);
3182 j++;
3183 } else {
3184 SLSI_ERR_NODEV("No ATTRIBUTE_MAC - %d\n", type);
3185 }
3186 }
3187
3188 r = slsi_mlme_del_range_req(sdev, dev, num_devices, addr, rtt_id);
3189 kfree(addr);
3190 }
3191 if (r)
3192 SLSI_ERR_NODEV("Failed to cancel rtt config\n");
3193 return r;
3194 }
3195
3196 static int slsi_configure_nd_offload(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
3197 {
3198 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
3199 struct net_device *dev = wdev->netdev;
3200 struct netdev_vif *ndev_vif;
3201 int ret = 0;
3202 int temp;
3203 int type;
3204 const struct nlattr *attr;
3205 u8 nd_offload_enabled = 0;
3206
3207 SLSI_DBG3(sdev, SLSI_GSCAN, "Received nd_offload command\n");
3208
3209 if (!dev) {
3210 SLSI_ERR(sdev, "dev is NULL!!\n");
3211 return -EINVAL;
3212 }
3213
3214 ndev_vif = netdev_priv(dev);
3215 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
3216
3217 if (!ndev_vif->activated || (ndev_vif->vif_type != FAPI_VIFTYPE_STATION) ||
3218 (ndev_vif->sta.vif_status != SLSI_VIF_STATUS_CONNECTED)) {
3219 SLSI_DBG3(sdev, SLSI_GSCAN, "vif error\n");
3220 ret = -EPERM;
3221 goto exit;
3222 }
3223
3224 nla_for_each_attr(attr, data, len, temp) {
3225 type = nla_type(attr);
3226 switch (type) {
3227 case SLSI_NL_ATTRIBUTE_ND_OFFLOAD_VALUE:
3228 {
3229 nd_offload_enabled = nla_get_u8(attr);
3230 break;
3231 }
3232 default:
3233 SLSI_ERR(sdev, "Invalid type : %d\n", type);
3234 ret = -EINVAL;
3235 goto exit;
3236 }
3237 }
3238
3239 ndev_vif->sta.nd_offload_enabled = nd_offload_enabled;
3240 ret = slsi_mlme_set_ipv6_address(sdev, dev);
3241 if (ret < 0) {
3242 SLSI_ERR(sdev, "Configure nd_offload failed ret:%d nd_offload_enabled: %d\n", ret, nd_offload_enabled);
3243 ret = -EINVAL;
3244 goto exit;
3245 }
3246 exit:
3247 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
3248 return ret;
3249 }
3250
3251 static int slsi_get_roaming_capabilities(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
3252 {
3253 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
3254 struct net_device *dev = wdev->netdev;
3255 struct netdev_vif *ndev_vif;
3256 int ret = 0;
3257 struct slsi_mib_value *values = NULL;
3258 struct slsi_mib_data mibrsp = { 0, NULL };
3259 struct slsi_mib_get_entry get_values[] = {{ SLSI_PSID_UNIFI_ROAM_BLACKLIST_SIZE, { 0, 0 } } };
3260 u32 max_blacklist_size = 0;
3261 u32 max_whitelist_size = 0;
3262 struct sk_buff *nl_skb;
3263 struct nlattr *nlattr_start;
3264
3265 if (!dev) {
3266 SLSI_ERR(sdev, "dev is NULL!!\n");
3267 return -EINVAL;
3268 }
3269
3270 ndev_vif = netdev_priv(dev);
3271
3272 SLSI_MUTEX_LOCK(ndev_vif->vif_mutex);
3273
3274 mibrsp.dataLength = 10;
3275 mibrsp.data = kmalloc(mibrsp.dataLength, GFP_KERNEL);
3276 if (!mibrsp.data) {
3277 SLSI_ERR(sdev, "Cannot kmalloc %d bytes\n", mibrsp.dataLength);
3278 ret = -ENOMEM;
3279 goto exit;
3280 }
3281 values = slsi_read_mibs(sdev, NULL, get_values, ARRAY_SIZE(get_values), &mibrsp);
3282 if (values && (values[0].type == SLSI_MIB_TYPE_UINT || values[0].type == SLSI_MIB_TYPE_INT))
3283 max_blacklist_size = values[0].u.uintValue;
3284 nl_skb = cfg80211_vendor_cmd_alloc_reply_skb(sdev->wiphy, NLMSG_DEFAULT_SIZE);
3285 if (!nl_skb) {
3286 SLSI_ERR(sdev, "NO MEM for nl_skb!!!\n");
3287 ret = -ENOMEM;
3288 goto exit_with_mib_resp;
3289 }
3290
3291 nlattr_start = nla_nest_start(nl_skb, NL80211_ATTR_VENDOR_DATA);
3292 if (!nlattr_start) {
3293 SLSI_ERR(sdev, "failed to put NL80211_ATTR_VENDOR_DATA\n");
3294 /* Dont use slsi skb wrapper for this free */
3295 kfree_skb(nl_skb);
3296 ret = -EINVAL;
3297 goto exit_with_mib_resp;
3298 }
3299
3300 ret = nla_put_u32(nl_skb, SLSI_NL_ATTR_MAX_BLACKLIST_SIZE, max_blacklist_size);
3301 ret |= nla_put_u32(nl_skb, SLSI_NL_ATTR_MAX_WHITELIST_SIZE, max_whitelist_size);
3302 if (ret) {
3303 SLSI_ERR(sdev, "Error in nla_put*:%x\n", ret);
3304 /* Dont use slsi skb wrapper for this free */
3305 kfree_skb(nl_skb);
3306 goto exit_with_mib_resp;
3307 }
3308
3309 ret = cfg80211_vendor_cmd_reply(nl_skb);
3310 if (ret)
3311 SLSI_ERR(sdev, "cfg80211_vendor_cmd_reply failed :%d\n", ret);
3312 exit_with_mib_resp:
3313 kfree(mibrsp.data);
3314 kfree(values);
3315 exit:
3316 SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
3317 return ret;
3318 }
3319
3320 static int slsi_set_roaming_state(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
3321 {
3322 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
3323 struct net_device *dev = wdev->netdev;
3324 int temp = 0;
3325 int type = 0;
3326 const struct nlattr *attr;
3327 int ret = 0;
3328 int roam_state = 0;
3329
3330 if (!dev) {
3331 SLSI_WARN_NODEV("net_dev is NULL\n");
3332 return -EINVAL;
3333 }
3334
3335 nla_for_each_attr(attr, data, len, temp) {
3336 type = nla_type(attr);
3337 switch (type) {
3338 case SLSI_NL_ATTR_ROAM_STATE:
3339 roam_state = nla_get_u8(attr);
3340 break;
3341 default:
3342 SLSI_ERR_NODEV("Unknown attribute: %d\n", type);
3343 ret = -EINVAL;
3344 goto exit;
3345 }
3346 }
3347
3348 SLSI_DBG1_NODEV(SLSI_GSCAN, "SUBCMD_SET_ROAMING_STATE roam_state = %d\n", roam_state);
3349 ret = slsi_set_mib_roam(sdev, NULL, SLSI_PSID_UNIFI_ROAMING_ENABLED, roam_state);
3350 if (ret < 0)
3351 SLSI_ERR_NODEV("Failed to set roaming state\n");
3352
3353 exit:
3354 return ret;
3355 }
3356
3357 char *slsi_get_roam_reason_str(int roam_reason)
3358 {
3359 switch (roam_reason) {
3360 case SLSI_WIFI_ROAMING_SEARCH_REASON_RESERVED:
3361 return "WIFI_ROAMING_SEARCH_REASON_RESERVED";
3362 case SLSI_WIFI_ROAMING_SEARCH_REASON_LOW_RSSI:
3363 return "WIFI_ROAMING_SEARCH_REASON_LOW_RSSI";
3364 case SLSI_WIFI_ROAMING_SEARCH_REASON_LINK_LOSS:
3365 return "WIFI_ROAMING_SEARCH_REASON_LINK_LOSS";
3366 case SLSI_WIFI_ROAMING_SEARCH_REASON_BTM_REQ:
3367 return "WIFI_ROAMING_SEARCH_REASON_BTM_REQ";
3368 case SLSI_WIFI_ROAMING_SEARCH_REASON_CU_TRIGGER:
3369 return "WIFI_ROAMING_SEARCH_REASON_CU_TRIGGER";
3370 default:
3371 return "UNKNOWN_REASON";
3372 }
3373 }
3374
3375 void slsi_rx_event_log_indication(struct slsi_dev *sdev, struct net_device *dev, struct sk_buff *skb)
3376 {
3377 u16 event_id = 0;
3378 u64 timestamp = 0;
3379 u8 *tlv_data;
3380 u32 roam_reason = 0, chan_utilisation = 0, btm_request_mode = 0, btm_response = 0, eapol_msg_type = 0;
3381 u32 deauth_reason = 0, eapol_retry_count = 0, roam_rssi, status_code = 0;
3382 u16 vendor_len, tag_id, tag_len, vtag_id, eapol_key_type = 0;
3383 u32 tag_value, vtag_value, rssi_bits = 0;
3384 int roam_rssi_val = 0;
3385 __le16 *le16_ptr = NULL;
3386 int tlv_buffer__len = fapi_get_datalen(skb), i = 0;
3387
3388 SLSI_MUTEX_LOCK(sdev->logger_mutex);
3389 event_id = fapi_get_s16(skb, u.mlme_event_log_ind.event);
3390 timestamp = fapi_get_u64(skb, u.mlme_event_log_ind.timestamp);
3391 tlv_data = fapi_get_data(skb);
3392
3393 SLSI_DBG3(sdev, SLSI_GSCAN,
3394 "slsi_rx_event_log_indication, event id = %d, len = %d\n", event_id, tlv_buffer__len);
3395
3396 #ifdef CONFIG_SCSC_WIFILOGGER
3397 SCSC_WLOG_FW_EVENT(WLOG_NORMAL, event_id, timestamp, fapi_get_data(skb), fapi_get_datalen(skb));
3398 #endif
3399 while (i + 4 < tlv_buffer__len) {
3400 le16_ptr = (__le16 *)&tlv_data[i];
3401 tag_id = le16_to_cpu(*le16_ptr);
3402 le16_ptr = (__le16 *)&tlv_data[i + 2];
3403 tag_len = le16_to_cpu(*le16_ptr);
3404 i += 4;
3405 if (i + tag_len > tlv_buffer__len) {
3406 SLSI_INFO(sdev, "Incorrect fapi bulk data\n");
3407 slsi_kfree_skb(skb);
3408 SLSI_MUTEX_UNLOCK(sdev->logger_mutex);
3409 return;
3410 }
3411 tag_value = slsi_convert_tlv_data_to_value(&tlv_data[i], tag_len);
3412 switch (tag_id) {
3413 case SLSI_WIFI_TAG_RSSI:
3414 roam_rssi = tag_value;
3415 while (roam_rssi) {
3416 rssi_bits++;
3417 roam_rssi >>= 1;
3418 }
3419 roam_rssi_val = ((1 << rssi_bits) - 1) ^ tag_value;
3420 roam_rssi_val = -(roam_rssi_val + 1);
3421 break;
3422 case SLSI_WIFI_TAG_REASON_CODE:
3423 deauth_reason = tag_value;
3424 break;
3425 case SLSI_WIFI_TAG_VENDOR_SPECIFIC:
3426 vendor_len = tag_len - 2;
3427 le16_ptr = (__le16 *)&tlv_data[i];
3428 vtag_id = le16_to_cpu(*le16_ptr);
3429 vtag_value = slsi_convert_tlv_data_to_value(&tlv_data[i + 2], vendor_len);
3430 switch (vtag_id) {
3431 case SLSI_WIFI_TAG_VD_CHANNEL_UTILISATION:
3432 chan_utilisation = vtag_value;
3433 break;
3434 case SLSI_WIFI_TAG_VD_ROAMING_REASON:
3435 roam_reason = vtag_value;
3436 break;
3437 case SLSI_WIFI_TAG_VD_BTM_REQUEST_MODE:
3438 btm_request_mode = vtag_value;
3439 break;
3440 case SLSI_WIFI_TAG_VD_BTM_RESPONSE_STATUS:
3441 btm_response = vtag_value;
3442 break;
3443 case SLSI_WIFI_TAG_VD_RETRY_COUNT:
3444 eapol_retry_count = vtag_value;
3445 break;
3446 case SLSI_WIFI_TAG_VD_EAPOL_KEY_TYPE:
3447 eapol_key_type = vtag_value;
3448 break;
3449 }
3450 break;
3451 case SLSI_WIFI_TAG_EAPOL_MESSAGE_TYPE:
3452 eapol_msg_type = tag_value;
3453 break;
3454 case SLSI_WIFI_TAG_STATUS:
3455 status_code = tag_value;
3456 break;
3457 }
3458 i += tag_len;
3459 }
3460 switch (event_id) {
3461 case FAPI_EVENT_WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_START:
3462 if (eapol_key_type == SLSI_WIFI_EAPOL_KEY_TYPE_GTK)
3463 SLSI_INFO(sdev, "WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_START, Send GTK, G%d\n", eapol_msg_type);
3464 else if (eapol_key_type == SLSI_WIFI_EAPOL_KEY_TYPE_PTK)
3465 SLSI_INFO(sdev, "WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_START, Send 4way-H/S, M%d\n",
3466 eapol_msg_type);
3467 break;
3468 case FAPI_EVENT_WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_STOP:
3469 SLSI_INFO(sdev, "WIFI_EVENT_FW_EAPOL_FRAME_TRANSMIT_STOP,Result Code:%d, Retry Count:%d\n",
3470 status_code, eapol_retry_count);
3471 break;
3472 case FAPI_EVENT_WIFI_EVENT_FW_EAPOL_FRAME_RECEIVED:
3473 if (eapol_key_type == SLSI_WIFI_EAPOL_KEY_TYPE_GTK)
3474 SLSI_INFO(sdev, "WIFI_EVENT_FW_EAPOL_FRAME_RECEIVED, Received GTK, G%d\n", eapol_msg_type);
3475 else if (eapol_key_type == SLSI_WIFI_EAPOL_KEY_TYPE_PTK)
3476 SLSI_INFO(sdev, "WIFI_EVENT_FW_EAPOL_FRAME_RECEIVED, Received 4way-H/S, M%d\n", eapol_msg_type);
3477 break;
3478 case WIFI_EVENT_FW_BTM_FRAME_REQUEST:
3479 SLSI_INFO(sdev, "WIFI_EVENT_FW_BTM_FRAME_REQUEST,Request Mode:%d\n", btm_request_mode);
3480 break;
3481 case WIFI_EVENT_FW_BTM_FRAME_RESPONSE:
3482 SLSI_INFO(sdev, "WIFI_EVENT_FW_BTM_FRAME_RESPONSE,Status code:%d\n", btm_response);
3483 break;
3484 case FAPI_EVENT_WIFI_EVENT_ROAM_SEARCH_STARTED:
3485 SLSI_INFO(sdev, "WIFI_EVENT_ROAM_SEARCH_STARTED, RSSI:%d, Deauth Reason:0x%04x, Channel Utilisation:%d,"
3486 "Roam Reason: %s\n", roam_rssi_val, deauth_reason, chan_utilisation,
3487 slsi_get_roam_reason_str(roam_reason));
3488 break;
3489 case FAPI_EVENT_WIFI_EVENT_FW_AUTH_STARTED:
3490 SLSI_INFO(sdev, "WIFI_EVENT_FW_AUTH_STARTED\n");
3491 break;
3492 case FAPI_EVENT_WIFI_EVENT_AUTH_COMPLETE:
3493 SLSI_INFO(sdev, "WIFI_EVENT_AUTH_COMPLETE,Status code:%d\n", status_code);
3494 break;
3495 case FAPI_EVENT_WIFI_EVENT_ROAM_ASSOC_COMPLETE:
3496 SLSI_INFO(sdev, "Received Association Response\n");
3497 break;
3498 case WIFI_EVENT_FW_NR_FRAME_REQUEST:
3499 SLSI_INFO(sdev, "Send Radio Measurement Frame (Neighbor Report Req)\n");
3500 break;
3501 case WIFI_EVENT_FW_RM_FRAME_RESPONSE:
3502 SLSI_INFO(sdev, "Received Radio Measurement Frame (Radio Measurement Rep)\n");
3503 break;
3504 }
3505
3506 slsi_kfree_skb(skb);
3507 SLSI_MUTEX_UNLOCK(sdev->logger_mutex);
3508 }
3509
3510 #ifdef CONFIG_SCSC_WLAN_ENHANCED_LOGGING
3511 static void slsi_on_ring_buffer_data(char *ring_name, char *buffer, int buffer_size,
3512 struct scsc_wifi_ring_buffer_status *buffer_status, void *ctx)
3513 {
3514 struct sk_buff *skb;
3515 int event_id = SLSI_NL80211_LOGGER_RING_EVENT;
3516 struct slsi_dev *sdev = ctx;
3517
3518 SLSI_DBG3(sdev, SLSI_GSCAN, "\n");
3519 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
3520 skb = cfg80211_vendor_event_alloc(sdev->wiphy, NULL, buffer_size, event_id, GFP_KERNEL);
3521 #else
3522 skb = cfg80211_vendor_event_alloc(sdev->wiphy, buffer_size, event_id, GFP_KERNEL);
3523 #endif
3524 if (!skb) {
3525 SLSI_ERR_NODEV("Failed to allocate skb for vendor event: %d\n", event_id);
3526 return;
3527 }
3528
3529 if (nla_put(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_RING_STATUS, sizeof(*buffer_status), buffer_status) ||
3530 nla_put(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_RING_DATA, buffer_size, buffer)) {
3531 SLSI_ERR_NODEV("Failed nla_put\n");
3532 slsi_kfree_skb(skb);
3533 return;
3534 }
3535 cfg80211_vendor_event(skb, GFP_KERNEL);
3536 }
3537
3538 static void slsi_on_alert(char *buffer, int buffer_size, int err_code, void *ctx)
3539 {
3540 struct sk_buff *skb;
3541 int event_id = SLSI_NL80211_LOGGER_FW_DUMP_EVENT;
3542 struct slsi_dev *sdev = ctx;
3543
3544 SLSI_DBG3(sdev, SLSI_GSCAN, "\n");
3545 SLSI_MUTEX_LOCK(sdev->logger_mutex);
3546 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
3547 skb = cfg80211_vendor_event_alloc(sdev->wiphy, NULL, buffer_size, event_id, GFP_KERNEL);
3548 #else
3549 skb = cfg80211_vendor_event_alloc(sdev->wiphy, buffer_size, event_id, GFP_KERNEL);
3550 #endif
3551 if (!skb) {
3552 SLSI_ERR_NODEV("Failed to allocate skb for vendor event: %d\n", event_id);
3553 goto exit;
3554 }
3555
3556 if (nla_put_u32(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_FW_DUMP_LEN, buffer_size) ||
3557 nla_put(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_RING_DATA, buffer_size, buffer)) {
3558 SLSI_ERR_NODEV("Failed nla_put\n");
3559 slsi_kfree_skb(skb);
3560 goto exit;
3561 }
3562 cfg80211_vendor_event(skb, GFP_KERNEL);
3563 exit:
3564 SLSI_MUTEX_UNLOCK(sdev->logger_mutex);
3565 }
3566
3567 static void slsi_on_firmware_memory_dump(char *buffer, int buffer_size, void *ctx)
3568 {
3569 SLSI_ERR_NODEV("slsi_on_firmware_memory_dump\n");
3570 kfree(mem_dump_buffer);
3571 mem_dump_buffer = NULL;
3572 mem_dump_buffer = kmalloc(buffer_size, GFP_KERNEL);
3573 if (!mem_dump_buffer) {
3574 SLSI_ERR_NODEV("Failed to allocate memory for mem_dump_buffer\n");
3575 return;
3576 }
3577 mem_dump_buffer_size = buffer_size;
3578 memcpy(mem_dump_buffer, buffer, mem_dump_buffer_size);
3579 }
3580
3581 static void slsi_on_driver_memory_dump(char *buffer, int buffer_size, void *ctx)
3582 {
3583 SLSI_ERR_NODEV("slsi_on_driver_memory_dump\n");
3584 kfree(mem_dump_buffer);
3585 mem_dump_buffer = NULL;
3586 mem_dump_buffer_size = buffer_size;
3587 mem_dump_buffer = kmalloc(mem_dump_buffer_size, GFP_KERNEL);
3588 if (!mem_dump_buffer) {
3589 SLSI_ERR_NODEV("Failed to allocate memory for mem_dump_buffer\n");
3590 return;
3591 }
3592 memcpy(mem_dump_buffer, buffer, mem_dump_buffer_size);
3593 }
3594
3595 static int slsi_enable_logging(struct slsi_dev *sdev, bool enable)
3596 {
3597 int status = 0;
3598 #ifdef ENABLE_WIFI_LOGGER_MIB_WRITE
3599 struct slsi_mib_data mib_data = { 0, NULL };
3600
3601 SLSI_DBG3(sdev, SLSI_GSCAN, "Value of enable is : %d\n", enable);
3602 status = slsi_mib_encode_bool(&mib_data, SLSI_PSID_UNIFI_LOGGER_ENABLED, enable, 0);
3603 if (status != SLSI_MIB_STATUS_SUCCESS) {
3604 SLSI_ERR(sdev, "slsi_enable_logging failed: no mem for MIB\n");
3605 status = -ENOMEM;
3606 goto exit;
3607 }
3608 status = slsi_mlme_set(sdev, NULL, mib_data.data, mib_data.dataLength);
3609 kfree(mib_data.data);
3610 if (status)
3611 SLSI_ERR(sdev, "Err setting unifiLoggerEnabled MIB. error = %d\n", status);
3612
3613 exit:
3614 return status;
3615 #else
3616 SLSI_DBG3(sdev, SLSI_GSCAN, "UnifiLoggerEnabled MIB write disabled\n");
3617 return status;
3618 #endif
3619 }
3620
3621 static int slsi_start_logging(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
3622 {
3623 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
3624 int ret = 0;
3625 int temp = 0;
3626 int type = 0;
3627 char ring_name[32] = {0};
3628 int verbose_level = 0;
3629 int ring_flags = 0;
3630 int max_interval_sec = 0;
3631 int min_data_size = 0;
3632 const struct nlattr *attr;
3633
3634 SLSI_DBG3(sdev, SLSI_GSCAN, "\n");
3635 SLSI_MUTEX_LOCK(sdev->logger_mutex);
3636 nla_for_each_attr(attr, data, len, temp) {
3637 if (!attr) {
3638 ret = -EINVAL;
3639 goto exit;
3640 }
3641
3642 type = nla_type(attr);
3643
3644 switch (type) {
3645 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_RING_NAME:
3646 strncpy(ring_name, nla_data(attr), MIN(sizeof(ring_name) - 1, nla_len(attr)));
3647 break;
3648 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_VERBOSE_LEVEL:
3649 if (nla_len(attr) != (SLSI_NL_ATTRIBUTE_U32_LEN - NLA_HDRLEN)) {
3650 ret = -EINVAL;
3651 goto exit;
3652 }
3653 verbose_level = nla_get_u32(attr);
3654 break;
3655 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_RING_FLAGS:
3656 if (nla_len(attr) != (SLSI_NL_ATTRIBUTE_U32_LEN - NLA_HDRLEN)) {
3657 ret = -EINVAL;
3658 goto exit;
3659 }
3660 ring_flags = nla_get_u32(attr);
3661 break;
3662 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_LOG_MAX_INTERVAL:
3663 if (nla_len(attr) != (SLSI_NL_ATTRIBUTE_U32_LEN - NLA_HDRLEN)) {
3664 ret = -EINVAL;
3665 goto exit;
3666 }
3667 max_interval_sec = nla_get_u32(attr);
3668 break;
3669 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_LOG_MIN_DATA_SIZE:
3670 if (nla_len(attr) != (SLSI_NL_ATTRIBUTE_U32_LEN - NLA_HDRLEN)) {
3671 ret = -EINVAL;
3672 goto exit;
3673 }
3674 min_data_size = nla_get_u32(attr);
3675 break;
3676 default:
3677 SLSI_ERR(sdev, "Unknown type: %d\n", type);
3678 ret = -EINVAL;
3679 goto exit;
3680 }
3681 }
3682 ret = scsc_wifi_set_log_handler(slsi_on_ring_buffer_data, sdev);
3683 if (ret < 0) {
3684 SLSI_ERR(sdev, "scsc_wifi_set_log_handler failed ret: %d\n", ret);
3685 goto exit;
3686 }
3687 ret = scsc_wifi_set_alert_handler(slsi_on_alert, sdev);
3688 if (ret < 0) {
3689 SLSI_ERR(sdev, "Warning : scsc_wifi_set_alert_handler failed ret: %d\n", ret);
3690 }
3691 ret = slsi_enable_logging(sdev, 1);
3692 if (ret < 0) {
3693 SLSI_ERR(sdev, "slsi_enable_logging for enable = 1, failed ret: %d\n", ret);
3694 goto exit_with_reset_alert_handler;
3695 }
3696 ret = scsc_wifi_start_logging(verbose_level, ring_flags, max_interval_sec, min_data_size, ring_name);
3697 if (ret < 0) {
3698 SLSI_ERR(sdev, "scsc_wifi_start_logging failed ret: %d\n", ret);
3699 goto exit_with_disable_logging;
3700 } else {
3701 goto exit;
3702 }
3703 exit_with_disable_logging:
3704 ret = slsi_enable_logging(sdev, 0);
3705 if (ret < 0)
3706 SLSI_ERR(sdev, "slsi_enable_logging for enable = 0, failed ret: %d\n", ret);
3707 exit_with_reset_alert_handler:
3708 ret = scsc_wifi_reset_alert_handler();
3709 if (ret < 0)
3710 SLSI_ERR(sdev, "Warning : scsc_wifi_reset_alert_handler failed ret: %d\n", ret);
3711 ret = scsc_wifi_reset_log_handler();
3712 if (ret < 0)
3713 SLSI_ERR(sdev, "scsc_wifi_reset_log_handler failed ret: %d\n", ret);
3714 exit:
3715 SLSI_MUTEX_UNLOCK(sdev->logger_mutex);
3716 return ret;
3717 }
3718
3719 static int slsi_reset_logging(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
3720 {
3721 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
3722 int ret = 0;
3723
3724 SLSI_DBG3(sdev, SLSI_GSCAN, "\n");
3725 SLSI_MUTEX_LOCK(sdev->logger_mutex);
3726 ret = slsi_enable_logging(sdev, 0);
3727 if (ret < 0)
3728 SLSI_ERR(sdev, "slsi_enable_logging for enable = 0, failed ret: %d\n", ret);
3729 ret = scsc_wifi_reset_log_handler();
3730 if (ret < 0)
3731 SLSI_ERR(sdev, "scsc_wifi_reset_log_handler failed ret: %d\n", ret);
3732 ret = scsc_wifi_reset_alert_handler();
3733 if (ret < 0)
3734 SLSI_ERR(sdev, "Warning : scsc_wifi_reset_alert_handler failed ret: %d\n", ret);
3735 SLSI_MUTEX_UNLOCK(sdev->logger_mutex);
3736 return ret;
3737 }
3738
3739 static int slsi_trigger_fw_mem_dump(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
3740 {
3741 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
3742 int ret = 0;
3743 struct sk_buff *skb = NULL;
3744 int length = 100;
3745
3746 SLSI_DBG3(sdev, SLSI_GSCAN, "\n");
3747 SLSI_MUTEX_LOCK(sdev->logger_mutex);
3748
3749 ret = scsc_wifi_get_firmware_memory_dump(slsi_on_firmware_memory_dump, sdev);
3750 if (ret) {
3751 SLSI_ERR(sdev, "scsc_wifi_get_firmware_memory_dump failed : %d\n", ret);
3752 goto exit;
3753 }
3754
3755 /* Alloc the SKB for vendor_event */
3756 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, length);
3757 if (!skb) {
3758 SLSI_ERR_NODEV("Failed to allocate skb for Vendor event\n");
3759 ret = -ENOMEM;
3760 goto exit;
3761 }
3762
3763 if (nla_put_u32(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_FW_DUMP_LEN, mem_dump_buffer_size)) {
3764 SLSI_ERR_NODEV("Failed nla_put\n");
3765 slsi_kfree_skb(skb);
3766 ret = -EINVAL;
3767 goto exit;
3768 }
3769
3770 ret = cfg80211_vendor_cmd_reply(skb);
3771
3772 if (ret)
3773 SLSI_ERR(sdev, "Vendor Command reply failed ret:%d\n", ret);
3774
3775 exit:
3776 SLSI_MUTEX_UNLOCK(sdev->logger_mutex);
3777 return ret;
3778 }
3779
3780 static int slsi_get_fw_mem_dump(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
3781 {
3782 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
3783 int ret = 0;
3784 int temp = 0;
3785 int type = 0;
3786 int buf_len = 0;
3787 void __user *user_buf = NULL;
3788 const struct nlattr *attr;
3789 struct sk_buff *skb;
3790
3791 SLSI_DBG3(sdev, SLSI_GSCAN, "\n");
3792 SLSI_MUTEX_LOCK(sdev->logger_mutex);
3793 nla_for_each_attr(attr, data, len, temp) {
3794 type = nla_type(attr);
3795 switch (type) {
3796 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_FW_DUMP_LEN:
3797 buf_len = nla_get_u32(attr);
3798 break;
3799 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_FW_DUMP_DATA:
3800 user_buf = (void __user *)(unsigned long)nla_get_u64(attr);
3801 break;
3802 default:
3803 SLSI_ERR(sdev, "Unknown type: %d\n", type);
3804 SLSI_MUTEX_UNLOCK(sdev->logger_mutex);
3805 return -EINVAL;
3806 }
3807 }
3808 if (buf_len > 0 && user_buf) {
3809 ret = copy_to_user(user_buf, mem_dump_buffer, buf_len);
3810 if (ret) {
3811 SLSI_ERR(sdev, "failed to copy memdump into user buffer : %d\n", ret);
3812 goto exit;
3813 }
3814
3815 /* Alloc the SKB for vendor_event */
3816 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, 100);
3817 if (!skb) {
3818 SLSI_ERR_NODEV("Failed to allocate skb for Vendor event\n");
3819 ret = -ENOMEM;
3820 goto exit;
3821 }
3822
3823 /* Indicate the memdump is successfully copied */
3824 if (nla_put(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_FW_DUMP_DATA, sizeof(ret), &ret)) {
3825 SLSI_ERR_NODEV("Failed nla_put\n");
3826 slsi_kfree_skb(skb);
3827 ret = -EINVAL;
3828 goto exit;
3829 }
3830
3831 ret = cfg80211_vendor_cmd_reply(skb);
3832
3833 if (ret)
3834 SLSI_ERR(sdev, "Vendor Command reply failed ret:%d\n", ret);
3835 }
3836
3837 exit:
3838 kfree(mem_dump_buffer);
3839 mem_dump_buffer = NULL;
3840 SLSI_MUTEX_UNLOCK(sdev->logger_mutex);
3841 return ret;
3842 }
3843
3844 static int slsi_trigger_driver_mem_dump(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
3845 {
3846 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
3847 int ret = 0;
3848 struct sk_buff *skb = NULL;
3849 int length = 100;
3850
3851 SLSI_DBG3(sdev, SLSI_GSCAN, "\n");
3852 SLSI_MUTEX_LOCK(sdev->logger_mutex);
3853
3854 ret = scsc_wifi_get_driver_memory_dump(slsi_on_driver_memory_dump, sdev);
3855 if (ret) {
3856 SLSI_ERR(sdev, "scsc_wifi_get_driver_memory_dump failed : %d\n", ret);
3857 goto exit;
3858 }
3859
3860 /* Alloc the SKB for vendor_event */
3861 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, length);
3862 if (!skb) {
3863 SLSI_ERR_NODEV("Failed to allocate skb for Vendor event\n");
3864 ret = -ENOMEM;
3865 goto exit;
3866 }
3867
3868 if (nla_put_u32(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_DRIVER_DUMP_LEN, mem_dump_buffer_size)) {
3869 SLSI_ERR_NODEV("Failed nla_put\n");
3870 slsi_kfree_skb(skb);
3871 ret = -EINVAL;
3872 goto exit;
3873 }
3874
3875 ret = cfg80211_vendor_cmd_reply(skb);
3876
3877 if (ret)
3878 SLSI_ERR(sdev, "Vendor Command reply failed ret:%d\n", ret);
3879
3880 exit:
3881 SLSI_MUTEX_UNLOCK(sdev->logger_mutex);
3882 return ret;
3883 }
3884
3885 static int slsi_get_driver_mem_dump(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
3886 {
3887 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
3888 int ret = 0;
3889 int temp = 0;
3890 int type = 0;
3891 int buf_len = 0;
3892 void __user *user_buf = NULL;
3893 const struct nlattr *attr;
3894 struct sk_buff *skb;
3895
3896 SLSI_DBG3(sdev, SLSI_GSCAN, "\n");
3897 SLSI_MUTEX_LOCK(sdev->logger_mutex);
3898 nla_for_each_attr(attr, data, len, temp) {
3899 type = nla_type(attr);
3900 switch (type) {
3901 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_DRIVER_DUMP_LEN:
3902 buf_len = nla_get_u32(attr);
3903 break;
3904 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_DRIVER_DUMP_DATA:
3905 user_buf = (void __user *)(unsigned long)nla_get_u64(attr);
3906 break;
3907 default:
3908 SLSI_ERR(sdev, "Unknown type: %d\n", type);
3909 SLSI_MUTEX_UNLOCK(sdev->logger_mutex);
3910 return -EINVAL;
3911 }
3912 }
3913 if (buf_len > 0 && user_buf) {
3914 ret = copy_to_user(user_buf, mem_dump_buffer, buf_len);
3915 if (ret) {
3916 SLSI_ERR(sdev, "failed to copy memdump into user buffer : %d\n", ret);
3917 goto exit;
3918 }
3919
3920 /* Alloc the SKB for vendor_event */
3921 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, 100);
3922 if (!skb) {
3923 SLSI_ERR_NODEV("Failed to allocate skb for Vendor event\n");
3924 ret = -ENOMEM;
3925 goto exit;
3926 }
3927
3928 /* Indicate the memdump is successfully copied */
3929 if (nla_put(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_DRIVER_DUMP_DATA, sizeof(ret), &ret)) {
3930 SLSI_ERR_NODEV("Failed nla_put\n");
3931 slsi_kfree_skb(skb);
3932 ret = -EINVAL;
3933 goto exit;
3934 }
3935
3936 ret = cfg80211_vendor_cmd_reply(skb);
3937
3938 if (ret)
3939 SLSI_ERR(sdev, "Vendor Command reply failed ret:%d\n", ret);
3940 }
3941
3942 exit:
3943 kfree(mem_dump_buffer);
3944 mem_dump_buffer = NULL;
3945 SLSI_MUTEX_UNLOCK(sdev->logger_mutex);
3946 return ret;
3947 }
3948
3949 static int slsi_get_version(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
3950 {
3951 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
3952 int ret = 0;
3953 int temp = 0;
3954 int type = 0;
3955 int buffer_size = 1024;
3956 bool log_version = false;
3957 char *buffer;
3958 const struct nlattr *attr;
3959
3960 buffer = kzalloc(buffer_size, GFP_KERNEL);
3961 if (!buffer) {
3962 SLSI_ERR(sdev, "No mem. Size:%d\n", buffer_size);
3963 return -ENOMEM;
3964 }
3965 SLSI_MUTEX_LOCK(sdev->logger_mutex);
3966 nla_for_each_attr(attr, data, len, temp) {
3967 type = nla_type(attr);
3968 switch (type) {
3969 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_DRIVER_VERSION:
3970 log_version = true;
3971 break;
3972 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_FW_VERSION:
3973 log_version = false;
3974 break;
3975 default:
3976 SLSI_ERR(sdev, "Unknown type: %d\n", type);
3977 ret = -EINVAL;
3978 goto exit;
3979 }
3980 }
3981
3982 if (log_version)
3983 ret = scsc_wifi_get_driver_version(buffer, buffer_size);
3984 else
3985 ret = scsc_wifi_get_firmware_version(buffer, buffer_size);
3986
3987 if (ret < 0) {
3988 SLSI_ERR(sdev, "failed to get the version %d\n", ret);
3989 goto exit;
3990 }
3991
3992 ret = slsi_vendor_cmd_reply(wiphy, buffer, strlen(buffer));
3993 exit:
3994 kfree(buffer);
3995 SLSI_MUTEX_UNLOCK(sdev->logger_mutex);
3996 return ret;
3997 }
3998
3999 static int slsi_get_ring_buffers_status(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
4000 {
4001 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
4002 int ret = 0;
4003 int num_rings = 10;
4004 struct sk_buff *skb;
4005 struct scsc_wifi_ring_buffer_status status[num_rings];
4006
4007 SLSI_DBG1(sdev, SLSI_GSCAN, "\n");
4008 SLSI_MUTEX_LOCK(sdev->logger_mutex);
4009 memset(status, 0, sizeof(struct scsc_wifi_ring_buffer_status) * num_rings);
4010 ret = scsc_wifi_get_ring_buffers_status(&num_rings, status);
4011 if (ret < 0) {
4012 SLSI_ERR(sdev, "scsc_wifi_get_ring_buffers_status failed ret:%d\n", ret);
4013 goto exit;
4014 }
4015
4016 /* Alloc the SKB for vendor_event */
4017 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, 700);
4018 if (!skb) {
4019 SLSI_ERR_NODEV("Failed to allocate skb for Vendor event\n");
4020 ret = -ENOMEM;
4021 goto exit;
4022 }
4023
4024 /* Indicate that the ring count and ring buffers status is successfully copied */
4025 if (nla_put_u8(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_RING_NUM, num_rings) ||
4026 nla_put(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_RING_STATUS, sizeof(status[0]) * num_rings, status)) {
4027 SLSI_ERR_NODEV("Failed nla_put\n");
4028 slsi_kfree_skb(skb);
4029 ret = -EINVAL;
4030 goto exit;
4031 }
4032
4033 ret = cfg80211_vendor_cmd_reply(skb);
4034
4035 if (ret)
4036 SLSI_ERR(sdev, "Vendor Command reply failed ret:%d\n", ret);
4037 exit:
4038 SLSI_MUTEX_UNLOCK(sdev->logger_mutex);
4039 return ret;
4040 }
4041
4042 static int slsi_get_ring_data(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
4043 {
4044 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
4045 int ret = 0;
4046 int temp = 0;
4047 int type = 0;
4048 char ring_name[32] = {0};
4049 const struct nlattr *attr;
4050
4051 SLSI_DBG3(sdev, SLSI_GSCAN, "\n");
4052 SLSI_MUTEX_LOCK(sdev->logger_mutex);
4053 nla_for_each_attr(attr, data, len, temp) {
4054 if (!attr) {
4055 ret = -EINVAL;
4056 goto exit;
4057 }
4058 type = nla_type(attr);
4059 switch (type) {
4060 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_RING_NAME:
4061 strncpy(ring_name, nla_data(attr), MIN(sizeof(ring_name) - 1, nla_len(attr)));
4062 break;
4063 default:
4064 SLSI_ERR(sdev, "Unknown type: %d\n", type);
4065 goto exit;
4066 }
4067 }
4068
4069 ret = scsc_wifi_get_ring_data(ring_name);
4070 if (ret < 0)
4071 SLSI_ERR(sdev, "trigger_get_data failed ret:%d\n", ret);
4072 exit:
4073 SLSI_MUTEX_UNLOCK(sdev->logger_mutex);
4074 return ret;
4075 }
4076
4077 static int slsi_get_logger_supported_feature_set(struct wiphy *wiphy, struct wireless_dev *wdev,
4078 const void *data, int len)
4079 {
4080 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
4081 int ret = 0;
4082 u32 supported_features = 0;
4083
4084 SLSI_DBG3(sdev, SLSI_GSCAN, "\n");
4085 SLSI_MUTEX_LOCK(sdev->logger_mutex);
4086 ret = scsc_wifi_get_logger_supported_feature_set(&supported_features);
4087 if (ret < 0) {
4088 SLSI_ERR(sdev, "scsc_wifi_get_logger_supported_feature_set failed ret:%d\n", ret);
4089 goto exit;
4090 }
4091 ret = slsi_vendor_cmd_reply(wiphy, &supported_features, sizeof(supported_features));
4092 exit:
4093 SLSI_MUTEX_UNLOCK(sdev->logger_mutex);
4094 return ret;
4095 }
4096
4097 static int slsi_start_pkt_fate_monitoring(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
4098 {
4099 int ret = 0;
4100 #ifdef ENABLE_WIFI_LOGGER_MIB_WRITE
4101 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
4102 struct slsi_mib_data mib_data = { 0, NULL };
4103
4104 SLSI_DBG3(sdev, SLSI_GSCAN, "\n");
4105 SLSI_MUTEX_LOCK(sdev->logger_mutex);
4106 ret = slsi_mib_encode_bool(&mib_data, SLSI_PSID_UNIFI_TX_DATA_CONFIRM, 1, 0);
4107 if (ret != SLSI_MIB_STATUS_SUCCESS) {
4108 SLSI_ERR(sdev, "Failed to set UnifiTxDataConfirm MIB : no mem for MIB\n");
4109 ret = -ENOMEM;
4110 goto exit;
4111 }
4112
4113 ret = slsi_mlme_set(sdev, NULL, mib_data.data, mib_data.dataLength);
4114
4115 if (ret) {
4116 SLSI_ERR(sdev, "Err setting UnifiTxDataConfirm MIB. error = %d\n", ret);
4117 goto exit;
4118 }
4119
4120 ret = scsc_wifi_start_pkt_fate_monitoring();
4121 if (ret < 0) {
4122 SLSI_ERR(sdev, "scsc_wifi_start_pkt_fate_monitoring failed, ret=%d\n", ret);
4123
4124 // Resetting the SLSI_PSID_UNIFI_TX_DATA_CONFIRM mib back to 0.
4125 mib_data.dataLength = 0;
4126 mib_data.data = NULL;
4127 ret = slsi_mib_encode_bool(&mib_data, SLSI_PSID_UNIFI_TX_DATA_CONFIRM, 1, 0);
4128 if (ret != SLSI_MIB_STATUS_SUCCESS) {
4129 SLSI_ERR(sdev, "Failed to set UnifiTxDataConfirm MIB : no mem for MIB\n");
4130 ret = -ENOMEM;
4131 goto exit;
4132 }
4133
4134 ret = slsi_mlme_set(sdev, NULL, mib_data.data, mib_data.dataLength);
4135
4136 if (ret) {
4137 SLSI_ERR(sdev, "Err setting UnifiTxDataConfirm MIB. error = %d\n", ret);
4138 goto exit;
4139 }
4140 }
4141 exit:
4142 kfree(mib_data.data);
4143 SLSI_MUTEX_UNLOCK(sdev->logger_mutex);
4144 return ret;
4145 #else
4146 SLSI_ERR_NODEV("slsi_start_pkt_fate_monitoring : UnifiTxDataConfirm MIB write disabled\n");
4147 return ret;
4148 #endif
4149 }
4150
4151 static int slsi_get_tx_pkt_fates(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
4152 {
4153 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
4154 int ret = 0;
4155 int temp = 0;
4156 int type = 0;
4157 void __user *user_buf = NULL;
4158 u32 req_count = 0;
4159 size_t provided_count = 0;
4160 struct sk_buff *skb;
4161 const struct nlattr *attr;
4162
4163 SLSI_DBG3(sdev, SLSI_GSCAN, "\n");
4164 SLSI_MUTEX_LOCK(sdev->logger_mutex);
4165 nla_for_each_attr(attr, data, len, temp) {
4166 type = nla_type(attr);
4167 switch (type) {
4168 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_PKT_FATE_NUM:
4169 req_count = nla_get_u32(attr);
4170 break;
4171 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_PKT_FATE_DATA:
4172 user_buf = (void __user *)(unsigned long)nla_get_u64(attr);
4173 break;
4174 default:
4175 SLSI_ERR(sdev, "Unknown type: %d\n", type);
4176 ret = -EINVAL;
4177 goto exit;
4178 }
4179 }
4180
4181 ret = scsc_wifi_get_tx_pkt_fates(user_buf, req_count, &provided_count);
4182 if (ret < 0) {
4183 SLSI_ERR(sdev, "scsc_wifi_get_tx_pkt_fates failed ret: %d\n", ret);
4184 goto exit;
4185 }
4186
4187 /* Alloc the SKB for vendor_event */
4188 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, 200);
4189 if (!skb) {
4190 SLSI_ERR_NODEV("Failed to allocate skb for Vendor event\n");
4191 ret = -ENOMEM;
4192 goto exit;
4193 }
4194
4195 if (nla_put(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_PKT_FATE_NUM, sizeof(provided_count), &provided_count)) {
4196 SLSI_ERR_NODEV("Failed nla_put\n");
4197 slsi_kfree_skb(skb);
4198 ret = -EINVAL;
4199 goto exit;
4200 }
4201
4202 ret = cfg80211_vendor_cmd_reply(skb);
4203
4204 if (ret)
4205 SLSI_ERR(sdev, "Vendor Command reply failed ret:%d\n", ret);
4206 exit:
4207 SLSI_MUTEX_UNLOCK(sdev->logger_mutex);
4208 return ret;
4209 }
4210
4211 static int slsi_get_rx_pkt_fates(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
4212 {
4213 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
4214 int ret = 0;
4215 int temp = 0;
4216 int type = 0;
4217 void __user *user_buf = NULL;
4218 u32 req_count = 0;
4219 size_t provided_count = 0;
4220 struct sk_buff *skb;
4221 const struct nlattr *attr;
4222
4223 SLSI_DBG3(sdev, SLSI_GSCAN, "\n");
4224 SLSI_MUTEX_LOCK(sdev->logger_mutex);
4225 nla_for_each_attr(attr, data, len, temp) {
4226 type = nla_type(attr);
4227 switch (type) {
4228 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_PKT_FATE_NUM:
4229 req_count = nla_get_u32(attr);
4230 break;
4231 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_PKT_FATE_DATA:
4232 user_buf = (void __user *)(unsigned long)nla_get_u64(attr);
4233 break;
4234 default:
4235 SLSI_ERR(sdev, "Unknown type: %d\n", type);
4236 ret = -EINVAL;
4237 goto exit;
4238 }
4239 }
4240
4241 ret = scsc_wifi_get_rx_pkt_fates(user_buf, req_count, &provided_count);
4242 if (ret < 0) {
4243 SLSI_ERR(sdev, "scsc_wifi_get_rx_pkt_fates failed ret: %d\n", ret);
4244 goto exit;
4245 }
4246
4247 /* Alloc the SKB for vendor_event */
4248 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, 200);
4249 if (!skb) {
4250 SLSI_ERR_NODEV("Failed to allocate skb for Vendor event\n");
4251 ret = -ENOMEM;
4252 goto exit;
4253 }
4254
4255 if (nla_put(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_PKT_FATE_NUM, sizeof(provided_count), &provided_count)) {
4256 SLSI_ERR_NODEV("Failed nla_put\n");
4257 slsi_kfree_skb(skb);
4258 ret = -EINVAL;
4259 goto exit;
4260 }
4261
4262 ret = cfg80211_vendor_cmd_reply(skb);
4263
4264 if (ret)
4265 SLSI_ERR(sdev, "Vendor Command reply failed ret:%d\n", ret);
4266 exit:
4267 SLSI_MUTEX_UNLOCK(sdev->logger_mutex);
4268 return ret;
4269 }
4270
4271 static int slsi_get_wake_reason_stats(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
4272 {
4273 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
4274 struct slsi_wlan_driver_wake_reason_cnt wake_reason_count;
4275 int ret = 0;
4276 int temp = 0;
4277 int type = 0;
4278 const struct nlattr *attr;
4279 struct sk_buff *skb;
4280
4281 SLSI_DBG3(sdev, SLSI_GSCAN, "\n");
4282 // Initialising the wake_reason_count structure values to 0.
4283 memset(&wake_reason_count, 0, sizeof(struct slsi_wlan_driver_wake_reason_cnt));
4284
4285 SLSI_MUTEX_LOCK(sdev->logger_mutex);
4286 nla_for_each_attr(attr, data, len, temp) {
4287 type = nla_type(attr);
4288 switch (type) {
4289 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_WAKE_STATS_CMD_EVENT_WAKE_CNT_SZ:
4290 wake_reason_count.cmd_event_wake_cnt_sz = nla_get_u32(attr);
4291 break;
4292 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_WAKE_STATS_DRIVER_FW_LOCAL_WAKE_CNT_SZ:
4293 wake_reason_count.driver_fw_local_wake_cnt_sz = nla_get_u32(attr);
4294 break;
4295 default:
4296 SLSI_ERR(sdev, "Unknown type: %d\n", type);
4297 ret = -EINVAL;
4298 goto exit;
4299 }
4300 }
4301
4302 if (ret < 0) {
4303 SLSI_ERR(sdev, "Failed to get wake reason stats : %d\n", ret);
4304 goto exit;
4305 }
4306
4307 /* Alloc the SKB for vendor_event */
4308 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, 700);
4309 if (!skb) {
4310 SLSI_ERR_NODEV("Failed to allocate skb for Vendor event\n");
4311 ret = -ENOMEM;
4312 goto exit;
4313 }
4314
4315 if (nla_put_u32(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_WAKE_STATS_TOTAL_CMD_EVENT_WAKE,
4316 wake_reason_count.total_cmd_event_wake)) {
4317 SLSI_ERR_NODEV("Failed nla_put\n");
4318 slsi_kfree_skb(skb);
4319 ret = -EINVAL;
4320 goto exit;
4321 }
4322 if (nla_put(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_WAKE_STATS_CMD_EVENT_WAKE_CNT_PTR, 0,
4323 wake_reason_count.cmd_event_wake_cnt)) {
4324 SLSI_ERR_NODEV("Failed nla_put\n");
4325 slsi_kfree_skb(skb);
4326 ret = -EINVAL;
4327 goto exit;
4328 }
4329 if (nla_put_u32(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_WAKE_STATS_TOTAL_DRIVER_FW_LOCAL_WAKE,
4330 wake_reason_count.total_driver_fw_local_wake)) {
4331 SLSI_ERR_NODEV("Failed nla_put\n");
4332 slsi_kfree_skb(skb);
4333 ret = -EINVAL;
4334 goto exit;
4335 }
4336 if (nla_put(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_WAKE_STATS_DRIVER_FW_LOCAL_WAKE_CNT_PTR, 0,
4337 wake_reason_count.driver_fw_local_wake_cnt)) {
4338 SLSI_ERR_NODEV("Failed nla_put\n");
4339 slsi_kfree_skb(skb);
4340 ret = -EINVAL;
4341 goto exit;
4342 }
4343 if (nla_put_u32(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_WAKE_STATS_TOTAL_RX_DATA_WAKE,
4344 wake_reason_count.total_rx_data_wake) ||
4345 nla_put_u32(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_WAKE_STATS_RX_UNICAST_CNT,
4346 wake_reason_count.rx_wake_details.rx_unicast_cnt) ||
4347 nla_put_u32(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_WAKE_STATS_RX_MULTICAST_CNT,
4348 wake_reason_count.rx_wake_details.rx_multicast_cnt) ||
4349 nla_put_u32(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_WAKE_STATS_RX_BROADCAST_CNT,
4350 wake_reason_count.rx_wake_details.rx_broadcast_cnt) ||
4351 nla_put_u32(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_WAKE_STATS_ICMP_PKT,
4352 wake_reason_count.rx_wake_pkt_classification_info.icmp_pkt) ||
4353 nla_put_u32(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_WAKE_STATS_ICMP6_PKT,
4354 wake_reason_count.rx_wake_pkt_classification_info.icmp6_pkt) ||
4355 nla_put_u32(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_WAKE_STATS_ICMP6_RA,
4356 wake_reason_count.rx_wake_pkt_classification_info.icmp6_ra) ||
4357 nla_put_u32(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_WAKE_STATS_ICMP6_NA,
4358 wake_reason_count.rx_wake_pkt_classification_info.icmp6_na) ||
4359 nla_put_u32(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_WAKE_STATS_ICMP6_NS,
4360 wake_reason_count.rx_wake_pkt_classification_info.icmp6_ns) ||
4361 nla_put_u32(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_WAKE_STATS_ICMP4_RX_MULTICAST_CNT,
4362 wake_reason_count.rx_multicast_wake_pkt_info.ipv4_rx_multicast_addr_cnt) ||
4363 nla_put_u32(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_WAKE_STATS_ICMP6_RX_MULTICAST_CNT,
4364 wake_reason_count.rx_multicast_wake_pkt_info.ipv6_rx_multicast_addr_cnt) ||
4365 nla_put_u32(skb, SLSI_ENHANCED_LOGGING_ATTRIBUTE_WAKE_STATS_OTHER_RX_MULTICAST_CNT,
4366 wake_reason_count.rx_multicast_wake_pkt_info.other_rx_multicast_addr_cnt)) {
4367 SLSI_ERR_NODEV("Failed nla_put\n");
4368 slsi_kfree_skb(skb);
4369 ret = -EINVAL;
4370 goto exit;
4371 }
4372 ret = cfg80211_vendor_cmd_reply(skb);
4373
4374 if (ret)
4375 SLSI_ERR(sdev, "Vendor Command reply failed ret:%d\n", ret);
4376 exit:
4377 SLSI_MUTEX_UNLOCK(sdev->logger_mutex);
4378 return ret;
4379 }
4380
4381 #endif /* CONFIG_SCSC_WLAN_ENHANCED_LOGGING */
4382
4383 static int slsi_acs_validate_width_hw_mode(struct slsi_acs_request *request)
4384 {
4385 if (request->hw_mode != SLSI_ACS_MODE_IEEE80211A && request->hw_mode != SLSI_ACS_MODE_IEEE80211B &&
4386 request->hw_mode != SLSI_ACS_MODE_IEEE80211G)
4387 return -EINVAL;
4388 if (request->ch_width != 20 && request->ch_width != 40 && request->ch_width != 80)
4389 return -EINVAL;
4390 return 0;
4391 }
4392
4393 static int slsi_acs_init(struct wiphy *wiphy,
4394 struct wireless_dev *wdev, const void *data, int len)
4395 {
4396 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
4397 struct net_device *dev = wdev->netdev;
4398 struct netdev_vif *ndev_vif;
4399 struct slsi_acs_request *request;
4400 int temp;
4401 int type;
4402 const struct nlattr *attr;
4403 int r = 0;
4404 u32 *freq_list = NULL;
4405 int freq_list_len = 0;
4406
4407 SLSI_INFO(sdev, "SUBCMD_ACS_INIT Received\n");
4408 if (slsi_is_test_mode_enabled()) {
4409 SLSI_ERR(sdev, "Not supported in WlanLite mode\n");
4410 return -EOPNOTSUPP;
4411 }
4412 if (wdev->iftype != NL80211_IFTYPE_AP) {
4413 SLSI_ERR(sdev, "Invalid iftype: %d\n", wdev->iftype);
4414 return -EINVAL;
4415 }
4416 if (!dev) {
4417 SLSI_ERR(sdev, "Dev not found!\n");
4418 return -ENODEV;
4419 }
4420 request = kcalloc(1, sizeof(*request), GFP_KERNEL);
4421 if (!request) {
4422 SLSI_ERR(sdev, "No memory for request!");
4423 return -ENOMEM;
4424 }
4425 ndev_vif = netdev_priv(dev);
4426
4427 SLSI_MUTEX_LOCK(ndev_vif->scan_mutex);
4428 nla_for_each_attr(attr, data, len, temp) {
4429 if (!attr) {
4430 kfree(request);
4431 r = -EINVAL;
4432 goto exit;
4433 }
4434
4435 type = nla_type(attr);
4436
4437 switch (type) {
4438 case SLSI_ACS_ATTR_HW_MODE:
4439 {
4440 if (nla_len(attr) != (SLSI_NL_ATTRIBUTE_U8_LEN - NLA_HDRLEN)) {
4441 kfree(request);
4442 r = -EINVAL;
4443 goto exit;
4444 }
4445 request->hw_mode = nla_get_u8(attr);
4446 SLSI_INFO(sdev, "ACS hw mode: %d\n", request->hw_mode);
4447 break;
4448 }
4449 case SLSI_ACS_ATTR_CHWIDTH:
4450 {
4451 if (nla_len(attr) != (SLSI_NL_ATTRIBUTE_U16_LEN - NLA_HDRLEN)) {
4452 kfree(request);
4453 r = -EINVAL;
4454 goto exit;
4455 }
4456 request->ch_width = nla_get_u16(attr);
4457 SLSI_INFO(sdev, "ACS ch_width: %d\n", request->ch_width);
4458 break;
4459 }
4460 case SLSI_ACS_ATTR_FREQ_LIST:
4461 {
4462 if (freq_list) /* This check is to avoid Prevent Issue */
4463 break;
4464
4465 freq_list = kmalloc(nla_len(attr), GFP_KERNEL);
4466 if (!freq_list) {
4467 SLSI_ERR(sdev, "No memory for frequency list!");
4468 kfree(request);
4469 SLSI_MUTEX_UNLOCK(ndev_vif->scan_mutex);
4470 return -ENOMEM;
4471 }
4472 memcpy(freq_list, nla_data(attr), nla_len(attr));
4473 freq_list_len = nla_len(attr) / sizeof(u32);
4474 SLSI_INFO(sdev, "ACS freq_list_len: %d\n", freq_list_len);
4475 break;
4476 }
4477 default:
4478 if (type > SLSI_ACS_ATTR_MAX)
4479 SLSI_ERR(sdev, "Invalid type : %d\n", type);
4480 break;
4481 }
4482 }
4483
4484 r = slsi_acs_validate_width_hw_mode(request);
4485 if (r == 0 && freq_list_len) {
4486 struct ieee80211_channel *channels[freq_list_len];
4487 struct slsi_acs_chan_info ch_info[MAX_CHAN_VALUE_ACS];
4488 struct slsi_acs_selected_channels acs_selected_channels;
4489 int i = 0, num_channels = 0;
4490 int idx;
4491 u32 chan_flags = (IEEE80211_CHAN_INDOOR_ONLY | IEEE80211_CHAN_RADAR |
4492 IEEE80211_CHAN_DISABLED |
4493 #if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 10, 13)
4494 IEEE80211_CHAN_PASSIVE_SCAN
4495 #else
4496 IEEE80211_CHAN_NO_IR
4497 #endif
4498 );
4499
4500 memset(channels, 0, sizeof(channels));
4501 memset(&ch_info, 0, sizeof(ch_info));
4502 for (i = 0; i < freq_list_len; i++) {
4503 channels[num_channels] = ieee80211_get_channel(wiphy, freq_list[i]);
4504 if (!channels[num_channels]) {
4505 SLSI_INFO(sdev, "Ignore invalid freq:%d in freq list\n", freq_list[i]);
4506 } else if (channels[num_channels]->flags & chan_flags) {
4507 SLSI_INFO(sdev, "Skip invalid channel:%d for ACS\n", channels[num_channels]->hw_value);
4508 } else {
4509 idx = slsi_find_chan_idx(channels[num_channels]->hw_value, request->hw_mode);
4510 ch_info[idx].chan = channels[num_channels]->hw_value;
4511 num_channels++;
4512 }
4513 }
4514
4515 if (num_channels == 1) {
4516 memset(&acs_selected_channels, 0, sizeof(acs_selected_channels));
4517 acs_selected_channels.ch_width = 20;
4518 acs_selected_channels.hw_mode = request->hw_mode;
4519 acs_selected_channels.pri_channel = channels[0]->hw_value;
4520 r = slsi_send_acs_event(sdev, acs_selected_channels);
4521 sdev->acs_channel_switched = true;
4522 kfree(freq_list);
4523 kfree(request);
4524 SLSI_MUTEX_UNLOCK(ndev_vif->scan_mutex);
4525 return r;
4526 }
4527
4528 if (request->hw_mode == SLSI_ACS_MODE_IEEE80211A)
4529 request->ch_list_len = 25;
4530 else
4531 request->ch_list_len = 14;
4532 memcpy(&request->acs_chan_info[0], &ch_info[0], sizeof(ch_info));
4533 ndev_vif->scan[SLSI_SCAN_HW_ID].acs_request = request;
4534 ndev_vif->scan[SLSI_SCAN_HW_ID].is_blocking_scan = false;
4535 r = slsi_mlme_add_scan(sdev,
4536 dev,
4537 FAPI_SCANTYPE_AP_AUTO_CHANNEL_SELECTION,
4538 FAPI_REPORTMODE_REAL_TIME,
4539 0, /* n_ssids */
4540 NULL, /* ssids */
4541 num_channels,
4542 channels,
4543 NULL,
4544 NULL, /* ie */
4545 0, /* ie_len */
4546 ndev_vif->scan[SLSI_SCAN_HW_ID].is_blocking_scan);
4547 } else {
4548 SLSI_ERR(sdev, "Invalid freq_list len:%d or ch_width:%d or hw_mode:%d\n", freq_list_len,
4549 request->ch_width, request->hw_mode);
4550 r = -EINVAL;
4551 kfree(request);
4552 }
4553 exit:
4554 kfree(freq_list);
4555 SLSI_MUTEX_UNLOCK(ndev_vif->scan_mutex);
4556 return r;
4557 }
4558
4559 static int slsi_configure_latency_mode(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int len)
4560 {
4561 struct slsi_dev *sdev = SDEV_FROM_WIPHY(wiphy);
4562 struct net_device *dev = wdev->netdev;
4563 int temp = 0;
4564 int type = 0;
4565 const struct nlattr *attr;
4566 int ret = 0;
4567 int low_latency_mode = 0;
4568
4569 if (!dev) {
4570 SLSI_ERR(sdev, "dev is NULL!!\n");
4571 return -EINVAL;
4572 }
4573
4574 nla_for_each_attr(attr, data, len, temp) {
4575 type = nla_type(attr);
4576 switch (type) {
4577 case SLSI_NL_ATTRIBUTE_LATENCY_MODE:
4578 low_latency_mode = nla_get_u8(attr);
4579 break;
4580 default:
4581 SLSI_ERR_NODEV("Unknown attribute: %d\n", type);
4582 ret = -EINVAL;
4583 goto exit;
4584 }
4585 }
4586
4587 ret = slsi_set_latency_mode(dev, low_latency_mode, len);
4588 if (ret)
4589 SLSI_ERR(sdev, "Error in setting low latency mode ret:%d\n", ret);
4590 exit:
4591 return ret;
4592 }
4593
4594 static const struct nl80211_vendor_cmd_info slsi_vendor_events[] = {
4595 /**********Deprecated now due to fapi updates.Do not remove*/
4596 { OUI_GOOGLE, SLSI_NL80211_SIGNIFICANT_CHANGE_EVENT },
4597 { OUI_GOOGLE, SLSI_NL80211_HOTLIST_AP_FOUND_EVENT },
4598 /******************************************/
4599 { OUI_GOOGLE, SLSI_NL80211_SCAN_RESULTS_AVAILABLE_EVENT },
4600 { OUI_GOOGLE, SLSI_NL80211_FULL_SCAN_RESULT_EVENT },
4601 { OUI_GOOGLE, SLSI_NL80211_SCAN_EVENT },
4602 /**********Deprecated now due to fapi updates.Do not remove*/
4603 { OUI_GOOGLE, SLSI_NL80211_HOTLIST_AP_LOST_EVENT },
4604 /******************************************/
4605 #ifdef CONFIG_SCSC_WLAN_KEY_MGMT_OFFLOAD
4606 { OUI_SAMSUNG, SLSI_NL80211_VENDOR_SUBCMD_KEY_MGMT_ROAM_AUTH },
4607 #endif
4608 { OUI_SAMSUNG, SLSI_NL80211_VENDOR_HANGED_EVENT },
4609 { OUI_GOOGLE, SLSI_NL80211_EPNO_EVENT },
4610 { OUI_GOOGLE, SLSI_NL80211_HOTSPOT_MATCH },
4611 { OUI_GOOGLE, SLSI_NL80211_RSSI_REPORT_EVENT},
4612 #ifdef CONFIG_SCSC_WLAN_ENHANCED_LOGGING
4613 { OUI_GOOGLE, SLSI_NL80211_LOGGER_RING_EVENT},
4614 { OUI_GOOGLE, SLSI_NL80211_LOGGER_FW_DUMP_EVENT},
4615 #endif
4616 { OUI_GOOGLE, SLSI_NL80211_NAN_RESPONSE_EVENT},
4617 { OUI_GOOGLE, SLSI_NL80211_NAN_PUBLISH_TERMINATED_EVENT},
4618 { OUI_GOOGLE, SLSI_NL80211_NAN_MATCH_EVENT},
4619 { OUI_GOOGLE, SLSI_NL80211_NAN_MATCH_EXPIRED_EVENT},
4620 { OUI_GOOGLE, SLSI_NL80211_NAN_SUBSCRIBE_TERMINATED_EVENT},
4621 { OUI_GOOGLE, SLSI_NL80211_NAN_FOLLOWUP_EVENT},
4622 { OUI_GOOGLE, SLSI_NL80211_NAN_DISCOVERY_ENGINE_EVENT},
4623 { OUI_GOOGLE, SLSI_NL80211_NAN_DISABLED_EVENT},
4624 { OUI_GOOGLE, SLSI_NL80211_RTT_RESULT_EVENT},
4625 { OUI_GOOGLE, SLSI_NL80211_RTT_COMPLETE_EVENT},
4626 { OUI_SAMSUNG, SLSI_NL80211_VENDOR_ACS_EVENT},
4627 { OUI_SAMSUNG, SLSI_NL80211_VENDOR_FORWARD_BEACON},
4628 { OUI_SAMSUNG, SLSI_NL80211_VENDOR_FORWARD_BEACON_ABORT},
4629 { OUI_GOOGLE, SLSI_NL80211_NAN_TRANSMIT_FOLLOWUP_STATUS}
4630 };
4631
4632 static const struct wiphy_vendor_command slsi_vendor_cmd[] = {
4633 {
4634 {
4635 .vendor_id = OUI_GOOGLE,
4636 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_GET_CAPABILITIES
4637 },
4638 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4639 .doit = slsi_gscan_get_capabilities
4640 },
4641 {
4642 {
4643 .vendor_id = OUI_GOOGLE,
4644 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_GET_VALID_CHANNELS
4645 },
4646 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4647 .doit = slsi_gscan_get_valid_channel
4648 },
4649 {
4650 {
4651 .vendor_id = OUI_GOOGLE,
4652 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_ADD_GSCAN
4653 },
4654 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4655 .doit = slsi_gscan_add
4656 },
4657 {
4658 {
4659 .vendor_id = OUI_GOOGLE,
4660 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_DEL_GSCAN
4661 },
4662 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4663 .doit = slsi_gscan_del
4664 },
4665 {
4666 {
4667 .vendor_id = OUI_GOOGLE,
4668 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_GET_SCAN_RESULTS
4669 },
4670 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4671 .doit = slsi_gscan_get_scan_results
4672 },
4673 {
4674 {
4675 .vendor_id = OUI_GOOGLE,
4676 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_SET_GSCAN_OUI
4677 },
4678 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4679 .doit = slsi_gscan_set_oui
4680 },
4681 #ifdef CONFIG_SCSC_WLAN_KEY_MGMT_OFFLOAD
4682 {
4683 {
4684 .vendor_id = OUI_SAMSUNG,
4685 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_KEY_MGMT_SET_KEY
4686 },
4687 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4688 .doit = slsi_key_mgmt_set_pmk
4689 },
4690 #endif
4691 {
4692 {
4693 .vendor_id = OUI_GOOGLE,
4694 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_SET_BSSID_BLACKLIST
4695 },
4696 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4697 .doit = slsi_set_bssid_blacklist
4698 },
4699 {
4700 {
4701 .vendor_id = OUI_GOOGLE,
4702 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_START_KEEP_ALIVE_OFFLOAD
4703 },
4704 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4705 .doit = slsi_start_keepalive_offload
4706 },
4707 {
4708 {
4709 .vendor_id = OUI_GOOGLE,
4710 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_STOP_KEEP_ALIVE_OFFLOAD
4711 },
4712 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4713 .doit = slsi_stop_keepalive_offload
4714 },
4715 {
4716 {
4717 .vendor_id = OUI_GOOGLE,
4718 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_SET_EPNO_LIST
4719 },
4720 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4721 .doit = slsi_set_epno_ssid
4722 },
4723 {
4724 {
4725 .vendor_id = OUI_GOOGLE,
4726 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_SET_HS_LIST
4727 },
4728 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4729 .doit = slsi_set_hs_params
4730 },
4731 {
4732 {
4733 .vendor_id = OUI_GOOGLE,
4734 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_RESET_HS_LIST
4735 },
4736 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4737 .doit = slsi_reset_hs_params
4738 },
4739 {
4740 {
4741 .vendor_id = OUI_GOOGLE,
4742 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_SET_RSSI_MONITOR
4743 },
4744 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4745 .doit = slsi_set_rssi_monitor
4746 },
4747 {
4748 {
4749 .vendor_id = OUI_GOOGLE,
4750 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_LSTATS_SUBCMD_SET_STATS
4751 },
4752 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4753 .doit = slsi_lls_set_stats
4754 },
4755 {
4756 {
4757 .vendor_id = OUI_GOOGLE,
4758 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_LSTATS_SUBCMD_GET_STATS
4759 },
4760 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4761 .doit = slsi_lls_get_stats
4762 },
4763 {
4764 {
4765 .vendor_id = OUI_GOOGLE,
4766 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_LSTATS_SUBCMD_CLEAR_STATS
4767 },
4768 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4769 .doit = slsi_lls_clear_stats
4770 },
4771 {
4772 {
4773 .vendor_id = OUI_GOOGLE,
4774 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_GET_FEATURE_SET
4775 },
4776 .flags = 0,
4777 .doit = slsi_get_feature_set
4778 },
4779 {
4780 {
4781 .vendor_id = OUI_GOOGLE,
4782 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_SET_COUNTRY_CODE
4783 },
4784 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4785 .doit = slsi_set_country_code
4786 },
4787 {
4788 {
4789 .vendor_id = OUI_GOOGLE,
4790 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_CONFIGURE_ND_OFFLOAD
4791 },
4792 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4793 .doit = slsi_configure_nd_offload
4794 },
4795 #ifdef CONFIG_SCSC_WLAN_ENHANCED_LOGGING
4796 {
4797 {
4798 .vendor_id = OUI_GOOGLE,
4799 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_START_LOGGING
4800 },
4801 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4802 .doit = slsi_start_logging
4803 },
4804 {
4805 {
4806 .vendor_id = OUI_GOOGLE,
4807 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_RESET_LOGGING
4808 },
4809 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4810 .doit = slsi_reset_logging
4811 },
4812 {
4813 {
4814 .vendor_id = OUI_GOOGLE,
4815 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_TRIGGER_FW_MEM_DUMP
4816 },
4817 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4818 .doit = slsi_trigger_fw_mem_dump
4819 },
4820 {
4821 {
4822 .vendor_id = OUI_GOOGLE,
4823 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_GET_FW_MEM_DUMP
4824 },
4825 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4826 .doit = slsi_get_fw_mem_dump
4827 },
4828 {
4829 {
4830 .vendor_id = OUI_GOOGLE,
4831 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_TRIGGER_DRIVER_MEM_DUMP
4832 },
4833 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4834 .doit = slsi_trigger_driver_mem_dump
4835 },
4836 {
4837 {
4838 .vendor_id = OUI_GOOGLE,
4839 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_GET_DRIVER_MEM_DUMP
4840 },
4841 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4842 .doit = slsi_get_driver_mem_dump
4843 },
4844 {
4845 {
4846 .vendor_id = OUI_GOOGLE,
4847 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_GET_VERSION
4848 },
4849 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4850 .doit = slsi_get_version
4851 },
4852 {
4853 {
4854 .vendor_id = OUI_GOOGLE,
4855 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_GET_RING_STATUS
4856 },
4857 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4858 .doit = slsi_get_ring_buffers_status
4859 },
4860 {
4861 {
4862 .vendor_id = OUI_GOOGLE,
4863 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_GET_RING_DATA
4864 },
4865 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4866 .doit = slsi_get_ring_data
4867 },
4868 {
4869 {
4870 .vendor_id = OUI_GOOGLE,
4871 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_GET_FEATURE
4872 },
4873 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4874 .doit = slsi_get_logger_supported_feature_set
4875 },
4876 {
4877 {
4878 .vendor_id = OUI_GOOGLE,
4879 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_START_PKT_FATE_MONITORING
4880 },
4881 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4882 .doit = slsi_start_pkt_fate_monitoring
4883 },
4884 {
4885 {
4886 .vendor_id = OUI_GOOGLE,
4887 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_GET_TX_PKT_FATES
4888 },
4889 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4890 .doit = slsi_get_tx_pkt_fates
4891 },
4892 {
4893 {
4894 .vendor_id = OUI_GOOGLE,
4895 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_GET_RX_PKT_FATES
4896 },
4897 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4898 .doit = slsi_get_rx_pkt_fates
4899 },
4900 {
4901 {
4902 .vendor_id = OUI_GOOGLE,
4903 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_GET_WAKE_REASON_STATS
4904 },
4905 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4906 .doit = slsi_get_wake_reason_stats
4907 },
4908 #endif /* CONFIG_SCSC_WLAN_ENHANCED_LOGGING */
4909 #ifdef CONFIG_SCSC_WIFI_NAN_ENABLE
4910 {
4911 {
4912 .vendor_id = OUI_GOOGLE,
4913 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_NAN_ENABLE
4914 },
4915 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4916 .doit = slsi_nan_enable
4917 },
4918 {
4919 {
4920 .vendor_id = OUI_GOOGLE,
4921 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_NAN_DISABLE
4922 },
4923 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4924 .doit = slsi_nan_disable
4925 },
4926 {
4927 {
4928 .vendor_id = OUI_GOOGLE,
4929 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_NAN_PUBLISH
4930 },
4931 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4932 .doit = slsi_nan_publish
4933 },
4934 {
4935 {
4936 .vendor_id = OUI_GOOGLE,
4937 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_NAN_PUBLISHCANCEL
4938 },
4939 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4940 .doit = slsi_nan_publish_cancel
4941 },
4942 {
4943 {
4944 .vendor_id = OUI_GOOGLE,
4945 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_NAN_SUBSCRIBE
4946 },
4947 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4948 .doit = slsi_nan_subscribe
4949 },
4950 {
4951 {
4952 .vendor_id = OUI_GOOGLE,
4953 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_NAN_SUBSCRIBECANCEL
4954 },
4955 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4956 .doit = slsi_nan_subscribe_cancel
4957 },
4958 {
4959 {
4960 .vendor_id = OUI_GOOGLE,
4961 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_NAN_TXFOLLOWUP
4962 },
4963 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4964 .doit = slsi_nan_transmit_followup
4965 },
4966 {
4967 {
4968 .vendor_id = OUI_GOOGLE,
4969 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_NAN_CONFIG
4970 },
4971 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4972 .doit = slsi_nan_set_config
4973 },
4974 {
4975 {
4976 .vendor_id = OUI_GOOGLE,
4977 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_NAN_CAPABILITIES
4978 },
4979 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4980 .doit = slsi_nan_get_capabilities
4981 },
4982 #endif
4983 {
4984 {
4985 .vendor_id = OUI_GOOGLE,
4986 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_GET_ROAMING_CAPABILITIES
4987 },
4988 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4989 .doit = slsi_get_roaming_capabilities
4990 },
4991 {
4992 {
4993 .vendor_id = OUI_GOOGLE,
4994 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_SET_ROAMING_STATE
4995 },
4996 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
4997 .doit = slsi_set_roaming_state
4998 },
4999 {
5000 {
5001 .vendor_id = OUI_GOOGLE,
5002 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_RTT_GET_CAPABILITIES
5003 },
5004 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
5005 .doit = slsi_rtt_get_capabilities
5006 },
5007 {
5008 {
5009 .vendor_id = OUI_GOOGLE,
5010 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_RTT_RANGE_START
5011 },
5012 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
5013 .doit = slsi_rtt_set_config
5014 },
5015 {
5016 {
5017 .vendor_id = OUI_GOOGLE,
5018 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_RTT_RANGE_CANCEL
5019 },
5020 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
5021 .doit = slsi_rtt_cancel_config
5022 },
5023 {
5024 {
5025 .vendor_id = OUI_SAMSUNG,
5026 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_ACS_INIT
5027 },
5028 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
5029 .doit = slsi_acs_init
5030 },
5031 {
5032 {
5033 .vendor_id = OUI_GOOGLE,
5034 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_APF_GET_CAPABILITIES
5035 },
5036 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
5037 .doit = slsi_apf_get_capabilities
5038 },
5039 {
5040 {
5041 .vendor_id = OUI_GOOGLE,
5042 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_APF_SET_FILTER
5043 },
5044 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
5045 .doit = slsi_apf_set_filter
5046 },
5047 {
5048 {
5049 .vendor_id = OUI_GOOGLE,
5050 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_APF_READ_FILTER
5051 },
5052 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
5053 .doit = slsi_apf_read_filter
5054 },
5055 {
5056 {
5057 .vendor_id = OUI_GOOGLE,
5058 .subcmd = SLSI_NL80211_VENDOR_SUBCMD_SET_LATENCY_MODE
5059 },
5060 .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV,
5061 .doit = slsi_configure_latency_mode
5062 }
5063 };
5064
5065 void slsi_nl80211_vendor_deinit(struct slsi_dev *sdev)
5066 {
5067 SLSI_DBG2(sdev, SLSI_GSCAN, "De-initialise vendor command and events\n");
5068 sdev->wiphy->vendor_commands = NULL;
5069 sdev->wiphy->n_vendor_commands = 0;
5070 sdev->wiphy->vendor_events = NULL;
5071 sdev->wiphy->n_vendor_events = 0;
5072
5073 SLSI_DBG2(sdev, SLSI_GSCAN, "Gscan cleanup\n");
5074 slsi_gscan_flush_scan_results(sdev);
5075
5076 }
5077
5078 void slsi_nl80211_vendor_init(struct slsi_dev *sdev)
5079 {
5080 int i;
5081
5082 SLSI_DBG2(sdev, SLSI_GSCAN, "Init vendor command and events\n");
5083
5084 sdev->wiphy->vendor_commands = slsi_vendor_cmd;
5085 sdev->wiphy->n_vendor_commands = ARRAY_SIZE(slsi_vendor_cmd);
5086 sdev->wiphy->vendor_events = slsi_vendor_events;
5087 sdev->wiphy->n_vendor_events = ARRAY_SIZE(slsi_vendor_events);
5088
5089 for (i = 0; i < SLSI_GSCAN_MAX_BUCKETS; i++)
5090 sdev->bucket[i].scan_id = (SLSI_GSCAN_SCAN_ID_START + i);
5091
5092 for (i = 0; i < SLSI_GSCAN_HASH_TABLE_SIZE; i++)
5093 sdev->gscan_hash_table[i] = NULL;
5094
5095 INIT_LIST_HEAD(&sdev->hotlist_results);
5096 }