1 /****************************************************************************
3 * Copyright (c) 2012 - 2018 Samsung Electronics Co., Ltd. All rights reserved
5 ****************************************************************************/
14 #include <net/netlink.h>
15 #include <linux/netdevice.h>
16 #include <linux/ieee80211.h>
18 #include <scsc/scsc_mx.h>
19 #include <scsc/scsc_log_collector.h>
23 #define CMD_RXFILTERADD "RXFILTER-ADD"
24 #define CMD_RXFILTERREMOVE "RXFILTER-REMOVE"
25 #define CMD_RXFILTERSTART "RXFILTER-START"
26 #define CMD_RXFILTERSTOP "RXFILTER-STOP"
27 #define CMD_SETCOUNTRYREV "SETCOUNTRYREV"
28 #define CMD_GETCOUNTRYREV "GETCOUNTRYREV"
29 #define CMD_SETROAMTRIGGER "SETROAMTRIGGER"
30 #define CMD_GETROAMTRIGGER "GETROAMTRIGGER"
31 #define CMD_SETSUSPENDMODE "SETSUSPENDMODE"
32 #define CMD_SETROAMDELTA "SETROAMDELTA"
33 #define CMD_GETROAMDELTA "GETROAMDELTA"
34 #define CMD_SETROAMSCANPERIOD "SETROAMSCANPERIOD"
35 #define CMD_GETROAMSCANPERIOD "GETROAMSCANPERIOD"
36 #define CMD_SETFULLROAMSCANPERIOD "SETFULLROAMSCANPERIOD"
37 #define CMD_GETFULLROAMSCANPERIOD "GETFULLROAMSCANPERIOD"
38 #define CMD_SETSCANCHANNELTIME "SETSCANCHANNELTIME"
39 #define CMD_GETSCANCHANNELTIME "GETSCANCHANNELTIME"
40 #define CMD_SETSCANNPROBES "SETSCANNPROBES"
41 #define CMD_GETSCANNPROBES "GETSCANNPROBES"
42 #define CMD_SETROAMMODE "SETROAMMODE"
43 #define CMD_GETROAMMODE "GETROAMMODE"
44 #define CMD_SETROAMINTRABAND "SETROAMINTRABAND"
45 #define CMD_GETROAMINTRABAND "GETROAMINTRABAND"
46 #define CMD_SETROAMBAND "SETROAMBAND"
47 #define CMD_GETROAMBAND "GETROAMBAND"
48 #define CMD_SETROAMSCANCONTROL "SETROAMSCANCONTROL"
49 #define CMD_GETROAMSCANCONTROL "GETROAMSCANCONTROL"
50 #define CMD_SETSCANHOMETIME "SETSCANHOMETIME"
51 #define CMD_GETSCANHOMETIME "GETSCANHOMETIME"
52 #define CMD_SETSCANHOMEAWAYTIME "SETSCANHOMEAWAYTIME"
53 #define CMD_GETSCANHOMEAWAYTIME "GETSCANHOMEAWAYTIME"
54 #define CMD_SETOKCMODE "SETOKCMODE"
55 #define CMD_GETOKCMODE "GETOKCMODE"
56 #define CMD_SETWESMODE "SETWESMODE"
57 #define CMD_GETWESMODE "GETWESMODE"
58 #define CMD_SET_PMK "SET_PMK"
59 #define CMD_HAPD_GET_CHANNEL "HAPD_GET_CHANNEL"
60 #define CMD_SET_SAP_CHANNEL_LIST "SET_SAP_CHANNEL_LIST"
61 #define CMD_REASSOC "REASSOC"
62 #define CMD_SETROAMSCANCHANNELS "SETROAMSCANCHANNELS"
63 #define CMD_GETROAMSCANCHANNELS "GETROAMSCANCHANNELS"
64 #define CMD_SENDACTIONFRAME "SENDACTIONFRAME"
65 #define CMD_HAPD_MAX_NUM_STA "HAPD_MAX_NUM_STA"
66 #define CMD_COUNTRY "COUNTRY"
67 #define CMD_SEND_GK "SEND_GK"
68 #define CMD_SETAPP2PWPSIE "SET_AP_P2P_WPS_IE"
69 #define CMD_P2PSETPS "P2P_SET_PS"
70 #define CMD_P2PSETNOA "P2P_SET_NOA"
71 #define CMD_P2PECSA "P2P_ECSA"
72 #define CMD_P2PLOSTART "P2P_LO_START"
73 #define CMD_P2PLOSTOP "P2P_LO_STOP"
74 #define CMD_TDLSCHANNELSWITCH "TDLS_CHANNEL_SWITCH"
75 #define CMD_SETROAMOFFLOAD "SETROAMOFFLOAD"
76 #define CMD_SETROAMOFFLAPLIST "SETROAMOFFLAPLIST"
77 #ifdef CONFIG_SCSC_WLAN_LOW_LATENCY_MODE
78 #define CMD_SET_LATENCY_MODE "SET_LATENCY_MODE"
79 #define CMD_SET_POWER_MGMT "SET_POWER_MGMT"
81 #define CMD_SET_DISCONNECT_IES "SET_DISCONNECT_IES"
83 #define CMD_SETBAND "SETBAND"
84 #define CMD_GETBAND "GETBAND"
85 #define CMD_SET_FCC_CHANNEL "SET_FCC_CHANNEL"
87 #define CMD_FAKEMAC "FAKEMAC"
89 #define CMD_GETBSSRSSI "GET_BSS_RSSI"
90 #define CMD_GETBSSINFO "GETBSSINFO"
91 #define CMD_GETSTAINFO "GETSTAINFO"
92 #define CMD_GETASSOCREJECTINFO "GETASSOCREJECTINFO"
94 #ifdef CONFIG_SLSI_WLAN_STA_FWD_BEACON
95 #define CMD_BEACON_RECV "BEACON_RECV"
97 #ifdef CONFIG_SCSC_WLAN_STA_ENHANCED_ARP_DETECT
98 #define CMD_SET_ENHANCED_ARP_TARGET "SET_ENHANCED_ARP_TARGET"
99 #define CMD_GET_ENHANCED_ARP_COUNTS "GET_ENHANCED_ARP_COUNTS"
102 /* Known commands from framework for which no handlers */
103 #define CMD_AMPDU_MPDU "AMPDU_MPDU"
104 #define CMD_BTCOEXMODE "BTCOEXMODE"
105 #define CMD_BTCOEXSCAN_START "BTCOEXSCAN-START"
106 #define CMD_BTCOEXSCAN_STOP "BTCOEXSCAN-STOP"
107 #define CMD_CHANGE_RL "CHANGE_RL"
108 #define CMD_INTERFACE_CREATE "INTERFACE_CREATE"
109 #define CMD_INTERFACE_DELETE "INTERFACE_DELETE"
110 #define CMD_SET_INDOOR_CHANNELS "SET_INDOOR_CHANNELS"
111 #define CMD_GET_INDOOR_CHANNELS "GET_INDOOR_CHANNELS"
112 #define CMD_LTECOEX "LTECOEX"
113 #define CMD_MIRACAST "MIRACAST"
114 #define CMD_RESTORE_RL "RESTORE_RL"
115 #define CMD_RPSMODE "RPSMODE"
116 #define CMD_SETCCXMODE "SETCCXMODE"
117 #define CMD_SETDFSSCANMODE "SETDFSSCANMODE"
118 #define CMD_SETJOINPREFER "SETJOINPREFER"
119 #define CMD_SETSINGLEANT "SETSINGLEANT"
120 #define CMD_SET_TX_POWER_CALLING "SET_TX_POWER_CALLING"
122 #define CMD_DRIVERDEBUGDUMP "DEBUG_DUMP"
123 #define CMD_DRIVERDEBUGCOMMAND "DEBUG_COMMAND"
124 #define CMD_TESTFORCEHANG "SLSI_TEST_FORCE_HANG"
125 #define CMD_GETREGULATORY "GETREGULATORY"
127 #define CMD_SET_TX_POWER_SAR "SET_TX_POWER_SAR"
128 #define CMD_GET_TX_POWER_SAR "GET_TX_POWER_SAR"
130 #ifdef CONFIG_SCSC_WLAN_ENHANCED_PKT_FILTER
131 #define CMD_ENHANCED_PKT_FILTER "ENHANCED_PKT_FILTER"
133 #define CMD_GET_MAX_LINK_SPEED "GET_MAX_LINK_SPEED"
135 #ifdef CONFIG_SCSC_WLAN_SET_NUM_ANTENNAS
136 #define CMD_SET_NUM_ANTENNAS "SET_NUM_ANTENNAS"
139 #define ROAMOFFLAPLIST_MIN 1
140 #define ROAMOFFLAPLIST_MAX 100
142 static int slsi_parse_hex(unsigned char c
)
144 if (c
>= '0' && c
<= '9')
146 if (c
>= 'a' && c
<= 'f')
148 if (c
>= 'A' && c
<= 'F')
153 static void slsi_machexstring_to_macarray(char *mac_str
, u8
*mac_arr
)
155 mac_arr
[0] = slsi_parse_hex(mac_str
[0]) << 4 | slsi_parse_hex(mac_str
[1]);
156 mac_arr
[1] = slsi_parse_hex(mac_str
[3]) << 4 | slsi_parse_hex(mac_str
[4]);
157 mac_arr
[2] = slsi_parse_hex(mac_str
[6]) << 4 | slsi_parse_hex(mac_str
[7]);
158 mac_arr
[3] = slsi_parse_hex(mac_str
[9]) << 4 | slsi_parse_hex(mac_str
[10]);
159 mac_arr
[4] = slsi_parse_hex(mac_str
[12]) << 4 | slsi_parse_hex(mac_str
[13]);
160 mac_arr
[5] = slsi_parse_hex(mac_str
[15]) << 4 | slsi_parse_hex(mac_str
[16]);
163 static ssize_t
slsi_set_suspend_mode(struct net_device
*dev
, char *command
)
166 struct netdev_vif
*netdev_vif
= netdev_priv(dev
);
167 struct slsi_dev
*sdev
= netdev_vif
->sdev
;
168 int user_suspend_mode
;
169 int previous_suspend_mode
;
173 user_suspend_mode
= *(command
+ strlen(CMD_SETSUSPENDMODE
) + 1) - '0';
175 SLSI_MUTEX_LOCK(sdev
->device_config_mutex
);
176 previous_suspend_mode
= sdev
->device_config
.user_suspend_mode
;
177 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
179 if (user_suspend_mode
!= previous_suspend_mode
) {
180 SLSI_MUTEX_LOCK(sdev
->netdev_add_remove_mutex
);
181 for (vif
= 1; vif
<= CONFIG_SCSC_WLAN_MAX_INTERFACES
; vif
++) {
182 struct net_device
*dev
= slsi_get_netdev_locked(sdev
, vif
);
183 struct netdev_vif
*ndev_vif
;
188 ndev_vif
= netdev_priv(dev
);
189 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
190 if ((ndev_vif
->activated
) &&
191 (ndev_vif
->vif_type
== FAPI_VIFTYPE_STATION
) &&
192 (ndev_vif
->sta
.vif_status
== SLSI_VIF_STATUS_CONNECTED
)) {
193 if (user_suspend_mode
)
194 ret
= slsi_update_packet_filters(sdev
, dev
);
196 ret
= slsi_clear_packet_filters(sdev
, dev
);
198 SLSI_NET_ERR(dev
, "Error in updating /clearing the packet filters,ret=%d", ret
);
201 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
203 SLSI_MUTEX_UNLOCK(sdev
->netdev_add_remove_mutex
);
206 SLSI_MUTEX_LOCK(sdev
->device_config_mutex
);
207 sdev
->device_config
.user_suspend_mode
= user_suspend_mode
;
208 host_state
= sdev
->device_config
.host_state
;
210 if (!sdev
->device_config
.user_suspend_mode
)
211 host_state
= host_state
| SLSI_HOSTSTATE_LCD_ACTIVE
;
213 host_state
= host_state
& ~SLSI_HOSTSTATE_LCD_ACTIVE
;
214 sdev
->device_config
.host_state
= host_state
;
216 ret
= slsi_mlme_set_host_state(sdev
, dev
, host_state
);
218 SLSI_NET_ERR(dev
, "Error in setting the Host State, ret=%d", ret
);
220 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
224 static ssize_t
slsi_set_p2p_oppps(struct net_device
*dev
, char *command
, int buf_len
)
226 struct netdev_vif
*ndev_vif
;
227 struct slsi_dev
*sdev
;
228 u8
*p2p_oppps_param
= NULL
;
230 unsigned int ct_param
;
231 unsigned int legacy_ps
;
236 p2p_oppps_param
= command
+ strlen(CMD_P2PSETPS
) + 1;
237 ndev_vif
= netdev_priv(dev
);
238 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
240 /* The NOA param shall be added only after P2P-VIF is active */
241 if ((!ndev_vif
->activated
) || (ndev_vif
->iftype
!= NL80211_IFTYPE_P2P_GO
)) {
242 SLSI_ERR_NODEV("P2P GO vif not activated\n");
247 sdev
= ndev_vif
->sdev
;
248 readbyte
= slsi_str_to_int(&p2p_oppps_param
[offset
], &legacy_ps
);
250 SLSI_ERR(sdev
, "ct_param: failed to read legacy_ps\n");
254 offset
= offset
+ readbyte
+ 1;
256 readbyte
= slsi_str_to_int(&p2p_oppps_param
[offset
], &opp_ps
);
258 SLSI_ERR(sdev
, "ct_param: failed to read ct_param\n");
262 offset
= offset
+ readbyte
+ 1;
264 readbyte
= slsi_str_to_int(&p2p_oppps_param
[offset
], &ct_param
);
266 SLSI_ERR(sdev
, "ct_param: failed to read ct_param\n");
272 result
= slsi_mlme_set_ctwindow(sdev
, dev
, opp_ps
);
273 else if (ct_param
< (unsigned int)ndev_vif
->ap
.beacon_interval
)
274 result
= slsi_mlme_set_ctwindow(sdev
, dev
, ct_param
);
276 SLSI_DBG1(sdev
, SLSI_CFG80211
, "p2p ct window = %d is out of range for beacon interval(%d)\n", ct_param
, ndev_vif
->ap
.beacon_interval
);
278 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
283 static ssize_t
slsi_p2p_set_noa_params(struct net_device
*dev
, char *command
, int buf_len
)
285 struct netdev_vif
*ndev_vif
;
286 struct slsi_dev
*sdev
;
288 u8
*noa_params
= NULL
;
291 unsigned int noa_count
;
292 unsigned int duration
;
293 unsigned int interval
;
295 noa_params
= command
+ strlen(CMD_P2PSETNOA
) + 1;
296 ndev_vif
= netdev_priv(dev
);
297 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
298 /* The NOA param shall be added only after P2P-VIF is active */
299 if ((!ndev_vif
->activated
) || (ndev_vif
->iftype
!= NL80211_IFTYPE_P2P_GO
)) {
300 SLSI_ERR_NODEV("P2P GO vif not activated\n");
305 sdev
= ndev_vif
->sdev
;
306 readbyte
= slsi_str_to_int(&noa_params
[offset
], &noa_count
);
308 SLSI_ERR(sdev
, "noa_count: failed to read a numeric value\n");
312 offset
= offset
+ readbyte
+ 1;
314 readbyte
= slsi_str_to_int(&noa_params
[offset
], &interval
);
316 SLSI_ERR(sdev
, "interval: failed to read a numeric value\n");
320 offset
= offset
+ readbyte
+ 1;
322 readbyte
= slsi_str_to_int(&noa_params
[offset
], &duration
);
324 SLSI_ERR(sdev
, "duration: failed to read a numeric value, at offset(%d)\n", offset
);
329 /* Skip start time */
330 result
= slsi_mlme_set_p2p_noa(sdev
, dev
, noa_count
, interval
, duration
);
333 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
337 static ssize_t
slsi_p2p_ecsa(struct net_device
*dev
, char *command
)
339 struct netdev_vif
*ndev_vif
;
340 struct netdev_vif
*group_dev_vif
;
341 struct slsi_dev
*sdev
;
342 struct net_device
*group_dev
= NULL
;
344 u8
*ecsa_params
= NULL
;
347 unsigned int channel
;
348 unsigned int bandwidth
;
351 struct cfg80211_chan_def chandef
;
352 enum nl80211_band band
;
353 enum nl80211_channel_type chan_type
= NL80211_CHAN_NO_HT
;
355 ecsa_params
= command
+ strlen(CMD_P2PECSA
) + 1;
356 ndev_vif
= netdev_priv(dev
);
357 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
358 sdev
= ndev_vif
->sdev
;
359 group_dev
= slsi_get_netdev(sdev
, SLSI_NET_INDEX_P2PX_SWLAN
);
361 SLSI_INFO(sdev
, "No Group net_dev found\n");
364 readbyte
= slsi_str_to_int(&ecsa_params
[offset
], &channel
);
366 SLSI_ERR(sdev
, "channel: failed to read a numeric value\n");
370 offset
= offset
+ readbyte
+ 1;
371 readbyte
= slsi_str_to_int(&ecsa_params
[offset
], &bandwidth
);
373 SLSI_ERR(sdev
, "bandwidth: failed to read a numeric value\n");
377 offset
= offset
+ readbyte
+ 1;
378 band
= (channel
<= 14) ? NL80211_BAND_2GHZ
: NL80211_BAND_5GHZ
;
379 center_freq
= ieee80211_channel_to_frequency(channel
, band
);
380 SLSI_DBG1(sdev
, SLSI_CFG80211
, "p2p ecsa_params (center_freq)= (%d)\n", center_freq
);
381 chandef
.chan
= ieee80211_get_channel(sdev
->wiphy
, center_freq
);
382 chandef
.width
= (band
== NL80211_BAND_2GHZ
) ? NL80211_CHAN_WIDTH_20_NOHT
: NL80211_CHAN_WIDTH_80
;
384 #ifndef SSB_4963_FIXED
385 /* Default HT40 configuration */
386 if (sdev
->band_5g_supported
) {
387 if (bandwidth
== 80) {
388 chandef
.width
= NL80211_CHAN_WIDTH_40
;
390 if (channel
== 36 || channel
== 44 || channel
== 149 || channel
== 157)
391 chan_type
= NL80211_CHAN_HT40PLUS
;
393 chan_type
= NL80211_CHAN_HT40MINUS
;
397 if (channel
== 165 && bandwidth
!= 20) {
399 chan_type
= NL80211_CHAN_HT20
;
401 cfg80211_chandef_create(&chandef
, chandef
.chan
, chan_type
);
402 chan_info
= slsi_get_chann_info(sdev
, &chandef
);
404 center_freq
= slsi_get_center_freq1(sdev
, chan_info
, center_freq
);
405 group_dev_vif
= netdev_priv(group_dev
);
406 SLSI_MUTEX_LOCK(group_dev_vif
->vif_mutex
);
407 result
= slsi_mlme_channel_switch(sdev
, group_dev
, center_freq
, chan_info
);
408 SLSI_MUTEX_UNLOCK(group_dev_vif
->vif_mutex
);
411 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
415 static ssize_t
slsi_ap_vendor_ies_write(struct slsi_dev
*sdev
, struct net_device
*dev
, u8
*ie
,
416 size_t ie_len
, u16 purpose
)
418 u8
*vendor_ie
= NULL
;
420 struct netdev_vif
*ndev_vif
;
422 ndev_vif
= netdev_priv(dev
);
423 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
424 /* During AP start before mlme_start_req, supplicant calls set_ap_wps_ie() to send the vendor IEs for each
425 * beacon, probe response and association response. As we get all of them in mlme_start_req, ignoring the
426 * same which comes before adding GO VIF
428 if (!ndev_vif
->activated
) {
429 SLSI_DBG1(sdev
, SLSI_CFG80211
, "vif not activated\n");
433 if (!(ndev_vif
->iftype
== NL80211_IFTYPE_P2P_GO
|| ndev_vif
->iftype
== NL80211_IFTYPE_AP
)) {
434 SLSI_ERR(sdev
, "Not AP or P2P interface. interfaceType:%d\n", ndev_vif
->iftype
);
439 vendor_ie
= kmalloc(ie_len
, GFP_KERNEL
);
441 SLSI_ERR(sdev
, "kmalloc failed\n");
445 memcpy(vendor_ie
, ie
, ie_len
);
447 slsi_clear_cached_ies(&ndev_vif
->ap
.add_info_ies
, &ndev_vif
->ap
.add_info_ies_len
);
448 result
= slsi_ap_prepare_add_info_ies(ndev_vif
, vendor_ie
, ie_len
);
451 result
= slsi_mlme_add_info_elements(sdev
, dev
, purpose
, ndev_vif
->ap
.add_info_ies
, ndev_vif
->ap
.add_info_ies_len
);
453 slsi_clear_cached_ies(&ndev_vif
->ap
.add_info_ies
, &ndev_vif
->ap
.add_info_ies_len
);
457 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
461 static ssize_t
slsi_set_ap_p2p_wps_ie(struct net_device
*dev
, char *command
, int buf_len
)
463 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
464 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
472 } iftype
= IF_TYPE_NONE
;
476 FRAME_TYPE_PROBE_RESPONSE
,
477 FRAME_TYPE_ASSOC_RESPONSE
478 } frametype
= FRAME_TYPE_NONE
;
479 u8
*params
= command
+ strlen(CMD_SETAPP2PWPSIE
) + 1;
480 int params_len
= buf_len
- strlen(CMD_SETAPP2PWPSIE
) - 1;
482 readbyte
= slsi_str_to_int(¶ms
[offset
], (int *)&frametype
);
484 SLSI_ERR(sdev
, "frametype: failed to read a numeric value\n");
488 offset
= offset
+ readbyte
+ 1;
489 readbyte
= slsi_str_to_int(¶ms
[offset
], (int *)&iftype
);
491 SLSI_ERR(sdev
, "iftype: failed to read a numeric value\n");
495 offset
= offset
+ readbyte
+ 1;
496 params_len
= params_len
- offset
;
498 SLSI_NET_DBG2(dev
, SLSI_NETDEV
,
499 "command=%s, frametype=%d, iftype=%d, total buf_len=%d, params_len=%d\n",
500 command
, frametype
, iftype
, buf_len
, params_len
);
502 /* check the net device interface type */
503 if (iftype
== IF_TYPE_P2P_DEVICE
) {
504 u8
*probe_resp_ie
= NULL
; /* params+offset; */
506 if (frametype
!= FRAME_TYPE_PROBE_RESPONSE
) {
507 SLSI_NET_ERR(dev
, "Wrong frame type received\n");
510 probe_resp_ie
= kmalloc(params_len
, GFP_KERNEL
);
511 if (probe_resp_ie
== NULL
) {
512 SLSI_ERR(sdev
, "Malloc for IEs failed\n");
516 memcpy(probe_resp_ie
, params
+offset
, params_len
);
518 return slsi_p2p_dev_probe_rsp_ie(sdev
, dev
, probe_resp_ie
, params_len
);
519 } else if (iftype
== IF_TYPE_AP_P2P
) {
520 if (frametype
== FRAME_TYPE_BEACON
)
521 return slsi_ap_vendor_ies_write(sdev
, dev
, params
+ offset
, params_len
, FAPI_PURPOSE_BEACON
);
522 else if (frametype
== FRAME_TYPE_PROBE_RESPONSE
)
523 return slsi_ap_vendor_ies_write(sdev
, dev
, params
+ offset
, params_len
,
524 FAPI_PURPOSE_PROBE_RESPONSE
);
525 else if (frametype
== FRAME_TYPE_ASSOC_RESPONSE
)
526 return slsi_ap_vendor_ies_write(sdev
, dev
, params
+ offset
, params_len
,
527 FAPI_PURPOSE_ASSOCIATION_RESPONSE
);
534 * P2P_LO_START handling.
535 * Add unsync vif, register for action frames and set the listen channel.
536 * The probe response IEs would be configured later.
538 static int slsi_p2p_lo_start(struct net_device
*dev
, char *command
)
540 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
541 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
542 struct ieee80211_channel
*chan
= NULL
;
543 char *lo_params
= NULL
;
544 unsigned int channel
, duration
, interval
, count
;
548 enum nl80211_band band
;
551 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
553 /* Reject LO if other operations are in progress. Back to back LO can be received.
554 * In such a case, if state is Listening then the listen offload flag should be true else
555 * reject the request as the Listening state would then be due to ROC.
557 if ((sdev
->p2p_state
== P2P_SCANNING
) || (sdev
->p2p_state
> P2P_LISTENING
) ||
558 ((sdev
->p2p_state
== P2P_LISTENING
) && (!ndev_vif
->unsync
.listen_offload
))) {
559 SLSI_NET_ERR(dev
, "Reject LO due to ongoing P2P operation (state: %s)\n", slsi_p2p_state_text(sdev
->p2p_state
));
564 lo_params
= command
+ strlen(CMD_P2PLOSTART
) + 1;
565 readbyte
= slsi_str_to_int(&lo_params
[offset
], &channel
);
567 SLSI_ERR(sdev
, "channel: failed to read a numeric value\n");
571 offset
= offset
+ readbyte
+ 1;
572 readbyte
= slsi_str_to_int(&lo_params
[offset
], &duration
);
574 SLSI_ERR(sdev
, "duration: failed to read a numeric value\n");
578 offset
= offset
+ readbyte
+ 1;
579 readbyte
= slsi_str_to_int(&lo_params
[offset
], &interval
);
581 SLSI_ERR(sdev
, "interval: failed to read a numeric value\n");
585 offset
= offset
+ readbyte
+ 1;
586 readbyte
= slsi_str_to_int(&lo_params
[offset
], &count
);
588 SLSI_ERR(sdev
, "count: failed to read a numeric value\n");
593 if (!ndev_vif
->activated
) {
594 ret
= slsi_mlme_add_vif(sdev
, dev
, dev
->dev_addr
, dev
->dev_addr
);
596 SLSI_NET_ERR(dev
, "Unsync vif addition failed\n");
600 ndev_vif
->activated
= true;
601 ndev_vif
->mgmt_tx_data
.exp_frame
= SLSI_P2P_PA_INVALID
;
602 SLSI_P2P_STATE_CHANGE(sdev
, P2P_IDLE_VIF_ACTIVE
);
604 ret
= slsi_mlme_register_action_frame(sdev
, dev
, SLSI_ACTION_FRAME_PUBLIC
, SLSI_ACTION_FRAME_PUBLIC
);
606 SLSI_NET_ERR(dev
, "Action frame registration for unsync vif failed\n");
607 goto exit_with_vif_deactivate
;
611 /* Send set_channel irrespective of the values of LO parameters as they are not cached
612 * in driver to check whether they have changed.
614 band
= (channel
<= 14) ? NL80211_BAND_2GHZ
: NL80211_BAND_5GHZ
;
615 freq
= ieee80211_channel_to_frequency(channel
, band
);
616 chan
= ieee80211_get_channel(sdev
->wiphy
, freq
);
618 SLSI_NET_ERR(dev
, "Incorrect channel: %u - Listen Offload failed\n", channel
);
620 goto exit_with_vif_deactivate
;
623 ret
= slsi_mlme_set_channel(sdev
, dev
, chan
, duration
, interval
, count
);
625 SLSI_NET_ERR(dev
, "Set channel for unsync vif failed\n");
626 goto exit_with_vif_deactivate
;
628 ndev_vif
->chan
= chan
;
629 ndev_vif
->driver_channel
= chan
->hw_value
;
631 /* If framework sends the values for listen offload as 1,500,5000 and 6,
632 * where 5000ms (5 seconds) is the listen interval which needs to be repeated
633 * 6 times(i.e. count). Hence listen_end_ind comes after 30 seconds
634 * (6 * 5000 = 30000ms) Hence host should wait 31 seconds to delete the
635 * unsync VIF for one such P2P listen offload request.
637 slsi_p2p_queue_unsync_vif_del_work(ndev_vif
, interval
* count
+ 1000);
638 ndev_vif
->unsync
.listen_offload
= true;
639 SLSI_P2P_STATE_CHANGE(ndev_vif
->sdev
, P2P_LISTENING
);
642 exit_with_vif_deactivate
:
643 slsi_p2p_vif_deactivate(sdev
, dev
, true);
645 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
650 * P2P_LO_STOP handling.
651 * Clear listen offload flag.
652 * Delete the P2P unsynchronized vif.
654 static int slsi_p2p_lo_stop(struct net_device
*dev
)
656 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
658 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
660 WARN_ON((!ndev_vif
->unsync
.listen_offload
) || (ndev_vif
->sdev
->p2p_state
!= P2P_LISTENING
));
662 ndev_vif
->unsync
.listen_offload
= false;
664 /* Deactivating the p2p unsynchronized vif */
665 if (ndev_vif
->sdev
->p2p_state
== P2P_LISTENING
)
666 slsi_p2p_vif_deactivate(ndev_vif
->sdev
, ndev_vif
->wdev
.netdev
, true);
668 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
673 static ssize_t
slsi_rx_filter_num_write(struct net_device
*dev
, int add_remove
, int filter_num
)
675 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
676 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
680 sdev
->device_config
.rx_filter_num
= filter_num
;
682 sdev
->device_config
.rx_filter_num
= 0;
686 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
687 #if !defined(CONFIG_SCSC_WLAN_MHS_STATIC_INTERFACE) || (defined(ANDROID_VERSION) && ANDROID_VERSION < 90000)
688 static ssize_t
slsi_create_interface(struct net_device
*dev
, char *intf_name
)
690 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
691 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
692 struct net_device
*ap_dev
;
694 ap_dev
= slsi_get_netdev(sdev
, SLSI_NET_INDEX_P2PX_SWLAN
);
695 if (ap_dev
&& (strcmp(ap_dev
->name
, intf_name
) == 0)) {
696 SLSI_NET_ERR(dev
, "%s already created\n", intf_name
);
700 ap_dev
= slsi_dynamic_interface_create(sdev
->wiphy
, intf_name
, NL80211_IFTYPE_AP
, NULL
);
702 sdev
->netdev_ap
= ap_dev
;
706 SLSI_NET_ERR(dev
, "Failed to create AP interface %s\n", intf_name
);
710 static ssize_t
slsi_delete_interface(struct net_device
*dev
, char *intf_name
)
712 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
713 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
715 if (strcmp(intf_name
, CONFIG_SCSC_AP_INTERFACE_NAME
) == 0)
716 dev
= sdev
->netdev
[SLSI_NET_INDEX_P2PX_SWLAN
];
719 SLSI_WARN(sdev
, "AP dev is NULL");
722 ndev_vif
= netdev_priv(dev
);
724 if (ndev_vif
->activated
)
725 slsi_stop_net_dev(sdev
, dev
);
726 slsi_netif_remove_rtlnl_locked(sdev
, dev
);
728 sdev
->netdev_ap
= NULL
;
729 SLSI_DBG1_NODEV(SLSI_MLME
, "Successfully deleted AP interface %s ", intf_name
);
735 static ssize_t
slsi_set_indoor_channels(struct net_device
*dev
, char *arg
)
737 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
738 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
744 readbyte
= slsi_str_to_int(&arg
[offset
], &res
);
746 ret
= slsi_set_mib_wifi_sharing_5ghz_channel(sdev
, SLSI_PSID_UNIFI_WI_FI_SHARING5_GHZ_CHANNEL
,
747 res
, offset
, readbyte
, arg
);
752 static ssize_t
slsi_get_indoor_channels(struct net_device
*dev
, char *command
, int buf_len
)
754 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
755 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
757 char int_string
[30] = "";
761 SLSI_DBG1_NODEV(SLSI_MLME
, "GET_INDOOR_CHANNELS : %d ", sdev
->num_5g_restricted_channels
);
763 for (i
= 0; i
< sdev
->num_5g_restricted_channels
; i
++) {
764 sprintf(int_string
, "%d", sdev
->wifi_sharing_5g_restricted_channels
[i
]);
765 strcat(op
, int_string
);
769 len
= snprintf(command
, buf_len
, "%d %s", sdev
->num_5g_restricted_channels
, op
);
774 static ssize_t
slsi_set_country_rev(struct net_device
*dev
, char *country_code
)
776 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
777 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
784 memcpy(alpha2_rev
, country_code
, 4);
786 status
= slsi_set_country_update_regd(sdev
, alpha2_rev
, 4);
791 static ssize_t
slsi_get_country_rev(struct net_device
*dev
, char *command
, int buf_len
)
793 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
794 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
798 memset(buf
, 0, sizeof(buf
));
800 len
= snprintf(command
, buf_len
, "%s %c%c %d", CMD_GETCOUNTRYREV
,
801 sdev
->device_config
.domain_info
.regdomain
->alpha2
[0],
802 sdev
->device_config
.domain_info
.regdomain
->alpha2
[1],
803 sdev
->device_config
.domain_info
.regdomain
->dfs_region
);
808 #ifdef CONFIG_SCSC_WLAN_WES_NCHO
809 static ssize_t
slsi_roam_scan_trigger_write(struct net_device
*dev
, char *command
, int buf_len
)
811 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
812 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
815 slsi_str_to_int(command
, &mib_value
);
817 return slsi_set_mib_roam(sdev
, NULL
, SLSI_PSID_UNIFI_RSSI_ROAM_SCAN_TRIGGER
, mib_value
);
820 static ssize_t
slsi_roam_scan_trigger_read(struct net_device
*dev
, char *command
, int buf_len
)
822 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
823 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
827 res
= slsi_get_mib_roam(sdev
, SLSI_PSID_UNIFI_RSSI_ROAM_SCAN_TRIGGER
, &mib_value
);
830 res
= snprintf(command
, buf_len
, "%s %d", CMD_GETROAMTRIGGER
, mib_value
);
834 static ssize_t
slsi_roam_delta_trigger_write(struct net_device
*dev
, char *command
, int buf_len
)
836 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
837 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
840 slsi_str_to_int(command
, &mib_value
);
842 return slsi_set_mib_roam(sdev
, NULL
, SLSI_PSID_UNIFI_ROAM_DELTA_TRIGGER
, mib_value
);
845 static ssize_t
slsi_roam_delta_trigger_read(struct net_device
*dev
, char *command
, int buf_len
)
847 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
848 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
852 res
= slsi_get_mib_roam(sdev
, SLSI_PSID_UNIFI_ROAM_DELTA_TRIGGER
, &mib_value
);
856 res
= snprintf(command
, buf_len
, "%s %d", CMD_GETROAMDELTA
, mib_value
);
860 static ssize_t
slsi_cached_channel_scan_period_write(struct net_device
*dev
, char *command
, int buf_len
)
862 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
863 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
866 slsi_str_to_int(command
, &mib_value
);
867 return slsi_set_mib_roam(sdev
, NULL
, SLSI_PSID_UNIFI_ROAM_CACHED_CHANNEL_SCAN_PERIOD
, mib_value
* 1000000);
870 static ssize_t
slsi_cached_channel_scan_period_read(struct net_device
*dev
, char *command
, int buf_len
)
872 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
873 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
877 res
= slsi_get_mib_roam(sdev
, SLSI_PSID_UNIFI_ROAM_CACHED_CHANNEL_SCAN_PERIOD
, &mib_value
);
881 res
= snprintf(command
, buf_len
, "%s %d", CMD_GETROAMSCANPERIOD
, mib_value
/ 1000000);
886 static ssize_t
slsi_full_roam_scan_period_write(struct net_device
*dev
, char *command
, int buf_len
)
888 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
889 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
892 slsi_str_to_int(command
, &mib_value
);
894 return slsi_set_mib_roam(sdev
, NULL
, SLSI_PSID_UNIFI_FULL_ROAM_SCAN_PERIOD
, mib_value
* 1000000);
897 static ssize_t
slsi_full_roam_scan_period_read(struct net_device
*dev
, char *command
, int buf_len
)
899 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
900 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
904 res
= slsi_get_mib_roam(sdev
, SLSI_PSID_UNIFI_FULL_ROAM_SCAN_PERIOD
, &mib_value
);
908 res
= snprintf(command
, buf_len
, "%s %d", CMD_GETFULLROAMSCANPERIOD
, mib_value
/ 1000000);
913 static ssize_t
slsi_roam_scan_max_active_channel_time_write(struct net_device
*dev
, char *command
, int buf_len
)
915 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
916 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
919 slsi_str_to_int(command
, &mib_value
);
921 return slsi_set_mib_roam(sdev
, NULL
, SLSI_PSID_UNIFI_ROAM_SCAN_MAX_ACTIVE_CHANNEL_TIME
, mib_value
);
924 static ssize_t
slsi_roam_scan_max_active_channel_time_read(struct net_device
*dev
, char *command
, int buf_len
)
926 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
927 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
931 res
= slsi_get_mib_roam(sdev
, SLSI_PSID_UNIFI_ROAM_SCAN_MAX_ACTIVE_CHANNEL_TIME
, &mib_value
);
935 res
= snprintf(command
, buf_len
, "%s %d", CMD_GETSCANCHANNELTIME
, mib_value
);
940 static ssize_t
slsi_roam_scan_probe_interval_write(struct net_device
*dev
, char *command
, int buf_len
)
942 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
943 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
946 slsi_str_to_int(command
, &mib_value
);
947 return slsi_set_mib_roam(sdev
, NULL
, SLSI_PSID_UNIFI_ROAM_SCAN_NPROBE
, mib_value
);
950 static ssize_t
slsi_roam_scan_probe_interval_read(struct net_device
*dev
, char *command
, int buf_len
)
952 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
953 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
957 res
= slsi_get_mib_roam(sdev
, SLSI_PSID_UNIFI_ROAM_SCAN_NPROBE
, &mib_value
);
961 res
= snprintf(command
, buf_len
, "%s %d", CMD_GETSCANNPROBES
, mib_value
);
966 static ssize_t
slsi_roam_mode_write(struct net_device
*dev
, char *command
, int buf_len
)
968 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
969 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
972 if (slsi_is_rf_test_mode_enabled()) {
973 SLSI_DBG1_NODEV(SLSI_MLME
, "SLSI_PSID_UNIFI_ROAM_MODE is not supported because of rf test mode.\n");
977 slsi_str_to_int(command
, &mib_value
);
979 return slsi_set_mib_roam(sdev
, NULL
, SLSI_PSID_UNIFI_ROAM_MODE
, mib_value
);
982 static ssize_t
slsi_roam_mode_read(struct net_device
*dev
, char *command
, int buf_len
)
984 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
985 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
989 res
= slsi_get_mib_roam(sdev
, SLSI_PSID_UNIFI_ROAM_MODE
, &mib_value
);
993 res
= snprintf(command
, buf_len
, "%s %d", CMD_GETROAMMODE
, mib_value
);
998 static int slsi_roam_offload_ap_list(struct net_device
*dev
, char *command
, int buf_len
)
1000 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1001 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1002 struct cfg80211_acl_data
*mac_acl
;
1009 * x,aa:bb:cc:dd:ee:ff,xx:yy:zz:qq:ww:ee...
1011 * each mac address id 17 bytes and every mac address is separated by ','
1013 buf_pos
= slsi_str_to_int(command
, &ap_count
);
1014 if (ap_count
< ROAMOFFLAPLIST_MIN
|| ap_count
> ROAMOFFLAPLIST_MAX
) {
1015 SLSI_ERR(sdev
, "ap_count: %d\n", ap_count
);
1019 /* each mac address takes 18 bytes(17 for mac address and 1 for ',') except the last one.
1020 * the last mac address is just 17 bytes(without a coma)
1022 if ((buf_len
- buf_pos
) < (ap_count
*18 - 1)) {
1023 SLSI_ERR(sdev
, "Invalid buff len:%d for %d APs\n", (buf_len
- buf_pos
), ap_count
);
1026 malloc_len
= sizeof(struct cfg80211_acl_data
) + sizeof(struct mac_address
) * ap_count
;
1027 mac_acl
= kmalloc(malloc_len
, GFP_KERNEL
);
1029 SLSI_ERR(sdev
, "MEM fail for size:%ld\n", sizeof(struct cfg80211_acl_data
) + sizeof(struct mac_address
) * ap_count
);
1033 for (i
= 0; i
< ap_count
; i
++) {
1034 slsi_machexstring_to_macarray(&command
[buf_pos
], mac_acl
->mac_addrs
[i
].addr
);
1036 SLSI_DBG3_NODEV(SLSI_MLME
, "[%pM]", mac_acl
->mac_addrs
[i
].addr
);
1038 mac_acl
->acl_policy
= NL80211_ACL_POLICY_DENY_UNLESS_LISTED
;
1039 mac_acl
->n_acl_entries
= ap_count
;
1041 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
1042 r
= slsi_mlme_set_acl(sdev
, dev
, ndev_vif
->ifnum
, mac_acl
);
1043 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1048 static ssize_t
slsi_roam_scan_band_write(struct net_device
*dev
, char *command
, int buf_len
)
1050 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1051 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1054 slsi_str_to_int(command
, &mib_value
);
1055 return slsi_set_mib_roam(sdev
, NULL
, SLSI_PSID_UNIFI_ROAM_SCAN_BAND
, mib_value
);
1058 static ssize_t
slsi_roam_scan_band_read(struct net_device
*dev
, char *command
, int buf_len
)
1060 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1061 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1065 res
= slsi_get_mib_roam(sdev
, SLSI_PSID_UNIFI_ROAM_SCAN_BAND
, &mib_value
);
1069 res
= snprintf(command
, buf_len
, "%s %d", CMD_GETROAMINTRABAND
, mib_value
);
1074 static ssize_t
slsi_freq_band_write(struct net_device
*dev
, uint band
)
1076 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1077 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1079 slsi_band_update(sdev
, band
);
1080 /* Convert to correct Mib value (intra_band:1, all_band:2) */
1081 return slsi_set_mib_roam(sdev
, NULL
, SLSI_PSID_UNIFI_ROAM_SCAN_BAND
, (band
== SLSI_FREQ_BAND_AUTO
) ? 2 : 1);
1084 static ssize_t
slsi_freq_band_read(struct net_device
*dev
, char *command
, int buf_len
)
1086 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1087 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1090 const size_t bufsz
= sizeof(buf
);
1092 memset(buf
, '\0', 128);
1093 pos
+= scnprintf(buf
+ pos
, bufsz
- pos
, "Band %d", sdev
->device_config
.supported_band
);
1096 memcpy(command
, buf
, pos
+ 1);
1101 static ssize_t
slsi_roam_scan_control_write(struct net_device
*dev
, int mode
)
1103 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1104 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1106 SLSI_MUTEX_LOCK(sdev
->device_config_mutex
);
1108 if (mode
== 0 || mode
== 1) {
1109 sdev
->device_config
.roam_scan_mode
= mode
;
1111 SLSI_ERR(sdev
, "Invalid roam Mode: Must be 0 or, 1 Not '%c'\n", mode
);
1112 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
1116 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
1117 return slsi_set_mib_roam(sdev
, NULL
, SLSI_PSID_UNIFI_ROAM_SCAN_CONTROL
, sdev
->device_config
.roam_scan_mode
);
1120 static ssize_t
slsi_roam_scan_control_read(struct net_device
*dev
, char *command
, int buf_len
)
1122 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1123 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1127 res
= slsi_get_mib_roam(sdev
, SLSI_PSID_UNIFI_ROAM_SCAN_CONTROL
, &mib_value
);
1131 res
= snprintf(command
, buf_len
, "%s %d", CMD_GETROAMSCANCONTROL
, mib_value
);
1136 static ssize_t
slsi_roam_scan_home_time_write(struct net_device
*dev
, char *command
, int buf_len
)
1138 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1139 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1142 slsi_str_to_int(command
, &mib_value
);
1144 return slsi_set_mib_roam(sdev
, NULL
, SLSI_PSID_UNIFI_ROAM_SCAN_HOME_TIME
, mib_value
);
1147 static ssize_t
slsi_roam_scan_home_time_read(struct net_device
*dev
, char *command
, int buf_len
)
1149 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1150 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1154 res
= slsi_get_mib_roam(sdev
, SLSI_PSID_UNIFI_ROAM_SCAN_HOME_TIME
, &mib_value
);
1158 res
= snprintf(command
, buf_len
, "%s %d", CMD_GETSCANHOMETIME
, mib_value
);
1163 static ssize_t
slsi_roam_scan_home_away_time_write(struct net_device
*dev
, char *command
, int buf_len
)
1165 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1166 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1169 slsi_str_to_int(command
, &mib_value
);
1170 return slsi_set_mib_roam(sdev
, NULL
, SLSI_PSID_UNIFI_ROAM_SCAN_HOME_AWAY_TIME
, mib_value
);
1173 static ssize_t
slsi_roam_scan_home_away_time_read(struct net_device
*dev
, char *command
, int buf_len
)
1175 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1176 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1180 res
= slsi_get_mib_roam(sdev
, SLSI_PSID_UNIFI_ROAM_SCAN_HOME_AWAY_TIME
, &mib_value
);
1184 res
= snprintf(command
, buf_len
, "%s %d", CMD_GETSCANHOMEAWAYTIME
, mib_value
);
1189 static ssize_t
slsi_roam_scan_channels_write(struct net_device
*dev
, char *command
, int buf_len
)
1191 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1192 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1194 int i
, channel_count
= 0;
1197 int channels
[MAX_CHANNEL_LIST
];
1199 readbyte
= slsi_str_to_int(command
, &channel_count
);
1202 SLSI_ERR(sdev
, "channel count: failed to read a numeric value");
1205 SLSI_MUTEX_LOCK(sdev
->device_config_mutex
);
1207 if (channel_count
> MAX_CHANNEL_LIST
)
1208 channel_count
= MAX_CHANNEL_LIST
;
1209 sdev
->device_config
.wes_roam_scan_list
.n
= channel_count
;
1211 for (i
= 0; i
< channel_count
; i
++) {
1212 offset
= offset
+ readbyte
+ 1;
1213 readbyte
= slsi_str_to_int(&command
[offset
], &channels
[i
]);
1215 SLSI_ERR(sdev
, "failed to read a numeric value\n");
1216 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
1220 sdev
->device_config
.wes_roam_scan_list
.channels
[i
] = channels
[i
];
1222 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
1224 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
1225 result
= slsi_mlme_set_cached_channels(sdev
, dev
, channel_count
, sdev
->device_config
.wes_roam_scan_list
.channels
);
1226 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1231 static ssize_t
slsi_roam_scan_channels_read(struct net_device
*dev
, char *command
, int buf_len
)
1233 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1234 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1235 char channel_buf
[128] = { 0 };
1238 int channel_count
= 0;
1240 SLSI_MUTEX_LOCK(sdev
->device_config_mutex
);
1241 channel_count
= sdev
->device_config
.wes_roam_scan_list
.n
;
1242 pos
= scnprintf(channel_buf
, sizeof(channel_buf
), "%s %d", CMD_GETROAMSCANCHANNELS
, channel_count
);
1243 for (i
= 0; i
< channel_count
; i
++)
1244 pos
+= scnprintf(channel_buf
+ pos
, sizeof(channel_buf
) - pos
, " %d", sdev
->device_config
.wes_roam_scan_list
.channels
[i
]);
1245 channel_buf
[pos
] = '\0';
1247 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
1249 memcpy(command
, channel_buf
, pos
+ 1);
1254 static ssize_t
slsi_okc_mode_write(struct net_device
*dev
, int mode
)
1256 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1257 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1259 SLSI_MUTEX_LOCK(sdev
->device_config_mutex
);
1261 if (mode
== 0 || mode
== 1) {
1262 sdev
->device_config
.okc_mode
= mode
;
1264 SLSI_ERR(sdev
, "Invalid OKC Mode: Must be 0 or, 1 Not '%c'\n", mode
);
1265 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
1269 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
1273 static ssize_t
slsi_okc_mode_read(struct net_device
*dev
, char *command
, int buf_len
)
1275 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1276 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1280 SLSI_MUTEX_LOCK(sdev
->device_config_mutex
);
1281 okc_mode
= sdev
->device_config
.okc_mode
;
1282 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
1284 res
= snprintf(command
, buf_len
, "%s %d", CMD_GETOKCMODE
, okc_mode
);
1289 static ssize_t
slsi_wes_mode_write(struct net_device
*dev
, int mode
)
1291 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1292 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1294 u32 action_frame_bmap
= SLSI_STA_ACTION_FRAME_BITMAP
;
1296 SLSI_MUTEX_LOCK(sdev
->device_config_mutex
);
1298 if (mode
== 0 || mode
== 1) {
1299 sdev
->device_config
.wes_mode
= mode
;
1301 SLSI_ERR(sdev
, "Invalid WES Mode: Must be 0 or 1 Not '%c'\n", mode
);
1302 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
1305 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
1306 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
1308 if ((ndev_vif
->activated
) && (ndev_vif
->vif_type
== FAPI_VIFTYPE_STATION
) &&
1309 (ndev_vif
->sta
.vif_status
== SLSI_VIF_STATUS_CONNECTED
)) {
1310 if (sdev
->device_config
.wes_mode
)
1311 action_frame_bmap
|= SLSI_ACTION_FRAME_VENDOR_SPEC
;
1313 result
= slsi_mlme_register_action_frame(sdev
, dev
, action_frame_bmap
, action_frame_bmap
);
1316 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1321 static ssize_t
slsi_wes_mode_read(struct net_device
*dev
, char *command
, int buf_len
)
1323 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1324 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1328 SLSI_MUTEX_LOCK(sdev
->device_config_mutex
);
1329 wes_mode
= sdev
->device_config
.wes_mode
;
1330 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
1332 res
= snprintf(command
, buf_len
, "%s %d", CMD_GETWESMODE
, wes_mode
);
1338 static ssize_t
slsi_set_pmk(struct net_device
*dev
, char *command
, int buf_len
)
1340 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1341 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1345 memcpy((u8
*)pmk
, command
+ strlen("SET_PMK "), 32);
1346 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
1348 result
= slsi_mlme_set_pmk(sdev
, dev
, pmk
, 32);
1350 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1354 static ssize_t
slsi_auto_chan_read(struct net_device
*dev
, char *command
, int buf_len
)
1356 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1357 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1361 SLSI_MUTEX_LOCK(sdev
->device_config_mutex
);
1362 ap_auto_chan
= sdev
->device_config
.ap_auto_chan
;
1363 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
1365 result
= snprintf(command
, buf_len
, "%d\n", ap_auto_chan
);
1369 static ssize_t
slsi_auto_chan_write(struct net_device
*dev
, char *command
)
1371 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1372 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1374 struct ieee80211_channel
*channels
[SLSI_NO_OF_SCAN_CHANLS_FOR_AUTO_CHAN_MAX
] = { NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
};
1379 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
1380 struct net_device
*sta_dev
= slsi_get_netdev(sdev
, SLSI_NET_INDEX_WLAN
);
1381 struct netdev_vif
*ndev_sta_vif
= netdev_priv(sta_dev
);
1385 offset
= slsi_str_to_int(&command
[index
], &n_channels
);
1387 SLSI_ERR(sdev
, "channel count: failed to read a numeric value");
1391 if (n_channels
> SLSI_NO_OF_SCAN_CHANLS_FOR_AUTO_CHAN_MAX
) {
1392 SLSI_ERR(sdev
, "channel count:%d > SLSI_NO_OF_SCAN_CHANLS_FOR_AUTO_CHAN_MAX:%d\n", n_channels
, SLSI_NO_OF_SCAN_CHANLS_FOR_AUTO_CHAN_MAX
);
1396 /* If "1 6 11" are passed, scan all "1 - 14" channels. If "1 6" are passed, scan "1 - 9" channels */
1397 if (n_channels
== 3)
1399 else if (n_channels
== 2)
1402 for (chan
= 1; chan
<= n_channels
; chan
++) {
1405 center_freq
= ieee80211_channel_to_frequency(chan
, NL80211_BAND_2GHZ
);
1406 channels
[count_channels
] = ieee80211_get_channel(sdev
->wiphy
, center_freq
);
1407 if (!channels
[count_channels
])
1408 SLSI_WARN(sdev
, "channel number:%d invalid\n", chan
);
1414 SLSI_DBG3(sdev
, SLSI_INIT_DEINIT
, "Number of channels for autochannel selection= %d", count_channels
);
1416 SLSI_MUTEX_LOCK(sdev
->device_config_mutex
);
1417 sdev
->device_config
.ap_auto_chan
= 0;
1418 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
1420 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
1421 if ((ndev_sta_vif
->activated
) && (ndev_sta_vif
->vif_type
== FAPI_VIFTYPE_STATION
) &&
1422 (ndev_sta_vif
->sta
.vif_status
== SLSI_VIF_STATUS_CONNECTING
||
1423 ndev_sta_vif
->sta
.vif_status
== SLSI_VIF_STATUS_CONNECTED
)) {
1424 sta_frequency
= ndev_sta_vif
->chan
->center_freq
;
1425 SLSI_MUTEX_LOCK(sdev
->device_config_mutex
);
1426 if ((sta_frequency
/ 1000) == 2)
1427 sdev
->device_config
.ap_auto_chan
= ieee80211_frequency_to_channel(sta_frequency
);
1429 sdev
->device_config
.ap_auto_chan
= 1;
1430 SLSI_INFO(sdev
, "Channel selected = %d", sdev
->device_config
.ap_auto_chan
);
1431 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
1434 #endif /*wifi sharing*/
1435 return slsi_auto_chan_select_scan(sdev
, count_channels
, channels
);
1438 static ssize_t
slsi_reassoc_write(struct net_device
*dev
, char *command
, int buf_len
)
1440 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1441 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1442 u8 bssid
[6] = { 0 };
1445 enum nl80211_band band
= NL80211_BAND_2GHZ
;
1448 if (command
[17] != ' ') {
1449 SLSI_ERR(sdev
, "Invalid Format '%s' '%c'\n", command
, command
[17]);
1455 slsi_machexstring_to_macarray(command
, bssid
);
1457 if (!slsi_str_to_int(&command
[18], &channel
)) {
1458 SLSI_ERR(sdev
, "Invalid channel string: '%s'\n", &command
[18]);
1463 band
= NL80211_BAND_5GHZ
;
1464 freq
= (u16
)ieee80211_channel_to_frequency(channel
, band
);
1466 ndev_vif
= netdev_priv(dev
);
1467 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
1469 r
= slsi_mlme_roam(sdev
, dev
, bssid
, freq
);
1471 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1475 static ssize_t
slsi_send_action_frame(struct net_device
*dev
, char *command
, int buf_len
)
1477 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1478 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1480 u8 bssid
[6] = { 0 };
1483 enum nl80211_band band
= NL80211_BAND_2GHZ
;
1485 u16 host_tag
= slsi_tx_mgmt_host_tag(sdev
);
1487 struct ieee80211_hdr
*hdr
;
1489 u8
*final_buf
= NULL
;
1492 int final_length
= 0;
1496 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
1498 if ((!ndev_vif
->activated
) || (ndev_vif
->vif_type
!= FAPI_VIFTYPE_STATION
) ||
1499 (ndev_vif
->sta
.vif_status
!= SLSI_VIF_STATUS_CONNECTED
)) {
1500 SLSI_ERR(sdev
, "Not a STA vif or status is not CONNECTED\n");
1501 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1504 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1507 slsi_machexstring_to_macarray(command
, bssid
);
1510 pos
= strchr(command
, ' ');
1515 if (!slsi_str_to_int(pos
, &channel
)) {
1516 SLSI_ERR(sdev
, "Invalid channel string: '%s'\n", pos
);
1522 band
= NL80211_BAND_5GHZ
;
1523 freq
= (u16
)ieee80211_channel_to_frequency(channel
, band
);
1525 pos
= strchr(pos
, ' ');
1530 if (!slsi_str_to_int(pos
, &dwell_time
)) {
1531 SLSI_ERR(sdev
, "Invalid dwell time string: '%s'\n", pos
);
1535 pos
= strchr(pos
, ' ');
1542 while (*temp
!= '\0')
1548 buf
= kmalloc((len
+ 1) / 2, GFP_KERNEL
);
1551 SLSI_ERR(sdev
, "Malloc failed\n");
1554 /*We receive a char buffer, convert to hex*/
1556 for (i
= 0, j
= 0; j
< len
; j
+= 2) {
1558 temp_byte
= slsi_parse_hex(temp
[j
]);
1560 temp_byte
= slsi_parse_hex(temp
[j
]) << 4 | slsi_parse_hex(temp
[j
+ 1]);
1561 buf
[i
++] = temp_byte
;
1565 final_length
= len
+ IEEE80211_HEADER_SIZE
;
1566 final_buf
= kmalloc(final_length
, GFP_KERNEL
);
1567 if (final_buf
== NULL
) {
1568 SLSI_ERR(sdev
, "Malloc failed\n");
1573 hdr
= (struct ieee80211_hdr
*)final_buf
;
1574 hdr
->frame_control
= IEEE80211_FC(IEEE80211_FTYPE_MGMT
, IEEE80211_STYPE_ACTION
);
1575 SLSI_ETHER_COPY(hdr
->addr1
, bssid
);
1576 SLSI_ETHER_COPY(hdr
->addr2
, sdev
->hw_addr
);
1577 SLSI_ETHER_COPY(hdr
->addr3
, bssid
);
1578 memcpy(final_buf
+ IEEE80211_HEADER_SIZE
, buf
, len
);
1582 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
1584 r
= slsi_mlme_send_frame_mgmt(sdev
, dev
, final_buf
, final_length
, FAPI_DATAUNITDESCRIPTOR_IEEE802_11_FRAME
, FAPI_MESSAGETYPE_IEEE80211_ACTION
, host_tag
, SLSI_FREQ_HOST_TO_FW(freq
), dwell_time
* 1000, 0);
1587 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1591 static ssize_t
slsi_setting_max_sta_write(struct net_device
*dev
, int sta_number
)
1593 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1594 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1595 struct slsi_mib_data mib_data
= { 0, NULL
};
1598 if (sta_number
> 10 || sta_number
< 1)
1600 result
= slsi_mib_encode_uint(&mib_data
, SLSI_PSID_UNIFI_MAX_CLIENT
, sta_number
, 0);
1601 if ((result
!= SLSI_MIB_STATUS_SUCCESS
) || (mib_data
.dataLength
== 0))
1603 result
= slsi_mlme_set(sdev
, dev
, mib_data
.data
, mib_data
.dataLength
);
1605 SLSI_ERR(sdev
, "max_sta: mlme_set_req failed: Result code: %d\n", result
);
1606 kfree(mib_data
.data
);
1611 static ssize_t
slsi_country_write(struct net_device
*dev
, char *country_code
)
1613 struct netdev_vif
*netdev_vif
= netdev_priv(dev
);
1614 struct slsi_dev
*sdev
= netdev_vif
->sdev
;
1615 char alpha2_code
[SLSI_COUNTRY_CODE_LEN
];
1618 if (strlen(country_code
) < 2)
1621 memcpy(alpha2_code
, country_code
, 2);
1622 alpha2_code
[2] = ' '; /* set 3rd byte of countrycode to ASCII space */
1624 status
= slsi_set_country_update_regd(sdev
, alpha2_code
, SLSI_COUNTRY_CODE_LEN
);
1629 #ifdef CONFIG_SLSI_WLAN_STA_FWD_BEACON
1630 static ssize_t
slsi_forward_beacon(struct net_device
*dev
, char *action
)
1632 struct netdev_vif
*netdev_vif
= netdev_priv(dev
);
1633 struct slsi_dev
*sdev
= netdev_vif
->sdev
;
1634 int intended_action
= 0;
1637 if (strncasecmp(action
, "stop", 4) == 0) {
1638 intended_action
= FAPI_ACTION_STOP
;
1639 } else if (strncasecmp(action
, "start", 5) == 0) {
1640 intended_action
= FAPI_ACTION_START
;
1642 SLSI_NET_ERR(dev
, "BEACON_RECV should be used with start or stop\n");
1646 SLSI_NET_DBG2(dev
, SLSI_MLME
, "BEACON_RECV %s!!\n", intended_action
? "START" : "STOP");
1647 SLSI_MUTEX_LOCK(netdev_vif
->vif_mutex
);
1649 if ((!netdev_vif
->activated
) || (netdev_vif
->vif_type
!= FAPI_VIFTYPE_STATION
) ||
1650 (netdev_vif
->sta
.vif_status
!= SLSI_VIF_STATUS_CONNECTED
)) {
1651 SLSI_ERR(sdev
, "Not a STA vif or status is not CONNECTED\n");
1653 goto exit_vif_mutex
;
1656 if (((intended_action
== FAPI_ACTION_START
) && netdev_vif
->is_wips_running
) ||
1657 ((intended_action
== FAPI_ACTION_STOP
) && !netdev_vif
->is_wips_running
)) {
1658 SLSI_NET_INFO(dev
, "Forwarding beacon is already %s!!\n",
1659 netdev_vif
->is_wips_running
? "running" : "stopped");
1661 goto exit_vif_mutex
;
1664 SLSI_MUTEX_LOCK(netdev_vif
->scan_mutex
);
1665 if (intended_action
== FAPI_ACTION_START
&&
1666 (netdev_vif
->scan
[SLSI_SCAN_HW_ID
].scan_req
|| netdev_vif
->sta
.roam_in_progress
)) {
1667 SLSI_NET_ERR(dev
, "Rejecting BEACON_RECV start as scan/roam is running\n");
1669 goto exit_scan_mutex
;
1672 ret
= slsi_mlme_set_forward_beacon(sdev
, dev
, intended_action
);
1674 SLSI_MUTEX_UNLOCK(netdev_vif
->scan_mutex
);
1676 SLSI_MUTEX_UNLOCK(netdev_vif
->vif_mutex
);
1681 static ssize_t
slsi_update_rssi_boost(struct net_device
*dev
, char *rssi_boost_string
)
1683 struct netdev_vif
*netdev_vif
= netdev_priv(dev
);
1684 struct slsi_dev
*sdev
= netdev_vif
->sdev
;
1685 int digit1
, digit2
, band
, lendigit1
, lendigit2
;
1686 int boost
= 0, length
= 0, i
= 0;
1688 if (strlen(rssi_boost_string
) < 8)
1690 for (i
= 0; i
< (strlen(rssi_boost_string
) - 4);) {
1691 if (rssi_boost_string
[i
] == '0' &&
1692 rssi_boost_string
[i
+ 1] == '4') {
1693 if (rssi_boost_string
[i
+ 2] == '0' &&
1694 rssi_boost_string
[i
+ 3] == '2' &&
1695 ((i
+ 7) < strlen(rssi_boost_string
)))
1699 digit1
= slsi_parse_hex(rssi_boost_string
[i
]);
1700 digit2
= slsi_parse_hex(rssi_boost_string
[i
+ 1]);
1701 boost
= (digit1
* 16) + digit2
;
1702 band
= rssi_boost_string
[i
+ 3] - '0';
1703 SLSI_MUTEX_LOCK(sdev
->device_config_mutex
);
1705 sdev
->device_config
.rssi_boost_2g
= 0;
1706 sdev
->device_config
.rssi_boost_5g
= 0;
1707 } else if (band
== 1) {
1708 sdev
->device_config
.rssi_boost_2g
= 0;
1709 sdev
->device_config
.rssi_boost_5g
= boost
;
1711 sdev
->device_config
.rssi_boost_2g
= boost
;
1712 sdev
->device_config
.rssi_boost_5g
= 0;
1714 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
1715 if ((netdev_vif
->activated
) &&
1716 (netdev_vif
->vif_type
== FAPI_VIFTYPE_STATION
)) {
1717 return slsi_set_boost(sdev
, dev
);
1723 lendigit1
= slsi_parse_hex(rssi_boost_string
[i
]);
1724 lendigit2
= slsi_parse_hex(rssi_boost_string
[i
+ 1]);
1725 length
= (lendigit1
* 16) + lendigit2
;
1726 i
= i
+ (length
* 2) + 2;
1732 int slsi_set_tx_power_calling(struct net_device
*dev
, char *command
, int buf_len
)
1734 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1735 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1740 (void)slsi_str_to_int(command
, &mode
);
1741 SLSI_MUTEX_LOCK(sdev
->device_config_mutex
);
1742 host_state
= sdev
->device_config
.host_state
;
1745 host_state
= host_state
| SLSI_HOSTSTATE_SAR_ACTIVE
;
1747 host_state
= host_state
& ~SLSI_HOSTSTATE_SAR_ACTIVE
;
1749 error
= slsi_mlme_set_host_state(sdev
, dev
, host_state
);
1751 sdev
->device_config
.host_state
= host_state
;
1753 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
1758 int slsi_set_tx_power_sar(struct net_device
*dev
, char *command
, int buf_len
)
1760 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1761 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1766 (void)slsi_str_to_int(command
, &mode
);
1767 SLSI_MUTEX_LOCK(sdev
->device_config_mutex
);
1768 host_state
= sdev
->device_config
.host_state
;
1769 host_state
&= ~(SLSI_HOSTSTATE_SAR_ACTIVE
| BIT(3) | BIT(4));
1772 host_state
|= ((mode
- 1) << 3) | SLSI_HOSTSTATE_SAR_ACTIVE
;
1774 error
= slsi_mlme_set_host_state(sdev
, dev
, host_state
);
1776 sdev
->device_config
.host_state
= host_state
;
1778 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
1783 int slsi_get_tx_power_sar(struct net_device
*dev
, char *command
, int buf_len
)
1785 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1786 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1788 u8 host_state
, index
;
1790 SLSI_MUTEX_LOCK(sdev
->device_config_mutex
);
1791 host_state
= sdev
->device_config
.host_state
;
1793 if (host_state
& SLSI_HOSTSTATE_SAR_ACTIVE
)
1794 index
= ((host_state
>> 3) & 3) + 1;
1798 len
= snprintf(command
, buf_len
, "%u", index
);
1799 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
1804 static int slsi_print_regulatory(struct slsi_802_11d_reg_domain
*domain_info
, char *buf
, int buf_len
, struct slsi_supported_channels
*supported_channels
, int supp_chan_length
)
1808 char *dfs_region_str
[] = {"unknown", "ETSI", "FCC", "JAPAN", "GLOBAL", "CHINA"};
1809 u8 dfs_region_index
;
1810 struct ieee80211_reg_rule
*reg_rule
;
1811 int channel_start_freq
= 0;
1812 int channel_end_freq
= 0;
1813 int channel_start_num
= 0;
1814 int channel_end_num
= 0;
1815 int channel_count
= 0;
1816 int channel_increment
= 0;
1817 int channel_band
= 0;
1818 bool display_pattern
= false;
1820 cur_pos
= snprintf(buf
, buf_len
, "country %c%c:", domain_info
->regdomain
->alpha2
[0],
1821 domain_info
->regdomain
->alpha2
[1]);
1822 dfs_region_index
= domain_info
->regdomain
->dfs_region
<= 5 ? domain_info
->regdomain
->dfs_region
: 0;
1823 cur_pos
+= snprintf(buf
+ cur_pos
, buf_len
- cur_pos
, "DFS-%s\n", dfs_region_str
[dfs_region_index
]);
1824 for (i
= 0; i
< domain_info
->regdomain
->n_reg_rules
; i
++) {
1825 reg_rule
= &domain_info
->regdomain
->reg_rules
[i
];
1826 cur_pos
+= snprintf(buf
+ cur_pos
, buf_len
- cur_pos
, "\t(%d-%d @ %d), (N/A, %d)",
1827 reg_rule
->freq_range
.start_freq_khz
/1000,
1828 reg_rule
->freq_range
.end_freq_khz
/1000,
1829 reg_rule
->freq_range
.max_bandwidth_khz
/1000,
1830 MBM_TO_DBM(reg_rule
->power_rule
.max_eirp
));
1831 if (reg_rule
->flags
) {
1832 if (reg_rule
->flags
& NL80211_RRF_DFS
)
1833 cur_pos
+= snprintf(buf
+ cur_pos
, buf_len
- cur_pos
, ", DFS");
1834 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 9))
1835 if (reg_rule
->flags
& NL80211_RRF_NO_OFDM
)
1836 cur_pos
+= snprintf(buf
+ cur_pos
, buf_len
- cur_pos
, ", NO_OFDM");
1838 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))
1839 if (reg_rule
->flags
& (NL80211_RRF_PASSIVE_SCAN
|NL80211_RRF_NO_IBSS
))
1840 cur_pos
+= snprintf(buf
+ cur_pos
, buf_len
- cur_pos
, ", NO_IR");
1842 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
1843 if (reg_rule
->flags
& (NL80211_RRF_NO_IR
))
1844 cur_pos
+= snprintf(buf
+ cur_pos
, buf_len
- cur_pos
, ", NO_IR");
1846 if (reg_rule
->flags
& NL80211_RRF_NO_INDOOR
)
1847 cur_pos
+= snprintf(buf
+ cur_pos
, buf_len
- cur_pos
, ", NO_INDOOR");
1848 if (reg_rule
->flags
& NL80211_RRF_NO_OUTDOOR
)
1849 cur_pos
+= snprintf(buf
+ cur_pos
, buf_len
- cur_pos
, ", NO_OUTDOOR");
1851 cur_pos
+= snprintf(buf
+ cur_pos
, buf_len
- cur_pos
, "\n");
1854 /* Display of Supported Channels for 2.4GHz and 5GHz */
1855 cur_pos
+= snprintf(buf
+ cur_pos
, buf_len
- cur_pos
, "Channels:");
1857 for (i
= 0; i
< supp_chan_length
; i
++) {
1858 channel_start_num
= supported_channels
[i
].start_chan_num
;
1859 channel_count
= supported_channels
[i
].channel_count
;
1860 channel_increment
= supported_channels
[i
].increment
;
1861 channel_band
= supported_channels
[i
].band
;
1862 channel_end_num
= channel_start_num
+ ((channel_count
- 1) * channel_increment
);
1863 for (j
= channel_start_num
; j
<= channel_end_num
; j
+= channel_increment
) {
1864 channel_start_freq
= (ieee80211_channel_to_frequency(j
, channel_band
)*1000) - 10000;
1865 channel_end_freq
= (ieee80211_channel_to_frequency(j
, channel_band
)*1000) + 10000;
1866 for (k
= 0; k
< domain_info
->regdomain
->n_reg_rules
; k
++) {
1867 reg_rule
= &domain_info
->regdomain
->reg_rules
[k
];
1868 if ((reg_rule
->freq_range
.start_freq_khz
<= channel_start_freq
) &&
1869 (reg_rule
->freq_range
.end_freq_khz
>= channel_end_freq
)) {
1870 if (display_pattern
)
1871 cur_pos
+= snprintf(buf
+ cur_pos
, buf_len
- cur_pos
, ", %d", j
);
1873 cur_pos
+= snprintf(buf
+ cur_pos
, buf_len
- cur_pos
, " %d", j
);
1874 display_pattern
= true;
1880 cur_pos
+= snprintf(buf
+ cur_pos
, buf_len
- cur_pos
, "\n");
1884 static int slsi_get_supported_channels(struct slsi_dev
*sdev
, struct net_device
*dev
, struct slsi_supported_channels
*supported_channels
)
1886 struct slsi_mib_data mibrsp
= { 0, NULL
};
1887 struct slsi_mib_data supported_chan_mib
= { 0, NULL
};
1888 struct slsi_mib_value
*values
= NULL
;
1889 struct slsi_mib_get_entry get_values
[] = {{SLSI_PSID_UNIFI_SUPPORTED_CHANNELS
, { 0, 0 } } };
1890 int i
, chan_count
, chan_start
;
1891 int supp_chan_length
= 0;
1893 /* Expect each mib length in response is <= 16. So assume 16 bytes for each MIB */
1894 mibrsp
.dataLength
= 16;
1895 mibrsp
.data
= kmalloc(mibrsp
.dataLength
, GFP_KERNEL
);
1896 if (mibrsp
.data
== NULL
) {
1897 SLSI_ERR(sdev
, "Cannot kmalloc %d bytes\n", mibrsp
.dataLength
);
1900 values
= slsi_read_mibs(sdev
, dev
, get_values
, 1, &mibrsp
);
1902 goto exit_with_mibrsp
;
1904 if (values
[0].type
!= SLSI_MIB_TYPE_OCTET
) {
1905 SLSI_ERR(sdev
, "Supported_Chan invalid type.");
1906 goto exit_with_values
;
1909 supported_chan_mib
= values
[0].u
.octetValue
;
1910 for (i
= 0; i
< supported_chan_mib
.dataLength
/ 2; i
++) {
1911 chan_start
= supported_chan_mib
.data
[i
*2];
1912 chan_count
= supported_chan_mib
.data
[i
*2 + 1];
1913 if (chan_start
== 1) { /* for 2.4GHz */
1914 supported_channels
[supp_chan_length
].start_chan_num
= 1;
1915 if (!(sdev
->device_config
.host_state
& SLSI_HOSTSTATE_CELLULAR_ACTIVE
) &&
1916 chan_count
> 11 && sdev
->device_config
.disable_ch12_ch13
) {
1918 SLSI_DBG1(sdev
, SLSI_CFG80211
, "Channels 12 and 13 have been disabled");
1920 supported_channels
[supp_chan_length
].channel_count
= chan_count
;
1921 supported_channels
[supp_chan_length
].increment
= 1;
1922 supported_channels
[supp_chan_length
].band
= NL80211_BAND_2GHZ
;
1923 supp_chan_length
= supp_chan_length
+ 1;
1924 } else { /* for 5GHz */
1925 supported_channels
[supp_chan_length
].start_chan_num
= chan_start
;
1926 supported_channels
[supp_chan_length
].channel_count
= chan_count
;
1927 supported_channels
[supp_chan_length
].increment
= 4;
1928 supported_channels
[supp_chan_length
].band
= NL80211_BAND_5GHZ
;
1929 supp_chan_length
= supp_chan_length
+ 1;
1936 return supp_chan_length
;
1939 static int slsi_get_regulatory(struct net_device
*dev
, char *buf
, int buf_len
)
1941 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
1942 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
1947 struct slsi_supported_channels supported_channels
[5];
1948 int supp_chan_length
;
1950 mode
= buf
[strlen(CMD_GETREGULATORY
) + 1] - '0';
1952 struct slsi_802_11d_reg_domain domain_info
;
1954 memset(&domain_info
, 0, sizeof(struct slsi_802_11d_reg_domain
));
1955 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
1956 if (!ndev_vif
->activated
|| ndev_vif
->vif_type
!= FAPI_VIFTYPE_STATION
|| !ndev_vif
->sta
.sta_bss
) {
1957 cur_pos
+= snprintf(buf
, buf_len
- cur_pos
, "Station not connected");
1958 SLSI_ERR(sdev
, "station not connected. vif.activated:%d, vif.type:%d, vif.bss:%s\n",
1959 ndev_vif
->activated
, ndev_vif
->vif_type
, ndev_vif
->sta
.sta_bss
? "yes" : "no");
1960 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1963 /* read vif specific country code, index = vifid+1 */
1964 status
= slsi_read_default_country(sdev
, alpha2
, ndev_vif
->ifnum
+ 1);
1965 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
1970 domain_info
.regdomain
= kmalloc(sizeof(*domain_info
.regdomain
) + sizeof(struct ieee80211_reg_rule
) * 20, GFP_KERNEL
);
1971 if (!domain_info
.regdomain
) {
1972 SLSI_ERR(sdev
, "no memory size:%lu\n",
1973 sizeof(struct ieee80211_regdomain
) + sizeof(struct ieee80211_reg_rule
) * 20);
1977 /* get regulatory rules based on country code */
1978 domain_info
.countrylist
= sdev
->device_config
.domain_info
.countrylist
;
1979 domain_info
.country_len
= sdev
->device_config
.domain_info
.country_len
;
1980 status
= slsi_read_regulatory_rules(sdev
, &domain_info
, alpha2
);
1982 kfree(domain_info
.regdomain
);
1985 /* get supported channels based on country code */
1986 supp_chan_length
= slsi_get_supported_channels(sdev
, dev
, &supported_channels
[0]);
1987 cur_pos
+= slsi_print_regulatory(&domain_info
, buf
+ cur_pos
, buf_len
- cur_pos
, &supported_channels
[0], supp_chan_length
);
1988 kfree(domain_info
.regdomain
);
1989 } else if (mode
== 0) {
1990 SLSI_MUTEX_LOCK(sdev
->device_config_mutex
);
1991 supp_chan_length
= slsi_get_supported_channels(sdev
, dev
, &supported_channels
[0]);
1992 cur_pos
+= slsi_print_regulatory(&sdev
->device_config
.domain_info
, buf
+ cur_pos
, buf_len
- cur_pos
, &supported_channels
[0], supp_chan_length
);
1993 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
1995 cur_pos
+= snprintf(buf
, buf_len
- cur_pos
, "invalid option %d", mode
);
1996 SLSI_ERR(sdev
, "invalid option:%d\n", mode
);
1999 /* Buf is somewhere close to 4Kbytes. so expect some spare space. If there is no spare
2000 * space we might have missed printing some text in buf.
2002 if (buf_len
- cur_pos
)
2008 void slsi_disable_ch12_13(struct slsi_dev
*sdev
)
2010 struct wiphy
*wiphy
= sdev
->wiphy
;
2011 struct ieee80211_channel
*chan
;
2013 if (wiphy
->bands
[0]) {
2014 chan
= &wiphy
->bands
[0]->channels
[11];
2015 chan
->flags
|= IEEE80211_CHAN_DISABLED
;
2016 chan
= &wiphy
->bands
[0]->channels
[12];
2017 chan
->flags
|= IEEE80211_CHAN_DISABLED
;
2020 SLSI_DBG1(sdev
, SLSI_CFG80211
, "Channels 12 and 13 have been disabled");
2023 int slsi_set_fcc_channel(struct net_device
*dev
, char *cmd
, int cmd_len
)
2025 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
2026 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
2028 bool flight_mode_ena
;
2033 /* SET_FCC_CHANNEL 0 when device is in flightmode */
2034 flight_mode_ena
= (cmd
[0] == '0');
2035 SLSI_MUTEX_LOCK(sdev
->device_config_mutex
);
2036 host_state
= sdev
->device_config
.host_state
;
2038 if (flight_mode_ena
)
2039 host_state
= host_state
& ~SLSI_HOSTSTATE_CELLULAR_ACTIVE
;
2041 host_state
= host_state
| SLSI_HOSTSTATE_CELLULAR_ACTIVE
;
2042 sdev
->device_config
.host_state
= host_state
;
2044 status
= slsi_mlme_set_host_state(sdev
, dev
, host_state
);
2046 SLSI_ERR(sdev
, "Err setting MMaxPowerEna. error = %d\n", status
);
2048 err
= slsi_read_default_country(sdev
, alpha2
, 1);
2050 SLSI_WARN(sdev
, "Err updating reg_rules = %d\n", err
);
2052 memcpy(sdev
->device_config
.domain_info
.regdomain
->alpha2
, alpha2
, 2);
2053 /* Read the regulatory params for the country.*/
2054 if (slsi_read_regulatory_rules(sdev
, &sdev
->device_config
.domain_info
, alpha2
) == 0) {
2055 slsi_reset_channel_flags(sdev
);
2056 wiphy_apply_custom_regulatory(sdev
->wiphy
, sdev
->device_config
.domain_info
.regdomain
);
2057 slsi_update_supported_channels_regd_flags(sdev
);
2058 if (flight_mode_ena
&& sdev
->device_config
.disable_ch12_ch13
)
2059 slsi_disable_ch12_13(sdev
);
2063 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
2068 int slsi_fake_mac_write(struct net_device
*dev
, char *cmd
)
2070 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
2071 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
2072 struct slsi_mib_data mib_data
= { 0, NULL
};
2076 if (strncmp(cmd
, "ON", strlen("ON")) == 0)
2081 status
= slsi_mib_encode_bool(&mib_data
, SLSI_PSID_UNIFI_MAC_ADDRESS_RANDOMISATION
, enable
, 0);
2082 if (status
!= SLSI_MIB_STATUS_SUCCESS
) {
2083 SLSI_ERR(sdev
, "FAKE MAC FAIL: no mem for MIB\n");
2087 status
= slsi_mlme_set(sdev
, NULL
, mib_data
.data
, mib_data
.dataLength
);
2089 kfree(mib_data
.data
);
2092 SLSI_ERR(sdev
, "Err setting unifiMacAddrRandomistaion MIB. error = %d\n", status
);
2097 static char *slsi_get_assoc_status(u16 fw_result_code
)
2099 char *assoc_status_label
= "unspecified_failure";
2101 switch (fw_result_code
) {
2102 case FAPI_RESULTCODE_SUCCESS
:
2103 assoc_status_label
= "success";
2105 case FAPI_RESULTCODE_TRANSMISSION_FAILURE
:
2106 assoc_status_label
= "transmission_failure";
2108 case FAPI_RESULTCODE_HOST_REQUEST_SUCCESS
:
2109 assoc_status_label
= "host_request_success";
2111 case FAPI_RESULTCODE_HOST_REQUEST_FAILED
:
2112 assoc_status_label
= "host_request_failed";
2114 case FAPI_RESULTCODE_PROBE_TIMEOUT
:
2115 assoc_status_label
= "probe_timeout";
2117 case FAPI_RESULTCODE_AUTH_TIMEOUT
:
2118 assoc_status_label
= "auth_timeout";
2120 case FAPI_RESULTCODE_ASSOC_TIMEOUT
:
2121 assoc_status_label
= "assoc_timeout";
2123 case FAPI_RESULTCODE_ASSOC_ABORT
:
2124 assoc_status_label
= "assoc_abort";
2127 return assoc_status_label
;
2130 int slsi_get_sta_info(struct net_device
*dev
, char *command
, int buf_len
)
2132 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
2133 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
2135 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
2136 struct net_device
*ap_dev
;
2137 struct netdev_vif
*ndev_ap_vif
;
2139 ap_dev
= slsi_get_netdev(sdev
, SLSI_NET_INDEX_P2PX_SWLAN
);
2142 ndev_ap_vif
= netdev_priv(ap_dev
);
2143 SLSI_MUTEX_LOCK(ndev_ap_vif
->vif_mutex
);
2144 if (SLSI_IS_VIF_INDEX_MHS(sdev
, ndev_ap_vif
))
2145 ndev_vif
= ndev_ap_vif
;
2146 SLSI_MUTEX_UNLOCK(ndev_ap_vif
->vif_mutex
);
2150 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
2152 if ((!ndev_vif
->activated
) || (ndev_vif
->vif_type
!= FAPI_VIFTYPE_AP
)) {
2153 SLSI_ERR(sdev
, "slsi_get_sta_info: AP is not up.Command not allowed vif.activated:%d, vif.type:%d\n",
2154 ndev_vif
->activated
, ndev_vif
->vif_type
);
2155 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
2159 #if defined(ANDROID_VERSION) && (ANDROID_VERSION >= 90000)
2160 len
= snprintf(command
, buf_len
, "GETSTAINFO %pM Rx_Retry_Pkts=%d Rx_BcMc_Pkts=%d CAP=%04x %02x:%02x:%02x ",
2161 ndev_vif
->ap
.last_disconnected_sta
.address
,
2162 ndev_vif
->ap
.last_disconnected_sta
.rx_retry_packets
,
2163 ndev_vif
->ap
.last_disconnected_sta
.rx_bc_mc_packets
,
2164 ndev_vif
->ap
.last_disconnected_sta
.capabilities
,
2165 ndev_vif
->ap
.last_disconnected_sta
.address
[0],
2166 ndev_vif
->ap
.last_disconnected_sta
.address
[1],
2167 ndev_vif
->ap
.last_disconnected_sta
.address
[2]);
2169 len
+= snprintf(&command
[len
], (buf_len
- len
), "%d %d %d %d %d %d %d %u %d",
2170 ieee80211_frequency_to_channel(ndev_vif
->ap
.channel_freq
),
2171 ndev_vif
->ap
.last_disconnected_sta
.bandwidth
, ndev_vif
->ap
.last_disconnected_sta
.rssi
,
2172 ndev_vif
->ap
.last_disconnected_sta
.tx_data_rate
, ndev_vif
->ap
.last_disconnected_sta
.mode
,
2173 ndev_vif
->ap
.last_disconnected_sta
.antenna_mode
,
2174 ndev_vif
->ap
.last_disconnected_sta
.mimo_used
, ndev_vif
->ap
.last_disconnected_sta
.reason
,
2175 ndev_vif
->ap
.last_disconnected_sta
.support_mode
);
2177 len
= snprintf(command
, buf_len
, "wl_get_sta_info : %02x%02x%02x %u %d %d %d %d %d %d %u ",
2178 ndev_vif
->ap
.last_disconnected_sta
.address
[0], ndev_vif
->ap
.last_disconnected_sta
.address
[1],
2179 ndev_vif
->ap
.last_disconnected_sta
.address
[2], ndev_vif
->ap
.channel_freq
,
2180 ndev_vif
->ap
.last_disconnected_sta
.bandwidth
, ndev_vif
->ap
.last_disconnected_sta
.rssi
,
2181 ndev_vif
->ap
.last_disconnected_sta
.tx_data_rate
, ndev_vif
->ap
.last_disconnected_sta
.mode
,
2182 ndev_vif
->ap
.last_disconnected_sta
.antenna_mode
,
2183 ndev_vif
->ap
.last_disconnected_sta
.mimo_used
, ndev_vif
->ap
.last_disconnected_sta
.reason
);
2186 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
2191 static int slsi_get_bss_rssi(struct net_device
*dev
, char *command
, int buf_len
)
2193 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
2196 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
2197 len
= snprintf(command
, buf_len
, "%d", ndev_vif
->sta
.last_connected_bss
.rssi
);
2198 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
2203 static int slsi_get_bss_info(struct net_device
*dev
, char *command
, int buf_len
)
2205 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
2208 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
2210 len
= snprintf(command
, buf_len
, "%02x:%02x:%02x %u %u %d %u %u %u %u %u %d %d %u %u %u %u",
2211 ndev_vif
->sta
.last_connected_bss
.address
[0], ndev_vif
->sta
.last_connected_bss
.address
[1],
2212 ndev_vif
->sta
.last_connected_bss
.address
[2],
2213 ndev_vif
->sta
.last_connected_bss
.channel_freq
, ndev_vif
->sta
.last_connected_bss
.bandwidth
,
2214 ndev_vif
->sta
.last_connected_bss
.rssi
, ndev_vif
->sta
.last_connected_bss
.tx_data_rate
,
2215 ndev_vif
->sta
.last_connected_bss
.mode
, ndev_vif
->sta
.last_connected_bss
.antenna_mode
,
2216 ndev_vif
->sta
.last_connected_bss
.mimo_used
,
2217 ndev_vif
->sta
.last_connected_bss
.passpoint_version
, ndev_vif
->sta
.last_connected_bss
.snr
,
2218 ndev_vif
->sta
.last_connected_bss
.noise_level
, ndev_vif
->sta
.last_connected_bss
.roaming_akm
,
2219 ndev_vif
->sta
.last_connected_bss
.roaming_count
, ndev_vif
->sta
.last_connected_bss
.kv
,
2220 ndev_vif
->sta
.last_connected_bss
.kvie
);
2222 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
2227 static int slsi_get_linkspeed(struct net_device
*dev
, char *command
, int buf_len
)
2229 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
2230 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
2233 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
2234 if (!ndev_vif
->activated
) {
2235 SLSI_ERR(sdev
, "Not Activated, Command not allowed vif.activated:%d, vif.type:%d\n",
2236 ndev_vif
->activated
, ndev_vif
->vif_type
);
2237 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
2241 if ((ndev_vif
->vif_type
!= FAPI_VIFTYPE_STATION
) && (ndev_vif
->sta
.vif_status
!= SLSI_VIF_STATUS_CONNECTED
)) {
2242 SLSI_NET_ERR(dev
, "sta is not in connected state\n");
2243 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
2247 len
= snprintf(command
, buf_len
, "MAX_SPEED %u CURRENT_LINK_SPEED %u",
2248 ndev_vif
->sta
.max_rate_mbps
, ndev_vif
->sta
.data_rate_mbps
);
2250 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
2255 static int slsi_get_assoc_reject_info(struct net_device
*dev
, char *command
, int buf_len
)
2257 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
2258 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
2261 len
= snprintf(command
, buf_len
, "assoc_reject.status : %d %s", sdev
->assoc_result_code
,
2262 slsi_get_assoc_status(sdev
->assoc_result_code
));
2267 #ifdef CONFIG_SCSC_WLAN_LOW_LATENCY_MODE
2268 static int slsi_set_power_mode(struct net_device
*dev
, char *command
, int buf_len
)
2270 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
2271 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
2275 power_mode
= (command
[0] == '0') ? FAPI_POWERMANAGEMENTMODE_ACTIVE_MODE
: FAPI_POWERMANAGEMENTMODE_POWER_SAVE
;
2276 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
2277 if ((!ndev_vif
->activated
) || (ndev_vif
->vif_type
!= FAPI_VIFTYPE_STATION
) ||
2278 !(ndev_vif
->sta
.vif_status
== SLSI_VIF_STATUS_CONNECTED
)) {
2279 SLSI_ERR(sdev
, "Command not allowed vif.activated:%d, vif.type:%d, ndev_vif->sta.vif_status:%d\n",
2280 ndev_vif
->activated
, ndev_vif
->vif_type
, ndev_vif
->sta
.vif_status
);
2281 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
2284 status
= slsi_mlme_powermgt(sdev
, dev
, power_mode
);
2285 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
2291 int slsi_set_disconnect_ies(struct net_device
*dev
, char *cmd
, int cmd_len
)
2293 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
2294 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
2295 char *disconnect_ies
= cmd
+ strlen(CMD_SET_DISCONNECT_IES
) + 1;
2297 u8
*disconnect_ies_bin
;
2303 SLSI_DBG1(sdev
, SLSI_CFG80211
, "Setting disconnect IE's\n");
2304 while (disconnect_ies
[ie_len
])
2307 /* ie_len has been trimmed to even, as odd length would mean that ie is invalid */
2309 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
2310 ndev_vif
->sta
.vendor_disconnect_ies_len
= (ie_len
/ 2);
2311 disconnect_ies_bin
= kmalloc(ndev_vif
->sta
.vendor_disconnect_ies_len
, GFP_KERNEL
);
2312 if (!disconnect_ies_bin
) {
2313 SLSI_ERR(sdev
, "Malloc failed\n");
2314 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
2318 for (i
= 0, j
= 0; j
< ie_len
; j
+= 2) {
2319 temp_byte
= slsi_parse_hex(disconnect_ies
[j
]) << 4 | slsi_parse_hex(disconnect_ies
[j
+ 1]);
2320 disconnect_ies_bin
[i
++] = temp_byte
;
2323 /* check if the IE is valid */
2324 for (i
= 0; i
< ndev_vif
->sta
.vendor_disconnect_ies_len
;) {
2325 if (disconnect_ies_bin
[i
] == 0xdd) {
2326 len
= disconnect_ies_bin
[i
+ 1];
2327 if ((ndev_vif
->sta
.vendor_disconnect_ies_len
- (i
+ 2)) < len
) {
2328 SLSI_WARN(sdev
, "The length of disconnect IE's is not proper\n");
2329 ndev_vif
->sta
.vendor_disconnect_ies_len
= 0;
2330 kfree(disconnect_ies_bin
);
2331 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
2337 SLSI_WARN(sdev
, "The tag of disconnect IE's is not proper\n");
2338 ndev_vif
->sta
.vendor_disconnect_ies_len
= 0;
2339 kfree(disconnect_ies_bin
);
2340 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
2344 ndev_vif
->sta
.vendor_disconnect_ies
= disconnect_ies_bin
;
2345 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
2350 #ifdef CONFIG_SCSC_WLAN_STA_ENHANCED_ARP_DETECT
2351 static int slsi_enhanced_arp_start_stop(struct net_device
*dev
, char *command
, int buf_len
)
2353 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
2354 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
2360 SLSI_MUTEX_LOCK(sdev
->device_config_mutex
);
2361 if (!sdev
->device_config
.fw_enhanced_arp_detect_supported
) {
2362 SLSI_ERR(sdev
, "Enhanced ARP Detect Feature is not supported.\n");
2363 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
2366 SLSI_MUTEX_UNLOCK(sdev
->device_config_mutex
);
2368 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
2369 if (ndev_vif
->vif_type
!= FAPI_VIFTYPE_STATION
) {
2370 SLSI_ERR(sdev
, "Not in STA mode\n");
2371 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
)
2375 SLSI_DBG1(sdev
, SLSI_CFG80211
, "Enhanced ARP Start/Stop\n");
2377 memset(ndev_vif
->target_ip_addr
, 0, sizeof(ndev_vif
->target_ip_addr
));
2378 for (i
= 0; i
< 4 ; i
++) {
2379 readbyte
= slsi_str_to_int(command
, &readvalue
);
2380 ndev_vif
->target_ip_addr
[i
] = readvalue
;
2381 command
= command
+ readbyte
+ 1;
2384 if (ndev_vif
->target_ip_addr
[0] != 0) { /* start enhanced arp detect */
2385 /* reset all the counters in host and firmware */
2386 slsi_read_enhanced_arp_rx_count_by_lower_mac(sdev
, dev
, SLSI_PSID_UNIFI_ARP_DETECT_RESPONSE_COUNTER
);
2387 memset(&ndev_vif
->enhanced_arp_stats
, 0, sizeof(ndev_vif
->enhanced_arp_stats
));
2388 ndev_vif
->enhanced_arp_detect_enabled
= true;
2389 result
= slsi_mlme_arp_detect_request(sdev
, dev
, FAPI_ACTION_START
, ndev_vif
->target_ip_addr
);
2390 } else { /* stop enhanced arp detect */
2391 ndev_vif
->enhanced_arp_detect_enabled
= false;
2392 result
= slsi_mlme_arp_detect_request(sdev
, dev
, FAPI_ACTION_STOP
, ndev_vif
->target_ip_addr
);
2395 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
2399 static int slsi_enhanced_arp_get_stats(struct net_device
*dev
, char *command
, int buf_len
)
2401 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
2402 struct slsi_dev
*sdev
= ndev_vif
->sdev
;
2406 r
= slsi_read_enhanced_arp_rx_count_by_lower_mac(sdev
, dev
, SLSI_PSID_UNIFI_ARP_DETECT_RESPONSE_COUNTER
);
2409 len
= snprintf(command
, buf_len
, "%d %d %d %d %d %d %d %d %d %d",
2410 ndev_vif
->enhanced_arp_stats
.arp_req_count_from_netdev
,
2411 ndev_vif
->enhanced_arp_stats
.arp_req_count_to_lower_mac
,
2412 ndev_vif
->enhanced_arp_stats
.arp_req_rx_count_by_lower_mac
,
2413 ndev_vif
->enhanced_arp_stats
.arp_req_count_tx_success
,
2414 ndev_vif
->enhanced_arp_stats
.arp_rsp_rx_count_by_lower_mac
,
2415 ndev_vif
->enhanced_arp_stats
.arp_rsp_rx_count_by_upper_mac
,
2416 ndev_vif
->enhanced_arp_stats
.arp_rsp_count_to_netdev
,
2417 ndev_vif
->enhanced_arp_stats
.arp_rsp_count_out_of_order_drop
,
2418 0, /*ap_link_active not supported, set as 0*/
2419 ndev_vif
->enhanced_arp_stats
.is_duplicate_addr_detected
);
2420 SLSI_DBG2(sdev
, SLSI_CFG80211
, "Enhanced ARP Stats: %s\n", command
);
2423 /*clear all the counters*/
2424 memset(&ndev_vif
->enhanced_arp_stats
, 0, sizeof(ndev_vif
->enhanced_arp_stats
));
2430 int slsi_ioctl(struct net_device
*dev
, struct ifreq
*rq
, int cmd
)
2432 #define MAX_LEN_PRIV_COMMAND 4096 /*This value is the max reply size set in supplicant*/
2433 struct android_wifi_priv_cmd priv_cmd
;
2442 if (!rq
->ifr_data
) {
2446 if (copy_from_user((void *)&priv_cmd
, (void *)rq
->ifr_data
, sizeof(struct android_wifi_priv_cmd
))) {
2448 SLSI_NET_ERR(dev
, "ifr data failed\n");
2452 if ((priv_cmd
.total_len
> MAX_LEN_PRIV_COMMAND
) || (priv_cmd
.total_len
< 0)) {
2454 SLSI_NET_ERR(dev
, "Length mismatch total_len = %d\n", priv_cmd
.total_len
);
2457 command
= kmalloc((priv_cmd
.total_len
+ 1), GFP_KERNEL
);
2460 SLSI_NET_ERR(dev
, "No memory\n");
2463 if (copy_from_user(command
, priv_cmd
.buf
, priv_cmd
.total_len
)) {
2465 SLSI_NET_ERR(dev
, "Buffer copy fail\n");
2468 command
[priv_cmd
.total_len
] = '\0';
2470 SLSI_INFO_NODEV("command: %.*s\n", priv_cmd
.total_len
, command
);
2472 if (strncasecmp(command
, CMD_SETSUSPENDMODE
, strlen(CMD_SETSUSPENDMODE
)) == 0) {
2473 ret
= slsi_set_suspend_mode(dev
, command
);
2474 } else if (strncasecmp(command
, CMD_SETJOINPREFER
, strlen(CMD_SETJOINPREFER
)) == 0) {
2475 char *rssi_boost_string
= command
+ strlen(CMD_SETJOINPREFER
) + 1;
2477 ret
= slsi_update_rssi_boost(dev
, rssi_boost_string
);
2478 } else if (strncasecmp(command
, CMD_RXFILTERADD
, strlen(CMD_RXFILTERADD
)) == 0) {
2479 int filter_num
= *(command
+ strlen(CMD_RXFILTERADD
) + 1) - '0';
2481 ret
= slsi_rx_filter_num_write(dev
, 1, filter_num
);
2482 } else if (strncasecmp(command
, CMD_RXFILTERREMOVE
, strlen(CMD_RXFILTERREMOVE
)) == 0) {
2483 int filter_num
= *(command
+ strlen(CMD_RXFILTERREMOVE
) + 1) - '0';
2485 ret
= slsi_rx_filter_num_write(dev
, 0, filter_num
);
2486 #ifdef CONFIG_SCSC_WLAN_WIFI_SHARING
2487 #if !defined(CONFIG_SCSC_WLAN_MHS_STATIC_INTERFACE) || (defined(ANDROID_VERSION) && ANDROID_VERSION < 90000)
2488 } else if (strncasecmp(command
, CMD_INTERFACE_CREATE
, strlen(CMD_INTERFACE_CREATE
)) == 0) {
2489 char *intf_name
= command
+ strlen(CMD_INTERFACE_CREATE
) + 1;
2491 ret
= slsi_create_interface(dev
, intf_name
);
2492 } else if (strncasecmp(command
, CMD_INTERFACE_DELETE
, strlen(CMD_INTERFACE_DELETE
)) == 0) {
2493 char *intf_name
= command
+ strlen(CMD_INTERFACE_DELETE
) + 1;
2495 ret
= slsi_delete_interface(dev
, intf_name
);
2497 } else if (strncasecmp(command
, CMD_SET_INDOOR_CHANNELS
, strlen(CMD_SET_INDOOR_CHANNELS
)) == 0) {
2498 char *arg
= command
+ strlen(CMD_SET_INDOOR_CHANNELS
) + 1;
2500 ret
= slsi_set_indoor_channels(dev
, arg
);
2501 } else if (strncasecmp(command
, CMD_GET_INDOOR_CHANNELS
, strlen(CMD_GET_INDOOR_CHANNELS
)) == 0) {
2502 ret
= slsi_get_indoor_channels(dev
, command
, priv_cmd
.total_len
);
2504 } else if (strncasecmp(command
, CMD_SETCOUNTRYREV
, strlen(CMD_SETCOUNTRYREV
)) == 0) {
2505 char *country_code
= command
+ strlen(CMD_SETCOUNTRYREV
) + 1;
2507 ret
= slsi_set_country_rev(dev
, country_code
);
2508 } else if (strncasecmp(command
, CMD_GETCOUNTRYREV
, strlen(CMD_GETCOUNTRYREV
)) == 0) {
2509 ret
= slsi_get_country_rev(dev
, command
, priv_cmd
.total_len
);
2510 #ifdef CONFIG_SCSC_WLAN_WES_NCHO
2511 } else if (strncasecmp(command
, CMD_SETROAMTRIGGER
, strlen(CMD_SETROAMTRIGGER
)) == 0) {
2512 int skip
= strlen(CMD_SETROAMTRIGGER
) + 1;
2514 ret
= slsi_roam_scan_trigger_write(dev
, command
+ skip
,
2515 priv_cmd
.total_len
- skip
);
2516 } else if (strncasecmp(command
, CMD_GETROAMTRIGGER
, strlen(CMD_GETROAMTRIGGER
)) == 0) {
2517 ret
= slsi_roam_scan_trigger_read(dev
, command
, priv_cmd
.total_len
);
2518 } else if (strncasecmp(command
, CMD_SETROAMDELTA
, strlen(CMD_SETROAMDELTA
)) == 0) {
2519 int skip
= strlen(CMD_SETROAMDELTA
) + 1;
2521 ret
= slsi_roam_delta_trigger_write(dev
, command
+ skip
,
2522 priv_cmd
.total_len
- skip
);
2523 } else if (strncasecmp(command
, CMD_GETROAMDELTA
, strlen(CMD_GETROAMDELTA
)) == 0) {
2524 ret
= slsi_roam_delta_trigger_read(dev
, command
, priv_cmd
.total_len
);
2525 } else if (strncasecmp(command
, CMD_SETROAMSCANPERIOD
, strlen(CMD_SETROAMSCANPERIOD
)) == 0) {
2526 int skip
= strlen(CMD_SETROAMSCANPERIOD
) + 1;
2528 ret
= slsi_cached_channel_scan_period_write(dev
, command
+ skip
,
2529 priv_cmd
.total_len
- skip
);
2530 } else if (strncasecmp(command
, CMD_GETROAMSCANPERIOD
, strlen(CMD_GETROAMSCANPERIOD
)) == 0) {
2531 ret
= slsi_cached_channel_scan_period_read(dev
, command
, priv_cmd
.total_len
);
2532 } else if (strncasecmp(command
, CMD_SETFULLROAMSCANPERIOD
, strlen(CMD_SETFULLROAMSCANPERIOD
)) == 0) {
2533 int skip
= strlen(CMD_SETFULLROAMSCANPERIOD
) + 1;
2535 ret
= slsi_full_roam_scan_period_write(dev
, command
+ skip
,
2536 priv_cmd
.total_len
- skip
);
2537 } else if (strncasecmp(command
, CMD_GETFULLROAMSCANPERIOD
, strlen(CMD_GETFULLROAMSCANPERIOD
)) == 0) {
2538 ret
= slsi_full_roam_scan_period_read(dev
, command
, priv_cmd
.total_len
);
2539 } else if (strncasecmp(command
, CMD_SETSCANCHANNELTIME
, strlen(CMD_SETSCANCHANNELTIME
)) == 0) {
2540 int skip
= strlen(CMD_SETSCANCHANNELTIME
) + 1;
2542 ret
= slsi_roam_scan_max_active_channel_time_write(dev
, command
+ skip
,
2543 priv_cmd
.total_len
- skip
);
2544 } else if (strncasecmp(command
, CMD_GETSCANCHANNELTIME
, strlen(CMD_GETSCANCHANNELTIME
)) == 0) {
2545 ret
= slsi_roam_scan_max_active_channel_time_read(dev
, command
, priv_cmd
.total_len
);
2546 } else if (strncasecmp(command
, CMD_SETSCANNPROBES
, strlen(CMD_SETSCANNPROBES
)) == 0) {
2547 int skip
= strlen(CMD_SETSCANNPROBES
) + 1;
2549 ret
= slsi_roam_scan_probe_interval_write(dev
, command
+ skip
,
2550 priv_cmd
.total_len
- skip
);
2551 } else if (strncasecmp(command
, CMD_GETSCANNPROBES
, strlen(CMD_GETSCANNPROBES
)) == 0) {
2552 ret
= slsi_roam_scan_probe_interval_read(dev
, command
, priv_cmd
.total_len
);
2553 } else if (strncasecmp(command
, CMD_SETROAMMODE
, strlen(CMD_SETROAMMODE
)) == 0) {
2554 int skip
= strlen(CMD_SETROAMMODE
) + 1;
2556 ret
= slsi_roam_mode_write(dev
, command
+ skip
,
2557 priv_cmd
.total_len
- skip
);
2558 } else if (strncasecmp(command
, CMD_GETROAMMODE
, strlen(CMD_GETROAMMODE
)) == 0) {
2559 ret
= slsi_roam_mode_read(dev
, command
, priv_cmd
.total_len
);
2560 } else if (strncasecmp(command
, CMD_SETROAMINTRABAND
, strlen(CMD_SETROAMINTRABAND
)) == 0) {
2561 int skip
= strlen(CMD_SETROAMINTRABAND
) + 1;
2563 ret
= slsi_roam_scan_band_write(dev
, command
+ skip
,
2564 priv_cmd
.total_len
- skip
);
2565 } else if (strncasecmp(command
, CMD_GETROAMINTRABAND
, strlen(CMD_GETROAMINTRABAND
)) == 0) {
2566 ret
= slsi_roam_scan_band_read(dev
, command
, priv_cmd
.total_len
);
2567 } else if (strncasecmp(command
, CMD_SETROAMBAND
, strlen(CMD_SETROAMBAND
)) == 0) {
2568 uint band
= *(command
+ strlen(CMD_SETROAMBAND
) + 1) - '0';
2570 ret
= slsi_freq_band_write(dev
, band
);
2571 } else if (strncasecmp(command
, CMD_SETBAND
, strlen(CMD_SETBAND
)) == 0) {
2572 uint band
= *(command
+ strlen(CMD_SETBAND
) + 1) - '0';
2574 ret
= slsi_freq_band_write(dev
, band
);
2575 } else if ((strncasecmp(command
, CMD_GETROAMBAND
, strlen(CMD_GETROAMBAND
)) == 0) || (strncasecmp(command
, CMD_GETBAND
, strlen(CMD_GETBAND
)) == 0)) {
2576 ret
= slsi_freq_band_read(dev
, command
, priv_cmd
.total_len
);
2577 } else if (strncasecmp(command
, CMD_SETROAMSCANCONTROL
, strlen(CMD_SETROAMSCANCONTROL
)) == 0) {
2578 int mode
= *(command
+ strlen(CMD_SETROAMSCANCONTROL
) + 1) - '0';
2580 ret
= slsi_roam_scan_control_write(dev
, mode
);
2581 } else if (strncasecmp(command
, CMD_GETROAMSCANCONTROL
, strlen(CMD_GETROAMSCANCONTROL
)) == 0) {
2582 ret
= slsi_roam_scan_control_read(dev
, command
, priv_cmd
.total_len
);
2583 } else if (strncasecmp(command
, CMD_SETSCANHOMETIME
, strlen(CMD_SETSCANHOMETIME
)) == 0) {
2584 int skip
= strlen(CMD_SETSCANHOMETIME
) + 1;
2586 ret
= slsi_roam_scan_home_time_write(dev
, command
+ skip
,
2587 priv_cmd
.total_len
- skip
);
2588 } else if (strncasecmp(command
, CMD_GETSCANHOMETIME
, strlen(CMD_GETSCANHOMETIME
)) == 0) {
2589 ret
= slsi_roam_scan_home_time_read(dev
, command
, priv_cmd
.total_len
);
2590 } else if (strncasecmp(command
, CMD_SETSCANHOMEAWAYTIME
, strlen(CMD_SETSCANHOMEAWAYTIME
)) == 0) {
2591 int skip
= strlen(CMD_SETSCANHOMEAWAYTIME
) + 1;
2593 ret
= slsi_roam_scan_home_away_time_write(dev
, command
+ skip
,
2594 priv_cmd
.total_len
- skip
);
2595 } else if (strncasecmp(command
, CMD_GETSCANHOMEAWAYTIME
, strlen(CMD_GETSCANHOMEAWAYTIME
)) == 0) {
2596 ret
= slsi_roam_scan_home_away_time_read(dev
, command
, priv_cmd
.total_len
);
2597 } else if (strncasecmp(command
, CMD_SETOKCMODE
, strlen(CMD_SETOKCMODE
)) == 0) {
2598 int mode
= *(command
+ strlen(CMD_SETOKCMODE
) + 1) - '0';
2600 ret
= slsi_okc_mode_write(dev
, mode
);
2601 } else if (strncasecmp(command
, CMD_GETOKCMODE
, strlen(CMD_GETOKCMODE
)) == 0) {
2602 ret
= slsi_okc_mode_read(dev
, command
, priv_cmd
.total_len
);
2603 } else if (strncasecmp(command
, CMD_SETWESMODE
, strlen(CMD_SETWESMODE
)) == 0) {
2604 int mode
= *(command
+ strlen(CMD_SETWESMODE
) + 1) - '0';
2606 ret
= slsi_wes_mode_write(dev
, mode
);
2607 } else if (strncasecmp(command
, CMD_GETWESMODE
, strlen(CMD_GETWESMODE
)) == 0) {
2608 ret
= slsi_wes_mode_read(dev
, command
, priv_cmd
.total_len
);
2609 } else if (strncasecmp(command
, CMD_SETROAMSCANCHANNELS
, strlen(CMD_SETROAMSCANCHANNELS
)) == 0) {
2610 int skip
= strlen(CMD_SETROAMSCANCHANNELS
) + 1;
2612 ret
= slsi_roam_scan_channels_write(dev
, command
+ skip
,
2613 priv_cmd
.total_len
- skip
);
2614 } else if (strncasecmp(command
, CMD_GETROAMSCANCHANNELS
, strlen(CMD_GETROAMSCANCHANNELS
)) == 0) {
2615 ret
= slsi_roam_scan_channels_read(dev
, command
, priv_cmd
.total_len
);
2617 } else if (strncasecmp(command
, CMD_SET_PMK
, strlen(CMD_SET_PMK
)) == 0) {
2618 ret
= slsi_set_pmk(dev
, command
, priv_cmd
.total_len
);
2619 } else if (strncasecmp(command
, CMD_HAPD_GET_CHANNEL
, strlen(CMD_HAPD_GET_CHANNEL
)) == 0) {
2620 ret
= slsi_auto_chan_read(dev
, command
, priv_cmd
.total_len
);
2621 } else if (strncasecmp(command
, CMD_SET_SAP_CHANNEL_LIST
, strlen(CMD_SET_SAP_CHANNEL_LIST
)) == 0) {
2622 int skip
= strlen(CMD_SET_SAP_CHANNEL_LIST
) + 1;
2624 ret
= slsi_auto_chan_write(dev
, command
+ skip
);
2625 } else if (strncasecmp(command
, CMD_REASSOC
, strlen(CMD_REASSOC
)) == 0) {
2626 int skip
= strlen(CMD_REASSOC
) + 1;
2628 ret
= slsi_reassoc_write(dev
, command
+ skip
,
2629 priv_cmd
.total_len
- skip
);
2630 } else if (strncasecmp(command
, CMD_SENDACTIONFRAME
, strlen(CMD_SENDACTIONFRAME
)) == 0) {
2631 int skip
= strlen(CMD_SENDACTIONFRAME
) + 1;
2633 ret
= slsi_send_action_frame(dev
, command
+ skip
,
2634 priv_cmd
.total_len
- skip
);
2635 } else if (strncasecmp(command
, CMD_HAPD_MAX_NUM_STA
, strlen(CMD_HAPD_MAX_NUM_STA
)) == 0) {
2637 u8
*max_sta
= command
+ strlen(CMD_HAPD_MAX_NUM_STA
) + 1;
2639 slsi_str_to_int(max_sta
, &sta_num
);
2640 ret
= slsi_setting_max_sta_write(dev
, sta_num
);
2641 } else if (strncasecmp(command
, CMD_COUNTRY
, strlen(CMD_COUNTRY
)) == 0) {
2642 char *country_code
= command
+ strlen(CMD_COUNTRY
) + 1;
2644 ret
= slsi_country_write(dev
, country_code
);
2645 #ifdef CONFIG_SLSI_WLAN_STA_FWD_BEACON
2646 } else if (strncasecmp(command
, CMD_BEACON_RECV
, strlen(CMD_BEACON_RECV
)) == 0) {
2647 char *action
= command
+ strlen(CMD_BEACON_RECV
) + 1;
2649 ret
= slsi_forward_beacon(dev
, action
);
2651 } else if (strncasecmp(command
, CMD_SETAPP2PWPSIE
, strlen(CMD_SETAPP2PWPSIE
)) == 0) {
2652 ret
= slsi_set_ap_p2p_wps_ie(dev
, command
, priv_cmd
.total_len
);
2653 } else if (strncasecmp(command
, CMD_P2PSETPS
, strlen(CMD_P2PSETPS
)) == 0) {
2654 ret
= slsi_set_p2p_oppps(dev
, command
, priv_cmd
.total_len
);
2655 } else if (strncasecmp(command
, CMD_P2PSETNOA
, strlen(CMD_P2PSETNOA
)) == 0) {
2656 ret
= slsi_p2p_set_noa_params(dev
, command
, priv_cmd
.total_len
);
2657 } else if (strncasecmp(command
, CMD_P2PECSA
, strlen(CMD_P2PECSA
)) == 0) {
2658 ret
= slsi_p2p_ecsa(dev
, command
);
2659 } else if (strncasecmp(command
, CMD_P2PLOSTART
, strlen(CMD_P2PLOSTART
)) == 0) {
2660 ret
= slsi_p2p_lo_start(dev
, command
);
2661 } else if (strncasecmp(command
, CMD_P2PLOSTOP
, strlen(CMD_P2PLOSTOP
)) == 0) {
2662 ret
= slsi_p2p_lo_stop(dev
);
2663 } else if (strncasecmp(command
, CMD_SETROAMOFFLOAD
, strlen(CMD_SETROAMOFFLOAD
)) == 0) {
2664 ret
= slsi_roam_mode_write(dev
, command
+ strlen(CMD_SETROAMOFFLOAD
) + 1,
2665 priv_cmd
.total_len
- (strlen(CMD_SETROAMOFFLOAD
) + 1));
2666 } else if (strncasecmp(command
, CMD_SETROAMOFFLAPLIST
, strlen(CMD_SETROAMOFFLAPLIST
)) == 0) {
2667 ret
= slsi_roam_offload_ap_list(dev
, command
+ strlen(CMD_SETROAMOFFLAPLIST
) + 1,
2668 priv_cmd
.total_len
- (strlen(CMD_SETROAMOFFLAPLIST
) + 1));
2669 } else if (strncasecmp(command
, CMD_SET_TX_POWER_CALLING
, strlen(CMD_SET_TX_POWER_CALLING
)) == 0) {
2670 ret
= slsi_set_tx_power_calling(dev
, command
+ strlen(CMD_SET_TX_POWER_CALLING
) + 1,
2671 priv_cmd
.total_len
- (strlen(CMD_SET_TX_POWER_CALLING
) + 1));
2672 } else if (strncasecmp(command
, CMD_SET_TX_POWER_SAR
, strlen(CMD_SET_TX_POWER_SAR
)) == 0) {
2673 ret
= slsi_set_tx_power_sar(dev
, command
+ strlen(CMD_SET_TX_POWER_SAR
) + 1,
2674 priv_cmd
.total_len
- (strlen(CMD_SET_TX_POWER_SAR
) + 1));
2675 } else if (strncasecmp(command
, CMD_GET_TX_POWER_SAR
, strlen(CMD_GET_TX_POWER_SAR
)) == 0) {
2676 ret
= slsi_get_tx_power_sar(dev
, command
, priv_cmd
.total_len
);
2677 } else if (strncasecmp(command
, CMD_GETREGULATORY
, strlen(CMD_GETREGULATORY
)) == 0) {
2678 ret
= slsi_get_regulatory(dev
, command
, priv_cmd
.total_len
);
2679 #ifdef CONFIG_SCSC_WLAN_HANG_TEST
2680 } else if (strncasecmp(command
, CMD_TESTFORCEHANG
, strlen(CMD_TESTFORCEHANG
)) == 0) {
2681 ret
= slsi_test_send_hanged_vendor_event(dev
);
2683 } else if (strncasecmp(command
, CMD_SET_FCC_CHANNEL
, strlen(CMD_SET_FCC_CHANNEL
)) == 0) {
2684 ret
= slsi_set_fcc_channel(dev
, command
+ strlen(CMD_SET_FCC_CHANNEL
) + 1,
2685 priv_cmd
.total_len
- (strlen(CMD_SET_FCC_CHANNEL
) + 1));
2686 } else if (strncasecmp(command
, CMD_FAKEMAC
, strlen(CMD_FAKEMAC
)) == 0) {
2687 ret
= slsi_fake_mac_write(dev
, command
+ strlen(CMD_FAKEMAC
) + 1);
2688 } else if (strncasecmp(command
, CMD_GETBSSRSSI
, strlen(CMD_GETBSSRSSI
)) == 0) {
2689 ret
= slsi_get_bss_rssi(dev
, command
, priv_cmd
.total_len
);
2690 } else if (strncasecmp(command
, CMD_GETBSSINFO
, strlen(CMD_GETBSSINFO
)) == 0) {
2691 ret
= slsi_get_bss_info(dev
, command
, priv_cmd
.total_len
);
2692 } else if (strncasecmp(command
, CMD_GETSTAINFO
, strlen(CMD_GETSTAINFO
)) == 0) {
2693 ret
= slsi_get_sta_info(dev
, command
, priv_cmd
.total_len
);
2694 } else if (strncasecmp(command
, CMD_GETASSOCREJECTINFO
, strlen(CMD_GETASSOCREJECTINFO
)) == 0) {
2695 ret
= slsi_get_assoc_reject_info(dev
, command
, priv_cmd
.total_len
);
2696 #ifdef CONFIG_SCSC_WLAN_LOW_LATENCY_MODE
2697 } else if (strncasecmp(command
, CMD_SET_LATENCY_MODE
, strlen(CMD_SET_LATENCY_MODE
)) == 0) {
2698 int latency_mode
= *(command
+ strlen(CMD_SET_LATENCY_MODE
) + 1) - '0';
2699 int cmd_len
= priv_cmd
.total_len
- (strlen(CMD_SET_LATENCY_MODE
) + 1);
2701 ret
= slsi_set_latency_mode(dev
, latency_mode
, cmd_len
);
2702 } else if (strncasecmp(command
, CMD_SET_POWER_MGMT
, strlen(CMD_SET_POWER_MGMT
)) == 0) {
2703 ret
= slsi_set_power_mode(dev
, command
+ strlen(CMD_SET_POWER_MGMT
) + 1,
2704 priv_cmd
.total_len
- (strlen(CMD_SET_POWER_MGMT
) + 1));
2706 } else if (strncasecmp(command
, CMD_SET_DISCONNECT_IES
, strlen(CMD_SET_DISCONNECT_IES
)) == 0) {
2707 ret
= slsi_set_disconnect_ies(dev
, command
, priv_cmd
.total_len
);
2708 #ifdef CONFIG_SCSC_WLAN_STA_ENHANCED_ARP_DETECT
2709 } else if (strncasecmp(command
, CMD_SET_ENHANCED_ARP_TARGET
, strlen(CMD_SET_ENHANCED_ARP_TARGET
)) == 0) {
2710 int skip
= strlen(CMD_SET_ENHANCED_ARP_TARGET
) + 1;
2712 ret
= slsi_enhanced_arp_start_stop(dev
, command
+ skip
, priv_cmd
.total_len
- skip
);
2713 } else if (strncasecmp(command
, CMD_GET_ENHANCED_ARP_COUNTS
, strlen(CMD_SET_ENHANCED_ARP_TARGET
)) == 0) {
2714 ret
= slsi_enhanced_arp_get_stats(dev
, command
, priv_cmd
.total_len
);
2716 } else if ((strncasecmp(command
, CMD_RXFILTERSTART
, strlen(CMD_RXFILTERSTART
)) == 0) ||
2717 (strncasecmp(command
, CMD_RXFILTERSTOP
, strlen(CMD_RXFILTERSTOP
)) == 0) ||
2718 (strncasecmp(command
, CMD_BTCOEXMODE
, strlen(CMD_BTCOEXMODE
)) == 0) ||
2719 (strncasecmp(command
, CMD_BTCOEXSCAN_START
, strlen(CMD_BTCOEXSCAN_START
)) == 0) ||
2720 (strncasecmp(command
, CMD_BTCOEXSCAN_STOP
, strlen(CMD_BTCOEXSCAN_STOP
)) == 0) ||
2721 (strncasecmp(command
, CMD_MIRACAST
, strlen(CMD_MIRACAST
)) == 0)) {
2723 } else if ((strncasecmp(command
, CMD_AMPDU_MPDU
, strlen(CMD_AMPDU_MPDU
)) == 0) ||
2724 (strncasecmp(command
, CMD_CHANGE_RL
, strlen(CMD_CHANGE_RL
)) == 0) ||
2725 (strncasecmp(command
, CMD_INTERFACE_CREATE
, strlen(CMD_INTERFACE_CREATE
)) == 0) ||
2726 (strncasecmp(command
, CMD_INTERFACE_DELETE
, strlen(CMD_INTERFACE_DELETE
)) == 0) ||
2727 (strncasecmp(command
, CMD_LTECOEX
, strlen(CMD_LTECOEX
)) == 0) ||
2728 (strncasecmp(command
, CMD_RESTORE_RL
, strlen(CMD_RESTORE_RL
)) == 0) ||
2729 (strncasecmp(command
, CMD_RPSMODE
, strlen(CMD_RPSMODE
)) == 0) ||
2730 (strncasecmp(command
, CMD_SETCCXMODE
, strlen(CMD_SETCCXMODE
)) == 0) ||
2731 (strncasecmp(command
, CMD_SETDFSSCANMODE
, strlen(CMD_SETDFSSCANMODE
)) == 0) ||
2732 (strncasecmp(command
, CMD_SETSINGLEANT
, strlen(CMD_SETSINGLEANT
)) == 0)) {
2734 #ifndef SLSI_TEST_DEV
2735 } else if ((strncasecmp(command
, CMD_DRIVERDEBUGDUMP
, strlen(CMD_DRIVERDEBUGDUMP
)) == 0) ||
2736 (strncasecmp(command
, CMD_DRIVERDEBUGCOMMAND
, strlen(CMD_DRIVERDEBUGCOMMAND
)) == 0)) {
2737 slsi_dump_stats(dev
);
2738 #ifdef CONFIG_SCSC_LOG_COLLECTION
2739 scsc_log_collector_schedule_collection(SCSC_LOG_DUMPSTATE
, SCSC_LOG_DUMPSTATE_REASON_DRIVERDEBUGDUMP
);
2741 ret
= mx140_log_dump();
2744 #ifdef CONFIG_SCSC_WLAN_ENHANCED_PKT_FILTER
2745 } else if ((strncasecmp(command
, CMD_ENHANCED_PKT_FILTER
, strlen(CMD_ENHANCED_PKT_FILTER
)) == 0)) {
2746 const u8 enable
= *(command
+ strlen(CMD_ENHANCED_PKT_FILTER
) + 1) - '0';
2748 ret
= slsi_set_enhanced_pkt_filter(dev
, enable
);
2750 #ifdef CONFIG_SCSC_WLAN_SET_NUM_ANTENNAS
2751 } else if (strncasecmp(command
, CMD_SET_NUM_ANTENNAS
, strlen(CMD_SET_NUM_ANTENNAS
)) == 0) {
2752 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
2753 const u16 num_of_antennas
= *(command
+ strlen(CMD_SET_NUM_ANTENNAS
) + 1) - '0';
2755 /* We cannot lock in slsi_set_num_antennas as
2756 * this is also called in slsi_start_ap with netdev_vif lock.
2758 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
2759 ret
= slsi_set_num_antennas(dev
, num_of_antennas
);
2760 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
2762 } else if ((strncasecmp(command
, CMD_GET_MAX_LINK_SPEED
, strlen(CMD_GET_MAX_LINK_SPEED
)) == 0)) {
2763 ret
= slsi_get_linkspeed(dev
, command
, priv_cmd
.total_len
);
2767 if (strncasecmp(command
, CMD_SETROAMBAND
, strlen(CMD_SETROAMBAND
)) != 0 && strncasecmp(command
, CMD_SETBAND
, strlen(CMD_SETBAND
)) != 0 && copy_to_user(priv_cmd
.buf
, command
, priv_cmd
.total_len
)) {
2769 SLSI_NET_ERR(dev
, "Buffer copy fail\n");