2 * ---------------------------------------------------------------------------
3 * FILE: sme_mgt_blocking.c
6 * This file contains the driver specific implementation of
7 * the WEXT <==> SME MGT interface for all SME builds that support WEXT.
9 * Copyright (C) 2009 by Cambridge Silicon Radio Ltd.
11 * Refer to LICENSE.txt included with this source code for details on
14 * ---------------------------------------------------------------------------
17 #include "unifi_priv.h"
21 * This file also contains the implementation of the asyncronous
22 * requests to the SME.
24 * Before calling an asyncronous SME function, we call sme_init_request()
25 * which gets hold of the SME semaphore and updates the request status.
26 * The semaphore makes sure that there is only one pending request to
29 * Now we are ready to call the SME function, but only if
30 * sme_init_request() has returned 0.
32 * When the SME function returns, we need to wait
33 * for the reply. This is done in sme_wait_for_reply().
34 * If the request times-out, the request status is set to SME_REQUEST_TIMEDOUT
35 * and the sme_wait_for_reply() returns.
37 * If the SME replies in time, we call sme_complete_request().
38 * There we change the request status to SME_REQUEST_RECEIVED. This will
39 * wake up the process waiting on sme_wait_for_reply().
40 * It is important that we copy the reply data in priv->sme_reply
41 * before calling sme_complete_request().
43 * Handling the wext requests, we need to block
44 * until the SME sends the response to our request.
45 * We use the sme_init_request() and sme_wait_for_reply()
46 * to implement this behavior in the following functions:
50 * sme_mgt_scan_results_get_async()
52 * unifi_mgt_media_status_ind()
53 * sme_mgt_disconnect()
58 * sme_mgt_versions_get()
61 * sme_mgt_set_value_async()
62 * sme_mgt_get_value_async()
63 * sme_mgt_packet_filter_set()
69 * Handling the suspend and resume system events, we need to block
70 * until the SME sends the response to our indication.
71 * We use the sme_init_request() and sme_wait_for_reply()
72 * to implement this behavior in the following functions:
77 #define UNIFI_SME_MGT_SHORT_TIMEOUT 10000
78 #define UNIFI_SME_MGT_LONG_TIMEOUT 19000
79 #define UNIFI_SME_SYS_LONG_TIMEOUT 10000
82 # define sme_wait_for_reply(priv, t) _sme_wait_for_reply(priv, t, __func__)
84 # define sme_wait_for_reply(priv, t) _sme_wait_for_reply(priv, t, NULL)
88 sme_init_request(unifi_priv_t
*priv
)
91 unifi_error(priv
, "sme_init_request: Invalid priv\n");
95 unifi_trace(priv
, UDBG5
, "sme_init_request: wait sem\n");
97 /* Grab the SME semaphore until the reply comes, or timeout */
98 if (down_interruptible(&priv
->sme_sem
)) {
99 unifi_error(priv
, "sme_init_request: Failed to get SME semaphore\n");
102 unifi_trace(priv
, UDBG5
, "sme_init_request: got sem: pending\n");
104 priv
->sme_reply
.request_status
= SME_REQUEST_PENDING
;
108 } /* sme_init_request() */
112 uf_sme_complete_request(unifi_priv_t
*priv
, CsrResult reply_status
, const char *func
)
115 unifi_error(priv
, "sme_complete_request: Invalid priv\n");
119 if (priv
->sme_reply
.request_status
!= SME_REQUEST_PENDING
) {
121 "sme_complete_request: request not pending %s (s:%d)\n",
122 (func
? func
: ""), priv
->sme_reply
.request_status
);
125 unifi_trace(priv
, UDBG5
,
126 "sme_complete_request: completed %s (s:%d)\n",
127 (func
? func
: ""), priv
->sme_reply
.request_status
);
129 priv
->sme_reply
.request_status
= SME_REQUEST_RECEIVED
;
130 priv
->sme_reply
.reply_status
= reply_status
;
132 wake_up_interruptible(&priv
->sme_request_wq
);
139 uf_sme_cancel_request(unifi_priv_t
*priv
, CsrResult reply_status
)
141 /* Check for a blocking SME request in progress, and cancel the wait.
142 * This should be used when the character device is closed.
146 unifi_error(priv
, "sme_cancel_request: Invalid priv\n");
150 /* If no request is pending, nothing to wake up */
151 if (priv
->sme_reply
.request_status
!= SME_REQUEST_PENDING
) {
152 unifi_trace(priv
, UDBG5
,
153 "sme_cancel_request: no request was pending (s:%d)\n",
154 priv
->sme_reply
.request_status
);
158 unifi_trace(priv
, UDBG5
,
159 "sme_cancel_request: request cancelled (s:%d)\n",
160 priv
->sme_reply
.request_status
);
162 /* Wake up the wait with an error status */
163 priv
->sme_reply
.request_status
= SME_REQUEST_CANCELLED
;
164 priv
->sme_reply
.reply_status
= reply_status
; /* unimportant since the CANCELLED state will fail the ioctl */
166 wake_up_interruptible(&priv
->sme_request_wq
);
173 _sme_wait_for_reply(unifi_priv_t
*priv
,
174 unsigned long timeout
, const char *func
)
178 unifi_trace(priv
, UDBG5
, "sme_wait_for_reply: %s sleep\n", func
? func
: "");
179 r
= wait_event_interruptible_timeout(priv
->sme_request_wq
,
180 (priv
->sme_reply
.request_status
!= SME_REQUEST_PENDING
),
181 msecs_to_jiffies(timeout
));
182 unifi_trace(priv
, UDBG5
, "sme_wait_for_reply: %s awake (%d)\n", func
? func
: "", r
);
184 if (r
== -ERESTARTSYS
) {
185 /* The thread was killed */
186 unifi_info(priv
, "ERESTARTSYS in _sme_wait_for_reply\n");
190 if (priv
->sme_reply
.request_status
== SME_REQUEST_CANCELLED
) {
191 unifi_trace(priv
, UDBG5
, "Cancelled waiting for SME to reply (%s s:%d, t:%d, r:%d)\n",
192 (func
? func
: ""), priv
->sme_reply
.request_status
, timeout
, r
);
194 /* Release the SME semaphore that was downed in sme_init_request() */
196 return -EIO
; /* fail the ioctl */
198 if ((r
== 0) && (priv
->sme_reply
.request_status
!= SME_REQUEST_RECEIVED
)) {
199 unifi_notice(priv
, "Timeout waiting for SME to reply (%s s:%d, t:%d)\n",
200 (func
? func
: ""), priv
->sme_reply
.request_status
, timeout
);
202 priv
->sme_reply
.request_status
= SME_REQUEST_TIMEDOUT
;
204 /* Release the SME semaphore that was downed in sme_init_request() */
210 unifi_trace(priv
, UDBG5
, "sme_wait_for_reply: %s received (%d)\n",
211 func
? func
: "", r
);
213 /* Release the SME semaphore that was downed in sme_init_request() */
217 } /* sme_wait_for_reply() */
222 #ifdef CSR_SUPPORT_WEXT
223 int sme_mgt_wifi_on(unifi_priv_t
*priv
)
226 CsrWifiSmeDataBlock
* dataList
;
227 #ifdef CSR_SUPPORT_WEXT_AP
231 if (priv
->smepriv
== NULL
) {
232 unifi_error(priv
, "sme_mgt_wifi_on: invalid smepriv\n");
236 if (priv
->mib_data
.length
) {
238 dataList
= &priv
->mib_data
;
244 #ifdef CSR_SUPPORT_WEXT_AP
245 r
= sme_init_request(priv
);
250 CsrWifiSmeWifiOnReqSend(0, priv
->sta_mac_address
, numElements
, dataList
);
251 #ifdef CSR_SUPPORT_WEXT_AP
252 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_LONG_TIMEOUT
);
253 unifi_trace(priv
, UDBG4
,
254 "sme_mgt_wifi_on: unifi_mgt_wifi_oo_req <-- (r=%d, status=%d)\n",
255 r
, priv
->sme_reply
.reply_status
);
256 return convert_sme_error(priv
->sme_reply
.reply_status
);
260 } /* sme_mgt_wifi_on() */
263 int sme_mgt_wifi_off(unifi_priv_t
*priv
)
267 if (priv
->smepriv
== NULL
) {
268 unifi_error(priv
, "sme_mgt_wifi_off: invalid smepriv\n");
272 r
= sme_init_request(priv
);
278 CsrWifiSmeWifiOffReqSend(0);
280 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_LONG_TIMEOUT
);
285 unifi_trace(priv
, UDBG4
,
286 "sme_mgt_wifi_off: unifi_mgt_wifi_off_req <-- (r=%d, status=%d)\n",
287 r
, priv
->sme_reply
.reply_status
);
288 return convert_sme_error(priv
->sme_reply
.reply_status
);
290 } /* sme_mgt_wifi_off */
292 int sme_mgt_key(unifi_priv_t
*priv
, CsrWifiSmeKey
*sme_key
,
293 CsrWifiSmeListAction action
)
297 if (priv
->smepriv
== NULL
) {
298 unifi_error(priv
, "sme_mgt_key: invalid smepriv\n");
302 r
= sme_init_request(priv
);
307 CsrWifiSmeKeyReqSend(0, CSR_WIFI_INTERFACE_IN_USE
, action
, *sme_key
);
309 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
314 return convert_sme_error(priv
->sme_reply
.reply_status
);
318 int sme_mgt_scan_full(unifi_priv_t
*priv
,
319 CsrWifiSsid
*specific_ssid
,
321 unsigned char *channel_list
)
323 CsrWifiMacAddress bcastAddress
= {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }};
324 u8 is_active
= (num_channels
> 0) ? TRUE
: FALSE
;
327 if (priv
->smepriv
== NULL
) {
328 unifi_error(priv
, "sme_mgt_scan_full: invalid smepriv\n");
332 unifi_trace(priv
, UDBG4
, "sme_mgt_scan_full: -->\n");
334 r
= sme_init_request(priv
);
339 /* If a channel list is provided, do an active scan */
341 unifi_trace(priv
, UDBG1
,
342 "channel list - num_channels: %d, active scan\n",
346 CsrWifiSmeScanFullReqSend(0,
347 specific_ssid
->length
?1:0, /* 0 or 1 SSIDS */
351 CSR_WIFI_SME_BSS_TYPE_ANY_BSS
,
352 CSR_WIFI_SME_SCAN_TYPE_ALL
,
353 (u16
)num_channels
, channel_list
,
356 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_LONG_TIMEOUT
);
361 unifi_trace(priv
, UDBG4
, "sme_mgt_scan_full: <-- (status=%d)\n", priv
->sme_reply
.reply_status
);
362 if (priv
->sme_reply
.reply_status
== CSR_WIFI_RESULT_UNAVAILABLE
) {
363 return 0; /* initial scan already underway */
365 return convert_sme_error(priv
->sme_reply
.reply_status
);
370 int sme_mgt_scan_results_get_async(unifi_priv_t
*priv
,
371 struct iw_request_info
*info
,
373 long scan_results_len
)
375 u16 scan_result_list_count
;
376 CsrWifiSmeScanResult
*scan_result_list
;
377 CsrWifiSmeScanResult
*scan_result
;
380 char *current_ev
= scan_results
;
382 if (priv
->smepriv
== NULL
) {
383 unifi_error(priv
, "sme_mgt_scan_results_get_async: invalid smepriv\n");
387 r
= sme_init_request(priv
);
392 CsrWifiSmeScanResultsGetReqSend(0);
393 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_LONG_TIMEOUT
);
398 scan_result_list_count
= priv
->sme_reply
.reply_scan_results_count
;
399 scan_result_list
= priv
->sme_reply
.reply_scan_results
;
400 unifi_trace(priv
, UDBG2
,
401 "scan_results: Scan returned %d, numElements=%d\n",
402 r
, scan_result_list_count
);
404 /* OK, now we have the scan results */
405 for (i
= 0; i
< scan_result_list_count
; ++i
) {
406 scan_result
= &scan_result_list
[i
];
408 unifi_trace(priv
, UDBG2
, "Scan Result: %.*s\n",
409 scan_result
->ssid
.length
,
410 scan_result
->ssid
.ssid
);
412 r
= unifi_translate_scan(priv
->netdev
[0], info
,
414 scan_results
+ scan_results_len
,
418 kfree(scan_result_list
);
419 priv
->sme_reply
.reply_scan_results_count
= 0;
420 priv
->sme_reply
.reply_scan_results
= NULL
;
428 * Free the scan results allocated in unifi_mgt_scan_results_get_cfm()
429 * and invalidate the reply_scan_results to avoid re-using
430 * the freed pointers.
432 kfree(scan_result_list
);
433 priv
->sme_reply
.reply_scan_results_count
= 0;
434 priv
->sme_reply
.reply_scan_results
= NULL
;
436 unifi_trace(priv
, UDBG2
,
437 "scan_results: Scan translated to %d bytes\n",
438 current_ev
- scan_results
);
439 return (current_ev
- scan_results
);
443 int sme_mgt_connect(unifi_priv_t
*priv
)
447 if (priv
->smepriv
== NULL
) {
448 unifi_error(priv
, "sme_mgt_connect: invalid smepriv\n");
452 unifi_trace(priv
, UDBG2
, "sme_mgt_connect: %.*s\n",
453 priv
->connection_config
.ssid
.length
,
454 priv
->connection_config
.ssid
.ssid
);
456 r
= sme_init_request(priv
);
461 CsrWifiSmeConnectReqSend(0, CSR_WIFI_INTERFACE_IN_USE
, priv
->connection_config
);
462 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
467 if (priv
->sme_reply
.reply_status
) {
468 unifi_trace(priv
, UDBG1
, "sme_mgt_connect: failed with SME status %d\n",
469 priv
->sme_reply
.reply_status
);
472 return convert_sme_error(priv
->sme_reply
.reply_status
);
476 int sme_mgt_disconnect(unifi_priv_t
*priv
)
480 if (priv
->smepriv
== NULL
) {
481 unifi_error(priv
, "sme_mgt_disconnect: invalid smepriv\n");
485 r
= sme_init_request(priv
);
490 CsrWifiSmeDisconnectReqSend(0, CSR_WIFI_INTERFACE_IN_USE
);
491 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
496 unifi_trace(priv
, UDBG4
, "sme_mgt_disconnect: <-- (status=%d)\n", priv
->sme_reply
.reply_status
);
497 return convert_sme_error(priv
->sme_reply
.reply_status
);
501 int sme_mgt_pmkid(unifi_priv_t
*priv
,
502 CsrWifiSmeListAction action
,
503 CsrWifiSmePmkidList
*pmkid_list
)
507 if (priv
->smepriv
== NULL
) {
508 unifi_error(priv
, "sme_mgt_pmkid: invalid smepriv\n");
512 r
= sme_init_request(priv
);
517 CsrWifiSmePmkidReqSend(0, CSR_WIFI_INTERFACE_IN_USE
, action
,
518 pmkid_list
->pmkidsCount
, pmkid_list
->pmkids
);
519 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
524 unifi_trace(priv
, UDBG4
, "sme_mgt_pmkid: <-- (status=%d)\n", priv
->sme_reply
.reply_status
);
525 return convert_sme_error(priv
->sme_reply
.reply_status
);
529 int sme_mgt_mib_get(unifi_priv_t
*priv
,
530 unsigned char *varbind
, int *length
)
534 if (priv
->smepriv
== NULL
) {
535 unifi_error(priv
, "sme_mgt_mib_get: invalid smepriv\n");
539 r
= sme_init_request(priv
);
544 priv
->mib_cfm_buffer
= varbind
;
545 priv
->mib_cfm_buffer_length
= MAX_VARBIND_LENGTH
;
547 CsrWifiSmeMibGetReqSend(0, *length
, varbind
);
548 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
550 priv
->mib_cfm_buffer_length
= 0;
551 priv
->mib_cfm_buffer
= NULL
;
555 *length
= priv
->mib_cfm_buffer_length
;
557 priv
->mib_cfm_buffer_length
= 0;
558 priv
->mib_cfm_buffer
= NULL
;
559 unifi_trace(priv
, UDBG4
, "sme_mgt_mib_get: <-- (status=%d)\n", priv
->sme_reply
.reply_status
);
560 return convert_sme_error(priv
->sme_reply
.reply_status
);
563 int sme_mgt_mib_set(unifi_priv_t
*priv
,
564 unsigned char *varbind
, int length
)
568 if (priv
->smepriv
== NULL
) {
569 unifi_error(priv
, "sme_mgt_mib_get: invalid smepriv\n");
573 r
= sme_init_request(priv
);
578 CsrWifiSmeMibSetReqSend(0, length
, varbind
);
579 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
584 unifi_trace(priv
, UDBG4
, "sme_mgt_mib_set: <-- (status=%d)\n", priv
->sme_reply
.reply_status
);
585 return convert_sme_error(priv
->sme_reply
.reply_status
);
588 #endif /* CSR_SUPPORT_WEXT */
590 int sme_mgt_power_config_set(unifi_priv_t
*priv
, CsrWifiSmePowerConfig
*powerConfig
)
592 #ifdef CSR_SME_USERSPACE
595 if (priv
->smepriv
== NULL
) {
596 unifi_error(priv
, "sme_mgt_set_value_async: invalid smepriv\n");
600 r
= sme_init_request(priv
);
605 CsrWifiSmePowerConfigSetReqSend(0, *powerConfig
);
607 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
612 unifi_trace(priv
, UDBG4
,
613 "sme_mgt_set_value_async: unifi_mgt_set_value_req <-- (r=%d status=%d)\n",
614 r
, priv
->sme_reply
.reply_status
);
615 return convert_sme_error(priv
->sme_reply
.reply_status
);
618 if (priv
->smepriv
== NULL
) {
619 unifi_error(priv
, "sme_mgt_set_value: invalid smepriv\n");
622 CsrWifiSmeMgtClaimSyncAccess(priv
->smepriv
);
623 status
= CsrWifiSmeMgtPowerConfigSetReq(priv
->smepriv
, *powerConfig
);
624 CsrWifiSmeMgtReleaseSyncAccess(priv
->smepriv
);
625 return convert_sme_error(status
);
629 int sme_mgt_sme_config_set(unifi_priv_t
*priv
, CsrWifiSmeStaConfig
*staConfig
, CsrWifiSmeDeviceConfig
*deviceConfig
)
631 #ifdef CSR_SME_USERSPACE
634 if (priv
->smepriv
== NULL
) {
635 unifi_error(priv
, "sme_mgt_sme_config_set: invalid smepriv\n");
639 r
= sme_init_request(priv
);
644 CsrWifiSmeSmeStaConfigSetReqSend(0, CSR_WIFI_INTERFACE_IN_USE
, *staConfig
);
645 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
649 unifi_trace(priv
, UDBG4
,
650 "sme_mgt_sme_config_set: CsrWifiSmeSmeStaConfigSetReq <-- (r=%d status=%d)\n",
651 r
, priv
->sme_reply
.reply_status
);
653 r
= sme_init_request(priv
);
658 CsrWifiSmeSmeCommonConfigSetReqSend(0, *deviceConfig
);
659 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
664 unifi_trace(priv
, UDBG4
,
665 "sme_mgt_sme_config_set: CsrWifiSmeSmeCommonConfigSetReq <-- (r=%d status=%d)\n",
666 r
, priv
->sme_reply
.reply_status
);
668 return convert_sme_error(priv
->sme_reply
.reply_status
);
671 if (priv
->smepriv
== NULL
) {
672 unifi_error(priv
, "sme_mgt_sme_config_set: invalid smepriv\n");
675 CsrWifiSmeMgtClaimSyncAccess(priv
->smepriv
);
676 status
= CsrWifiSmeMgtSmeConfigSetReq(priv
->smepriv
, *staConfig
);
677 status
= CsrWifiSmeMgtDeviceConfigSetReq(priv
->smepriv
, *deviceConfig
);
678 CsrWifiSmeMgtReleaseSyncAccess(priv
->smepriv
);
679 return convert_sme_error(status
);
683 #ifdef CSR_SUPPORT_WEXT
685 int sme_mgt_mib_config_set(unifi_priv_t
*priv
, CsrWifiSmeMibConfig
*mibConfig
)
687 #ifdef CSR_SME_USERSPACE
690 if (priv
->smepriv
== NULL
) {
691 unifi_error(priv
, "sme_mgt_mib_config_set: invalid smepriv\n");
695 r
= sme_init_request(priv
);
700 CsrWifiSmeMibConfigSetReqSend(0, *mibConfig
);
702 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
707 unifi_trace(priv
, UDBG4
,
708 "sme_mgt_mib_config_set: unifi_mgt_set_mib_config_req <-- (r=%d status=%d)\n",
709 r
, priv
->sme_reply
.reply_status
);
710 return convert_sme_error(priv
->sme_reply
.reply_status
);
713 if (priv
->smepriv
== NULL
) {
714 unifi_error(priv
, "sme_mgt_mib_config_set: invalid smepriv\n");
717 CsrWifiSmeMgtClaimSyncAccess(priv
->smepriv
);
718 status
= CsrWifiSmeMgtMibConfigSetReq(priv
->smepriv
, *mibConfig
);
719 CsrWifiSmeMgtReleaseSyncAccess(priv
->smepriv
);
720 return convert_sme_error(status
);
724 int sme_mgt_coex_config_set(unifi_priv_t
*priv
, CsrWifiSmeCoexConfig
*coexConfig
)
726 #ifdef CSR_SME_USERSPACE
729 if (priv
->smepriv
== NULL
) {
730 unifi_error(priv
, "sme_mgt_coex_config_set: invalid smepriv\n");
734 r
= sme_init_request(priv
);
739 CsrWifiSmeCoexConfigSetReqSend(0, *coexConfig
);
741 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
746 unifi_trace(priv
, UDBG4
,
747 "sme_mgt_coex_config_set: unifi_mgt_set_mib_config_req <-- (r=%d status=%d)\n",
748 r
, priv
->sme_reply
.reply_status
);
749 return convert_sme_error(priv
->sme_reply
.reply_status
);
752 if (priv
->smepriv
== NULL
) {
753 unifi_error(priv
, "sme_mgt_coex_config_set: invalid smepriv\n");
756 CsrWifiSmeMgtClaimSyncAccess(priv
->smepriv
);
757 status
= CsrWifiSmeMgtCoexConfigSetReq(priv
->smepriv
, *coexConfig
);
758 CsrWifiSmeMgtReleaseSyncAccess(priv
->smepriv
);
759 return convert_sme_error(status
);
763 #endif /* CSR_SUPPORT_WEXT */
765 int sme_mgt_host_config_set(unifi_priv_t
*priv
, CsrWifiSmeHostConfig
*hostConfig
)
767 #ifdef CSR_SME_USERSPACE
770 if (priv
->smepriv
== NULL
) {
771 unifi_error(priv
, "sme_mgt_host_config_set: invalid smepriv\n");
775 r
= sme_init_request(priv
);
780 CsrWifiSmeHostConfigSetReqSend(0, CSR_WIFI_INTERFACE_IN_USE
, *hostConfig
);
782 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
787 unifi_trace(priv
, UDBG4
,
788 "sme_mgt_host_config_set: unifi_mgt_set_host_config_req <-- (r=%d status=%d)\n",
789 r
, priv
->sme_reply
.reply_status
);
790 return convert_sme_error(priv
->sme_reply
.reply_status
);
793 if (priv
->smepriv
== NULL
) {
794 unifi_error(priv
, "sme_mgt_host_config_set: invalid smepriv\n");
797 CsrWifiSmeMgtClaimSyncAccess(priv
->smepriv
);
798 status
= CsrWifiSmeMgtHostConfigSetReq(priv
->smepriv
, *hostConfig
);
799 CsrWifiSmeMgtReleaseSyncAccess(priv
->smepriv
);
800 return convert_sme_error(status
);
804 #ifdef CSR_SUPPORT_WEXT
806 int sme_mgt_versions_get(unifi_priv_t
*priv
, CsrWifiSmeVersions
*versions
)
808 #ifdef CSR_SME_USERSPACE
811 if (priv
->smepriv
== NULL
) {
812 unifi_error(priv
, "sme_mgt_versions_get: invalid smepriv\n");
816 unifi_trace(priv
, UDBG4
, "sme_mgt_versions_get: unifi_mgt_versions_get_req -->\n");
817 r
= sme_init_request(priv
);
822 CsrWifiSmeVersionsGetReqSend(0);
824 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
829 /* store the reply */
830 if (versions
!= NULL
) {
831 memcpy((unsigned char*)versions
,
832 (unsigned char*)&priv
->sme_reply
.versions
,
833 sizeof(CsrWifiSmeVersions
));
836 unifi_trace(priv
, UDBG4
,
837 "sme_mgt_versions_get: unifi_mgt_versions_get_req <-- (r=%d status=%d)\n",
838 r
, priv
->sme_reply
.reply_status
);
840 return convert_sme_error(priv
->sme_reply
.reply_status
);
843 CsrWifiSmeMgtClaimSyncAccess(priv
->smepriv
);
844 status
= CsrWifiSmeMgtVersionsGetReq(priv
->smepriv
, versions
);
845 CsrWifiSmeMgtReleaseSyncAccess(priv
->smepriv
);
846 return convert_sme_error(status
);
850 #endif /* CSR_SUPPORT_WEXT */
852 int sme_mgt_power_config_get(unifi_priv_t
*priv
, CsrWifiSmePowerConfig
*powerConfig
)
854 #ifdef CSR_SME_USERSPACE
857 if (priv
->smepriv
== NULL
) {
858 unifi_error(priv
, "sme_mgt_power_config_get: invalid smepriv\n");
862 unifi_trace(priv
, UDBG4
, "sme_mgt_power_config_get: unifi_mgt_power_config_req -->\n");
863 r
= sme_init_request(priv
);
868 CsrWifiSmePowerConfigGetReqSend(0);
870 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
875 /* store the reply */
876 if (powerConfig
!= NULL
) {
877 memcpy((unsigned char*)powerConfig
,
878 (unsigned char*)&priv
->sme_reply
.powerConfig
,
879 sizeof(CsrWifiSmePowerConfig
));
882 unifi_trace(priv
, UDBG4
,
883 "sme_mgt_get_versions: unifi_mgt_power_config_req <-- (r=%d status=%d)\n",
884 r
, priv
->sme_reply
.reply_status
);
886 return convert_sme_error(priv
->sme_reply
.reply_status
);
889 CsrWifiSmeMgtClaimSyncAccess(priv
->smepriv
);
890 status
= CsrWifiSmeMgtPowerConfigGetReq(priv
->smepriv
, powerConfig
);
891 CsrWifiSmeMgtReleaseSyncAccess(priv
->smepriv
);
892 return convert_sme_error(status
);
896 int sme_mgt_host_config_get(unifi_priv_t
*priv
, CsrWifiSmeHostConfig
*hostConfig
)
898 #ifdef CSR_SME_USERSPACE
901 if (priv
->smepriv
== NULL
) {
902 unifi_error(priv
, "sme_mgt_host_config_get: invalid smepriv\n");
906 unifi_trace(priv
, UDBG4
, "sme_mgt_host_config_get: unifi_mgt_host_config_get_req -->\n");
907 r
= sme_init_request(priv
);
912 CsrWifiSmeHostConfigGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE
);
914 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
919 /* store the reply */
920 if (hostConfig
!= NULL
) {
921 memcpy((unsigned char*)hostConfig
,
922 (unsigned char*)&priv
->sme_reply
.hostConfig
,
923 sizeof(CsrWifiSmeHostConfig
));
926 unifi_trace(priv
, UDBG4
,
927 "sme_mgt_host_config_get: unifi_mgt_host_config_get_req <-- (r=%d status=%d)\n",
928 r
, priv
->sme_reply
.reply_status
);
930 return convert_sme_error(priv
->sme_reply
.reply_status
);
933 CsrWifiSmeMgtClaimSyncAccess(priv
->smepriv
);
934 status
= CsrWifiSmeMgtHostConfigGetReq(priv
->smepriv
, hostConfig
);
935 CsrWifiSmeMgtReleaseSyncAccess(priv
->smepriv
);
936 return convert_sme_error(status
);
940 int sme_mgt_sme_config_get(unifi_priv_t
*priv
, CsrWifiSmeStaConfig
*staConfig
, CsrWifiSmeDeviceConfig
*deviceConfig
)
942 #ifdef CSR_SME_USERSPACE
945 if (priv
->smepriv
== NULL
) {
946 unifi_error(priv
, "sme_mgt_sme_config_get: invalid smepriv\n");
950 unifi_trace(priv
, UDBG4
, "sme_mgt_sme_config_get: unifi_mgt_sme_config_get_req -->\n");
952 /* Common device config */
953 r
= sme_init_request(priv
);
958 CsrWifiSmeSmeCommonConfigGetReqSend(0);
959 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
964 /* store the reply */
965 if (deviceConfig
!= NULL
) {
966 memcpy((unsigned char*)deviceConfig
,
967 (unsigned char*)&priv
->sme_reply
.deviceConfig
,
968 sizeof(CsrWifiSmeDeviceConfig
));
972 r
= sme_init_request(priv
);
977 CsrWifiSmeSmeStaConfigGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE
);
978 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
983 /* store the reply */
984 if (staConfig
!= NULL
) {
985 memcpy((unsigned char*)staConfig
,
986 (unsigned char*)&priv
->sme_reply
.staConfig
,
987 sizeof(CsrWifiSmeStaConfig
));
990 unifi_trace(priv
, UDBG4
,
991 "sme_mgt_sme_config_get: unifi_mgt_sme_config_get_req <-- (r=%d status=%d)\n",
992 r
, priv
->sme_reply
.reply_status
);
994 return convert_sme_error(priv
->sme_reply
.reply_status
);
997 CsrWifiSmeMgtClaimSyncAccess(priv
->smepriv
);
998 status
= CsrWifiSmeMgtSmeConfigGetReq(priv
->smepriv
, staConfig
);
999 status
= CsrWifiSmeMgtDeviceConfigGetReq(priv
->smepriv
, deviceConfig
);
1000 CsrWifiSmeMgtReleaseSyncAccess(priv
->smepriv
);
1001 return convert_sme_error(status
);
1005 int sme_mgt_coex_info_get(unifi_priv_t
*priv
, CsrWifiSmeCoexInfo
*coexInfo
)
1007 #ifdef CSR_SME_USERSPACE
1010 if (priv
->smepriv
== NULL
) {
1011 unifi_error(priv
, "sme_mgt_coex_info_get: invalid smepriv\n");
1015 unifi_trace(priv
, UDBG4
, "sme_mgt_coex_info_get: unifi_mgt_coex_info_get_req -->\n");
1016 r
= sme_init_request(priv
);
1021 CsrWifiSmeCoexInfoGetReqSend(0);
1023 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
1028 /* store the reply */
1029 if (coexInfo
!= NULL
) {
1030 memcpy((unsigned char*)coexInfo
,
1031 (unsigned char*)&priv
->sme_reply
.coexInfo
,
1032 sizeof(CsrWifiSmeCoexInfo
));
1035 unifi_trace(priv
, UDBG4
,
1036 "sme_mgt_coex_info_get: unifi_mgt_coex_info_get_req <-- (r=%d status=%d)\n",
1037 r
, priv
->sme_reply
.reply_status
);
1039 return convert_sme_error(priv
->sme_reply
.reply_status
);
1042 CsrWifiSmeMgtClaimSyncAccess(priv
->smepriv
);
1043 status
= CsrWifiSmeMgtCoexInfoGetReq(priv
->smepriv
, coexInfo
);
1044 CsrWifiSmeMgtReleaseSyncAccess(priv
->smepriv
);
1045 return convert_sme_error(status
);
1049 #ifdef CSR_SUPPORT_WEXT
1051 int sme_mgt_coex_config_get(unifi_priv_t
*priv
, CsrWifiSmeCoexConfig
*coexConfig
)
1053 #ifdef CSR_SME_USERSPACE
1056 if (priv
->smepriv
== NULL
) {
1057 unifi_error(priv
, "sme_mgt_coex_config_get: invalid smepriv\n");
1061 unifi_trace(priv
, UDBG4
, "sme_mgt_coex_config_get: unifi_mgt_coex_config_get_req -->\n");
1062 r
= sme_init_request(priv
);
1067 CsrWifiSmeCoexConfigGetReqSend(0);
1069 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
1074 /* store the reply */
1075 if (coexConfig
!= NULL
) {
1076 memcpy((unsigned char*)coexConfig
,
1077 (unsigned char*)&priv
->sme_reply
.coexConfig
,
1078 sizeof(CsrWifiSmeCoexConfig
));
1081 unifi_trace(priv
, UDBG4
,
1082 "sme_mgt_coex_config_get: unifi_mgt_coex_config_get_req <-- (r=%d status=%d)\n",
1083 r
, priv
->sme_reply
.reply_status
);
1085 return convert_sme_error(priv
->sme_reply
.reply_status
);
1088 CsrWifiSmeMgtClaimSyncAccess(priv
->smepriv
);
1089 status
= CsrWifiSmeMgtCoexConfigGetReq(priv
->smepriv
, coexConfig
);
1090 CsrWifiSmeMgtReleaseSyncAccess(priv
->smepriv
);
1091 return convert_sme_error(status
);
1095 int sme_mgt_mib_config_get(unifi_priv_t
*priv
, CsrWifiSmeMibConfig
*mibConfig
)
1097 #ifdef CSR_SME_USERSPACE
1100 if (priv
->smepriv
== NULL
) {
1101 unifi_error(priv
, "sme_mgt_mib_config_get: invalid smepriv\n");
1105 unifi_trace(priv
, UDBG4
, "sme_mgt_mib_config_get: unifi_mgt_mib_config_get_req -->\n");
1106 r
= sme_init_request(priv
);
1111 CsrWifiSmeMibConfigGetReqSend(0);
1113 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
1118 /* store the reply */
1119 if (mibConfig
!= NULL
) {
1120 memcpy((unsigned char*)mibConfig
,
1121 (unsigned char*)&priv
->sme_reply
.mibConfig
,
1122 sizeof(CsrWifiSmeMibConfig
));
1125 unifi_trace(priv
, UDBG4
,
1126 "sme_mgt_mib_config_get: unifi_mgt_mib_config_get_req <-- (r=%d status=%d)\n",
1127 r
, priv
->sme_reply
.reply_status
);
1129 return convert_sme_error(priv
->sme_reply
.reply_status
);
1132 CsrWifiSmeMgtClaimSyncAccess(priv
->smepriv
);
1133 status
= CsrWifiSmeMgtMibConfigGetReq(priv
->smepriv
, mibConfig
);
1134 CsrWifiSmeMgtReleaseSyncAccess(priv
->smepriv
);
1135 return convert_sme_error(status
);
1139 int sme_mgt_connection_info_get(unifi_priv_t
*priv
, CsrWifiSmeConnectionInfo
*connectionInfo
)
1141 #ifdef CSR_SME_USERSPACE
1144 if (priv
->smepriv
== NULL
) {
1145 unifi_error(priv
, "sme_mgt_connection_info_get: invalid smepriv\n");
1149 unifi_trace(priv
, UDBG4
, "sme_mgt_connection_info_get: unifi_mgt_connection_info_get_req -->\n");
1150 r
= sme_init_request(priv
);
1155 CsrWifiSmeConnectionInfoGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE
);
1157 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
1162 /* store the reply */
1163 if (connectionInfo
!= NULL
) {
1164 memcpy((unsigned char*)connectionInfo
,
1165 (unsigned char*)&priv
->sme_reply
.connectionInfo
,
1166 sizeof(CsrWifiSmeConnectionInfo
));
1169 unifi_trace(priv
, UDBG4
,
1170 "sme_mgt_connection_info_get: unifi_mgt_connection_info_get_req <-- (r=%d status=%d)\n",
1171 r
, priv
->sme_reply
.reply_status
);
1173 return convert_sme_error(priv
->sme_reply
.reply_status
);
1176 CsrWifiSmeMgtClaimSyncAccess(priv
->smepriv
);
1177 status
= CsrWifiSmeMgtConnectionInfoGetReq(priv
->smepriv
, connectionInfo
);
1178 CsrWifiSmeMgtReleaseSyncAccess(priv
->smepriv
);
1179 return convert_sme_error(status
);
1183 int sme_mgt_connection_config_get(unifi_priv_t
*priv
, CsrWifiSmeConnectionConfig
*connectionConfig
)
1185 #ifdef CSR_SME_USERSPACE
1188 if (priv
->smepriv
== NULL
) {
1189 unifi_error(priv
, "sme_mgt_connection_config_get: invalid smepriv\n");
1193 unifi_trace(priv
, UDBG4
, "sme_mgt_connection_config_get: unifi_mgt_connection_config_get_req -->\n");
1194 r
= sme_init_request(priv
);
1199 CsrWifiSmeConnectionConfigGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE
);
1201 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
1206 /* store the reply */
1207 if (connectionConfig
!= NULL
) {
1208 memcpy((unsigned char*)connectionConfig
,
1209 (unsigned char*)&priv
->sme_reply
.connectionConfig
,
1210 sizeof(CsrWifiSmeConnectionConfig
));
1213 unifi_trace(priv
, UDBG4
,
1214 "sme_mgt_connection_config_get: unifi_mgt_connection_config_get_req <-- (r=%d status=%d)\n",
1215 r
, priv
->sme_reply
.reply_status
);
1217 return convert_sme_error(priv
->sme_reply
.reply_status
);
1220 CsrWifiSmeMgtClaimSyncAccess(priv
->smepriv
);
1221 status
= CsrWifiSmeMgtConnectionConfigGetReq(priv
->smepriv
, connectionConfig
);
1222 CsrWifiSmeMgtReleaseSyncAccess(priv
->smepriv
);
1223 return convert_sme_error(status
);
1227 int sme_mgt_connection_stats_get(unifi_priv_t
*priv
, CsrWifiSmeConnectionStats
*connectionStats
)
1229 #ifdef CSR_SME_USERSPACE
1232 if (priv
->smepriv
== NULL
) {
1233 unifi_error(priv
, "sme_mgt_connection_stats_get: invalid smepriv\n");
1237 unifi_trace(priv
, UDBG4
, "sme_mgt_connection_stats_get: unifi_mgt_connection_stats_get_req -->\n");
1238 r
= sme_init_request(priv
);
1243 CsrWifiSmeConnectionStatsGetReqSend(0, CSR_WIFI_INTERFACE_IN_USE
);
1245 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
1250 /* store the reply */
1251 if (connectionStats
!= NULL
) {
1252 memcpy((unsigned char*)connectionStats
,
1253 (unsigned char*)&priv
->sme_reply
.connectionStats
,
1254 sizeof(CsrWifiSmeConnectionStats
));
1257 unifi_trace(priv
, UDBG4
,
1258 "sme_mgt_connection_stats_get: unifi_mgt_connection_stats_get_req <-- (r=%d status=%d)\n",
1259 r
, priv
->sme_reply
.reply_status
);
1261 return convert_sme_error(priv
->sme_reply
.reply_status
);
1264 CsrWifiSmeMgtClaimSyncAccess(priv
->smepriv
);
1265 status
= CsrWifiSmeMgtConnectionStatsGetReq(priv
->smepriv
, connectionStats
);
1266 CsrWifiSmeMgtReleaseSyncAccess(priv
->smepriv
);
1267 return convert_sme_error(status
);
1271 #endif /* CSR_SUPPORT_WEXT */
1273 int sme_mgt_packet_filter_set(unifi_priv_t
*priv
)
1275 CsrWifiIp4Address ipAddress
= {{0xFF, 0xFF, 0xFF, 0xFF }};
1276 if (priv
->smepriv
== NULL
) {
1277 unifi_error(priv
, "sme_mgt_packet_filter_set: invalid smepriv\n");
1280 if (priv
->packet_filters
.arp_filter
) {
1281 ipAddress
.a
[0] = (priv
->sta_ip_address
) & 0xFF;
1282 ipAddress
.a
[1] = (priv
->sta_ip_address
>> 8) & 0xFF;
1283 ipAddress
.a
[2] = (priv
->sta_ip_address
>> 16) & 0xFF;
1284 ipAddress
.a
[3] = (priv
->sta_ip_address
>> 24) & 0xFF;
1287 unifi_trace(priv
, UDBG5
,
1288 "sme_mgt_packet_filter_set: IP address %d.%d.%d.%d\n",
1289 ipAddress
.a
[0], ipAddress
.a
[1],
1290 ipAddress
.a
[2], ipAddress
.a
[3]);
1292 /* Doesn't block for a confirm */
1293 CsrWifiSmePacketFilterSetReqSend(0, CSR_WIFI_INTERFACE_IN_USE
,
1294 priv
->packet_filters
.tclas_ies_length
,
1295 priv
->filter_tclas_ies
,
1296 priv
->packet_filters
.filter_mode
,
1301 int sme_mgt_tspec(unifi_priv_t
*priv
, CsrWifiSmeListAction action
,
1302 u32 tid
, CsrWifiSmeDataBlock
*tspec
, CsrWifiSmeDataBlock
*tclas
)
1306 if (priv
->smepriv
== NULL
) {
1307 unifi_error(priv
, "sme_mgt_tspec: invalid smepriv\n");
1311 r
= sme_init_request(priv
);
1316 CsrWifiSmeTspecReqSend(0, CSR_WIFI_INTERFACE_IN_USE
,
1317 action
, tid
, TRUE
, 0,
1318 tspec
->length
, tspec
->data
,
1319 tclas
->length
, tclas
->data
);
1320 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
1325 unifi_trace(priv
, UDBG4
, "sme_mgt_tspec: <-- (status=%d)\n", priv
->sme_reply
.reply_status
);
1326 return convert_sme_error(priv
->sme_reply
.reply_status
);
1331 int sme_sys_suspend(unifi_priv_t
*priv
)
1334 CsrResult csrResult
;
1336 if (priv
->smepriv
== NULL
) {
1337 unifi_error(priv
, "sme_sys_suspend: invalid smepriv\n");
1341 r
= sme_init_request(priv
);
1346 /* Suspend the SME, which MAY cause it to power down UniFi */
1347 CsrWifiRouterCtrlSuspendIndSend(priv
->CSR_WIFI_SME_IFACEQUEUE
,0, 0, priv
->wol_suspend
);
1348 r
= sme_wait_for_reply(priv
, UNIFI_SME_SYS_LONG_TIMEOUT
);
1350 /* No reply - forcibly power down in case the request wasn't processed */
1352 "suspend: SME did not reply %s, ",
1353 (priv
->ptest_mode
| priv
->wol_suspend
) ? "leave powered" : "power off UniFi anyway\n");
1355 /* Leave power on for production test, though */
1356 if (!priv
->ptest_mode
) {
1357 /* Put UniFi to deep sleep, in case we can not power it off */
1358 CsrSdioClaim(priv
->sdio
);
1359 unifi_trace(priv
, UDBG1
, "Force deep sleep");
1360 csrResult
= unifi_force_low_power_mode(priv
->card
);
1362 /* For WOL, the UniFi must stay powered */
1363 if (!priv
->wol_suspend
) {
1364 unifi_trace(priv
, UDBG1
, "Power off\n");
1365 CsrSdioPowerOff(priv
->sdio
);
1367 CsrSdioRelease(priv
->sdio
);
1371 if (priv
->wol_suspend
) {
1372 unifi_trace(priv
, UDBG1
, "UniFi left powered for WOL\n");
1374 /* Remove the IRQ, which also disables the card SDIO interrupt.
1375 * Disabling the card SDIO interrupt enables the PIO WOL source.
1376 * Removal of the of the handler ensures that in both SDIO and PIO cases
1377 * the card interrupt only wakes the host. The card will be polled
1378 * after resume to handle any pending data.
1380 if (csr_sdio_linux_remove_irq(priv
->sdio
)) {
1381 unifi_notice(priv
, "WOL csr_sdio_linux_remove_irq failed\n");
1384 if (enable_wol
== UNIFI_WOL_SDIO
) {
1385 /* Because csr_sdio_linux_remove_irq() disabled the card SDIO interrupt,
1386 * it must be left enabled to wake-on-SDIO.
1388 unifi_trace(priv
, UDBG1
, "Enable card SDIO interrupt for SDIO WOL\n");
1390 CsrSdioClaim(priv
->sdio
);
1391 csrResult
= CsrSdioInterruptEnable(priv
->sdio
);
1392 CsrSdioRelease(priv
->sdio
);
1394 if (csrResult
!= CSR_RESULT_SUCCESS
) {
1395 unifi_error(priv
, "WOL CsrSdioInterruptEnable failed %d\n", csrResult
);
1398 unifi_trace(priv
, UDBG1
, "Disabled card SDIO interrupt for PIO WOL\n");
1401 /* Prevent the BH thread from running during the suspend.
1402 * Upon resume, sme_sys_resume() will trigger a wifi-on, this will cause
1403 * the BH thread to be re-enabled and reinstall the ISR.
1405 priv
->bh_thread
.block_thread
= 1;
1407 unifi_trace(priv
, UDBG1
, "unifi_suspend: suspended BH");
1410 /* Consider UniFi to be uninitialised */
1411 priv
->init_progress
= UNIFI_INIT_NONE
;
1413 unifi_trace(priv
, UDBG1
, "sme_sys_suspend: <-- (r=%d status=%d)\n", r
, priv
->sme_reply
.reply_status
);
1414 return convert_sme_error(priv
->sme_reply
.reply_status
);
1418 int sme_sys_resume(unifi_priv_t
*priv
)
1422 unifi_trace(priv
, UDBG1
, "sme_sys_resume %s\n", priv
->wol_suspend
? "warm" : "");
1424 if (priv
->smepriv
== NULL
) {
1425 unifi_error(priv
, "sme_sys_resume: invalid smepriv\n");
1429 r
= sme_init_request(priv
);
1434 CsrWifiRouterCtrlResumeIndSend(priv
->CSR_WIFI_SME_IFACEQUEUE
,0, priv
->wol_suspend
);
1436 r
= sme_wait_for_reply(priv
, UNIFI_SME_SYS_LONG_TIMEOUT
);
1439 "resume: SME did not reply, return success anyway\n");
1445 #ifdef CSR_SUPPORT_WEXT_AP
1446 int sme_ap_stop(unifi_priv_t
*priv
,u16 interface_tag
)
1450 if (priv
->smepriv
== NULL
) {
1451 unifi_error(priv
, "sme_ap_stop: invalid smepriv\n");
1455 r
= sme_init_request(priv
);
1460 CsrWifiNmeApStopReqSend(0,interface_tag
);
1462 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
1467 unifi_trace(priv
, UDBG4
,
1468 "sme_ap_stop <-- (r=%d status=%d)\n",
1469 r
, priv
->sme_reply
.reply_status
);
1470 return convert_sme_error(priv
->sme_reply
.reply_status
);
1474 int sme_ap_start(unifi_priv_t
*priv
,u16 interface_tag
,
1475 CsrWifiSmeApConfig_t
* ap_config
)
1478 CsrWifiSmeApP2pGoConfig p2p_go_param
;
1479 memset(&p2p_go_param
,0,sizeof(CsrWifiSmeApP2pGoConfig
));
1481 if (priv
->smepriv
== NULL
) {
1482 unifi_error(priv
, "sme_ap_start: invalid smepriv\n");
1486 r
= sme_init_request(priv
);
1491 CsrWifiNmeApStartReqSend(0,interface_tag
,CSR_WIFI_AP_TYPE_LEGACY
,FALSE
,
1492 ap_config
->ssid
,1,ap_config
->channel
,
1493 ap_config
->credentials
,ap_config
->max_connections
,
1494 p2p_go_param
,FALSE
);
1496 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
1501 unifi_trace(priv
, UDBG4
,
1502 "sme_ap_start <-- (r=%d status=%d)\n",
1503 r
, priv
->sme_reply
.reply_status
);
1504 return convert_sme_error(priv
->sme_reply
.reply_status
);
1507 int sme_ap_config(unifi_priv_t
*priv
,
1508 CsrWifiSmeApMacConfig
*ap_mac_config
,
1509 CsrWifiNmeApConfig
*group_security_config
)
1512 CsrWifiSmeApP2pGoConfig p2p_go_param
;
1513 memset(&p2p_go_param
,0,sizeof(CsrWifiSmeApP2pGoConfig
));
1515 if (priv
->smepriv
== NULL
) {
1516 unifi_error(priv
, "sme_ap_config: invalid smepriv\n");
1520 r
= sme_init_request(priv
);
1525 CsrWifiNmeApConfigSetReqSend(0,*group_security_config
,
1528 r
= sme_wait_for_reply(priv
, UNIFI_SME_MGT_SHORT_TIMEOUT
);
1530 unifi_trace(priv
, UDBG4
,
1531 "sme_ap_config <-- (r=%d status=%d)\n",
1532 r
, priv
->sme_reply
.reply_status
);
1533 return convert_sme_error(priv
->sme_reply
.reply_status
);