Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sme_blocking.c
Go to the documentation of this file.
1 /*
2  * ---------------------------------------------------------------------------
3  * FILE: sme_mgt_blocking.c
4  *
5  * PURPOSE:
6  * This file contains the driver specific implementation of
7  * the WEXT <==> SME MGT interface for all SME builds that support WEXT.
8  *
9  * Copyright (C) 2009 by Cambridge Silicon Radio Ltd.
10  *
11  * Refer to LICENSE.txt included with this source code for details on
12  * the license terms.
13  *
14  * ---------------------------------------------------------------------------
15  */
16 
17 #include "unifi_priv.h"
18 
19 
20 /*
21  * This file also contains the implementation of the asynchronous
22  * requests to the SME.
23  *
24  * Before calling an asynchronous 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
27  * the SME at a time.
28  *
29  * Now we are ready to call the SME function, but only if
30  * sme_init_request() has returned 0.
31  *
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.
36  *
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().
42  *
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:
47  * sme_mgt_wifi_on()
48  * sme_mgt_wifi_off()
49  * sme_mgt_scan_full()
50  * sme_mgt_scan_results_get_async()
51  * sme_mgt_connect()
52  * unifi_mgt_media_status_ind()
53  * sme_mgt_disconnect()
54  * sme_mgt_pmkid()
55  * sme_mgt_key()
56  * sme_mgt_mib_get()
57  * sme_mgt_mib_set()
58  * sme_mgt_versions_get()
59  * sme_mgt_set_value()
60  * sme_mgt_get_value()
61  * sme_mgt_set_value_async()
62  * sme_mgt_get_value_async()
63  * sme_mgt_packet_filter_set()
64  * sme_mgt_tspec()
65  */
66 
67 
68 /*
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:
73  * sme_sys_suspend()
74  * sme_sys_resume()
75  */
76 
77 #define UNIFI_SME_MGT_SHORT_TIMEOUT 10000
78 #define UNIFI_SME_MGT_LONG_TIMEOUT 19000
79 #define UNIFI_SME_SYS_LONG_TIMEOUT 10000
80 
81 #ifdef UNIFI_DEBUG
82 # define sme_wait_for_reply(priv, t) _sme_wait_for_reply(priv, t, __func__)
83 #else
84 # define sme_wait_for_reply(priv, t) _sme_wait_for_reply(priv, t, NULL)
85 #endif
86 
87 static int
88 sme_init_request(unifi_priv_t *priv)
89 {
90  if (priv == NULL) {
91  unifi_error(priv, "sme_init_request: Invalid priv\n");
92  return -EIO;
93  }
94 
95  unifi_trace(priv, UDBG5, "sme_init_request: wait sem\n");
96 
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");
100  return -EIO;
101  }
102  unifi_trace(priv, UDBG5, "sme_init_request: got sem: pending\n");
103 
104  priv->sme_reply.request_status = SME_REQUEST_PENDING;
105 
106  return 0;
107 
108 } /* sme_init_request() */
109 
110 
111 void
113 {
114  if (priv == NULL) {
115  unifi_error(priv, "sme_complete_request: Invalid priv\n");
116  return;
117  }
118 
119  if (priv->sme_reply.request_status != SME_REQUEST_PENDING) {
120  unifi_notice(priv,
121  "sme_complete_request: request not pending %s (s:%d)\n",
122  (func ? func : ""), priv->sme_reply.request_status);
123  return;
124  }
125  unifi_trace(priv, UDBG5,
126  "sme_complete_request: completed %s (s:%d)\n",
127  (func ? func : ""), priv->sme_reply.request_status);
128 
129  priv->sme_reply.request_status = SME_REQUEST_RECEIVED;
130  priv->sme_reply.reply_status = reply_status;
131 
132  wake_up_interruptible(&priv->sme_request_wq);
133 
134  return;
135 }
136 
137 
138 void
140 {
141  /* Check for a blocking SME request in progress, and cancel the wait.
142  * This should be used when the character device is closed.
143  */
144 
145  if (priv == NULL) {
146  unifi_error(priv, "sme_cancel_request: Invalid priv\n");
147  return;
148  }
149 
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);
155  /* Nothing to do */
156  return;
157  }
158  unifi_trace(priv, UDBG5,
159  "sme_cancel_request: request cancelled (s:%d)\n",
160  priv->sme_reply.request_status);
161 
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 */
165 
166  wake_up_interruptible(&priv->sme_request_wq);
167 
168  return;
169 }
170 
171 
172 static int
173 _sme_wait_for_reply(unifi_priv_t *priv,
174  unsigned long timeout, const char *func)
175 {
176  long r;
177 
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);
183 
184  if (r == -ERESTARTSYS) {
185  /* The thread was killed */
186  unifi_info(priv, "ERESTARTSYS in _sme_wait_for_reply\n");
187  up(&priv->sme_sem);
188  return r;
189  }
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);
193 
194  /* Release the SME semaphore that was downed in sme_init_request() */
195  up(&priv->sme_sem);
196  return -EIO; /* fail the ioctl */
197  }
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);
201 
202  priv->sme_reply.request_status = SME_REQUEST_TIMEDOUT;
203 
204  /* Release the SME semaphore that was downed in sme_init_request() */
205  up(&priv->sme_sem);
206 
207  return -ETIMEDOUT;
208  }
209 
210  unifi_trace(priv, UDBG5, "sme_wait_for_reply: %s received (%d)\n",
211  func ? func : "", r);
212 
213  /* Release the SME semaphore that was downed in sme_init_request() */
214  up(&priv->sme_sem);
215 
216  return 0;
217 } /* sme_wait_for_reply() */
218 
219 
220 
221 
222 #ifdef CSR_SUPPORT_WEXT
223 int sme_mgt_wifi_on(unifi_priv_t *priv)
224 {
225  u16 numElements;
226  CsrWifiSmeDataBlock* dataList;
227 #ifdef CSR_SUPPORT_WEXT_AP
228  int r;
229 #endif
230 
231  if (priv->smepriv == NULL) {
232  unifi_error(priv, "sme_mgt_wifi_on: invalid smepriv\n");
233  return -EIO;
234  }
235 
236  if (priv->mib_data.length) {
237  numElements = 1;
238  dataList = &priv->mib_data;
239  } else {
240  numElements = 0;
241  dataList = NULL;
242  }
243  /* Start the SME */
244 #ifdef CSR_SUPPORT_WEXT_AP
245  r = sme_init_request(priv);
246  if (r) {
247  return -EIO;
248  }
249 #endif
250  CsrWifiSmeWifiOnReqSend(0, priv->sta_mac_address, numElements, dataList);
251 #ifdef CSR_SUPPORT_WEXT_AP
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);
257 #else
258  return 0;
259 #endif
260 } /* sme_mgt_wifi_on() */
261 
262 
263 int sme_mgt_wifi_off(unifi_priv_t *priv)
264 {
265  int r;
266 
267  if (priv->smepriv == NULL) {
268  unifi_error(priv, "sme_mgt_wifi_off: invalid smepriv\n");
269  return -EIO;
270  }
271 
272  r = sme_init_request(priv);
273  if (r) {
274  return -EIO;
275  }
276 
277  /* Stop the SME */
279 
281  if (r) {
282  return r;
283  }
284 
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);
289 
290 } /* sme_mgt_wifi_off */
291 
292 int sme_mgt_key(unifi_priv_t *priv, CsrWifiSmeKey *sme_key,
294 {
295  int r;
296 
297  if (priv->smepriv == NULL) {
298  unifi_error(priv, "sme_mgt_key: invalid smepriv\n");
299  return -EIO;
300  }
301 
302  r = sme_init_request(priv);
303  if (r) {
304  return -EIO;
305  }
306 
307  CsrWifiSmeKeyReqSend(0, CSR_WIFI_INTERFACE_IN_USE, action, *sme_key);
308 
310  if (r) {
311  return r;
312  }
313 
314  return convert_sme_error(priv->sme_reply.reply_status);
315 }
316 
317 
318 int sme_mgt_scan_full(unifi_priv_t *priv,
319  CsrWifiSsid *specific_ssid,
320  int num_channels,
321  unsigned char *channel_list)
322 {
323  CsrWifiMacAddress bcastAddress = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }};
324  u8 is_active = (num_channels > 0) ? TRUE : FALSE;
325  int r;
326 
327  if (priv->smepriv == NULL) {
328  unifi_error(priv, "sme_mgt_scan_full: invalid smepriv\n");
329  return -EIO;
330  }
331 
332  unifi_trace(priv, UDBG4, "sme_mgt_scan_full: -->\n");
333 
334  r = sme_init_request(priv);
335  if (r) {
336  return -EIO;
337  }
338 
339  /* If a channel list is provided, do an active scan */
340  if (is_active) {
341  unifi_trace(priv, UDBG1,
342  "channel list - num_channels: %d, active scan\n",
343  num_channels);
344  }
345 
347  specific_ssid->length?1:0, /* 0 or 1 SSIDS */
348  specific_ssid,
349  bcastAddress,
350  is_active,
353  (u16)num_channels, channel_list,
354  0, NULL);
355 
357  if (r) {
358  return r;
359  }
360 
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 */
364  } else {
365  return convert_sme_error(priv->sme_reply.reply_status);
366  }
367 }
368 
369 
370 int sme_mgt_scan_results_get_async(unifi_priv_t *priv,
371  struct iw_request_info *info,
372  char *scan_results,
373  long scan_results_len)
374 {
375  u16 scan_result_list_count;
376  CsrWifiSmeScanResult *scan_result_list;
377  CsrWifiSmeScanResult *scan_result;
378  int r;
379  int i;
380  char *current_ev = scan_results;
381 
382  if (priv->smepriv == NULL) {
383  unifi_error(priv, "sme_mgt_scan_results_get_async: invalid smepriv\n");
384  return -EIO;
385  }
386 
387  r = sme_init_request(priv);
388  if (r) {
389  return -EIO;
390  }
391 
394  if (r) {
395  return r;
396  }
397 
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);
403 
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];
407 
408  unifi_trace(priv, UDBG2, "Scan Result: %.*s\n",
409  scan_result->ssid.length,
410  scan_result->ssid.ssid);
411 
412  r = unifi_translate_scan(priv->netdev[0], info,
413  current_ev,
414  scan_results + scan_results_len,
415  scan_result, i+1);
416 
417  if (r < 0) {
418  kfree(scan_result_list);
419  priv->sme_reply.reply_scan_results_count = 0;
420  priv->sme_reply.reply_scan_results = NULL;
421  return r;
422  }
423 
424  current_ev += r;
425  }
426 
427  /*
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.
431  */
432  kfree(scan_result_list);
433  priv->sme_reply.reply_scan_results_count = 0;
434  priv->sme_reply.reply_scan_results = NULL;
435 
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);
440 }
441 
442 
443 int sme_mgt_connect(unifi_priv_t *priv)
444 {
445  int r;
446 
447  if (priv->smepriv == NULL) {
448  unifi_error(priv, "sme_mgt_connect: invalid smepriv\n");
449  return -EIO;
450  }
451 
452  unifi_trace(priv, UDBG2, "sme_mgt_connect: %.*s\n",
453  priv->connection_config.ssid.length,
454  priv->connection_config.ssid.ssid);
455 
456  r = sme_init_request(priv);
457  if (r) {
458  return -EIO;
459  }
460 
461  CsrWifiSmeConnectReqSend(0, CSR_WIFI_INTERFACE_IN_USE, priv->connection_config);
463  if (r) {
464  return r;
465  }
466 
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);
470  }
471 
472  return convert_sme_error(priv->sme_reply.reply_status);
473 }
474 
475 
476 int sme_mgt_disconnect(unifi_priv_t *priv)
477 {
478  int r;
479 
480  if (priv->smepriv == NULL) {
481  unifi_error(priv, "sme_mgt_disconnect: invalid smepriv\n");
482  return -EIO;
483  }
484 
485  r = sme_init_request(priv);
486  if (r) {
487  return -EIO;
488  }
489 
492  if (r) {
493  return r;
494  }
495 
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);
498 }
499 
500 
501 int sme_mgt_pmkid(unifi_priv_t *priv,
502  CsrWifiSmeListAction action,
504 {
505  int r;
506 
507  if (priv->smepriv == NULL) {
508  unifi_error(priv, "sme_mgt_pmkid: invalid smepriv\n");
509  return -EIO;
510  }
511 
512  r = sme_init_request(priv);
513  if (r) {
514  return -EIO;
515  }
516 
518  pmkid_list->pmkidsCount, pmkid_list->pmkids);
520  if (r) {
521  return r;
522  }
523 
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);
526 }
527 
528 
529 int sme_mgt_mib_get(unifi_priv_t *priv,
530  unsigned char *varbind, int *length)
531 {
532  int r;
533 
534  if (priv->smepriv == NULL) {
535  unifi_error(priv, "sme_mgt_mib_get: invalid smepriv\n");
536  return -EIO;
537  }
538 
539  r = sme_init_request(priv);
540  if (r) {
541  return -EIO;
542  }
543 
544  priv->mib_cfm_buffer = varbind;
546 
547  CsrWifiSmeMibGetReqSend(0, *length, varbind);
549  if (r) {
550  priv->mib_cfm_buffer_length = 0;
551  priv->mib_cfm_buffer = NULL;
552  return r;
553  }
554 
555  *length = priv->mib_cfm_buffer_length;
556 
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);
561 }
562 
563 int sme_mgt_mib_set(unifi_priv_t *priv,
564  unsigned char *varbind, int length)
565 {
566  int r;
567 
568  if (priv->smepriv == NULL) {
569  unifi_error(priv, "sme_mgt_mib_get: invalid smepriv\n");
570  return -EIO;
571  }
572 
573  r = sme_init_request(priv);
574  if (r) {
575  return -EIO;
576  }
577 
578  CsrWifiSmeMibSetReqSend(0, length, varbind);
580  if (r) {
581  return r;
582  }
583 
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);
586 }
587 
588 #endif /* CSR_SUPPORT_WEXT */
589 
591 {
592 #ifdef CSR_SME_USERSPACE
593  int r;
594 
595  if (priv->smepriv == NULL) {
596  unifi_error(priv, "sme_mgt_set_value_async: invalid smepriv\n");
597  return -EIO;
598  }
599 
600  r = sme_init_request(priv);
601  if (r) {
602  return -EIO;
603  }
604 
605  CsrWifiSmePowerConfigSetReqSend(0, *powerConfig);
606 
608  if (r) {
609  return r;
610  }
611 
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);
616 #else
618  if (priv->smepriv == NULL) {
619  unifi_error(priv, "sme_mgt_set_value: invalid smepriv\n");
620  return -EIO;
621  }
622  CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
623  status = CsrWifiSmeMgtPowerConfigSetReq(priv->smepriv, *powerConfig);
624  CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
625  return convert_sme_error(status);
626 #endif
627 }
628 
630 {
631 #ifdef CSR_SME_USERSPACE
632  int r;
633 
634  if (priv->smepriv == NULL) {
635  unifi_error(priv, "sme_mgt_sme_config_set: invalid smepriv\n");
636  return -EIO;
637  }
638 
639  r = sme_init_request(priv);
640  if (r) {
641  return -EIO;
642  }
643 
646  if (r) {
647  return r;
648  }
649  unifi_trace(priv, UDBG4,
650  "sme_mgt_sme_config_set: CsrWifiSmeSmeStaConfigSetReq <-- (r=%d status=%d)\n",
651  r, priv->sme_reply.reply_status);
652 
653  r = sme_init_request(priv);
654  if (r) {
655  return -EIO;
656  }
657 
658  CsrWifiSmeSmeCommonConfigSetReqSend(0, *deviceConfig);
660  if (r) {
661  return r;
662  }
663 
664  unifi_trace(priv, UDBG4,
665  "sme_mgt_sme_config_set: CsrWifiSmeSmeCommonConfigSetReq <-- (r=%d status=%d)\n",
666  r, priv->sme_reply.reply_status);
667 
668  return convert_sme_error(priv->sme_reply.reply_status);
669 #else
671  if (priv->smepriv == NULL) {
672  unifi_error(priv, "sme_mgt_sme_config_set: invalid smepriv\n");
673  return -EIO;
674  }
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);
680 #endif
681 }
682 
683 #ifdef CSR_SUPPORT_WEXT
684 
685 int sme_mgt_mib_config_set(unifi_priv_t *priv, CsrWifiSmeMibConfig *mibConfig)
686 {
687 #ifdef CSR_SME_USERSPACE
688  int r;
689 
690  if (priv->smepriv == NULL) {
691  unifi_error(priv, "sme_mgt_mib_config_set: invalid smepriv\n");
692  return -EIO;
693  }
694 
695  r = sme_init_request(priv);
696  if (r) {
697  return -EIO;
698  }
699 
700  CsrWifiSmeMibConfigSetReqSend(0, *mibConfig);
701 
703  if (r) {
704  return r;
705  }
706 
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);
711 #else
713  if (priv->smepriv == NULL) {
714  unifi_error(priv, "sme_mgt_mib_config_set: invalid smepriv\n");
715  return -EIO;
716  }
717  CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
718  status = CsrWifiSmeMgtMibConfigSetReq(priv->smepriv, *mibConfig);
719  CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
720  return convert_sme_error(status);
721 #endif
722 }
723 
724 int sme_mgt_coex_config_set(unifi_priv_t *priv, CsrWifiSmeCoexConfig *coexConfig)
725 {
726 #ifdef CSR_SME_USERSPACE
727  int r;
728 
729  if (priv->smepriv == NULL) {
730  unifi_error(priv, "sme_mgt_coex_config_set: invalid smepriv\n");
731  return -EIO;
732  }
733 
734  r = sme_init_request(priv);
735  if (r) {
736  return -EIO;
737  }
738 
739  CsrWifiSmeCoexConfigSetReqSend(0, *coexConfig);
740 
742  if (r) {
743  return r;
744  }
745 
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);
750 #else
752  if (priv->smepriv == NULL) {
753  unifi_error(priv, "sme_mgt_coex_config_set: invalid smepriv\n");
754  return -EIO;
755  }
756  CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
757  status = CsrWifiSmeMgtCoexConfigSetReq(priv->smepriv, *coexConfig);
758  CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
759  return convert_sme_error(status);
760 #endif
761 }
762 
763 #endif /* CSR_SUPPORT_WEXT */
764 
766 {
767 #ifdef CSR_SME_USERSPACE
768  int r;
769 
770  if (priv->smepriv == NULL) {
771  unifi_error(priv, "sme_mgt_host_config_set: invalid smepriv\n");
772  return -EIO;
773  }
774 
775  r = sme_init_request(priv);
776  if (r) {
777  return -EIO;
778  }
779 
781 
783  if (r) {
784  return r;
785  }
786 
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);
791 #else
793  if (priv->smepriv == NULL) {
794  unifi_error(priv, "sme_mgt_host_config_set: invalid smepriv\n");
795  return -EIO;
796  }
797  CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
798  status = CsrWifiSmeMgtHostConfigSetReq(priv->smepriv, *hostConfig);
799  CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
800  return convert_sme_error(status);
801 #endif
802 }
803 
804 #ifdef CSR_SUPPORT_WEXT
805 
806 int sme_mgt_versions_get(unifi_priv_t *priv, CsrWifiSmeVersions *versions)
807 {
808 #ifdef CSR_SME_USERSPACE
809  int r;
810 
811  if (priv->smepriv == NULL) {
812  unifi_error(priv, "sme_mgt_versions_get: invalid smepriv\n");
813  return -EIO;
814  }
815 
816  unifi_trace(priv, UDBG4, "sme_mgt_versions_get: unifi_mgt_versions_get_req -->\n");
817  r = sme_init_request(priv);
818  if (r) {
819  return -EIO;
820  }
821 
823 
825  if (r) {
826  return r;
827  }
828 
829  /* store the reply */
830  if (versions != NULL) {
831  memcpy((unsigned char*)versions,
832  (unsigned char*)&priv->sme_reply.versions,
833  sizeof(CsrWifiSmeVersions));
834  }
835 
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);
839 
840  return convert_sme_error(priv->sme_reply.reply_status);
841 #else
843  CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
844  status = CsrWifiSmeMgtVersionsGetReq(priv->smepriv, versions);
845  CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
846  return convert_sme_error(status);
847 #endif
848 }
849 
850 #endif /* CSR_SUPPORT_WEXT */
851 
853 {
854 #ifdef CSR_SME_USERSPACE
855  int r;
856 
857  if (priv->smepriv == NULL) {
858  unifi_error(priv, "sme_mgt_power_config_get: invalid smepriv\n");
859  return -EIO;
860  }
861 
862  unifi_trace(priv, UDBG4, "sme_mgt_power_config_get: unifi_mgt_power_config_req -->\n");
863  r = sme_init_request(priv);
864  if (r) {
865  return -EIO;
866  }
867 
869 
871  if (r) {
872  return r;
873  }
874 
875  /* store the reply */
876  if (powerConfig != NULL) {
877  memcpy((unsigned char*)powerConfig,
878  (unsigned char*)&priv->sme_reply.powerConfig,
879  sizeof(CsrWifiSmePowerConfig));
880  }
881 
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);
885 
886  return convert_sme_error(priv->sme_reply.reply_status);
887 #else
889  CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
890  status = CsrWifiSmeMgtPowerConfigGetReq(priv->smepriv, powerConfig);
891  CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
892  return convert_sme_error(status);
893 #endif
894 }
895 
897 {
898 #ifdef CSR_SME_USERSPACE
899  int r;
900 
901  if (priv->smepriv == NULL) {
902  unifi_error(priv, "sme_mgt_host_config_get: invalid smepriv\n");
903  return -EIO;
904  }
905 
906  unifi_trace(priv, UDBG4, "sme_mgt_host_config_get: unifi_mgt_host_config_get_req -->\n");
907  r = sme_init_request(priv);
908  if (r) {
909  return -EIO;
910  }
911 
913 
915  if (r) {
916  return r;
917  }
918 
919  /* store the reply */
920  if (hostConfig != NULL) {
921  memcpy((unsigned char*)hostConfig,
922  (unsigned char*)&priv->sme_reply.hostConfig,
923  sizeof(CsrWifiSmeHostConfig));
924  }
925 
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);
929 
930  return convert_sme_error(priv->sme_reply.reply_status);
931 #else
933  CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
934  status = CsrWifiSmeMgtHostConfigGetReq(priv->smepriv, hostConfig);
935  CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
936  return convert_sme_error(status);
937 #endif
938 }
939 
941 {
942 #ifdef CSR_SME_USERSPACE
943  int r;
944 
945  if (priv->smepriv == NULL) {
946  unifi_error(priv, "sme_mgt_sme_config_get: invalid smepriv\n");
947  return -EIO;
948  }
949 
950  unifi_trace(priv, UDBG4, "sme_mgt_sme_config_get: unifi_mgt_sme_config_get_req -->\n");
951 
952  /* Common device config */
953  r = sme_init_request(priv);
954  if (r) {
955  return -EIO;
956  }
957 
960  if (r) {
961  return r;
962  }
963 
964  /* store the reply */
965  if (deviceConfig != NULL) {
966  memcpy((unsigned char*)deviceConfig,
967  (unsigned char*)&priv->sme_reply.deviceConfig,
968  sizeof(CsrWifiSmeDeviceConfig));
969  }
970 
971  /* STA config */
972  r = sme_init_request(priv);
973  if (r) {
974  return -EIO;
975  }
976 
979  if (r) {
980  return r;
981  }
982 
983  /* store the reply */
984  if (staConfig != NULL) {
985  memcpy((unsigned char*)staConfig,
986  (unsigned char*)&priv->sme_reply.staConfig,
987  sizeof(CsrWifiSmeStaConfig));
988  }
989 
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);
993 
994  return convert_sme_error(priv->sme_reply.reply_status);
995 #else
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);
1002 #endif
1003 }
1004 
1006 {
1007 #ifdef CSR_SME_USERSPACE
1008  int r;
1009 
1010  if (priv->smepriv == NULL) {
1011  unifi_error(priv, "sme_mgt_coex_info_get: invalid smepriv\n");
1012  return -EIO;
1013  }
1014 
1015  unifi_trace(priv, UDBG4, "sme_mgt_coex_info_get: unifi_mgt_coex_info_get_req -->\n");
1016  r = sme_init_request(priv);
1017  if (r) {
1018  return -EIO;
1019  }
1020 
1022 
1024  if (r) {
1025  return r;
1026  }
1027 
1028  /* store the reply */
1029  if (coexInfo != NULL) {
1030  memcpy((unsigned char*)coexInfo,
1031  (unsigned char*)&priv->sme_reply.coexInfo,
1032  sizeof(CsrWifiSmeCoexInfo));
1033  }
1034 
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);
1038 
1039  return convert_sme_error(priv->sme_reply.reply_status);
1040 #else
1041  CsrResult status;
1042  CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
1043  status = CsrWifiSmeMgtCoexInfoGetReq(priv->smepriv, coexInfo);
1044  CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
1045  return convert_sme_error(status);
1046 #endif
1047 }
1048 
1049 #ifdef CSR_SUPPORT_WEXT
1050 
1051 int sme_mgt_coex_config_get(unifi_priv_t *priv, CsrWifiSmeCoexConfig *coexConfig)
1052 {
1053 #ifdef CSR_SME_USERSPACE
1054  int r;
1055 
1056  if (priv->smepriv == NULL) {
1057  unifi_error(priv, "sme_mgt_coex_config_get: invalid smepriv\n");
1058  return -EIO;
1059  }
1060 
1061  unifi_trace(priv, UDBG4, "sme_mgt_coex_config_get: unifi_mgt_coex_config_get_req -->\n");
1062  r = sme_init_request(priv);
1063  if (r) {
1064  return -EIO;
1065  }
1066 
1068 
1070  if (r) {
1071  return r;
1072  }
1073 
1074  /* store the reply */
1075  if (coexConfig != NULL) {
1076  memcpy((unsigned char*)coexConfig,
1077  (unsigned char*)&priv->sme_reply.coexConfig,
1078  sizeof(CsrWifiSmeCoexConfig));
1079  }
1080 
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);
1084 
1085  return convert_sme_error(priv->sme_reply.reply_status);
1086 #else
1087  CsrResult status;
1088  CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
1089  status = CsrWifiSmeMgtCoexConfigGetReq(priv->smepriv, coexConfig);
1090  CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
1091  return convert_sme_error(status);
1092 #endif
1093 }
1094 
1095 int sme_mgt_mib_config_get(unifi_priv_t *priv, CsrWifiSmeMibConfig *mibConfig)
1096 {
1097 #ifdef CSR_SME_USERSPACE
1098  int r;
1099 
1100  if (priv->smepriv == NULL) {
1101  unifi_error(priv, "sme_mgt_mib_config_get: invalid smepriv\n");
1102  return -EIO;
1103  }
1104 
1105  unifi_trace(priv, UDBG4, "sme_mgt_mib_config_get: unifi_mgt_mib_config_get_req -->\n");
1106  r = sme_init_request(priv);
1107  if (r) {
1108  return -EIO;
1109  }
1110 
1112 
1114  if (r) {
1115  return r;
1116  }
1117 
1118  /* store the reply */
1119  if (mibConfig != NULL) {
1120  memcpy((unsigned char*)mibConfig,
1121  (unsigned char*)&priv->sme_reply.mibConfig,
1122  sizeof(CsrWifiSmeMibConfig));
1123  }
1124 
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);
1128 
1129  return convert_sme_error(priv->sme_reply.reply_status);
1130 #else
1131  CsrResult status;
1132  CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
1133  status = CsrWifiSmeMgtMibConfigGetReq(priv->smepriv, mibConfig);
1134  CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
1135  return convert_sme_error(status);
1136 #endif
1137 }
1138 
1139 int sme_mgt_connection_info_get(unifi_priv_t *priv, CsrWifiSmeConnectionInfo *connectionInfo)
1140 {
1141 #ifdef CSR_SME_USERSPACE
1142  int r;
1143 
1144  if (priv->smepriv == NULL) {
1145  unifi_error(priv, "sme_mgt_connection_info_get: invalid smepriv\n");
1146  return -EIO;
1147  }
1148 
1149  unifi_trace(priv, UDBG4, "sme_mgt_connection_info_get: unifi_mgt_connection_info_get_req -->\n");
1150  r = sme_init_request(priv);
1151  if (r) {
1152  return -EIO;
1153  }
1154 
1156 
1158  if (r) {
1159  return r;
1160  }
1161 
1162  /* store the reply */
1163  if (connectionInfo != NULL) {
1164  memcpy((unsigned char*)connectionInfo,
1165  (unsigned char*)&priv->sme_reply.connectionInfo,
1166  sizeof(CsrWifiSmeConnectionInfo));
1167  }
1168 
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);
1172 
1173  return convert_sme_error(priv->sme_reply.reply_status);
1174 #else
1175  CsrResult status;
1176  CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
1177  status = CsrWifiSmeMgtConnectionInfoGetReq(priv->smepriv, connectionInfo);
1178  CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
1179  return convert_sme_error(status);
1180 #endif
1181 }
1182 
1183 int sme_mgt_connection_config_get(unifi_priv_t *priv, CsrWifiSmeConnectionConfig *connectionConfig)
1184 {
1185 #ifdef CSR_SME_USERSPACE
1186  int r;
1187 
1188  if (priv->smepriv == NULL) {
1189  unifi_error(priv, "sme_mgt_connection_config_get: invalid smepriv\n");
1190  return -EIO;
1191  }
1192 
1193  unifi_trace(priv, UDBG4, "sme_mgt_connection_config_get: unifi_mgt_connection_config_get_req -->\n");
1194  r = sme_init_request(priv);
1195  if (r) {
1196  return -EIO;
1197  }
1198 
1200 
1202  if (r) {
1203  return r;
1204  }
1205 
1206  /* store the reply */
1207  if (connectionConfig != NULL) {
1208  memcpy((unsigned char*)connectionConfig,
1209  (unsigned char*)&priv->sme_reply.connectionConfig,
1210  sizeof(CsrWifiSmeConnectionConfig));
1211  }
1212 
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);
1216 
1217  return convert_sme_error(priv->sme_reply.reply_status);
1218 #else
1219  CsrResult status;
1220  CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
1221  status = CsrWifiSmeMgtConnectionConfigGetReq(priv->smepriv, connectionConfig);
1222  CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
1223  return convert_sme_error(status);
1224 #endif
1225 }
1226 
1227 int sme_mgt_connection_stats_get(unifi_priv_t *priv, CsrWifiSmeConnectionStats *connectionStats)
1228 {
1229 #ifdef CSR_SME_USERSPACE
1230  int r;
1231 
1232  if (priv->smepriv == NULL) {
1233  unifi_error(priv, "sme_mgt_connection_stats_get: invalid smepriv\n");
1234  return -EIO;
1235  }
1236 
1237  unifi_trace(priv, UDBG4, "sme_mgt_connection_stats_get: unifi_mgt_connection_stats_get_req -->\n");
1238  r = sme_init_request(priv);
1239  if (r) {
1240  return -EIO;
1241  }
1242 
1244 
1246  if (r) {
1247  return r;
1248  }
1249 
1250  /* store the reply */
1251  if (connectionStats != NULL) {
1252  memcpy((unsigned char*)connectionStats,
1253  (unsigned char*)&priv->sme_reply.connectionStats,
1254  sizeof(CsrWifiSmeConnectionStats));
1255  }
1256 
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);
1260 
1261  return convert_sme_error(priv->sme_reply.reply_status);
1262 #else
1263  CsrResult status;
1264  CsrWifiSmeMgtClaimSyncAccess(priv->smepriv);
1265  status = CsrWifiSmeMgtConnectionStatsGetReq(priv->smepriv, connectionStats);
1266  CsrWifiSmeMgtReleaseSyncAccess(priv->smepriv);
1267  return convert_sme_error(status);
1268 #endif
1269 }
1270 
1271 #endif /* CSR_SUPPORT_WEXT */
1272 
1274 {
1275  CsrWifiIp4Address ipAddress = {{0xFF, 0xFF, 0xFF, 0xFF }};
1276  if (priv->smepriv == NULL) {
1277  unifi_error(priv, "sme_mgt_packet_filter_set: invalid smepriv\n");
1278  return -EIO;
1279  }
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;
1285  }
1286 
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]);
1291 
1292  /* Doesn't block for a confirm */
1294  priv->packet_filters.tclas_ies_length,
1295  priv->filter_tclas_ies,
1296  priv->packet_filters.filter_mode,
1297  ipAddress);
1298  return 0;
1299 }
1300 
1303 {
1304  int r;
1305 
1306  if (priv->smepriv == NULL) {
1307  unifi_error(priv, "sme_mgt_tspec: invalid smepriv\n");
1308  return -EIO;
1309  }
1310 
1311  r = sme_init_request(priv);
1312  if (r) {
1313  return -EIO;
1314  }
1315 
1317  action, tid, TRUE, 0,
1318  tspec->length, tspec->data,
1319  tclas->length, tclas->data);
1321  if (r) {
1322  return r;
1323  }
1324 
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);
1327 }
1328 
1329 
1330 
1332 {
1333  int r;
1334  CsrResult csrResult;
1335 
1336  if (priv->smepriv == NULL) {
1337  unifi_error(priv, "sme_sys_suspend: invalid smepriv\n");
1338  return -EIO;
1339  }
1340 
1341  r = sme_init_request(priv);
1342  if (r) {
1343  return -EIO;
1344  }
1345 
1346  /* Suspend the SME, which MAY cause it to power down UniFi */
1347  CsrWifiRouterCtrlSuspendIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, 0, priv->wol_suspend);
1349  if (r) {
1350  /* No reply - forcibly power down in case the request wasn't processed */
1351  unifi_notice(priv,
1352  "suspend: SME did not reply %s, ",
1353  (priv->ptest_mode | priv->wol_suspend) ? "leave powered" : "power off UniFi anyway\n");
1354 
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);
1361 
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);
1366  }
1367  CsrSdioRelease(priv->sdio);
1368  }
1369  }
1370 
1371  if (priv->wol_suspend) {
1372  unifi_trace(priv, UDBG1, "UniFi left powered for WOL\n");
1373 
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.
1379  */
1380  if (csr_sdio_linux_remove_irq(priv->sdio)) {
1381  unifi_notice(priv, "WOL csr_sdio_linux_remove_irq failed\n");
1382  }
1383 
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.
1387  */
1388  unifi_trace(priv, UDBG1, "Enable card SDIO interrupt for SDIO WOL\n");
1389 
1390  CsrSdioClaim(priv->sdio);
1391  csrResult = CsrSdioInterruptEnable(priv->sdio);
1392  CsrSdioRelease(priv->sdio);
1393 
1394  if (csrResult != CSR_RESULT_SUCCESS) {
1395  unifi_error(priv, "WOL CsrSdioInterruptEnable failed %d\n", csrResult);
1396  }
1397  } else {
1398  unifi_trace(priv, UDBG1, "Disabled card SDIO interrupt for PIO WOL\n");
1399  }
1400 
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.
1404  */
1405  priv->bh_thread.block_thread = 1;
1406 
1407  unifi_trace(priv, UDBG1, "unifi_suspend: suspended BH");
1408  }
1409 
1410  /* Consider UniFi to be uninitialised */
1412 
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);
1415 }
1416 
1417 
1419 {
1420  int r;
1421 
1422  unifi_trace(priv, UDBG1, "sme_sys_resume %s\n", priv->wol_suspend ? "warm" : "");
1423 
1424  if (priv->smepriv == NULL) {
1425  unifi_error(priv, "sme_sys_resume: invalid smepriv\n");
1426  return -EIO;
1427  }
1428 
1429  r = sme_init_request(priv);
1430  if (r) {
1431  return -EIO;
1432  }
1433 
1434  CsrWifiRouterCtrlResumeIndSend(priv->CSR_WIFI_SME_IFACEQUEUE,0, priv->wol_suspend);
1435 
1437  if (r) {
1438  unifi_notice(priv,
1439  "resume: SME did not reply, return success anyway\n");
1440  }
1441 
1442  return 0;
1443 }
1444 
1445 #ifdef CSR_SUPPORT_WEXT_AP
1446 int sme_ap_stop(unifi_priv_t *priv,u16 interface_tag)
1447 {
1448  int r;
1449 
1450  if (priv->smepriv == NULL) {
1451  unifi_error(priv, "sme_ap_stop: invalid smepriv\n");
1452  return -EIO;
1453  }
1454 
1455  r = sme_init_request(priv);
1456  if (r) {
1457  return -EIO;
1458  }
1459 
1460  CsrWifiNmeApStopReqSend(0,interface_tag);
1461 
1463  if (r) {
1464  return r;
1465  }
1466 
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);
1471 
1472 }
1473 
1474 int sme_ap_start(unifi_priv_t *priv,u16 interface_tag,
1475  CsrWifiSmeApConfig_t * ap_config)
1476 {
1477  int r;
1478  CsrWifiSmeApP2pGoConfig p2p_go_param;
1479  memset(&p2p_go_param,0,sizeof(CsrWifiSmeApP2pGoConfig));
1480 
1481  if (priv->smepriv == NULL) {
1482  unifi_error(priv, "sme_ap_start: invalid smepriv\n");
1483  return -EIO;
1484  }
1485 
1486  r = sme_init_request(priv);
1487  if (r) {
1488  return -EIO;
1489  }
1490 
1492  ap_config->ssid,1,ap_config->channel,
1493  ap_config->credentials,ap_config->max_connections,
1494  p2p_go_param,FALSE);
1495 
1497  if (r) {
1498  return r;
1499  }
1500 
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);
1505 }
1506 
1507 int sme_ap_config(unifi_priv_t *priv,
1508  CsrWifiSmeApMacConfig *ap_mac_config,
1509  CsrWifiNmeApConfig *group_security_config)
1510 {
1511  int r;
1512  CsrWifiSmeApP2pGoConfig p2p_go_param;
1513  memset(&p2p_go_param,0,sizeof(CsrWifiSmeApP2pGoConfig));
1514 
1515  if (priv->smepriv == NULL) {
1516  unifi_error(priv, "sme_ap_config: invalid smepriv\n");
1517  return -EIO;
1518  }
1519 
1520  r = sme_init_request(priv);
1521  if (r) {
1522  return -EIO;
1523  }
1524 
1525  CsrWifiNmeApConfigSetReqSend(0,*group_security_config,
1526  *ap_mac_config);
1527 
1529 
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);
1534 }
1535 #endif