1 /*****************************************************************************
3 * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved
5 ****************************************************************************/
6 #include <linux/version.h>
7 #include <net/cfg80211.h>
9 #include <linux/etherdevice.h>
11 #include "cfg80211_ops.h"
18 #include "nl80211_vendor.h"
20 #ifdef CONFIG_SCSC_WLAN_ENHANCED_LOGGING
21 #include "scsc_wifilogger.h"
22 #include "scsc_wifilogger_rings.h"
23 #include "scsc_wifilogger_types.h"
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
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
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
54 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
56 #ifdef CONFIG_SCSC_WLAN_ENHANCED_LOGGING
57 static int mem_dump_buffer_size
;
58 static char *mem_dump_buffer
;
60 #ifdef CONFIG_SCSC_WLAN_DEBUG
61 char *slsi_print_event_name(int 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";
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";
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";
111 return "UNKNOWN_EVENT";
116 int slsi_vendor_event(struct slsi_dev
*sdev
, int event_id
, const void *data
, int len
)
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
);
125 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
126 skb
= cfg80211_vendor_event_alloc(sdev
->wiphy
, NULL
, len
, event_id
, GFP_KERNEL
);
128 skb
= cfg80211_vendor_event_alloc(sdev
->wiphy
, len
, event_id
, GFP_KERNEL
);
131 SLSI_ERR_NODEV("Failed to allocate skb for vendor event: %d\n", event_id
);
135 nla_put_nohdr(skb
, len
, data
);
137 cfg80211_vendor_event(skb
, GFP_KERNEL
);
142 static int slsi_vendor_cmd_reply(struct wiphy
*wiphy
, const void *data
, int len
)
146 skb
= cfg80211_vendor_cmd_alloc_reply_skb(wiphy
, len
);
148 SLSI_ERR_NODEV("Failed to allocate skb\n");
152 nla_put_nohdr(skb
, len
, data
);
154 return cfg80211_vendor_cmd_reply(skb
);
157 static struct net_device
*slsi_gscan_get_netdev(struct slsi_dev
*sdev
)
159 return slsi_get_netdev(sdev
, SLSI_NET_INDEX_WLAN
);
162 static struct netdev_vif
*slsi_gscan_get_vif(struct slsi_dev
*sdev
)
164 struct net_device
*dev
;
166 dev
= slsi_gscan_get_netdev(sdev
);
168 SLSI_WARN_NODEV("Dev is NULL\n");
172 return netdev_priv(dev
);
175 #ifdef CONFIG_SCSC_WLAN_DEBUG
176 static void slsi_gscan_add_dump_params(struct slsi_nl_gscan_param
*nl_gscan_param
)
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
);
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
);
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
);
200 void slsi_gscan_scan_res_dump(struct slsi_gscan_result
*scan_data
)
202 struct slsi_nl_scan_result_param
*nl_scan_res
= &scan_data
->nl_scan_res
;
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
);
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");
216 static int slsi_gscan_get_capabilities(struct wiphy
*wiphy
,
217 struct wireless_dev
*wdev
, const void *data
, int len
)
219 struct slsi_nl_gscan_capabilities nl_cap
;
221 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
223 SLSI_DBG1_NODEV(SLSI_GSCAN
, "SUBCMD_GET_GSCAN_CAPABILITIES\n");
225 memset(&nl_cap
, 0, sizeof(struct slsi_nl_gscan_capabilities
));
227 ret
= slsi_mib_get_gscan_cap(sdev
, &nl_cap
);
229 SLSI_ERR(sdev
, "Failed to read mib\n");
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
;
237 ret
= slsi_vendor_cmd_reply(wiphy
, &nl_cap
, sizeof(struct slsi_nl_gscan_capabilities
));
239 SLSI_ERR_NODEV("gscan_get_capabilities vendor cmd reply failed (err = %d)\n", ret
);
244 static u32
slsi_gscan_put_channels(struct ieee80211_supported_band
*chan_data
, bool no_dfs
, bool only_dfs
, u32
*buf
)
250 if (chan_data
== NULL
) {
251 SLSI_DBG3_NODEV(SLSI_GSCAN
, "Band not supported\n");
254 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)
255 chan_flags
= (IEEE80211_CHAN_PASSIVE_SCAN
| IEEE80211_CHAN_NO_OFDM
| IEEE80211_CHAN_RADAR
);
257 chan_flags
= (IEEE80211_CHAN_NO_IR
| IEEE80211_CHAN_NO_OFDM
| IEEE80211_CHAN_RADAR
);
260 for (i
= 0; i
< chan_data
->n_channels
; i
++) {
261 if (chan_data
->channels
[i
].flags
& IEEE80211_CHAN_DISABLED
)
264 if (chan_data
->channels
[i
].flags
& chan_flags
)
265 buf
[chan_count
++] = chan_data
->channels
[i
].center_freq
;
268 if (no_dfs
&& (chan_data
->channels
[i
].flags
& chan_flags
))
270 buf
[chan_count
++] = chan_data
->channels
[i
].center_freq
;
275 static int slsi_gscan_get_valid_channel(struct wiphy
*wiphy
,
276 struct wireless_dev
*wdev
, const void *data
, int len
)
278 int ret
= 0, type
, band
;
279 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
281 u32 chan_count
= 0, mem_len
= 0;
282 struct sk_buff
*reply
;
284 if (len
< SLSI_NL_VENDOR_DATA_OVERHEAD
|| !data
)
287 type
= nla_type(data
);
289 if (type
== GSCAN_ATTRIBUTE_BAND
) {
290 if (nla_len((struct nlattr
*)data
) != (SLSI_NL_ATTRIBUTE_U32_LEN
- NLA_HDRLEN
))
292 band
= nla_get_u32(data
);
298 SLSI_WARN(sdev
, "NO Bands. return 0 channel\n");
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
);
307 if (wiphy
->bands
[NL80211_BAND_5GHZ
])
308 mem_len
+= wiphy
->bands
[NL80211_BAND_5GHZ
]->n_channels
* sizeof(u32
);
315 chan_list
= kmalloc(mem_len
, GFP_KERNEL
);
316 if (chan_list
== NULL
) {
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
);
324 goto exit_with_chan_list
;
328 chan_count
= slsi_gscan_put_channels(wiphy
->bands
[NL80211_BAND_2GHZ
], false, false, chan_list
);
331 chan_count
= slsi_gscan_put_channels(wiphy
->bands
[NL80211_BAND_5GHZ
], true, false, chan_list
);
333 case WIFI_BAND_A_DFS
:
334 chan_count
= slsi_gscan_put_channels(wiphy
->bands
[NL80211_BAND_5GHZ
], false, true, chan_list
);
336 case WIFI_BAND_A_WITH_DFS
:
337 chan_count
= slsi_gscan_put_channels(wiphy
->bands
[NL80211_BAND_5GHZ
], false, false, chan_list
);
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
);
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
);
349 SLSI_WARN(sdev
, "Invalid Band %d\n", band
);
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
);
354 ret
= cfg80211_vendor_cmd_reply(reply
);
357 SLSI_ERR(sdev
, "FAILED to reply GET_VALID_CHANNELS\n");
362 SLSI_MUTEX_UNLOCK(sdev
->netdev_add_remove_mutex
);
366 struct slsi_gscan_result
*slsi_prepare_scan_result(struct sk_buff
*skb
, u16 anqp_length
, int hs2_id
)
368 struct ieee80211_mgmt
*mgmt
= fapi_get_mgmt(skb
);
369 struct slsi_gscan_result
*scan_res
;
376 ie
= &mgmt
->u
.beacon
.variable
[0];
377 ie_len
= fapi_get_datalen(skb
) - (ie
- (u8
*)mgmt
) - anqp_length
;
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
);
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");
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;
393 get_monotonic_boottime(&ts
);
394 scan_res
->nl_scan_res
.ts
= (u64
)TIMESPEC_TO_US(ts
);
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';
401 scan_res
->nl_scan_res
.ssid
[0] = '\0';
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
));
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);
420 #ifdef CONFIG_SCSC_WLAN_DEBUG
421 slsi_gscan_scan_res_dump(scan_res
);
427 static void slsi_gscan_hash_add(struct slsi_dev
*sdev
, struct slsi_gscan_result
*scan_res
)
429 u8 key
= SLSI_GSCAN_GET_HASH_KEY(scan_res
->nl_scan_res
.bssid
[5]);
430 struct netdev_vif
*ndev_vif
;
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");
436 scan_res
->hnext
= sdev
->gscan_hash_table
[key
];
437 sdev
->gscan_hash_table
[key
] = scan_res
;
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
++;
444 static struct slsi_gscan_result
*slsi_gscan_hash_get(struct slsi_dev
*sdev
, u8
*mac
)
446 struct slsi_gscan_result
*temp
;
447 struct netdev_vif
*ndev_vif
;
448 u8 key
= SLSI_GSCAN_GET_HASH_KEY(mac
[5]);
450 ndev_vif
= slsi_gscan_get_vif(sdev
);
452 if (!SLSI_MUTEX_IS_LOCKED(ndev_vif
->scan_mutex
))
453 SLSI_WARN_NODEV("ndev_vif->scan_mutex is not locked\n");
455 temp
= sdev
->gscan_hash_table
[key
];
456 while (temp
!= NULL
) {
457 if (memcmp(temp
->nl_scan_res
.bssid
, mac
, ETH_ALEN
) == 0)
465 void slsi_gscan_hash_remove(struct slsi_dev
*sdev
, u8
*mac
)
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
;
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");
477 if (sdev
->gscan_hash_table
[key
] == NULL
)
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
;
484 prev
= sdev
->gscan_hash_table
[key
];
487 while (curr
!= NULL
) {
488 if (memcmp(curr
->nl_scan_res
.bssid
, mac
, ETH_ALEN
) == 0) {
490 prev
->hnext
= curr
->hnext
;
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
--;
505 if (sdev
->num_gscan_results
< 0)
506 SLSI_ERR(sdev
, "Wrong num_gscan_results: %d\n", sdev
->num_gscan_results
);
509 int slsi_check_scan_result(struct slsi_dev
*sdev
, struct slsi_bucket
*bucket
, struct slsi_gscan_result
*new_scan_res
)
511 struct slsi_gscan_result
*scan_res
;
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
);
521 /* Scan buffer is full can't store anymore new results */
522 return SLSI_DISCARD_SCAN_RESULT
;
525 return SLSI_KEEP_SCAN_RESULT
;
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
;
534 /* Remove the existing scan result */
535 slsi_gscan_hash_remove(sdev
, scan_res
->nl_scan_res
.bssid
);
537 return SLSI_KEEP_SCAN_RESULT
;
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
)
542 struct slsi_gscan_result
*scan_res
= NULL
;
543 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
544 struct slsi_bucket
*bucket
;
546 int event_type
= WIFI_SCAN_FAILED
;
550 if (!SLSI_MUTEX_IS_LOCKED(ndev_vif
->scan_mutex
))
551 SLSI_WARN_NODEV("ndev_vif->scan_mutex is not locked\n");
553 SLSI_NET_DBG_HEX(dev
, SLSI_GSCAN
, skb
->data
, skb
->len
, "mlme_scan_ind skb->len: %d\n", skb
->len
);
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
);
561 bucket
= &sdev
->bucket
[bucket_index
];
563 SLSI_NET_DBG1(dev
, SLSI_GSCAN
, "Bucket is not active, index: %d (scan_id = %#x)\n", bucket_index
, scan_id
);
567 /* For scan_done indication - no need to store the results */
569 bucket
->scan_cycle
++;
570 bucket
->gscan
->num_scans
++;
572 SLSI_NET_DBG3(dev
, SLSI_GSCAN
, "scan done, scan_cycle = %d, num_scans = %d\n",
573 bucket
->scan_cycle
, bucket
->gscan
->num_scans
);
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
;
582 if (event_type
!= WIFI_SCAN_FAILED
)
583 slsi_vendor_event(sdev
, SLSI_NL80211_SCAN_EVENT
, &event_type
, sizeof(event_type
));
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. */
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");
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
);
604 slsi_vendor_event(sdev
, SLSI_NL80211_HOTSPOT_MATCH
,
605 &scan_res
->nl_scan_res
, scan_res
->scan_res_len
+ scan_res
->anqp_length
);
608 if (bucket
->report_events
& SLSI_REPORT_EVENTS_FULL_RESULTS
) {
609 struct sk_buff
*nlevent
;
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
);
615 nlevent
= cfg80211_vendor_event_alloc(sdev
->wiphy
, scan_res
->scan_res_len
+ 4, SLSI_NL80211_FULL_SCAN_RESULT_EVENT
, GFP_KERNEL
);
618 SLSI_ERR(sdev
, "failed to allocate sbk of size:%d\n", scan_res
->scan_res_len
+ 4);
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");
629 cfg80211_vendor_event(nlevent
, GFP_KERNEL
);
632 if (slsi_check_scan_result(sdev
, bucket
, scan_res
) == SLSI_DISCARD_SCAN_RESULT
) {
636 slsi_gscan_hash_add(sdev
, scan_res
);
642 u8
slsi_gscan_get_scan_policy(enum wifi_band band
)
647 case WIFI_BAND_UNSPECIFIED
:
648 scan_policy
= FAPI_SCANPOLICY_ANY_RA
;
651 scan_policy
= FAPI_SCANPOLICY_2_4GHZ
;
654 scan_policy
= (FAPI_SCANPOLICY_5GHZ
|
655 FAPI_SCANPOLICY_NON_DFS
);
657 case WIFI_BAND_A_DFS
:
658 scan_policy
= (FAPI_SCANPOLICY_5GHZ
|
659 FAPI_SCANPOLICY_DFS
);
661 case WIFI_BAND_A_WITH_DFS
:
662 scan_policy
= (FAPI_SCANPOLICY_5GHZ
|
663 FAPI_SCANPOLICY_NON_DFS
|
664 FAPI_SCANPOLICY_DFS
);
667 scan_policy
= (FAPI_SCANPOLICY_5GHZ
|
668 FAPI_SCANPOLICY_NON_DFS
|
669 FAPI_SCANPOLICY_2_4GHZ
);
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
);
678 scan_policy
= FAPI_SCANPOLICY_ANY_RA
;
682 SLSI_DBG2_NODEV(SLSI_GSCAN
, "Scan Policy: %#x\n", scan_policy
);
687 static int slsi_gscan_add_read_params(struct slsi_nl_gscan_param
*nl_gscan_param
, const void *data
, int len
)
690 int type
, tmp
, tmp1
, tmp2
, k
= 0;
691 const struct nlattr
*iter
, *iter1
, *iter2
;
692 struct slsi_nl_bucket_param
*nl_bucket
;
694 nla_for_each_attr(iter
, data
, len
, tmp
) {
698 type
= nla_type(iter
);
700 if (j
>= SLSI_GSCAN_MAX_BUCKETS
)
704 case GSCAN_ATTRIBUTE_BASE_PERIOD
:
705 if (nla_len(iter
) != SLSI_NL_ATTRIBUTE_U32_LEN
)
707 nl_gscan_param
->base_period
= nla_get_u32(iter
);
709 case GSCAN_ATTRIBUTE_NUM_AP_PER_SCAN
:
710 if (nla_len(iter
) != SLSI_NL_ATTRIBUTE_U32_LEN
)
712 nl_gscan_param
->max_ap_per_scan
= nla_get_u32(iter
);
714 case GSCAN_ATTRIBUTE_REPORT_THRESHOLD
:
715 if (nla_len(iter
) != SLSI_NL_ATTRIBUTE_U32_LEN
)
717 nl_gscan_param
->report_threshold_percent
= nla_get_u32(iter
);
719 case GSCAN_ATTRIBUTE_REPORT_THRESHOLD_NUM_SCANS
:
720 if (nla_len(iter
) != SLSI_NL_ATTRIBUTE_U32_LEN
)
722 nl_gscan_param
->report_threshold_num_scans
= nla_get_u32(iter
);
724 case GSCAN_ATTRIBUTE_NUM_BUCKETS
:
725 if (nla_len(iter
) != SLSI_NL_ATTRIBUTE_U32_LEN
)
727 nl_gscan_param
->num_buckets
= nla_get_u32(iter
);
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
) {
741 type
= nla_type(iter1
);
743 nl_bucket
= nl_gscan_param
->nl_bucket
;
746 case GSCAN_ATTRIBUTE_BUCKET_ID
:
747 if (nla_len(iter1
) != (SLSI_NL_ATTRIBUTE_U32_LEN
- NLA_HDRLEN
))
749 nl_bucket
[j
].bucket_index
= nla_get_u32(iter1
);
751 case GSCAN_ATTRIBUTE_BUCKET_PERIOD
:
752 if (nla_len(iter1
) != (SLSI_NL_ATTRIBUTE_U32_LEN
- NLA_HDRLEN
))
754 nl_bucket
[j
].period
= nla_get_u32(iter1
);
756 case GSCAN_ATTRIBUTE_BUCKET_NUM_CHANNELS
:
757 if (nla_len(iter1
) != (SLSI_NL_ATTRIBUTE_U32_LEN
- NLA_HDRLEN
))
759 nl_bucket
[j
].num_channels
= nla_get_u32(iter1
);
761 case GSCAN_ATTRIBUTE_BUCKET_CHANNELS
:
762 nla_for_each_nested(iter2
, iter1
, tmp2
) {
763 if (k
>= SLSI_GSCAN_MAX_CHANNELS
)
766 if (nla_len(iter2
) != (SLSI_NL_ATTRIBUTE_U32_LEN
- NLA_HDRLEN
))
769 nl_bucket
[j
].channels
[k
].channel
= nla_get_u32(iter2
);
774 case GSCAN_ATTRIBUTE_BUCKETS_BAND
:
775 if (nla_len(iter1
) != (SLSI_NL_ATTRIBUTE_U32_LEN
- NLA_HDRLEN
))
777 nl_bucket
[j
].band
= nla_get_u32(iter1
);
779 case GSCAN_ATTRIBUTE_REPORT_EVENTS
:
780 if (nla_len(iter1
) != (SLSI_NL_ATTRIBUTE_U32_LEN
- NLA_HDRLEN
))
782 nl_bucket
[j
].report_events
= nla_get_u32(iter1
);
784 case GSCAN_ATTRIBUTE_BUCKET_EXPONENT
:
785 if (nla_len(iter1
) != (SLSI_NL_ATTRIBUTE_U32_LEN
- NLA_HDRLEN
))
787 nl_bucket
[j
].exponent
= nla_get_u32(iter1
);
789 case GSCAN_ATTRIBUTE_BUCKET_STEP_COUNT
:
790 if (nla_len(iter1
) != (SLSI_NL_ATTRIBUTE_U32_LEN
- NLA_HDRLEN
))
792 nl_bucket
[j
].step_count
= nla_get_u32(iter1
);
794 case GSCAN_ATTRIBUTE_BUCKET_MAX_PERIOD
:
795 if (nla_len(iter1
) != (SLSI_NL_ATTRIBUTE_U32_LEN
- NLA_HDRLEN
))
797 nl_bucket
[j
].max_period
= nla_get_u32(iter1
);
800 SLSI_ERR_NODEV("No ATTR_BUKTS_type - %x\n", type
);
807 SLSI_ERR_NODEV("No GSCAN_ATTR_CH_BUKT_type - %x\n", type
);
815 int slsi_gscan_add_verify_params(struct slsi_nl_gscan_param
*nl_gscan_param
)
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
);
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
);
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
);
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
);
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
);
850 void slsi_gscan_add_to_list(struct slsi_gscan
**sdev_gscan
, struct slsi_gscan
*gscan
)
852 gscan
->next
= *sdev_gscan
;
856 int slsi_gscan_alloc_buckets(struct slsi_dev
*sdev
, struct slsi_gscan
*gscan
, int num_buckets
)
859 int bucket_index
= 0;
860 int free_buckets
= 0;
862 for (i
= 0; i
< SLSI_GSCAN_MAX_BUCKETS
; i
++)
863 if (!sdev
->bucket
[i
].used
)
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
);
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
];
879 if (bucket_index
== num_buckets
)
886 static void slsi_gscan_free_buckets(struct slsi_gscan
*gscan
)
888 struct slsi_bucket
*bucket
;
891 SLSI_DBG1_NODEV(SLSI_GSCAN
, "gscan = %p, num_buckets = %d\n", gscan
, gscan
->num_buckets
);
893 for (i
= 0; i
< gscan
->num_buckets
; i
++) {
894 bucket
= gscan
->bucket
[i
];
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
);
899 bucket
->used
= false;
900 bucket
->report_events
= 0;
901 bucket
->gscan
= NULL
;
906 void slsi_gscan_flush_scan_results(struct slsi_dev
*sdev
)
908 struct netdev_vif
*ndev_vif
;
909 struct slsi_gscan_result
*temp
;
912 ndev_vif
= slsi_gscan_get_vif(sdev
);
914 SLSI_WARN_NODEV("ndev_vif is NULL");
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
;
928 SLSI_DBG2(sdev
, SLSI_GSCAN
, "num_gscan_results: %d, buffer_consumed = %d\n",
929 sdev
->num_gscan_results
, sdev
->buffer_consumed
);
931 if (sdev
->num_gscan_results
!= 0)
932 SLSI_WARN_NODEV("sdev->num_gscan_results is not zero\n");
934 if (sdev
->buffer_consumed
!= 0)
935 SLSI_WARN_NODEV("sdev->buffer_consumedis not zero\n");
937 SLSI_MUTEX_UNLOCK(ndev_vif
->scan_mutex
);
940 static int slsi_gscan_add_mlme(struct slsi_dev
*sdev
, struct slsi_nl_gscan_param
*nl_gscan_param
, struct slsi_gscan
*gscan
)
942 struct slsi_gscan_param gscan_param
;
943 struct net_device
*dev
;
946 #ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION
947 u8 mac_addr_mask
[ETH_ALEN
];
950 dev
= slsi_gscan_get_netdev(sdev
);
953 SLSI_WARN_NODEV("dev is NULL\n");
957 for (i
= 0; i
< nl_gscan_param
->num_buckets
; i
++) {
960 gscan_param
.nl_bucket
= &nl_gscan_param
->nl_bucket
[i
]; /* current bucket */
961 gscan_param
.bucket
= gscan
->bucket
[i
];
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
;
971 report_mode
= FAPI_REPORTMODE_RESERVED
;
974 if (report_mode
== 0) {
975 SLSI_NET_ERR(dev
, "Invalid report event value: %d\n", gscan_param
.bucket
->report_events
);
979 /* In case of epno no_batch mode should be set. */
980 if (sdev
->epno_active
)
981 report_mode
|= FAPI_REPORTMODE_NO_BATCH
;
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
);
990 sdev
->scan_addr_set
= 0;
992 slsi_set_mac_randomisation_mask(sdev
, mac_addr_mask
);
994 ret
= slsi_mlme_add_scan(sdev
,
1000 nl_gscan_param
->nl_bucket
[i
].num_channels
,
1001 NULL
, /* ieee80211_channel */
1005 false /* wait_for_ind */);
1008 SLSI_NET_ERR(dev
, "Failed to add bucket: %d\n", i
);
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);
1020 static int slsi_gscan_add(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
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
;
1030 SLSI_DBG1_NODEV(SLSI_GSCAN
, "SUBCMD_ADD_GSCAN\n");
1033 SLSI_WARN_NODEV("sdev is NULL\n");
1037 if (!slsi_dev_gscan_supported())
1040 ndev_vif
= slsi_gscan_get_vif(sdev
);
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");
1051 slsi_gscan_add_read_params(nl_gscan_param
, data
, len
);
1053 #ifdef CONFIG_SCSC_WLAN_DEBUG
1054 slsi_gscan_add_dump_params(nl_gscan_param
);
1057 ret
= slsi_gscan_add_verify_params(nl_gscan_param
);
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
);
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");
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];
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
;
1087 ret
= slsi_gscan_alloc_buckets(sdev
, gscan
, nl_gscan_param
->num_buckets
);
1089 goto exit_with_gscan_free
;
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
;
1094 ret
= slsi_gscan_add_mlme(sdev
, nl_gscan_param
, gscan
);
1096 /* Free the buckets */
1097 slsi_gscan_free_buckets(gscan
);
1099 goto exit_with_gscan_free
;
1102 slsi_gscan_add_to_list(&sdev
->gscan
, gscan
);
1106 exit_with_gscan_free
:
1109 kfree(nl_gscan_param
);
1111 SLSI_MUTEX_UNLOCK(ndev_vif
->scan_mutex
);
1115 static int slsi_gscan_del(struct wiphy
*wiphy
,
1116 struct wireless_dev
*wdev
, const void *data
, int len
)
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
;
1125 SLSI_DBG1_NODEV(SLSI_GSCAN
, "SUBCMD_DEL_GSCAN\n");
1127 dev
= slsi_gscan_get_netdev(sdev
);
1129 SLSI_WARN_NODEV("dev is NULL\n");
1133 ndev_vif
= netdev_priv(dev
);
1135 SLSI_MUTEX_LOCK(ndev_vif
->scan_mutex
);
1136 while (sdev
->gscan
!= NULL
) {
1137 gscan
= sdev
->gscan
;
1139 SLSI_DBG3(sdev
, SLSI_GSCAN
, "gscan = %p, num_buckets = %d\n", gscan
, gscan
->num_buckets
);
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
;
1148 SLSI_MUTEX_UNLOCK(ndev_vif
->scan_mutex
);
1150 slsi_gscan_flush_scan_results(sdev
);
1152 sdev
->buffer_threshold
= 0;
1157 static int slsi_gscan_get_scan_results(struct wiphy
*wiphy
,
1158 struct wireless_dev
*wdev
, const void *data
, int len
)
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;
1167 const struct nlattr
*attr
;
1168 int nl_num_results
= 0;
1174 SLSI_DBG1_NODEV(SLSI_GSCAN
, "SUBCMD_GET_SCAN_RESULTS\n");
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
);
1181 case GSCAN_ATTRIBUTE_NUM_OF_RESULTS
:
1182 if (nla_len(attr
) != SLSI_NL_ATTRIBUTE_U32_LEN
)
1184 nl_num_results
= nla_get_u32(attr
);
1187 SLSI_ERR_NODEV("Unknown attribute: %d\n", type
);
1192 ndev_vif
= slsi_gscan_get_vif(sdev
);
1194 SLSI_WARN_NODEV("ndev_vif is NULL\n");
1198 SLSI_MUTEX_LOCK(ndev_vif
->scan_mutex
);
1200 num_results
= sdev
->num_gscan_results
;
1202 SLSI_DBG3(sdev
, SLSI_GSCAN
, "nl_num_results: %d, num_results = %d\n", nl_num_results
, sdev
->num_gscan_results
);
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 */
1210 /* Find the number of results to return */
1211 if (num_results
> nl_num_results
)
1212 num_results
= nl_num_results
;
1214 /* 12 bytes additional for scan_id, flags and num_resuls */
1215 mem_needed
= num_results
* sizeof(struct slsi_nl_scan_result_param
) + 12;
1217 skb
= cfg80211_vendor_cmd_alloc_reply_skb(wiphy
, mem_needed
);
1219 SLSI_ERR_NODEV("skb alloc failed");
1224 scan_hdr
= nla_nest_start(skb
, GSCAN_ATTRIBUTE_SCAN_RESULTS
);
1225 if (scan_hdr
== NULL
) {
1227 SLSI_ERR_NODEV("scan_hdr is NULL.\n");
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
);
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
);
1246 if (num_results
== 0)
1250 nla_nest_end(skb
, scan_hdr
);
1252 ret
= cfg80211_vendor_cmd_reply(skb
);
1254 SLSI_MUTEX_UNLOCK(ndev_vif
->scan_mutex
);
1258 void slsi_rx_rssi_report_ind(struct slsi_dev
*sdev
, struct net_device
*dev
, struct sk_buff
*skb
)
1260 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1261 struct slsi_rssi_monitor_evt event_data
;
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
);
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
)
1276 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
1277 struct net_device
*net_dev
;
1278 struct netdev_vif
*ndev_vif
;
1281 if (wdev
->iftype
== NL80211_IFTYPE_P2P_CLIENT
) {
1282 SLSI_DBG3(sdev
, SLSI_GSCAN
, "Not required to set PMK for P2P client\n");
1285 SLSI_DBG3(sdev
, SLSI_GSCAN
, "SUBCMD_SET_PMK Received\n");
1287 net_dev
= slsi_get_netdev(sdev
, SLSI_NET_INDEX_WLAN
);
1288 ndev_vif
= netdev_priv(net_dev
);
1290 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
1292 r
= slsi_mlme_set_pmk(sdev
, net_dev
, pmk
, (u16
)pmklen
);
1294 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1299 static int slsi_set_bssid_blacklist(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
1301 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
1302 struct net_device
*net_dev
;
1303 struct netdev_vif
*ndev_vif
;
1306 const struct nlattr
*attr
;
1311 struct cfg80211_acl_data
*acl_data
= NULL
;
1313 SLSI_DBG1_NODEV(SLSI_GSCAN
, "SUBCMD_SET_BSSID_BLACK_LIST\n");
1315 net_dev
= slsi_get_netdev(sdev
, SLSI_NET_INDEX_WLAN
);
1317 SLSI_WARN_NODEV("net_dev is NULL\n");
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
1325 SLSI_MUTEX_LOCK(ndev_vif
->scan_mutex
);
1326 nla_for_each_attr(attr
, data
, len
, temp1
) {
1332 type
= nla_type(attr
);
1335 case GSCAN_ATTRIBUTE_NUM_BSSID
:
1339 if (nla_len(attr
) != (SLSI_NL_ATTRIBUTE_U32_LEN
- NLA_HDRLEN
)) {
1343 num_bssids
= nla_get_u32(attr
);
1344 if (num_bssids
== 0 || (num_bssids
> (u32
)(0xFFFFFFFF / (sizeof(*acl_data
) + sizeof(struct mac_address
))))) {
1348 acl_data
= kmalloc(sizeof(*acl_data
) + (sizeof(struct mac_address
) * num_bssids
), GFP_KERNEL
);
1353 acl_data
->n_acl_entries
= num_bssids
;
1356 case GSCAN_ATTRIBUTE_BLACKLIST_BSSID
:
1362 if (nla_len(attr
) != (SLSI_NL_ATTRIBUTE_U8_LEN
- NLA_HDRLEN
)) {
1367 if (i
>= num_bssids
) {
1372 bssid
= (u8
*)nla_data(attr
);
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
);
1379 SLSI_ERR_NODEV("Unknown attribute: %d\n", type
);
1386 acl_data
->acl_policy
= FAPI_ACLPOLICY_BLACKLIST
;
1387 ret
= slsi_mlme_set_acl(sdev
, net_dev
, 0, acl_data
);
1389 SLSI_ERR_NODEV("Failed to set bssid blacklist\n");
1394 SLSI_MUTEX_UNLOCK(ndev_vif
->scan_mutex
);
1399 static int slsi_start_keepalive_offload(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
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
;
1408 const struct nlattr
*attr
;
1410 u8
*ip_pkt
= NULL
, *src_mac_addr
= NULL
, *dst_mac_addr
= NULL
;
1412 struct slsi_peer
*peer
;
1413 struct sk_buff
*skb
;
1414 struct ethhdr
*ehdr
;
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
);
1423 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
1424 if (!ndev_vif
->activated
) {
1425 SLSI_WARN_NODEV("ndev_vif is not activated\n");
1429 if (ndev_vif
->vif_type
!= FAPI_VIFTYPE_STATION
) {
1430 SLSI_WARN_NODEV("ndev_vif->vif_type is not FAPI_VIFTYPE_STATION\n");
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");
1440 peer
= slsi_get_peer_from_qs(sdev
, net_dev
, SLSI_STA_PEER_QUEUESET
);
1442 SLSI_WARN_NODEV("peer is NULL\n");
1447 nla_for_each_attr(attr
, data
, len
, temp
) {
1448 type
= nla_type(attr
);
1451 case MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN
:
1452 ip_pkt_len
= nla_get_u16(attr
);
1455 case MKEEP_ALIVE_ATTRIBUTE_IP_PKT
:
1456 ip_pkt
= (u8
*)nla_data(attr
);
1459 case MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC
:
1460 period
= nla_get_u32(attr
);
1463 case MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR
:
1464 dst_mac_addr
= (u8
*)nla_data(attr
);
1467 case MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR
:
1468 src_mac_addr
= (u8
*)nla_data(attr
);
1471 case MKEEP_ALIVE_ATTRIBUTE_ID
:
1472 index
= nla_get_u8(attr
);
1476 SLSI_ERR_NODEV("Unknown attribute: %d\n", type
);
1482 /* Stop any existing request. This may fail if no request exists
1483 * so ignore the return value
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);
1490 skb
= slsi_alloc_skb_headroom(sizeof(struct ethhdr
) + ip_pkt_len
, GFP_KERNEL
);
1492 SLSI_WARN_NODEV("Memory allocation failed for skb\n");
1497 skb_reset_mac_header(skb
);
1498 skb_set_network_header(skb
, sizeof(struct ethhdr
));
1500 /* Ethernet Header */
1501 ehdr
= (struct ethhdr
*)skb_put(skb
, sizeof(struct ethhdr
));
1504 SLSI_ETHER_COPY(ehdr
->h_dest
, dst_mac_addr
);
1506 SLSI_ETHER_COPY(ehdr
->h_source
, src_mac_addr
);
1507 ehdr
->h_proto
= cpu_to_be16(ETH_P_IP
);
1509 memcpy(skb_put(skb
, ip_pkt_len
), ip_pkt
, ip_pkt_len
);
1512 skb
->protocol
= ETH_P_IP
;
1513 skb
->ip_summed
= CHECKSUM_UNNECESSARY
;
1515 /* Queueset 0 AC 0 */
1516 skb
->queue_mapping
= slsi_netif_get_peer_queue(0, 0);
1518 /* Enabling the "Don't Fragment" Flag in the IP Header */
1519 ip_hdr(skb
)->frag_off
|= htons(IP_DF
);
1521 /* Calculation of IP header checksum */
1522 ip_hdr(skb
)->check
= 0;
1523 ip_send_check(ip_hdr(skb
));
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));
1529 ndev_vif
->sta
.keepalive_host_tag
[index
- 1] = host_tag
;
1531 slsi_kfree_skb(skb
);
1534 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
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");
1544 static int slsi_stop_keepalive_offload(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
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
;
1553 const struct nlattr
*attr
;
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
);
1560 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
1561 if (!ndev_vif
->activated
) {
1562 SLSI_WARN(sdev
, "VIF is not activated\n");
1566 if (ndev_vif
->vif_type
!= FAPI_VIFTYPE_STATION
) {
1567 SLSI_WARN(sdev
, "Not a STA VIF\n");
1571 if (ndev_vif
->sta
.vif_status
!= SLSI_VIF_STATUS_CONNECTED
) {
1572 SLSI_WARN(sdev
, "VIF is not connected\n");
1577 nla_for_each_attr(attr
, data
, len
, temp
) {
1578 type
= nla_type(attr
);
1581 case MKEEP_ALIVE_ATTRIBUTE_ID
:
1582 index
= nla_get_u8(attr
);
1586 SLSI_ERR_NODEV("Unknown attribute: %d\n", type
);
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;
1597 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
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");
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
)
1613 const struct nlattr
*inner
;
1615 nla_for_each_nested(inner
, outer
, tmp
) {
1616 type
= nla_type(inner
);
1618 case SLSI_ATTRIBUTE_EPNO_FLAGS
:
1619 epno_ssid_params
->flags
|= nla_get_u16(inner
);
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
;
1630 case SLSI_ATTRIBUTE_EPNO_SSID_LEN
:
1631 len
= nla_get_u8(inner
);
1633 epno_ssid_params
->ssid_len
= len
;
1635 SLSI_ERR(sdev
, "SSID too long %d\n", len
);
1639 case SLSI_ATTRIBUTE_EPNO_SSID
:
1640 memcpy(epno_ssid_params
->ssid
, nla_data(inner
), len
);
1643 SLSI_WARN(sdev
, "Ignoring unknown type:%d\n", type
);
1649 static int slsi_set_epno_ssid(struct wiphy
*wiphy
,
1650 struct wireless_dev
*wdev
, const void *data
, int len
)
1652 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
1653 struct net_device
*net_dev
;
1654 struct netdev_vif
*ndev_vif
;
1656 int tmp
, tmp1
, type
, num
= 0;
1657 const struct nlattr
*outer
, *iter
;
1659 struct slsi_epno_ssid_param
*epno_ssid_params
;
1660 struct slsi_epno_param
*epno_params
;
1662 SLSI_DBG3(sdev
, SLSI_GSCAN
, "SUBCMD_SET_EPNO_LIST Received\n");
1664 if (!slsi_dev_epno_supported())
1667 epno_params
= kmalloc((sizeof(*epno_params
) + (sizeof(*epno_ssid_params
) * SLSI_GSCAN_MAX_EPNO_SSIDS
)),
1670 SLSI_ERR(sdev
, "Mem alloc fail\n");
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
);
1678 case SLSI_ATTRIBUTE_EPNO_MINIMUM_5G_RSSI
:
1679 epno_params
->min_5g_rssi
= nla_get_u16(iter
);
1681 case SLSI_ATTRIBUTE_EPNO_MINIMUM_2G_RSSI
:
1682 epno_params
->min_2g_rssi
= nla_get_u16(iter
);
1684 case SLSI_ATTRIBUTE_EPNO_INITIAL_SCORE_MAX
:
1685 epno_params
->initial_score_max
= nla_get_u16(iter
);
1687 case SLSI_ATTRIBUTE_EPNO_CUR_CONN_BONUS
:
1688 epno_params
->current_connection_bonus
= nla_get_u8(iter
);
1690 case SLSI_ATTRIBUTE_EPNO_SAME_NETWORK_BONUS
:
1691 epno_params
->same_network_bonus
= nla_get_u8(iter
);
1693 case SLSI_ATTRIBUTE_EPNO_SECURE_BONUS
:
1694 epno_params
->secure_bonus
= nla_get_u8(iter
);
1696 case SLSI_ATTRIBUTE_EPNO_5G_BONUS
:
1697 epno_params
->band_5g_bonus
= nla_get_u8(iter
);
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
);
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
);
1716 epno_params
->num_networks
= num
;
1719 SLSI_ERR(sdev
, "Invalid attribute %d\n", type
);
1726 SLSI_ERR(sdev
, "num_ssid %d does not match ssids sent %d\n", num
, i
);
1730 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
1731 r
= slsi_mlme_set_pno_list(sdev
, num
, epno_params
, NULL
);
1733 sdev
->epno_active
= (num
!= 0);
1735 sdev
->epno_active
= false;
1736 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1742 static int slsi_set_hs_params(struct wiphy
*wiphy
,
1743 struct wireless_dev
*wdev
, const void *data
, int len
)
1745 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
1746 struct net_device
*net_dev
;
1747 struct netdev_vif
*ndev_vif
;
1749 int tmp
, tmp1
, tmp2
, type
, num
= 0;
1750 const struct nlattr
*outer
, *inner
, *iter
;
1752 struct slsi_epno_hs2_param
*epno_hs2_params_array
;
1753 struct slsi_epno_hs2_param
*epno_hs2_params
;
1755 SLSI_DBG3(sdev
, SLSI_GSCAN
, "SUBCMD_SET_HS_LIST Received\n");
1757 if (!slsi_dev_epno_supported())
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");
1766 net_dev
= slsi_get_netdev(sdev
, SLSI_NET_INDEX_WLAN
);
1767 ndev_vif
= netdev_priv(net_dev
);
1769 nla_for_each_attr(iter
, data
, len
, tmp2
) {
1770 type
= nla_type(iter
);
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
];
1776 nla_for_each_nested(inner
, outer
, tmp1
) {
1777 type
= nla_type(inner
);
1780 case SLSI_ATTRIBUTE_EPNO_HS_ID
:
1781 epno_hs2_params
->id
= (u32
)nla_get_u32(inner
);
1783 case SLSI_ATTRIBUTE_EPNO_HS_REALM
:
1784 memcpy(epno_hs2_params
->realm
, nla_data(inner
), 256);
1786 case SLSI_ATTRIBUTE_EPNO_HS_CONSORTIUM_IDS
:
1787 memcpy(epno_hs2_params
->roaming_consortium_ids
, nla_data(inner
), 16 * 8);
1789 case SLSI_ATTRIBUTE_EPNO_HS_PLMN
:
1790 memcpy(epno_hs2_params
->plmn
, nla_data(inner
), 3);
1793 SLSI_WARN(sdev
, "Ignoring unknown type:%d\n", type
);
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
);
1807 SLSI_ERR(sdev
, "Invalid attribute %d\n", type
);
1813 SLSI_ERR(sdev
, "num_ssid %d does not match ssids sent %d\n", num
, i
);
1818 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
1819 r
= slsi_mlme_set_pno_list(sdev
, num
, NULL
, epno_hs2_params_array
);
1821 sdev
->epno_active
= true;
1822 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1824 kfree(epno_hs2_params_array
);
1828 static int slsi_reset_hs_params(struct wiphy
*wiphy
,
1829 struct wireless_dev
*wdev
, const void *data
, int len
)
1831 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
1832 struct net_device
*net_dev
;
1833 struct netdev_vif
*ndev_vif
;
1836 SLSI_DBG3(sdev
, SLSI_GSCAN
, "SUBCMD_RESET_HS_LIST Received\n");
1838 if (!slsi_dev_epno_supported())
1841 net_dev
= slsi_get_netdev(sdev
, SLSI_NET_INDEX_WLAN
);
1842 ndev_vif
= netdev_priv(net_dev
);
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;
1851 static int slsi_set_rssi_monitor(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
1853 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
1854 struct net_device
*net_dev
;
1855 struct netdev_vif
*ndev_vif
;
1859 const struct nlattr
*attr
;
1860 s8 min_rssi
= 0, max_rssi
= 0;
1863 SLSI_DBG3(sdev
, SLSI_GSCAN
, "Recd RSSI monitor command\n");
1865 net_dev
= slsi_get_netdev(sdev
, SLSI_NET_INDEX_WLAN
);
1866 if (net_dev
== NULL
) {
1867 SLSI_ERR(sdev
, "netdev is NULL!!\n");
1871 ndev_vif
= netdev_priv(net_dev
);
1872 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
1874 if (!ndev_vif
->activated
) {
1875 SLSI_ERR(sdev
, "Vif not activated\n");
1879 if (ndev_vif
->vif_type
!= FAPI_VIFTYPE_STATION
) {
1880 SLSI_ERR(sdev
, "Not a STA vif\n");
1884 if (ndev_vif
->sta
.vif_status
!= SLSI_VIF_STATUS_CONNECTED
) {
1885 SLSI_ERR(sdev
, "STA vif not connected\n");
1890 nla_for_each_attr(attr
, data
, len
, temp
) {
1891 type
= nla_type(attr
);
1893 case SLSI_RSSI_MONITOR_ATTRIBUTE_START
:
1894 enable
= (u16
)nla_get_u8(attr
);
1896 case SLSI_RSSI_MONITOR_ATTRIBUTE_MIN_RSSI
:
1897 min_rssi
= nla_get_s8(attr
);
1899 case SLSI_RSSI_MONITOR_ATTRIBUTE_MAX_RSSI
:
1900 max_rssi
= nla_get_s8(attr
);
1907 if (min_rssi
> max_rssi
) {
1908 SLSI_ERR(sdev
, "Invalid params, min_rssi= %d ,max_rssi = %d\n", min_rssi
, max_rssi
);
1912 r
= slsi_mlme_set_rssi_monitor(sdev
, net_dev
, enable
, min_rssi
, max_rssi
);
1914 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
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
)
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
);
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
));
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
);
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
);
1947 SLSI_DBG_HEX(sdev
, SLSI_GSCAN
, buf
, buf_len
, "return buffer\n");
1951 static int slsi_lls_set_stats(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
1953 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
1954 struct net_device
*net_dev
= NULL
;
1955 struct netdev_vif
*ndev_vif
= NULL
;
1958 const struct nlattr
*attr
;
1959 u32 mpdu_size_threshold
= 0;
1960 u32 aggr_stat_gathering
= 0;
1963 if (!slsi_dev_lls_supported())
1966 if (slsi_is_test_mode_enabled()) {
1967 SLSI_WARN(sdev
, "not supported in WlanLite mode\n");
1971 nla_for_each_attr(attr
, data
, len
, temp
) {
1972 type
= nla_type(attr
);
1975 case LLS_ATTRIBUTE_SET_MPDU_SIZE_THRESHOLD
:
1976 mpdu_size_threshold
= nla_get_u32(attr
);
1979 case LLS_ATTRIBUTE_SET_AGGR_STATISTICS_GATHERING
:
1980 aggr_stat_gathering
= nla_get_u32(attr
);
1984 SLSI_ERR_NODEV("Unknown attribute: %d\n", type
);
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
);
1993 net_dev
= slsi_get_netdev(sdev
, SLSI_NET_INDEX_WLAN
);
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;
2002 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
2006 static int slsi_lls_clear_stats(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
2008 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
2011 const struct nlattr
*attr
;
2012 u32 stats_clear_req_mask
= 0;
2015 struct net_device
*net_dev
= NULL
;
2016 struct netdev_vif
*ndev_vif
= NULL
;
2018 SLSI_DBG3(sdev
, SLSI_GSCAN
, "\n");
2020 nla_for_each_attr(attr
, data
, len
, temp
) {
2021 type
= nla_type(attr
);
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
);
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
);
2035 SLSI_ERR(sdev
, "Unknown attribute:%d\n", type
);
2040 /* stop_req = 0 : clear the stats which are flaged 0
2041 * stop_req = 1 : clear the stats which are flaged 1
2044 stats_clear_req_mask
= ~stats_clear_req_mask
;
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
);
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;
2057 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
2061 static u32
slsi_lls_ie_to_cap(const u8
*ies
, int ies_len
)
2063 u32 capabilities
= 0;
2068 if (!ies
|| ies_len
== 0) {
2069 SLSI_ERR_NODEV("no ie[&%p %d]\n", ies
, ies_len
);
2072 ie
= cfg80211_find_ie(WLAN_EID_EXT_CAPABILITY
, ies
, ies_len
);
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
;
2082 ie
= cfg80211_find_vendor_ie(WLAN_OUI_WFA
, SLSI_WLAN_OUI_TYPE_WFA_HS20_IND
, ies
, ies_len
);
2084 capabilities
|= SLSI_LLS_CAPABILITY_HS20
;
2085 return capabilities
;
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
)
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
;
2098 SLSI_DBG3(sdev
, SLSI_GSCAN
, "\n");
2100 if (ndev_vif
->ifnum
== SLSI_NET_INDEX_WLAN
) {
2101 lls_info
->mode
= SLSI_LLS_INTERFACE_STA
;
2102 peer_type
= SLSI_LLS_PEER_AP
;
2104 lls_info
->mode
= SLSI_LLS_INTERFACE_P2P_CLIENT
;
2105 peer_type
= SLSI_LLS_PEER_P2P_GO
;
2108 switch (ndev_vif
->sta
.vif_status
) {
2109 case SLSI_VIF_STATUS_CONNECTING
:
2110 lls_info
->state
= SLSI_LLS_AUTHENTICATING
;
2112 case SLSI_VIF_STATUS_CONNECTED
:
2113 lls_info
->state
= SLSI_LLS_ASSOCIATED
;
2116 lls_info
->state
= SLSI_LLS_DISCONNECTED
;
2118 lls_info
->roaming
= ndev_vif
->sta
.roam_in_progress
?
2119 SLSI_LLS_ROAMING_ACTIVE
: SLSI_LLS_ROAMING_IDLE
;
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
);
2129 memcpy(lls_info
->ssid
, ie_data
, ie_len
);
2130 lls_info
->ssid
[ie_len
] = 0;
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
);
2137 memcpy(lls_info
->ap_country_str
, ie_data
, 3);
2138 iface_stat
->peer_info
[0].capabilities
|= SLSI_LLS_CAPABILITY_COUNTRY
;
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
;
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
;
2153 iface_stat
->peer_info
[0].capabilities
|= slsi_lls_ie_to_cap(peer
->assoc_resp_ie
->data
, peer
->assoc_resp_ie
->len
);
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;
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
++;
2173 static void slsi_lls_iface_ap_stats(struct slsi_dev
*sdev
, struct netdev_vif
*ndev_vif
, struct slsi_lls_iface_stat
*iface_stat
)
2175 enum slsi_lls_peer_type peer_type
= SLSI_LLS_PEER_INVALID
;
2176 struct slsi_peer
*peer
;
2178 struct net_device
*dev
;
2180 SLSI_DBG3(sdev
, SLSI_GSCAN
, "\n");
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);
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
;
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
++;
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
;
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
)
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} } };
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> */
2238 for (i
= 0; i
< SLSI_LLS_AC_MAX
; i
++)
2239 iface_stat
->ac
[i
].ac
= SLSI_LLS_AC_MAX
;
2244 ndev_vif
= netdev_priv(net_dev
);
2245 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
2247 if (!ndev_vif
->activated
)
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
);
2256 SLSI_ETHER_COPY(iface_stat
->info
.mac_addr
, net_dev
->dev_addr
);
2258 mibrsp
.dataLength
= 10 * sizeof(get_values
) / sizeof(get_values
[0]);
2259 mibrsp
.data
= kmalloc(mibrsp
.dataLength
, GFP_KERNEL
);
2261 SLSI_ERR(sdev
, "Cannot kmalloc %d bytes for interface MIBs\n", mibrsp
.dataLength
);
2265 values
= slsi_read_mibs(sdev
, net_dev
, get_values
, sizeof(get_values
) / sizeof(get_values
[0]), &mibrsp
);
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
];
2277 SLSI_WARN(sdev
, "LLS: expected datatype 1 but received %d\n", values
[i
].type
);
2281 if (values
[4].type
== SLSI_MIB_TYPE_UINT
)
2282 iface_stat
->beacon_rx
= values
[4].u
.uintValue
;
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 */
2289 if (values
[6].type
== SLSI_MIB_TYPE_INT
)
2290 iface_stat
->rssi_data
= values
[6].u
.intValue
;
2295 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
2298 void slsi_check_num_radios(struct slsi_dev
*sdev
)
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 } } };
2304 if (slsi_is_test_mode_enabled()) {
2305 SLSI_WARN(sdev
, "not supported in WlanLite mode\n");
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
);
2313 SLSI_ERR(sdev
, "Cannot kmalloc %d bytes\n", mibrsp
.dataLength
);
2314 sdev
->lls_num_radio
= 0;
2318 values
= slsi_read_mibs(sdev
, NULL
, get_values
, ARRAY_SIZE(get_values
), &mibrsp
);
2320 sdev
->lls_num_radio
= 0;
2322 sdev
->lls_num_radio
= values
[0].type
== SLSI_MIB_TYPE_NONE
? 1 : 2;
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
)
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
;
2345 radio_stat
->radio
= radio_index
;
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
);
2354 values
= slsi_read_mibs(sdev
, NULL
, get_values
, sizeof(get_values
) / sizeof(get_values
[0]), &mibrsp
);
2356 goto exit_with_mibrsp
;
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
;
2362 SLSI_ERR(sdev
, "invalid type. iter:%d", i
);
2365 if (values
[4].type
!= SLSI_MIB_TYPE_OCTET
) {
2366 SLSI_ERR(sdev
, "Supported_Chan invalid type.");
2367 goto exit_with_values
;
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
;
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;
2384 radio_chan
->center_freq
= 2407 + (chan_start
+ k
) * 5;
2385 radio_chan
->width
= SLSI_LLS_CHAN_WIDTH_20
;
2387 radio_stat
->num_channels
+= chan_count
;
2388 } else if (chan_start
!= 1 && (twoorfive
& BIT(1))) {
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
;
2395 radio_stat
->num_channels
+= chan_count
;
2404 static int slsi_lls_fill(struct slsi_dev
*sdev
, u8
**src_buf
)
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
;
2411 int max_chan_count
= 0;
2413 int num_of_radios_supported
;
2415 int radio_type
[2] = {BIT(0), BIT(1)};
2417 if (sdev
->lls_num_radio
== 0) {
2418 slsi_check_num_radios(sdev
);
2419 if (sdev
->lls_num_radio
== 0)
2423 num_of_radios_supported
= sdev
->lls_num_radio
;
2424 net_dev
= slsi_get_netdev(sdev
, SLSI_NET_INDEX_WLAN
);
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
)
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
);
2437 SLSI_ERR(sdev
, "No mem. Size:%d\n", buf_len
);
2440 buf
[0] = num_of_radios_supported
;
2442 iface_stat
= (struct slsi_lls_iface_stat
*)(buf
+ sizeof(u8
));
2443 slsi_lls_iface_stat_fill(sdev
, net_dev
, iface_stat
);
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
));
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
));
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
);
2468 static int slsi_lls_get_stats(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
2470 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
2475 if (!slsi_dev_lls_supported())
2478 if (slsi_is_test_mode_enabled()) {
2479 SLSI_WARN(sdev
, "not supported in WlanLite mode\n");
2484 SLSI_ERR(sdev
, "sdev is Null\n");
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
)
2493 buf_len
= slsi_lls_fill(sdev
, &buf
);
2494 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
2497 ret
= slsi_vendor_cmd_reply(wiphy
, buf
, buf_len
);
2499 SLSI_ERR_NODEV("vendor cmd reply failed (err:%d)\n", ret
);
2507 static int slsi_gscan_set_oui(struct wiphy
*wiphy
,
2508 struct wireless_dev
*wdev
, const void *data
, int len
)
2512 #ifdef CONFIG_SCSC_WLAN_ENABLE_MAC_RANDOMISATION
2514 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
2515 struct net_device
*dev
= wdev
->netdev
;
2516 struct netdev_vif
*ndev_vif
;
2519 const struct nlattr
*attr
;
2522 memset(&scan_oui
, 0, 6);
2525 SLSI_ERR(sdev
, "dev is NULL!!\n");
2529 ndev_vif
= netdev_priv(dev
);
2530 SLSI_MUTEX_LOCK(ndev_vif
->scan_mutex
);
2531 sdev
->scan_addr_set
= 0;
2533 nla_for_each_attr(attr
, data
, len
, temp
) {
2539 type
= nla_type(attr
);
2541 case SLSI_NL_ATTRIBUTE_PNO_RANDOM_MAC_OUI
:
2543 if (nla_len(attr
) != 3) {
2547 memcpy(&scan_oui
, nla_data(attr
), 3);
2548 memcpy(sdev
->scan_mac_addr
, scan_oui
, 6);
2549 sdev
->scan_addr_set
= 1;
2554 SLSI_ERR(sdev
, "Invalid type : %d\n", type
);
2558 SLSI_MUTEX_UNLOCK(ndev_vif
->scan_mutex
);
2563 static int slsi_get_feature_set(struct wiphy
*wiphy
,
2564 struct wireless_dev
*wdev
, const void *data
, int len
)
2566 u32 feature_set
= 0;
2569 SLSI_DBG3_NODEV(SLSI_GSCAN
, "\n");
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
;
2577 #ifdef CONFIG_SCSC_WLAN_ENHANCED_LOGGING
2578 feature_set
|= SLSI_WIFI_HAL_FEATURE_LOGGER
;
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
;
2593 ret
= slsi_vendor_cmd_reply(wiphy
, &feature_set
, sizeof(feature_set
));
2598 static int slsi_set_country_code(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
2600 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
2604 const struct nlattr
*attr
;
2605 char country_code
[SLSI_COUNTRY_CODE_LEN
];
2607 SLSI_DBG3(sdev
, SLSI_GSCAN
, "Received country code command\n");
2609 nla_for_each_attr(attr
, data
, len
, temp
) {
2610 type
= nla_type(attr
);
2612 case SLSI_NL_ATTRIBUTE_COUNTRY_CODE
:
2614 if (nla_len(attr
) < (SLSI_COUNTRY_CODE_LEN
- 1)) {
2616 SLSI_ERR(sdev
, "Insufficient Country Code Length : %d\n", nla_len(attr
));
2619 memcpy(country_code
, nla_data(attr
), (SLSI_COUNTRY_CODE_LEN
- 1));
2624 SLSI_ERR(sdev
, "Invalid type : %d\n", type
);
2628 ret
= slsi_set_country_update_regd(sdev
, country_code
, SLSI_COUNTRY_CODE_LEN
);
2630 SLSI_ERR(sdev
, "Set country failed ret:%d\n", ret
);
2634 static int slsi_apf_read_filter(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
2637 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
2638 struct net_device
*dev
= wdev
->netdev
;
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
);
2650 ret
= slsi_mlme_read_apf_request(sdev
, dev
, &host_dst
, &datalen
);
2652 ret
= slsi_vendor_cmd_reply(wiphy
, host_dst
, datalen
);
2654 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
2658 static int slsi_apf_get_capabilities(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
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
;
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");
2673 memset(&sdev
->device_config
.apf_cap
, 0, sizeof(struct slsi_apf_capabilities
));
2675 ret
= slsi_mib_get_apf_cap(sdev
, dev
);
2677 SLSI_ERR(sdev
, "Failed to read mib\n");
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
);
2684 SLSI_ERR(sdev
, "NO MEM for nl_skb!!!\n");
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 */
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
);
2701 SLSI_ERR(sdev
, "Error in nla_put*:%x\n", ret
);
2702 /* Dont use slsi skb wrapper for this free */
2707 ret
= cfg80211_vendor_cmd_reply(nl_skb
);
2709 SLSI_ERR(sdev
, "apf_get_capabilities cfg80211_vendor_cmd_reply failed :%d\n", ret
);
2711 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
2715 static int slsi_apf_set_filter(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
2717 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
2718 struct net_device
*dev
= wdev
->netdev
;
2722 const struct nlattr
*attr
;
2723 u32 program_len
= 0;
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");
2735 SLSI_ERR(sdev
, "dev is NULL!!\n");
2740 nla_for_each_attr(attr
, data
, len
, temp
) {
2741 type
= nla_type(attr
);
2743 case SLSI_APF_ATTR_PROGRAM_LEN
:
2745 program_len
= nla_get_u32(attr
);
2747 program
= kmalloc(program_len
, GFP_KERNEL
);
2754 case SLSI_APF_ATTR_PROGRAM
:
2756 memcpy(program
, (u8
*)nla_data(attr
), program_len
);
2760 SLSI_ERR(sdev
, "Invalid type : %d\n", type
);
2766 ret
= slsi_mlme_install_apf_request(sdev
, dev
, program
, program_len
);
2768 SLSI_ERR(sdev
, "apf_set_filter failed ret:%d\n", ret
);
2774 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
2778 static int slsi_rtt_get_capabilities(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
2780 struct slsi_rtt_capabilities rtt_cap
;
2782 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
2783 struct net_device
*dev
= wdev
->netdev
;
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");
2790 memset(&rtt_cap
, 0, sizeof(struct slsi_rtt_capabilities
));
2792 ret
= slsi_mib_get_rtt_cap(sdev
, dev
, &rtt_cap
);
2794 SLSI_ERR(sdev
, "Failed to read mib\n");
2797 ret
= slsi_vendor_cmd_reply(wiphy
, &rtt_cap
, sizeof(struct slsi_rtt_capabilities
));
2799 SLSI_ERR_NODEV("rtt_get_capabilities vendor cmd reply failed (err = %d)\n", ret
);
2803 static int slsi_rtt_set_config(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
2806 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
2807 #ifdef CONFIG_SCSC_WIFI_NAN_ENABLE
2808 struct netdev_vif
*ndev_vif
;
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
;
2817 u16 rtt_peer
= SLSI_RTT_PEER_AP
;
2819 u16 channel_freq
= 0;
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
;
2826 nla_for_each_attr(iter
, data
, len
, tmp
) {
2827 type
= nla_type(iter
);
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
);
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
);
2838 SLSI_ERR_NODEV("Unexpected RTT attribute:type - %d\n", type
);
2843 SLSI_ERR_NODEV("No device found for rtt configuration!\n");
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");
2852 nla_for_each_attr(iter
, data
, len
, tmp
) {
2853 type
= nla_type(iter
);
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
);
2862 case SLSI_RTT_ATTRIBUTE_TARGET_TYPE
:
2863 nl_rtt_params
[j
].type
= nla_get_u16(inner
);
2865 case SLSI_RTT_ATTRIBUTE_TARGET_PEER
:
2866 rtt_peer
= nla_get_u16(inner
);
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;
2872 case SLSI_RTT_ATTRIBUTE_TARGET_PERIOD
:
2873 nl_rtt_params
[j
].burst_period
= nla_get_u8(inner
);
2875 case SLSI_RTT_ATTRIBUTE_TARGET_NUM_BURST
:
2876 nl_rtt_params
[j
].num_burst
= nla_get_u8(inner
);
2878 case SLSI_RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST
:
2879 nl_rtt_params
[j
].num_frames_per_burst
= nla_get_u8(inner
);
2881 case SLSI_RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR
:
2882 nl_rtt_params
[j
].num_retries_per_ftmr
= nla_get_u8(inner
);
2884 case SLSI_RTT_ATTRIBUTE_TARGET_BURST_DURATION
:
2885 nl_rtt_params
[j
].burst_duration
= nla_get_u8(inner
);
2887 case SLSI_RTT_ATTRIBUTE_TARGET_PREAMBLE
:
2888 nl_rtt_params
[j
].preamble
= nla_get_u16(inner
);
2890 case SLSI_RTT_ATTRIBUTE_TARGET_BW
:
2891 nl_rtt_params
[j
].bw
= nla_get_u16(inner
);
2893 case SLSI_RTT_ATTRIBUTE_TARGET_LCI
:
2894 nl_rtt_params
[j
].LCI_request
= nla_get_u16(inner
);
2896 case SLSI_RTT_ATTRIBUTE_TARGET_LCR
:
2897 nl_rtt_params
[j
].LCR_request
= nla_get_u16(inner
);
2900 SLSI_ERR_NODEV("Unknown RTT INFO ATTRIBUTE type: %d\n", type
);
2908 SLSI_ERR_NODEV("No ATTRIBUTE_Target cnt - %d\n", type
);
2913 SLSI_ETHER_COPY(source_addr
, dev
->dev_addr
);
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
;
2922 ndev_vif
= netdev_priv(dev
);
2923 if (ndev_vif
->activated
) {
2924 vif_idx
= ndev_vif
->vif_type
;
2926 SLSI_ERR(sdev
, "NAN vif not activated\n");
2927 kfree(nl_rtt_params
);
2931 SLSI_ERR(sdev
, "NAN not enabled\n");
2935 r
= slsi_mlme_add_range_req(sdev
, num_devices
, nl_rtt_params
, rtt_id
, vif_idx
, source_addr
);
2938 SLSI_ERR_NODEV("Failed to set rtt config\n");
2940 sdev
->rtt_vif
[rtt_id
] = vif_idx
;
2941 SLSI_DBG1_NODEV(SLSI_GSCAN
, "Successfully set rtt config\n");
2943 kfree(nl_rtt_params
);
2947 int slsi_tx_rate_calc(struct sk_buff
*nl_skb
, u16 fw_rate
, int res
, bool tx_rate
)
2950 const u32 fw_rate_idx_to_80211_rate
[] = { 0, 10, 20, 55, 60, 90, 110, 120, 180, 240, 360, 480, 540 };
2952 u32 mcs
= 0, nss
= 0;
2953 u32 chan_bw_idx
= 0;
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
;
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) {
2971 data_rate
= (nss
+ 1) * 67;
2973 data_rate
= (nss
+ 1) * 60;
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
);
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.
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
];
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
);
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
);
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
);
3013 void slsi_rx_range_ind(struct slsi_dev
*sdev
, struct net_device
*dev
, struct sk_buff
*skb
)
3015 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
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
;
3025 struct nlattr
*nlattr_nested
;
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
);
3035 nl_skb
= cfg80211_vendor_event_alloc(sdev
->wiphy
, NLMSG_DEFAULT_SIZE
, SLSI_NL80211_RTT_RESULT_EVENT
,
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
);
3044 SLSI_ERR(sdev
, "NO MEM for nl_skb!!!\n");
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 */
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
);
3064 res
|= nla_put_u16(nl_skb
, SLSI_RTT_EVENT_ATTR_BURST_NUM
, *ip_ptr
);
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
);
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
);
3074 res
|= nla_put_u16(nl_skb
, SLSI_RTT_EVENT_ATTR_RSSI
, *ip_ptr
);
3076 res
|= nla_put_u16(nl_skb
, SLSI_RTT_EVENT_ATTR_RSSI_SPREAD
, *ip_ptr
);
3078 memcpy(&tx_data
, ip_ptr
, 2);
3079 res
= slsi_tx_rate_calc(nl_skb
, tx_data
, res
, 1);
3081 memcpy(&rx_data
, ip_ptr
, 2);
3082 res
= slsi_tx_rate_calc(nl_skb
, rx_data
, res
, 0);
3084 res
|= nla_put_u32(nl_skb
, SLSI_RTT_EVENT_ATTR_RTT
, *ip_ptr
);
3086 res
|= nla_put_u16(nl_skb
, SLSI_RTT_EVENT_ATTR_RTT_SD
, *ip_ptr
);
3088 res
|= nla_put_u16(nl_skb
, SLSI_RTT_EVENT_ATTR_RTT_SPREAD
, *ip_ptr
);
3090 get_monotonic_boottime(&ts
);
3091 tkernel
= (u64
)TIMESPEC_TO_US(ts
);
3093 res
|= nla_put_u32(nl_skb
, SLSI_RTT_EVENT_ATTR_TIMESTAMP_US
, tkernel
- (tmac
- tm
));
3095 res
|= nla_put_u32(nl_skb
, SLSI_RTT_EVENT_ATTR_DISTANCE_MM
, *ip_ptr
);
3097 res
|= nla_put_u32(nl_skb
, SLSI_RTT_EVENT_ATTR_DISTANCE_SD_MM
, *ip_ptr
);
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;
3112 nla_nest_end(nl_skb
, nlattr_nested
);
3114 SLSI_DBG_HEX(sdev
, SLSI_GSCAN
, fapi_get_data(skb
), fapi_get_datalen(skb
), "range indication skb buffer:\n");
3116 SLSI_ERR(sdev
, "Error in nla_put*:%x\n", res
);
3120 cfg80211_vendor_event(nl_skb
, GFP_KERNEL
);
3122 slsi_kfree_skb(skb
);
3123 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
3126 void slsi_rx_range_done_ind(struct slsi_dev
*sdev
, struct net_device
*dev
, struct sk_buff
*skb
)
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
);
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
);
3140 static int slsi_rtt_cancel_config(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
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
;
3146 const struct nlattr
*iter
;
3147 u16 num_devices
= 0, rtt_id
= 0;
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");
3154 nla_for_each_attr(iter
, data
, len
, temp
) {
3155 type
= nla_type(iter
);
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
);
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
);
3166 SLSI_ERR_NODEV("No ATTRIBUTE_Target cnt - %d\n", type
);
3170 /* Allocate memory for the received mac addresses */
3172 addr
= kzalloc(ETH_ALEN
* num_devices
, GFP_KERNEL
);
3174 SLSI_ERR_NODEV("Failed for allocate memory for mac addresses\n");
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
);
3184 SLSI_ERR_NODEV("No ATTRIBUTE_MAC - %d\n", type
);
3188 r
= slsi_mlme_del_range_req(sdev
, dev
, num_devices
, addr
, rtt_id
);
3192 SLSI_ERR_NODEV("Failed to cancel rtt config\n");
3196 static int slsi_configure_nd_offload(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
3198 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
3199 struct net_device
*dev
= wdev
->netdev
;
3200 struct netdev_vif
*ndev_vif
;
3204 const struct nlattr
*attr
;
3205 u8 nd_offload_enabled
= 0;
3207 SLSI_DBG3(sdev
, SLSI_GSCAN
, "Received nd_offload command\n");
3210 SLSI_ERR(sdev
, "dev is NULL!!\n");
3214 ndev_vif
= netdev_priv(dev
);
3215 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
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");
3224 nla_for_each_attr(attr
, data
, len
, temp
) {
3225 type
= nla_type(attr
);
3227 case SLSI_NL_ATTRIBUTE_ND_OFFLOAD_VALUE
:
3229 nd_offload_enabled
= nla_get_u8(attr
);
3233 SLSI_ERR(sdev
, "Invalid type : %d\n", type
);
3239 ndev_vif
->sta
.nd_offload_enabled
= nd_offload_enabled
;
3240 ret
= slsi_mlme_set_ipv6_address(sdev
, dev
);
3242 SLSI_ERR(sdev
, "Configure nd_offload failed ret:%d nd_offload_enabled: %d\n", ret
, nd_offload_enabled
);
3247 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
3251 static int slsi_get_roaming_capabilities(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
3253 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
3254 struct net_device
*dev
= wdev
->netdev
;
3255 struct netdev_vif
*ndev_vif
;
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
;
3266 SLSI_ERR(sdev
, "dev is NULL!!\n");
3270 ndev_vif
= netdev_priv(dev
);
3272 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
3274 mibrsp
.dataLength
= 10;
3275 mibrsp
.data
= kmalloc(mibrsp
.dataLength
, GFP_KERNEL
);
3277 SLSI_ERR(sdev
, "Cannot kmalloc %d bytes\n", mibrsp
.dataLength
);
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
);
3286 SLSI_ERR(sdev
, "NO MEM for nl_skb!!!\n");
3288 goto exit_with_mib_resp
;
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 */
3297 goto exit_with_mib_resp
;
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
);
3303 SLSI_ERR(sdev
, "Error in nla_put*:%x\n", ret
);
3304 /* Dont use slsi skb wrapper for this free */
3306 goto exit_with_mib_resp
;
3309 ret
= cfg80211_vendor_cmd_reply(nl_skb
);
3311 SLSI_ERR(sdev
, "cfg80211_vendor_cmd_reply failed :%d\n", ret
);
3316 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
3320 static int slsi_set_roaming_state(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
3322 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
3323 struct net_device
*dev
= wdev
->netdev
;
3326 const struct nlattr
*attr
;
3331 SLSI_WARN_NODEV("net_dev is NULL\n");
3335 nla_for_each_attr(attr
, data
, len
, temp
) {
3336 type
= nla_type(attr
);
3338 case SLSI_NL_ATTR_ROAM_STATE
:
3339 roam_state
= nla_get_u8(attr
);
3342 SLSI_ERR_NODEV("Unknown attribute: %d\n", type
);
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
);
3351 SLSI_ERR_NODEV("Failed to set roaming state\n");
3357 char *slsi_get_roam_reason_str(int roam_reason
)
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";
3371 return "UNKNOWN_REASON";
3375 void slsi_rx_event_log_indication(struct slsi_dev
*sdev
, struct net_device
*dev
, struct sk_buff
*skb
)
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;
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
);
3393 SLSI_DBG3(sdev
, SLSI_GSCAN
,
3394 "slsi_rx_event_log_indication, event id = %d, len = %d\n", event_id
, tlv_buffer__len
);
3396 #ifdef CONFIG_SCSC_WIFILOGGER
3397 SCSC_WLOG_FW_EVENT(WLOG_NORMAL
, event_id
, timestamp
, fapi_get_data(skb
), fapi_get_datalen(skb
));
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
);
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
);
3411 tag_value
= slsi_convert_tlv_data_to_value(&tlv_data
[i
], tag_len
);
3413 case SLSI_WIFI_TAG_RSSI
:
3414 roam_rssi
= tag_value
;
3419 roam_rssi_val
= ((1 << rssi_bits
) - 1) ^ tag_value
;
3420 roam_rssi_val
= -(roam_rssi_val
+ 1);
3422 case SLSI_WIFI_TAG_REASON_CODE
:
3423 deauth_reason
= tag_value
;
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
);
3431 case SLSI_WIFI_TAG_VD_CHANNEL_UTILISATION
:
3432 chan_utilisation
= vtag_value
;
3434 case SLSI_WIFI_TAG_VD_ROAMING_REASON
:
3435 roam_reason
= vtag_value
;
3437 case SLSI_WIFI_TAG_VD_BTM_REQUEST_MODE
:
3438 btm_request_mode
= vtag_value
;
3440 case SLSI_WIFI_TAG_VD_BTM_RESPONSE_STATUS
:
3441 btm_response
= vtag_value
;
3443 case SLSI_WIFI_TAG_VD_RETRY_COUNT
:
3444 eapol_retry_count
= vtag_value
;
3446 case SLSI_WIFI_TAG_VD_EAPOL_KEY_TYPE
:
3447 eapol_key_type
= vtag_value
;
3451 case SLSI_WIFI_TAG_EAPOL_MESSAGE_TYPE
:
3452 eapol_msg_type
= tag_value
;
3454 case SLSI_WIFI_TAG_STATUS
:
3455 status_code
= tag_value
;
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",
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
);
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
);
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
);
3481 case WIFI_EVENT_FW_BTM_FRAME_RESPONSE
:
3482 SLSI_INFO(sdev
, "WIFI_EVENT_FW_BTM_FRAME_RESPONSE,Status code:%d\n", btm_response
);
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
));
3489 case FAPI_EVENT_WIFI_EVENT_FW_AUTH_STARTED
:
3490 SLSI_INFO(sdev
, "WIFI_EVENT_FW_AUTH_STARTED\n");
3492 case FAPI_EVENT_WIFI_EVENT_AUTH_COMPLETE
:
3493 SLSI_INFO(sdev
, "WIFI_EVENT_AUTH_COMPLETE,Status code:%d\n", status_code
);
3495 case FAPI_EVENT_WIFI_EVENT_ROAM_ASSOC_COMPLETE
:
3496 SLSI_INFO(sdev
, "Received Association Response\n");
3498 case WIFI_EVENT_FW_NR_FRAME_REQUEST
:
3499 SLSI_INFO(sdev
, "Send Radio Measurement Frame (Neighbor Report Req)\n");
3501 case WIFI_EVENT_FW_RM_FRAME_RESPONSE
:
3502 SLSI_INFO(sdev
, "Received Radio Measurement Frame (Radio Measurement Rep)\n");
3506 slsi_kfree_skb(skb
);
3507 SLSI_MUTEX_UNLOCK(sdev
->logger_mutex
);
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
)
3514 struct sk_buff
*skb
;
3515 int event_id
= SLSI_NL80211_LOGGER_RING_EVENT
;
3516 struct slsi_dev
*sdev
= ctx
;
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
);
3522 skb
= cfg80211_vendor_event_alloc(sdev
->wiphy
, buffer_size
, event_id
, GFP_KERNEL
);
3525 SLSI_ERR_NODEV("Failed to allocate skb for vendor event: %d\n", event_id
);
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
);
3535 cfg80211_vendor_event(skb
, GFP_KERNEL
);
3538 static void slsi_on_alert(char *buffer
, int buffer_size
, int err_code
, void *ctx
)
3540 struct sk_buff
*skb
;
3541 int event_id
= SLSI_NL80211_LOGGER_FW_DUMP_EVENT
;
3542 struct slsi_dev
*sdev
= ctx
;
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
);
3549 skb
= cfg80211_vendor_event_alloc(sdev
->wiphy
, buffer_size
, event_id
, GFP_KERNEL
);
3552 SLSI_ERR_NODEV("Failed to allocate skb for vendor event: %d\n", event_id
);
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
);
3562 cfg80211_vendor_event(skb
, GFP_KERNEL
);
3564 SLSI_MUTEX_UNLOCK(sdev
->logger_mutex
);
3567 static void slsi_on_firmware_memory_dump(char *buffer
, int buffer_size
, void *ctx
)
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");
3577 mem_dump_buffer_size
= buffer_size
;
3578 memcpy(mem_dump_buffer
, buffer
, mem_dump_buffer_size
);
3581 static void slsi_on_driver_memory_dump(char *buffer
, int buffer_size
, void *ctx
)
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");
3592 memcpy(mem_dump_buffer
, buffer
, mem_dump_buffer_size
);
3595 static int slsi_enable_logging(struct slsi_dev
*sdev
, bool enable
)
3598 #ifdef ENABLE_WIFI_LOGGER_MIB_WRITE
3599 struct slsi_mib_data mib_data
= { 0, NULL
};
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");
3608 status
= slsi_mlme_set(sdev
, NULL
, mib_data
.data
, mib_data
.dataLength
);
3609 kfree(mib_data
.data
);
3611 SLSI_ERR(sdev
, "Err setting unifiLoggerEnabled MIB. error = %d\n", status
);
3616 SLSI_DBG3(sdev
, SLSI_GSCAN
, "UnifiLoggerEnabled MIB write disabled\n");
3621 static int slsi_start_logging(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
3623 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
3627 char ring_name
[32] = {0};
3628 int verbose_level
= 0;
3630 int max_interval_sec
= 0;
3631 int min_data_size
= 0;
3632 const struct nlattr
*attr
;
3634 SLSI_DBG3(sdev
, SLSI_GSCAN
, "\n");
3635 SLSI_MUTEX_LOCK(sdev
->logger_mutex
);
3636 nla_for_each_attr(attr
, data
, len
, temp
) {
3642 type
= nla_type(attr
);
3645 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_RING_NAME
:
3646 strncpy(ring_name
, nla_data(attr
), MIN(sizeof(ring_name
) - 1, nla_len(attr
)));
3648 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_VERBOSE_LEVEL
:
3649 if (nla_len(attr
) != (SLSI_NL_ATTRIBUTE_U32_LEN
- NLA_HDRLEN
)) {
3653 verbose_level
= nla_get_u32(attr
);
3655 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_RING_FLAGS
:
3656 if (nla_len(attr
) != (SLSI_NL_ATTRIBUTE_U32_LEN
- NLA_HDRLEN
)) {
3660 ring_flags
= nla_get_u32(attr
);
3662 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_LOG_MAX_INTERVAL
:
3663 if (nla_len(attr
) != (SLSI_NL_ATTRIBUTE_U32_LEN
- NLA_HDRLEN
)) {
3667 max_interval_sec
= nla_get_u32(attr
);
3669 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_LOG_MIN_DATA_SIZE
:
3670 if (nla_len(attr
) != (SLSI_NL_ATTRIBUTE_U32_LEN
- NLA_HDRLEN
)) {
3674 min_data_size
= nla_get_u32(attr
);
3677 SLSI_ERR(sdev
, "Unknown type: %d\n", type
);
3682 ret
= scsc_wifi_set_log_handler(slsi_on_ring_buffer_data
, sdev
);
3684 SLSI_ERR(sdev
, "scsc_wifi_set_log_handler failed ret: %d\n", ret
);
3687 ret
= scsc_wifi_set_alert_handler(slsi_on_alert
, sdev
);
3689 SLSI_ERR(sdev
, "Warning : scsc_wifi_set_alert_handler failed ret: %d\n", ret
);
3691 ret
= slsi_enable_logging(sdev
, 1);
3693 SLSI_ERR(sdev
, "slsi_enable_logging for enable = 1, failed ret: %d\n", ret
);
3694 goto exit_with_reset_alert_handler
;
3696 ret
= scsc_wifi_start_logging(verbose_level
, ring_flags
, max_interval_sec
, min_data_size
, ring_name
);
3698 SLSI_ERR(sdev
, "scsc_wifi_start_logging failed ret: %d\n", ret
);
3699 goto exit_with_disable_logging
;
3703 exit_with_disable_logging
:
3704 ret
= slsi_enable_logging(sdev
, 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();
3710 SLSI_ERR(sdev
, "Warning : scsc_wifi_reset_alert_handler failed ret: %d\n", ret
);
3711 ret
= scsc_wifi_reset_log_handler();
3713 SLSI_ERR(sdev
, "scsc_wifi_reset_log_handler failed ret: %d\n", ret
);
3715 SLSI_MUTEX_UNLOCK(sdev
->logger_mutex
);
3719 static int slsi_reset_logging(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
3721 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
3724 SLSI_DBG3(sdev
, SLSI_GSCAN
, "\n");
3725 SLSI_MUTEX_LOCK(sdev
->logger_mutex
);
3726 ret
= slsi_enable_logging(sdev
, 0);
3728 SLSI_ERR(sdev
, "slsi_enable_logging for enable = 0, failed ret: %d\n", ret
);
3729 ret
= scsc_wifi_reset_log_handler();
3731 SLSI_ERR(sdev
, "scsc_wifi_reset_log_handler failed ret: %d\n", ret
);
3732 ret
= scsc_wifi_reset_alert_handler();
3734 SLSI_ERR(sdev
, "Warning : scsc_wifi_reset_alert_handler failed ret: %d\n", ret
);
3735 SLSI_MUTEX_UNLOCK(sdev
->logger_mutex
);
3739 static int slsi_trigger_fw_mem_dump(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
3741 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
3743 struct sk_buff
*skb
= NULL
;
3746 SLSI_DBG3(sdev
, SLSI_GSCAN
, "\n");
3747 SLSI_MUTEX_LOCK(sdev
->logger_mutex
);
3749 ret
= scsc_wifi_get_firmware_memory_dump(slsi_on_firmware_memory_dump
, sdev
);
3751 SLSI_ERR(sdev
, "scsc_wifi_get_firmware_memory_dump failed : %d\n", ret
);
3755 /* Alloc the SKB for vendor_event */
3756 skb
= cfg80211_vendor_cmd_alloc_reply_skb(wiphy
, length
);
3758 SLSI_ERR_NODEV("Failed to allocate skb for Vendor event\n");
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
);
3770 ret
= cfg80211_vendor_cmd_reply(skb
);
3773 SLSI_ERR(sdev
, "Vendor Command reply failed ret:%d\n", ret
);
3776 SLSI_MUTEX_UNLOCK(sdev
->logger_mutex
);
3780 static int slsi_get_fw_mem_dump(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
3782 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
3787 void __user
*user_buf
= NULL
;
3788 const struct nlattr
*attr
;
3789 struct sk_buff
*skb
;
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
);
3796 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_FW_DUMP_LEN
:
3797 buf_len
= nla_get_u32(attr
);
3799 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_FW_DUMP_DATA
:
3800 user_buf
= (void __user
*)(unsigned long)nla_get_u64(attr
);
3803 SLSI_ERR(sdev
, "Unknown type: %d\n", type
);
3804 SLSI_MUTEX_UNLOCK(sdev
->logger_mutex
);
3808 if (buf_len
> 0 && user_buf
) {
3809 ret
= copy_to_user(user_buf
, mem_dump_buffer
, buf_len
);
3811 SLSI_ERR(sdev
, "failed to copy memdump into user buffer : %d\n", ret
);
3815 /* Alloc the SKB for vendor_event */
3816 skb
= cfg80211_vendor_cmd_alloc_reply_skb(wiphy
, 100);
3818 SLSI_ERR_NODEV("Failed to allocate skb for Vendor event\n");
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
);
3831 ret
= cfg80211_vendor_cmd_reply(skb
);
3834 SLSI_ERR(sdev
, "Vendor Command reply failed ret:%d\n", ret
);
3838 kfree(mem_dump_buffer
);
3839 mem_dump_buffer
= NULL
;
3840 SLSI_MUTEX_UNLOCK(sdev
->logger_mutex
);
3844 static int slsi_trigger_driver_mem_dump(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
3846 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
3848 struct sk_buff
*skb
= NULL
;
3851 SLSI_DBG3(sdev
, SLSI_GSCAN
, "\n");
3852 SLSI_MUTEX_LOCK(sdev
->logger_mutex
);
3854 ret
= scsc_wifi_get_driver_memory_dump(slsi_on_driver_memory_dump
, sdev
);
3856 SLSI_ERR(sdev
, "scsc_wifi_get_driver_memory_dump failed : %d\n", ret
);
3860 /* Alloc the SKB for vendor_event */
3861 skb
= cfg80211_vendor_cmd_alloc_reply_skb(wiphy
, length
);
3863 SLSI_ERR_NODEV("Failed to allocate skb for Vendor event\n");
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
);
3875 ret
= cfg80211_vendor_cmd_reply(skb
);
3878 SLSI_ERR(sdev
, "Vendor Command reply failed ret:%d\n", ret
);
3881 SLSI_MUTEX_UNLOCK(sdev
->logger_mutex
);
3885 static int slsi_get_driver_mem_dump(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
3887 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
3892 void __user
*user_buf
= NULL
;
3893 const struct nlattr
*attr
;
3894 struct sk_buff
*skb
;
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
);
3901 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_DRIVER_DUMP_LEN
:
3902 buf_len
= nla_get_u32(attr
);
3904 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_DRIVER_DUMP_DATA
:
3905 user_buf
= (void __user
*)(unsigned long)nla_get_u64(attr
);
3908 SLSI_ERR(sdev
, "Unknown type: %d\n", type
);
3909 SLSI_MUTEX_UNLOCK(sdev
->logger_mutex
);
3913 if (buf_len
> 0 && user_buf
) {
3914 ret
= copy_to_user(user_buf
, mem_dump_buffer
, buf_len
);
3916 SLSI_ERR(sdev
, "failed to copy memdump into user buffer : %d\n", ret
);
3920 /* Alloc the SKB for vendor_event */
3921 skb
= cfg80211_vendor_cmd_alloc_reply_skb(wiphy
, 100);
3923 SLSI_ERR_NODEV("Failed to allocate skb for Vendor event\n");
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
);
3936 ret
= cfg80211_vendor_cmd_reply(skb
);
3939 SLSI_ERR(sdev
, "Vendor Command reply failed ret:%d\n", ret
);
3943 kfree(mem_dump_buffer
);
3944 mem_dump_buffer
= NULL
;
3945 SLSI_MUTEX_UNLOCK(sdev
->logger_mutex
);
3949 static int slsi_get_version(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
3951 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
3955 int buffer_size
= 1024;
3956 bool log_version
= false;
3958 const struct nlattr
*attr
;
3960 buffer
= kzalloc(buffer_size
, GFP_KERNEL
);
3962 SLSI_ERR(sdev
, "No mem. Size:%d\n", buffer_size
);
3965 SLSI_MUTEX_LOCK(sdev
->logger_mutex
);
3966 nla_for_each_attr(attr
, data
, len
, temp
) {
3967 type
= nla_type(attr
);
3969 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_DRIVER_VERSION
:
3972 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_FW_VERSION
:
3973 log_version
= false;
3976 SLSI_ERR(sdev
, "Unknown type: %d\n", type
);
3983 ret
= scsc_wifi_get_driver_version(buffer
, buffer_size
);
3985 ret
= scsc_wifi_get_firmware_version(buffer
, buffer_size
);
3988 SLSI_ERR(sdev
, "failed to get the version %d\n", ret
);
3992 ret
= slsi_vendor_cmd_reply(wiphy
, buffer
, strlen(buffer
));
3995 SLSI_MUTEX_UNLOCK(sdev
->logger_mutex
);
3999 static int slsi_get_ring_buffers_status(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
4001 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
4004 struct sk_buff
*skb
;
4005 struct scsc_wifi_ring_buffer_status status
[num_rings
];
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
);
4012 SLSI_ERR(sdev
, "scsc_wifi_get_ring_buffers_status failed ret:%d\n", ret
);
4016 /* Alloc the SKB for vendor_event */
4017 skb
= cfg80211_vendor_cmd_alloc_reply_skb(wiphy
, 700);
4019 SLSI_ERR_NODEV("Failed to allocate skb for Vendor event\n");
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
);
4033 ret
= cfg80211_vendor_cmd_reply(skb
);
4036 SLSI_ERR(sdev
, "Vendor Command reply failed ret:%d\n", ret
);
4038 SLSI_MUTEX_UNLOCK(sdev
->logger_mutex
);
4042 static int slsi_get_ring_data(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
4044 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
4048 char ring_name
[32] = {0};
4049 const struct nlattr
*attr
;
4051 SLSI_DBG3(sdev
, SLSI_GSCAN
, "\n");
4052 SLSI_MUTEX_LOCK(sdev
->logger_mutex
);
4053 nla_for_each_attr(attr
, data
, len
, temp
) {
4058 type
= nla_type(attr
);
4060 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_RING_NAME
:
4061 strncpy(ring_name
, nla_data(attr
), MIN(sizeof(ring_name
) - 1, nla_len(attr
)));
4064 SLSI_ERR(sdev
, "Unknown type: %d\n", type
);
4069 ret
= scsc_wifi_get_ring_data(ring_name
);
4071 SLSI_ERR(sdev
, "trigger_get_data failed ret:%d\n", ret
);
4073 SLSI_MUTEX_UNLOCK(sdev
->logger_mutex
);
4077 static int slsi_get_logger_supported_feature_set(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
4078 const void *data
, int len
)
4080 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
4082 u32 supported_features
= 0;
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
);
4088 SLSI_ERR(sdev
, "scsc_wifi_get_logger_supported_feature_set failed ret:%d\n", ret
);
4091 ret
= slsi_vendor_cmd_reply(wiphy
, &supported_features
, sizeof(supported_features
));
4093 SLSI_MUTEX_UNLOCK(sdev
->logger_mutex
);
4097 static int slsi_start_pkt_fate_monitoring(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
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
};
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");
4113 ret
= slsi_mlme_set(sdev
, NULL
, mib_data
.data
, mib_data
.dataLength
);
4116 SLSI_ERR(sdev
, "Err setting UnifiTxDataConfirm MIB. error = %d\n", ret
);
4120 ret
= scsc_wifi_start_pkt_fate_monitoring();
4122 SLSI_ERR(sdev
, "scsc_wifi_start_pkt_fate_monitoring failed, ret=%d\n", ret
);
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");
4134 ret
= slsi_mlme_set(sdev
, NULL
, mib_data
.data
, mib_data
.dataLength
);
4137 SLSI_ERR(sdev
, "Err setting UnifiTxDataConfirm MIB. error = %d\n", ret
);
4142 kfree(mib_data
.data
);
4143 SLSI_MUTEX_UNLOCK(sdev
->logger_mutex
);
4146 SLSI_ERR_NODEV("slsi_start_pkt_fate_monitoring : UnifiTxDataConfirm MIB write disabled\n");
4151 static int slsi_get_tx_pkt_fates(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
4153 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
4157 void __user
*user_buf
= NULL
;
4159 size_t provided_count
= 0;
4160 struct sk_buff
*skb
;
4161 const struct nlattr
*attr
;
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
);
4168 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_PKT_FATE_NUM
:
4169 req_count
= nla_get_u32(attr
);
4171 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_PKT_FATE_DATA
:
4172 user_buf
= (void __user
*)(unsigned long)nla_get_u64(attr
);
4175 SLSI_ERR(sdev
, "Unknown type: %d\n", type
);
4181 ret
= scsc_wifi_get_tx_pkt_fates(user_buf
, req_count
, &provided_count
);
4183 SLSI_ERR(sdev
, "scsc_wifi_get_tx_pkt_fates failed ret: %d\n", ret
);
4187 /* Alloc the SKB for vendor_event */
4188 skb
= cfg80211_vendor_cmd_alloc_reply_skb(wiphy
, 200);
4190 SLSI_ERR_NODEV("Failed to allocate skb for Vendor event\n");
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
);
4202 ret
= cfg80211_vendor_cmd_reply(skb
);
4205 SLSI_ERR(sdev
, "Vendor Command reply failed ret:%d\n", ret
);
4207 SLSI_MUTEX_UNLOCK(sdev
->logger_mutex
);
4211 static int slsi_get_rx_pkt_fates(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
4213 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
4217 void __user
*user_buf
= NULL
;
4219 size_t provided_count
= 0;
4220 struct sk_buff
*skb
;
4221 const struct nlattr
*attr
;
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
);
4228 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_PKT_FATE_NUM
:
4229 req_count
= nla_get_u32(attr
);
4231 case SLSI_ENHANCED_LOGGING_ATTRIBUTE_PKT_FATE_DATA
:
4232 user_buf
= (void __user
*)(unsigned long)nla_get_u64(attr
);
4235 SLSI_ERR(sdev
, "Unknown type: %d\n", type
);
4241 ret
= scsc_wifi_get_rx_pkt_fates(user_buf
, req_count
, &provided_count
);
4243 SLSI_ERR(sdev
, "scsc_wifi_get_rx_pkt_fates failed ret: %d\n", ret
);
4247 /* Alloc the SKB for vendor_event */
4248 skb
= cfg80211_vendor_cmd_alloc_reply_skb(wiphy
, 200);
4250 SLSI_ERR_NODEV("Failed to allocate skb for Vendor event\n");
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
);
4262 ret
= cfg80211_vendor_cmd_reply(skb
);
4265 SLSI_ERR(sdev
, "Vendor Command reply failed ret:%d\n", ret
);
4267 SLSI_MUTEX_UNLOCK(sdev
->logger_mutex
);
4271 static int slsi_get_wake_reason_stats(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
4273 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
4274 struct slsi_wlan_driver_wake_reason_cnt wake_reason_count
;
4278 const struct nlattr
*attr
;
4279 struct sk_buff
*skb
;
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
));
4285 SLSI_MUTEX_LOCK(sdev
->logger_mutex
);
4286 nla_for_each_attr(attr
, data
, len
, temp
) {
4287 type
= nla_type(attr
);
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
);
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
);
4296 SLSI_ERR(sdev
, "Unknown type: %d\n", type
);
4303 SLSI_ERR(sdev
, "Failed to get wake reason stats : %d\n", ret
);
4307 /* Alloc the SKB for vendor_event */
4308 skb
= cfg80211_vendor_cmd_alloc_reply_skb(wiphy
, 700);
4310 SLSI_ERR_NODEV("Failed to allocate skb for Vendor event\n");
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
);
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
);
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
);
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
);
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
);
4372 ret
= cfg80211_vendor_cmd_reply(skb
);
4375 SLSI_ERR(sdev
, "Vendor Command reply failed ret:%d\n", ret
);
4377 SLSI_MUTEX_UNLOCK(sdev
->logger_mutex
);
4381 #endif /* CONFIG_SCSC_WLAN_ENHANCED_LOGGING */
4383 static int slsi_acs_validate_width_hw_mode(struct slsi_acs_request
*request
)
4385 if (request
->hw_mode
!= SLSI_ACS_MODE_IEEE80211A
&& request
->hw_mode
!= SLSI_ACS_MODE_IEEE80211B
&&
4386 request
->hw_mode
!= SLSI_ACS_MODE_IEEE80211G
)
4388 if (request
->ch_width
!= 20 && request
->ch_width
!= 40 && request
->ch_width
!= 80)
4393 static int slsi_acs_init(struct wiphy
*wiphy
,
4394 struct wireless_dev
*wdev
, const void *data
, int len
)
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
;
4402 const struct nlattr
*attr
;
4404 u32
*freq_list
= NULL
;
4405 int freq_list_len
= 0;
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");
4412 if (wdev
->iftype
!= NL80211_IFTYPE_AP
) {
4413 SLSI_ERR(sdev
, "Invalid iftype: %d\n", wdev
->iftype
);
4417 SLSI_ERR(sdev
, "Dev not found!\n");
4420 request
= kcalloc(1, sizeof(*request
), GFP_KERNEL
);
4422 SLSI_ERR(sdev
, "No memory for request!");
4425 ndev_vif
= netdev_priv(dev
);
4427 SLSI_MUTEX_LOCK(ndev_vif
->scan_mutex
);
4428 nla_for_each_attr(attr
, data
, len
, temp
) {
4435 type
= nla_type(attr
);
4438 case SLSI_ACS_ATTR_HW_MODE
:
4440 if (nla_len(attr
) != (SLSI_NL_ATTRIBUTE_U8_LEN
- NLA_HDRLEN
)) {
4445 request
->hw_mode
= nla_get_u8(attr
);
4446 SLSI_INFO(sdev
, "ACS hw mode: %d\n", request
->hw_mode
);
4449 case SLSI_ACS_ATTR_CHWIDTH
:
4451 if (nla_len(attr
) != (SLSI_NL_ATTRIBUTE_U16_LEN
- NLA_HDRLEN
)) {
4456 request
->ch_width
= nla_get_u16(attr
);
4457 SLSI_INFO(sdev
, "ACS ch_width: %d\n", request
->ch_width
);
4460 case SLSI_ACS_ATTR_FREQ_LIST
:
4462 if (freq_list
) /* This check is to avoid Prevent Issue */
4465 freq_list
= kmalloc(nla_len(attr
), GFP_KERNEL
);
4467 SLSI_ERR(sdev
, "No memory for frequency list!");
4469 SLSI_MUTEX_UNLOCK(ndev_vif
->scan_mutex
);
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
);
4478 if (type
> SLSI_ACS_ATTR_MAX
)
4479 SLSI_ERR(sdev
, "Invalid type : %d\n", type
);
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;
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
4496 IEEE80211_CHAN_NO_IR
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
);
4509 idx
= slsi_find_chan_idx(channels
[num_channels
]->hw_value
, request
->hw_mode
);
4510 ch_info
[idx
].chan
= channels
[num_channels
]->hw_value
;
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;
4524 SLSI_MUTEX_UNLOCK(ndev_vif
->scan_mutex
);
4528 if (request
->hw_mode
== SLSI_ACS_MODE_IEEE80211A
)
4529 request
->ch_list_len
= 25;
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
,
4537 FAPI_SCANTYPE_AP_AUTO_CHANNEL_SELECTION
,
4538 FAPI_REPORTMODE_REAL_TIME
,
4546 ndev_vif
->scan
[SLSI_SCAN_HW_ID
].is_blocking_scan
);
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
);
4555 SLSI_MUTEX_UNLOCK(ndev_vif
->scan_mutex
);
4559 static int slsi_configure_latency_mode(struct wiphy
*wiphy
, struct wireless_dev
*wdev
, const void *data
, int len
)
4561 struct slsi_dev
*sdev
= SDEV_FROM_WIPHY(wiphy
);
4562 struct net_device
*dev
= wdev
->netdev
;
4565 const struct nlattr
*attr
;
4567 int low_latency_mode
= 0;
4570 SLSI_ERR(sdev
, "dev is NULL!!\n");
4574 nla_for_each_attr(attr
, data
, len
, temp
) {
4575 type
= nla_type(attr
);
4577 case SLSI_NL_ATTRIBUTE_LATENCY_MODE
:
4578 low_latency_mode
= nla_get_u8(attr
);
4581 SLSI_ERR_NODEV("Unknown attribute: %d\n", type
);
4587 ret
= slsi_set_latency_mode(dev
, low_latency_mode
, len
);
4589 SLSI_ERR(sdev
, "Error in setting low latency mode ret:%d\n", ret
);
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
},
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
},
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
}
4632 static const struct wiphy_vendor_command slsi_vendor_cmd
[] = {
4635 .vendor_id
= OUI_GOOGLE
,
4636 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_GET_CAPABILITIES
4638 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4639 .doit
= slsi_gscan_get_capabilities
4643 .vendor_id
= OUI_GOOGLE
,
4644 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_GET_VALID_CHANNELS
4646 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4647 .doit
= slsi_gscan_get_valid_channel
4651 .vendor_id
= OUI_GOOGLE
,
4652 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_ADD_GSCAN
4654 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4655 .doit
= slsi_gscan_add
4659 .vendor_id
= OUI_GOOGLE
,
4660 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_DEL_GSCAN
4662 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4663 .doit
= slsi_gscan_del
4667 .vendor_id
= OUI_GOOGLE
,
4668 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_GET_SCAN_RESULTS
4670 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4671 .doit
= slsi_gscan_get_scan_results
4675 .vendor_id
= OUI_GOOGLE
,
4676 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_SET_GSCAN_OUI
4678 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4679 .doit
= slsi_gscan_set_oui
4681 #ifdef CONFIG_SCSC_WLAN_KEY_MGMT_OFFLOAD
4684 .vendor_id
= OUI_SAMSUNG
,
4685 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_KEY_MGMT_SET_KEY
4687 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4688 .doit
= slsi_key_mgmt_set_pmk
4693 .vendor_id
= OUI_GOOGLE
,
4694 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_SET_BSSID_BLACKLIST
4696 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4697 .doit
= slsi_set_bssid_blacklist
4701 .vendor_id
= OUI_GOOGLE
,
4702 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_START_KEEP_ALIVE_OFFLOAD
4704 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4705 .doit
= slsi_start_keepalive_offload
4709 .vendor_id
= OUI_GOOGLE
,
4710 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_STOP_KEEP_ALIVE_OFFLOAD
4712 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4713 .doit
= slsi_stop_keepalive_offload
4717 .vendor_id
= OUI_GOOGLE
,
4718 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_SET_EPNO_LIST
4720 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4721 .doit
= slsi_set_epno_ssid
4725 .vendor_id
= OUI_GOOGLE
,
4726 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_SET_HS_LIST
4728 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4729 .doit
= slsi_set_hs_params
4733 .vendor_id
= OUI_GOOGLE
,
4734 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_RESET_HS_LIST
4736 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4737 .doit
= slsi_reset_hs_params
4741 .vendor_id
= OUI_GOOGLE
,
4742 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_SET_RSSI_MONITOR
4744 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4745 .doit
= slsi_set_rssi_monitor
4749 .vendor_id
= OUI_GOOGLE
,
4750 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_LSTATS_SUBCMD_SET_STATS
4752 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4753 .doit
= slsi_lls_set_stats
4757 .vendor_id
= OUI_GOOGLE
,
4758 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_LSTATS_SUBCMD_GET_STATS
4760 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4761 .doit
= slsi_lls_get_stats
4765 .vendor_id
= OUI_GOOGLE
,
4766 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_LSTATS_SUBCMD_CLEAR_STATS
4768 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4769 .doit
= slsi_lls_clear_stats
4773 .vendor_id
= OUI_GOOGLE
,
4774 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_GET_FEATURE_SET
4777 .doit
= slsi_get_feature_set
4781 .vendor_id
= OUI_GOOGLE
,
4782 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_SET_COUNTRY_CODE
4784 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4785 .doit
= slsi_set_country_code
4789 .vendor_id
= OUI_GOOGLE
,
4790 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_CONFIGURE_ND_OFFLOAD
4792 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4793 .doit
= slsi_configure_nd_offload
4795 #ifdef CONFIG_SCSC_WLAN_ENHANCED_LOGGING
4798 .vendor_id
= OUI_GOOGLE
,
4799 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_START_LOGGING
4801 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4802 .doit
= slsi_start_logging
4806 .vendor_id
= OUI_GOOGLE
,
4807 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_RESET_LOGGING
4809 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4810 .doit
= slsi_reset_logging
4814 .vendor_id
= OUI_GOOGLE
,
4815 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_TRIGGER_FW_MEM_DUMP
4817 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4818 .doit
= slsi_trigger_fw_mem_dump
4822 .vendor_id
= OUI_GOOGLE
,
4823 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_GET_FW_MEM_DUMP
4825 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4826 .doit
= slsi_get_fw_mem_dump
4830 .vendor_id
= OUI_GOOGLE
,
4831 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_TRIGGER_DRIVER_MEM_DUMP
4833 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4834 .doit
= slsi_trigger_driver_mem_dump
4838 .vendor_id
= OUI_GOOGLE
,
4839 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_GET_DRIVER_MEM_DUMP
4841 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4842 .doit
= slsi_get_driver_mem_dump
4846 .vendor_id
= OUI_GOOGLE
,
4847 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_GET_VERSION
4849 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4850 .doit
= slsi_get_version
4854 .vendor_id
= OUI_GOOGLE
,
4855 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_GET_RING_STATUS
4857 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4858 .doit
= slsi_get_ring_buffers_status
4862 .vendor_id
= OUI_GOOGLE
,
4863 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_GET_RING_DATA
4865 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4866 .doit
= slsi_get_ring_data
4870 .vendor_id
= OUI_GOOGLE
,
4871 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_GET_FEATURE
4873 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4874 .doit
= slsi_get_logger_supported_feature_set
4878 .vendor_id
= OUI_GOOGLE
,
4879 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_START_PKT_FATE_MONITORING
4881 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4882 .doit
= slsi_start_pkt_fate_monitoring
4886 .vendor_id
= OUI_GOOGLE
,
4887 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_GET_TX_PKT_FATES
4889 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4890 .doit
= slsi_get_tx_pkt_fates
4894 .vendor_id
= OUI_GOOGLE
,
4895 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_GET_RX_PKT_FATES
4897 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4898 .doit
= slsi_get_rx_pkt_fates
4902 .vendor_id
= OUI_GOOGLE
,
4903 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_GET_WAKE_REASON_STATS
4905 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4906 .doit
= slsi_get_wake_reason_stats
4908 #endif /* CONFIG_SCSC_WLAN_ENHANCED_LOGGING */
4909 #ifdef CONFIG_SCSC_WIFI_NAN_ENABLE
4912 .vendor_id
= OUI_GOOGLE
,
4913 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_NAN_ENABLE
4915 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4916 .doit
= slsi_nan_enable
4920 .vendor_id
= OUI_GOOGLE
,
4921 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_NAN_DISABLE
4923 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4924 .doit
= slsi_nan_disable
4928 .vendor_id
= OUI_GOOGLE
,
4929 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_NAN_PUBLISH
4931 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4932 .doit
= slsi_nan_publish
4936 .vendor_id
= OUI_GOOGLE
,
4937 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_NAN_PUBLISHCANCEL
4939 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4940 .doit
= slsi_nan_publish_cancel
4944 .vendor_id
= OUI_GOOGLE
,
4945 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_NAN_SUBSCRIBE
4947 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4948 .doit
= slsi_nan_subscribe
4952 .vendor_id
= OUI_GOOGLE
,
4953 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_NAN_SUBSCRIBECANCEL
4955 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4956 .doit
= slsi_nan_subscribe_cancel
4960 .vendor_id
= OUI_GOOGLE
,
4961 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_NAN_TXFOLLOWUP
4963 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4964 .doit
= slsi_nan_transmit_followup
4968 .vendor_id
= OUI_GOOGLE
,
4969 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_NAN_CONFIG
4971 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4972 .doit
= slsi_nan_set_config
4976 .vendor_id
= OUI_GOOGLE
,
4977 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_NAN_CAPABILITIES
4979 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4980 .doit
= slsi_nan_get_capabilities
4985 .vendor_id
= OUI_GOOGLE
,
4986 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_GET_ROAMING_CAPABILITIES
4988 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4989 .doit
= slsi_get_roaming_capabilities
4993 .vendor_id
= OUI_GOOGLE
,
4994 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_SET_ROAMING_STATE
4996 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
4997 .doit
= slsi_set_roaming_state
5001 .vendor_id
= OUI_GOOGLE
,
5002 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_RTT_GET_CAPABILITIES
5004 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
5005 .doit
= slsi_rtt_get_capabilities
5009 .vendor_id
= OUI_GOOGLE
,
5010 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_RTT_RANGE_START
5012 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
5013 .doit
= slsi_rtt_set_config
5017 .vendor_id
= OUI_GOOGLE
,
5018 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_RTT_RANGE_CANCEL
5020 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
5021 .doit
= slsi_rtt_cancel_config
5025 .vendor_id
= OUI_SAMSUNG
,
5026 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_ACS_INIT
5028 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
5029 .doit
= slsi_acs_init
5033 .vendor_id
= OUI_GOOGLE
,
5034 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_APF_GET_CAPABILITIES
5036 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
5037 .doit
= slsi_apf_get_capabilities
5041 .vendor_id
= OUI_GOOGLE
,
5042 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_APF_SET_FILTER
5044 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
5045 .doit
= slsi_apf_set_filter
5049 .vendor_id
= OUI_GOOGLE
,
5050 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_APF_READ_FILTER
5052 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
5053 .doit
= slsi_apf_read_filter
5057 .vendor_id
= OUI_GOOGLE
,
5058 .subcmd
= SLSI_NL80211_VENDOR_SUBCMD_SET_LATENCY_MODE
5060 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
| WIPHY_VENDOR_CMD_NEED_NETDEV
,
5061 .doit
= slsi_configure_latency_mode
5065 void slsi_nl80211_vendor_deinit(struct slsi_dev
*sdev
)
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;
5073 SLSI_DBG2(sdev
, SLSI_GSCAN
, "Gscan cleanup\n");
5074 slsi_gscan_flush_scan_results(sdev
);
5078 void slsi_nl80211_vendor_init(struct slsi_dev
*sdev
)
5082 SLSI_DBG2(sdev
, SLSI_GSCAN
, "Init vendor command and events\n");
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
);
5089 for (i
= 0; i
< SLSI_GSCAN_MAX_BUCKETS
; i
++)
5090 sdev
->bucket
[i
].scan_id
= (SLSI_GSCAN_SCAN_ID_START
+ i
);
5092 for (i
= 0; i
< SLSI_GSCAN_HASH_TABLE_SIZE
; i
++)
5093 sdev
->gscan_hash_table
[i
] = NULL
;
5095 INIT_LIST_HEAD(&sdev
->hotlist_results
);