1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include <a_config.h>
27#include <athdefs.h>
28#include <a_types.h>
29#include <a_osapi.h>
30#include "htc.h"
31#include "htc_api.h"
32#include "wmi.h"
33#include <wlan_api.h>
34#include <wmi_api.h>
35#include <ieee80211.h>
36#include <ieee80211_node.h>
37#include "dset_api.h"
38#include "gpio_api.h"
39#include "wmi_host.h"
40#include "a_drv.h"
41#include "a_drv_api.h"
42#define ATH_MODULE_NAME wmi
43#include "a_debug.h"
44#include "dbglog_api.h"
45#include "roaming.h"
46
47#define ATH_DEBUG_WMI ATH_DEBUG_MAKE_MODULE_MASK(0)
48
49#ifdef ATH_DEBUG_MODULE
50
51static ATH_DEBUG_MASK_DESCRIPTION wmi_debug_desc[] = {
52 { ATH_DEBUG_WMI , "General WMI Tracing"},
53};
54
55ATH_DEBUG_INSTANTIATE_MODULE_VAR(wmi,
56 "wmi",
57 "Wireless Module Interface",
58 ATH_DEBUG_MASK_DEFAULTS,
59 ATH_DEBUG_DESCRIPTION_COUNT(wmi_debug_desc),
60 wmi_debug_desc);
61
62#endif
63
64#ifndef REXOS
65#define DBGARG _A_FUNCNAME_
66#define DBGFMT "%s() : "
67#define DBG_WMI ATH_DEBUG_WMI
68#define DBG_ERROR ATH_DEBUG_ERR
69#define DBG_WMI2 ATH_DEBUG_WMI
70#define A_DPRINTF AR_DEBUG_PRINTF
71#endif
72
73static A_STATUS wmi_ready_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
74
75static A_STATUS wmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
76 int len);
77static A_STATUS wmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
78 int len);
79
80static A_STATUS wmi_tkip_micerr_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
81 int len);
82static A_STATUS wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
83 int len);
84static A_STATUS wmi_opt_frame_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
85 int len);
86static A_STATUS wmi_pstream_timeout_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
87 int len);
88static A_STATUS wmi_sync_point(struct wmi_t *wmip);
89
90static A_STATUS wmi_bitrate_reply_rx(struct wmi_t *wmip, A_UINT8 *datap,
91 int len);
92static A_STATUS wmi_ratemask_reply_rx(struct wmi_t *wmip, A_UINT8 *datap,
93 int len);
94static A_STATUS wmi_channelList_reply_rx(struct wmi_t *wmip, A_UINT8 *datap,
95 int len);
96static A_STATUS wmi_regDomain_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
97 int len);
98static A_STATUS wmi_txPwr_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
99static A_STATUS wmi_neighborReport_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
100 int len);
101
102static A_STATUS wmi_dset_open_req_rx(struct wmi_t *wmip, A_UINT8 *datap,
103 int len);
104#ifdef CONFIG_HOST_DSET_SUPPORT
105static A_STATUS wmi_dset_close_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
106static A_STATUS wmi_dset_data_req_rx(struct wmi_t *wmip, A_UINT8 *datap,
107 int len);
108#endif
109
110
111static A_STATUS wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap,
112 int len);
113static A_STATUS wmi_errorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
114static A_STATUS wmi_statsEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
115static A_STATUS wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
116static A_STATUS wmi_hbChallengeResp_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
117static A_STATUS wmi_reportErrorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
118static A_STATUS wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
119static A_STATUS wmi_channel_change_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
120static A_STATUS wmi_roam_tbl_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
121 int len);
122static A_STATUS wmi_roam_data_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
123 int len);
124static A_STATUS wmi_get_wow_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
125 int len);
126static A_STATUS
127wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len);
128
129static A_STATUS
130wmi_set_params_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len);
131
132static A_STATUS
133wmi_acm_reject_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len);
134
135#ifdef CONFIG_HOST_GPIO_SUPPORT
136static A_STATUS wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
137static A_STATUS wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
138static A_STATUS wmi_gpio_ack_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
139#endif
140
141#ifdef CONFIG_HOST_TCMD_SUPPORT
142static A_STATUS
143wmi_tcmd_test_report_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
144#endif
145
146static A_STATUS
147wmi_txRetryErrEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
148
149static A_STATUS
150wmi_snrThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
151
152static A_STATUS
153wmi_lqThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
154
155static A_BOOL
156wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_INT32 rateIndex);
157
158static A_STATUS
159wmi_aplistEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
160
161static A_STATUS
162wmi_dbglog_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
163
164static A_STATUS wmi_keepalive_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
165
166A_STATUS wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId,
167 WMI_SYNC_FLAG syncflag);
168
169A_UINT8 ar6000_get_upper_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, A_UINT32 size);
170A_UINT8 ar6000_get_lower_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, A_UINT32 size);
171
172void wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd);
173void wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd);
174static A_STATUS wmi_send_rssi_threshold_params(struct wmi_t *wmip,
175 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd);
176static A_STATUS wmi_send_snr_threshold_params(struct wmi_t *wmip,
177 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd);
178#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
179static A_STATUS
180wmi_prof_count_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
181#endif
182
183static A_STATUS wmi_pspoll_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
184 int len);
185static A_STATUS wmi_dtimexpiry_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
186 int len);
187
188static A_STATUS wmi_peer_node_event_rx (struct wmi_t *wmip, A_UINT8 *datap,
189 int len);
190#ifdef ATH_AR6K_11N_SUPPORT
191static A_STATUS wmi_addba_req_event_rx(struct wmi_t *, A_UINT8 *, int);
192static A_STATUS wmi_addba_resp_event_rx(struct wmi_t *, A_UINT8 *, int);
193static A_STATUS wmi_delba_req_event_rx(struct wmi_t *, A_UINT8 *, int);
194static A_STATUS wmi_btcoex_config_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
195static A_STATUS wmi_btcoex_stats_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
196#endif
197static A_STATUS wmi_hci_event_rx(struct wmi_t *, A_UINT8 *, int);
198
199#ifdef WAPI_ENABLE
200static A_STATUS wmi_wapi_rekey_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
201 int len);
202#endif
203
204#if defined(UNDER_CE)
205#if defined(NDIS51_MINIPORT)
206unsigned int processDot11Hdr = 0;
207#else
208unsigned int processDot11Hdr = 1;
209#endif
210#else
211extern unsigned int processDot11Hdr;
212#endif
213
214int wps_enable;
215static const A_INT32 wmi_rateTable[][2] = {
216
217 {1000, 1000},
218 {2000, 2000},
219 {5500, 5500},
220 {11000, 11000},
221 {6000, 6000},
222 {9000, 9000},
223 {12000, 12000},
224 {18000, 18000},
225 {24000, 24000},
226 {36000, 36000},
227 {48000, 48000},
228 {54000, 54000},
229 {6500, 7200},
230 {13000, 14400},
231 {19500, 21700},
232 {26000, 28900},
233 {39000, 43300},
234 {52000, 57800},
235 {58500, 65000},
236 {65000, 72200},
237 {13500, 15000},
238 {27000, 30000},
239 {40500, 45000},
240 {54000, 60000},
241 {81000, 90000},
242 {108000, 120000},
243 {121500, 135000},
244 {135000, 150000},
245 {0, 0}};
246
247#define MODE_A_SUPPORT_RATE_START ((A_INT32) 4)
248#define MODE_A_SUPPORT_RATE_STOP ((A_INT32) 11)
249
250#define MODE_GONLY_SUPPORT_RATE_START MODE_A_SUPPORT_RATE_START
251#define MODE_GONLY_SUPPORT_RATE_STOP MODE_A_SUPPORT_RATE_STOP
252
253#define MODE_B_SUPPORT_RATE_START ((A_INT32) 0)
254#define MODE_B_SUPPORT_RATE_STOP ((A_INT32) 3)
255
256#define MODE_G_SUPPORT_RATE_START ((A_INT32) 0)
257#define MODE_G_SUPPORT_RATE_STOP ((A_INT32) 11)
258
259#define MODE_GHT20_SUPPORT_RATE_START ((A_INT32) 0)
260#define MODE_GHT20_SUPPORT_RATE_STOP ((A_INT32) 19)
261
262#define MAX_NUMBER_OF_SUPPORT_RATES (MODE_GHT20_SUPPORT_RATE_STOP + 1)
263
264
265const A_UINT8 up_to_ac[]= {
266 WMM_AC_BE,
267 WMM_AC_BK,
268 WMM_AC_BK,
269 WMM_AC_BE,
270 WMM_AC_VI,
271 WMM_AC_VI,
272 WMM_AC_VO,
273 WMM_AC_VO,
274 };
275
276#include "athstartpack.h"
277
278
279typedef PREPACK struct _iphdr {
280 A_UINT8 ip_ver_hdrlen;
281 A_UINT8 ip_tos;
282 A_UINT16 ip_len;
283 A_UINT16 ip_id;
284 A_INT16 ip_off;
285#define IP_DF 0x4000
286#define IP_MF 0x2000
287#define IP_OFFMASK 0x1fff
288 A_UINT8 ip_ttl;
289 A_UINT8 ip_p;
290 A_UINT16 ip_sum;
291 A_UINT8 ip_src[4];
292 A_UINT8 ip_dst[4];
293} POSTPACK iphdr;
294
295#include "athendpack.h"
296
297static A_INT16 rssi_event_value = 0;
298static A_INT16 snr_event_value = 0;
299
300A_BOOL is_probe_ssid = FALSE;
301
302void *
303wmi_init(void *devt)
304{
305 struct wmi_t *wmip;
306
307 A_REGISTER_MODULE_DEBUG_INFO(wmi);
308
309 wmip = A_MALLOC (sizeof(struct wmi_t));
310 if (wmip == NULL) {
311 return (NULL);
312 }
313 A_MEMZERO(wmip, sizeof(struct wmi_t ));
314#ifdef THREAD_X
315 INIT_WMI_LOCK(wmip);
316#else
317 A_MUTEX_INIT(&wmip->wmi_lock);
318#endif
319 wmip->wmi_devt = devt;
320 wlan_node_table_init(wmip, &wmip->wmi_scan_table);
321 wmi_qos_state_init(wmip);
322
323 wmip->wmi_powerMode = REC_POWER;
324 wmip->wmi_phyMode = WMI_11G_MODE;
325
326 wmip->wmi_pair_crypto_type = NONE_CRYPT;
327 wmip->wmi_grp_crypto_type = NONE_CRYPT;
328
329 wmip->wmi_ht_allowed[A_BAND_24GHZ] = 1;
330 wmip->wmi_ht_allowed[A_BAND_5GHZ] = 1;
331
332 return (wmip);
333}
334
335void
336wmi_qos_state_init(struct wmi_t *wmip)
337{
338 A_UINT8 i;
339
340 if (wmip == NULL) {
341 return;
342 }
343 LOCK_WMI(wmip);
344
345
346 wmip->wmi_numQoSStream = 0;
347
348 wmip->wmi_fatPipeExists = 0;
349
350 for (i=0; i < WMM_NUM_AC; i++) {
351 wmip->wmi_streamExistsForAC[i]=0;
352 }
353
354 UNLOCK_WMI(wmip);
355
356 A_WMI_SET_NUMDATAENDPTS(wmip->wmi_devt, 1);
357}
358
359void
360wmi_set_control_ep(struct wmi_t * wmip, HTC_ENDPOINT_ID eid)
361{
362 A_ASSERT( eid != ENDPOINT_UNUSED);
363 wmip->wmi_endpoint_id = eid;
364}
365
366HTC_ENDPOINT_ID
367wmi_get_control_ep(struct wmi_t * wmip)
368{
369 return(wmip->wmi_endpoint_id);
370}
371
372void
373wmi_shutdown(struct wmi_t *wmip)
374{
375 if (wmip != NULL) {
376 wlan_node_table_cleanup(&wmip->wmi_scan_table);
377 if (A_IS_MUTEX_VALID(&wmip->wmi_lock)) {
378#ifdef THREAD_X
379 DELETE_WMI_LOCK(&wmip);
380#else
381 A_MUTEX_DELETE(&wmip->wmi_lock);
382#endif
383 }
384 A_FREE(wmip);
385 }
386}
387
388
389
390
391
392
393
394A_STATUS
395wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf)
396{
397 A_UINT8 *datap;
398 A_UINT16 typeorlen;
399 ATH_MAC_HDR macHdr;
400 ATH_LLC_SNAP_HDR *llcHdr;
401
402 A_ASSERT(osbuf != NULL);
403
404 if (A_NETBUF_HEADROOM(osbuf) <
405 (sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR)))
406 {
407 return A_NO_MEMORY;
408 }
409
410 datap = A_NETBUF_DATA(osbuf);
411
412 typeorlen = *(A_UINT16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN);
413
414 if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) {
415
416
417
418 A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG));
419 return (A_OK);
420 }
421
422
423
424
425 A_MEMCPY(macHdr.dstMac, datap, ATH_MAC_LEN);
426 A_MEMCPY(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN);
427 macHdr.typeOrLen = A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) +
428 sizeof(ATH_LLC_SNAP_HDR));
429
430
431
432
433 if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != A_OK) {
434 return A_NO_MEMORY;
435 }
436 datap = A_NETBUF_DATA(osbuf);
437
438 A_MEMCPY(datap, &macHdr, sizeof (ATH_MAC_HDR));
439
440 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR));
441 llcHdr->dsap = 0xAA;
442 llcHdr->ssap = 0xAA;
443 llcHdr->cntl = 0x03;
444 llcHdr->orgCode[0] = 0x0;
445 llcHdr->orgCode[1] = 0x0;
446 llcHdr->orgCode[2] = 0x0;
447 llcHdr->etherType = typeorlen;
448
449 return (A_OK);
450}
451
452A_STATUS wmi_meta_add(struct wmi_t *wmip, void *osbuf, A_UINT8 *pVersion,void *pTxMetaS)
453{
454 switch(*pVersion){
455 case 0:
456 return (A_OK);
457 case WMI_META_VERSION_1:
458 {
459 WMI_TX_META_V1 *pV1= NULL;
460 A_ASSERT(osbuf != NULL);
461 if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != A_OK) {
462 return A_NO_MEMORY;
463 }
464
465 pV1 = (WMI_TX_META_V1 *)A_NETBUF_DATA(osbuf);
466
467
468
469 pV1->pktID = 0;
470
471
472 pV1->ratePolicyID = 0;
473 A_ASSERT(pVersion != NULL);
474
475 *pVersion = WMI_META_VERSION_1;
476 return (A_OK);
477 }
478#ifdef CONFIG_CHECKSUM_OFFLOAD
479 case WMI_META_VERSION_2:
480 {
481 WMI_TX_META_V2 *pV2 ;
482 A_ASSERT(osbuf != NULL);
483 if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != A_OK) {
484 return A_NO_MEMORY;
485 }
486 pV2 = (WMI_TX_META_V2 *)A_NETBUF_DATA(osbuf);
487 A_MEMCPY(pV2,(WMI_TX_META_V2 *)pTxMetaS,sizeof(WMI_TX_META_V2));
488 return (A_OK);
489 }
490#endif
491 default:
492 return (A_OK);
493 }
494}
495
496
497A_STATUS
498wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, A_UINT8 msgType, A_BOOL bMoreData,
499 WMI_DATA_HDR_DATA_TYPE data_type,A_UINT8 metaVersion, void *pTxMetaS)
500{
501 WMI_DATA_HDR *dtHdr;
502
503 A_STATUS status;
504
505 A_ASSERT(osbuf != NULL);
506
507
508
509 if ((status = wmi_meta_add(wmip, osbuf, &metaVersion,pTxMetaS)) != A_OK) {
510 return status;
511 }
512
513 if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != A_OK) {
514 return A_NO_MEMORY;
515 }
516
517 dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf);
518 A_MEMZERO(dtHdr, sizeof(WMI_DATA_HDR));
519
520 WMI_DATA_HDR_SET_MSG_TYPE(dtHdr, msgType);
521 WMI_DATA_HDR_SET_DATA_TYPE(dtHdr, data_type);
522
523 if (bMoreData) {
524 WMI_DATA_HDR_SET_MORE_BIT(dtHdr);
525 }
526
527 WMI_DATA_HDR_SET_META(dtHdr, metaVersion);
528
529
530 return (A_OK);
531}
532
533
534A_UINT8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 layer2Priority, A_BOOL wmmEnabled)
535{
536 A_UINT8 *datap;
537 A_UINT8 trafficClass = WMM_AC_BE;
538 A_UINT16 ipType = IP_ETHERTYPE;
539 WMI_DATA_HDR *dtHdr;
540 A_BOOL streamExists = FALSE;
541 A_UINT8 userPriority;
542 A_UINT32 hdrsize, metasize;
543 ATH_LLC_SNAP_HDR *llcHdr;
544
545 WMI_CREATE_PSTREAM_CMD cmd;
546
547 A_ASSERT(osbuf != NULL);
548
549
550
551
552 hdrsize = 0;
553
554 datap = A_NETBUF_DATA(osbuf);
555 dtHdr = (WMI_DATA_HDR *)datap;
556 metasize = (WMI_DATA_HDR_GET_META(dtHdr))? WMI_MAX_TX_META_SZ : 0;
557
558 if (!wmmEnabled)
559 {
560
561 userPriority = 0;
562 }
563 else
564 {
565 if (processDot11Hdr)
566 {
567 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(A_UINT32));
568 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) + metasize +
569 hdrsize);
570
571
572 }
573 else
574 {
575 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) + metasize +
576 sizeof(ATH_MAC_HDR));
577 }
578
579 if (llcHdr->etherType == A_CPU2BE16(ipType))
580 {
581
582
583 userPriority = wmi_determine_userPriority (((A_UINT8 *)llcHdr) + sizeof(ATH_LLC_SNAP_HDR),layer2Priority);
584 }
585 else
586 {
587 userPriority = layer2Priority & 0x7;
588 }
589 }
590
591
592
593 if ((WMM_AC_VI == wmip->wmi_traffic_class) && ((5 == userPriority) || (4 == userPriority)))
594 {
595 userPriority = 1;
596 }
597
598 trafficClass = convert_userPriority_to_trafficClass(userPriority);
599
600 WMI_DATA_HDR_SET_UP(dtHdr, userPriority);
601
602
603
604 LOCK_WMI(wmip);
605 streamExists = wmip->wmi_fatPipeExists;
606 UNLOCK_WMI(wmip);
607
608 if (!(streamExists & (1 << trafficClass)))
609 {
610
611 A_MEMZERO(&cmd, sizeof(cmd));
612 cmd.trafficClass = trafficClass;
613 cmd.userPriority = userPriority;
614 cmd.inactivityInt = WMI_IMPLICIT_PSTREAM_INACTIVITY_INT;
615
616
617 cmd.tsid = WMI_IMPLICIT_PSTREAM;
618 wmi_create_pstream_cmd(wmip, &cmd);
619 }
620
621 return trafficClass;
622}
623
624A_STATUS
625wmi_dot11_hdr_add (struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode)
626{
627 A_UINT8 *datap;
628 A_UINT16 typeorlen;
629 ATH_MAC_HDR macHdr;
630 ATH_LLC_SNAP_HDR *llcHdr;
631 struct ieee80211_frame *wh;
632 A_UINT32 hdrsize;
633
634 A_ASSERT(osbuf != NULL);
635
636 if (A_NETBUF_HEADROOM(osbuf) <
637 (sizeof(struct ieee80211_qosframe) + sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR)))
638 {
639 return A_NO_MEMORY;
640 }
641
642 datap = A_NETBUF_DATA(osbuf);
643
644 typeorlen = *(A_UINT16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN);
645
646 if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) {
647
648
649
650 A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG));
651 goto AddDot11Hdr;
652 }
653
654
655
656
657 A_MEMCPY(macHdr.dstMac, datap, ATH_MAC_LEN);
658 A_MEMCPY(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN);
659 macHdr.typeOrLen = A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) +
660 sizeof(ATH_LLC_SNAP_HDR));
661
662
663 A_NETBUF_PULL(osbuf, sizeof(ATH_MAC_HDR));
664
665
666
667 if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != A_OK) {
668 return A_NO_MEMORY;
669 }
670 datap = A_NETBUF_DATA(osbuf);
671
672 llcHdr = (ATH_LLC_SNAP_HDR *)(datap);
673 llcHdr->dsap = 0xAA;
674 llcHdr->ssap = 0xAA;
675 llcHdr->cntl = 0x03;
676 llcHdr->orgCode[0] = 0x0;
677 llcHdr->orgCode[1] = 0x0;
678 llcHdr->orgCode[2] = 0x0;
679 llcHdr->etherType = typeorlen;
680
681AddDot11Hdr:
682
683 if (wmip->wmi_is_wmm_enabled)
684 {
685 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(A_UINT32));
686 if (A_NETBUF_PUSH(osbuf, hdrsize) != A_OK)
687 {
688 return A_NO_MEMORY;
689 }
690 wh = (struct ieee80211_frame *) A_NETBUF_DATA(osbuf);
691 wh->i_fc[0] = IEEE80211_FC0_SUBTYPE_QOS;
692 }
693 else
694 {
695 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_frame),sizeof(A_UINT32));
696 if (A_NETBUF_PUSH(osbuf, hdrsize) != A_OK)
697 {
698 return A_NO_MEMORY;
699 }
700 wh = (struct ieee80211_frame *) A_NETBUF_DATA(osbuf);
701 wh->i_fc[0] = IEEE80211_FC0_SUBTYPE_DATA;
702 }
703
704 IEEE80211_ADDR_COPY(wh->i_addr2, macHdr.srcMac);
705
706 if (mode == INFRA_NETWORK) {
707 IEEE80211_ADDR_COPY(wh->i_addr3, macHdr.dstMac);
708 }
709 else if (mode == ADHOC_NETWORK) {
710 IEEE80211_ADDR_COPY(wh->i_addr1, macHdr.dstMac);
711 }
712
713 return (A_OK);
714}
715
716A_STATUS
717wmi_dot11_hdr_remove(struct wmi_t *wmip, void *osbuf)
718{
719 A_UINT8 *datap;
720 struct ieee80211_frame *pwh,wh;
721 A_UINT8 type,subtype;
722 ATH_LLC_SNAP_HDR *llcHdr;
723 ATH_MAC_HDR macHdr;
724 A_UINT32 hdrsize;
725
726 A_ASSERT(osbuf != NULL);
727 datap = A_NETBUF_DATA(osbuf);
728
729 pwh = (struct ieee80211_frame *)datap;
730 type = pwh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
731 subtype = pwh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
732
733 A_MEMCPY((A_UINT8 *)&wh, datap, sizeof(struct ieee80211_frame));
734
735
736 if (subtype == IEEE80211_FC0_SUBTYPE_QOS) {
737 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(A_UINT32));
738 A_NETBUF_PULL(osbuf, hdrsize);
739 } else if (subtype == IEEE80211_FC0_SUBTYPE_DATA) {
740 A_NETBUF_PULL(osbuf, sizeof(struct ieee80211_frame));
741 }
742
743 datap = A_NETBUF_DATA(osbuf);
744 llcHdr = (ATH_LLC_SNAP_HDR *)(datap);
745
746 macHdr.typeOrLen = llcHdr->etherType;
747 A_MEMZERO(macHdr.dstMac, sizeof(macHdr.dstMac));
748 A_MEMZERO(macHdr.srcMac, sizeof(macHdr.srcMac));
749
750 switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) {
751 case IEEE80211_FC1_DIR_NODS:
752 IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr1);
753 IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr2);
754 break;
755 case IEEE80211_FC1_DIR_TODS:
756 IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr3);
757 IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr2);
758 break;
759 case IEEE80211_FC1_DIR_FROMDS:
760 IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr1);
761 IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr3);
762 break;
763 case IEEE80211_FC1_DIR_DSTODS:
764 break;
765 }
766
767
768 A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR));
769
770
771
772 A_NETBUF_PUSH(osbuf, sizeof(ATH_MAC_HDR));
773 datap = A_NETBUF_DATA(osbuf);
774
775 A_MEMCPY (datap, &macHdr, sizeof(ATH_MAC_HDR));
776
777 return A_OK;
778}
779
780
781
782
783
784A_STATUS
785wmi_dot3_2_dix(void *osbuf)
786{
787 A_UINT8 *datap;
788 ATH_MAC_HDR macHdr;
789 ATH_LLC_SNAP_HDR *llcHdr;
790
791 A_ASSERT(osbuf != NULL);
792 datap = A_NETBUF_DATA(osbuf);
793
794 A_MEMCPY(&macHdr, datap, sizeof(ATH_MAC_HDR));
795 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR));
796 macHdr.typeOrLen = llcHdr->etherType;
797
798 if (A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != A_OK) {
799 return A_NO_MEMORY;
800 }
801
802 datap = A_NETBUF_DATA(osbuf);
803
804 A_MEMCPY(datap, &macHdr, sizeof (ATH_MAC_HDR));
805
806 return (A_OK);
807}
808
809
810
811
812A_STATUS
813wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf)
814{
815 A_ASSERT(osbuf != NULL);
816
817 return (A_NETBUF_PULL(osbuf, sizeof(WMI_DATA_HDR)));
818}
819
820void
821wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg)
822{
823 wlan_iterate_nodes(&wmip->wmi_scan_table, f, arg);
824}
825
826
827
828
829A_STATUS
830wmi_control_rx_xtnd(struct wmi_t *wmip, void *osbuf)
831{
832 WMIX_CMD_HDR *cmd;
833 A_UINT16 id;
834 A_UINT8 *datap;
835 A_UINT32 len;
836 A_STATUS status = A_OK;
837
838 if (A_NETBUF_LEN(osbuf) < sizeof(WMIX_CMD_HDR)) {
839 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG));
840 wmip->wmi_stats.cmd_len_err++;
841 return A_ERROR;
842 }
843
844 cmd = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf);
845 id = cmd->commandId;
846
847 if (A_NETBUF_PULL(osbuf, sizeof(WMIX_CMD_HDR)) != A_OK) {
848 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG));
849 wmip->wmi_stats.cmd_len_err++;
850 return A_ERROR;
851 }
852
853 datap = A_NETBUF_DATA(osbuf);
854 len = A_NETBUF_LEN(osbuf);
855
856 switch (id) {
857 case (WMIX_DSETOPENREQ_EVENTID):
858 status = wmi_dset_open_req_rx(wmip, datap, len);
859 break;
860#ifdef CONFIG_HOST_DSET_SUPPORT
861 case (WMIX_DSETCLOSE_EVENTID):
862 status = wmi_dset_close_rx(wmip, datap, len);
863 break;
864 case (WMIX_DSETDATAREQ_EVENTID):
865 status = wmi_dset_data_req_rx(wmip, datap, len);
866 break;
867#endif
868#ifdef CONFIG_HOST_GPIO_SUPPORT
869 case (WMIX_GPIO_INTR_EVENTID):
870 wmi_gpio_intr_rx(wmip, datap, len);
871 break;
872 case (WMIX_GPIO_DATA_EVENTID):
873 wmi_gpio_data_rx(wmip, datap, len);
874 break;
875 case (WMIX_GPIO_ACK_EVENTID):
876 wmi_gpio_ack_rx(wmip, datap, len);
877 break;
878#endif
879 case (WMIX_HB_CHALLENGE_RESP_EVENTID):
880 wmi_hbChallengeResp_rx(wmip, datap, len);
881 break;
882 case (WMIX_DBGLOG_EVENTID):
883 wmi_dbglog_event_rx(wmip, datap, len);
884 break;
885#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
886 case (WMIX_PROF_COUNT_EVENTID):
887 wmi_prof_count_rx(wmip, datap, len);
888 break;
889#endif
890 default:
891 A_DPRINTF(DBG_WMI|DBG_ERROR,
892 (DBGFMT "Unknown id 0x%x\n", DBGARG, id));
893 wmip->wmi_stats.cmd_id_err++;
894 status = A_ERROR;
895 break;
896 }
897
898 return status;
899}
900
901
902
903
904A_UINT32 cmdRecvNum;
905
906A_STATUS
907wmi_control_rx(struct wmi_t *wmip, void *osbuf)
908{
909 WMI_CMD_HDR *cmd;
910 A_UINT16 id;
911 A_UINT8 *datap;
912 A_UINT32 len, i, loggingReq;
913 A_STATUS status = A_OK;
914
915 A_ASSERT(osbuf != NULL);
916 if (A_NETBUF_LEN(osbuf) < sizeof(WMI_CMD_HDR)) {
917 A_NETBUF_FREE(osbuf);
918 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG));
919 wmip->wmi_stats.cmd_len_err++;
920 return A_ERROR;
921 }
922
923 cmd = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf);
924 id = cmd->commandId;
925
926 if (A_NETBUF_PULL(osbuf, sizeof(WMI_CMD_HDR)) != A_OK) {
927 A_NETBUF_FREE(osbuf);
928 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG));
929 wmip->wmi_stats.cmd_len_err++;
930 return A_ERROR;
931 }
932
933 datap = A_NETBUF_DATA(osbuf);
934 len = A_NETBUF_LEN(osbuf);
935
936 loggingReq = 0;
937
938 ar6000_get_driver_cfg(wmip->wmi_devt,
939 AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS,
940 &loggingReq);
941
942 if(loggingReq) {
943 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI %d \n",id));
944 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI recv, MsgNo %d : ", cmdRecvNum));
945 for(i = 0; i < len; i++)
946 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("%x ", datap[i]));
947 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("\n"));
948 }
949
950 LOCK_WMI(wmip);
951 cmdRecvNum++;
952 UNLOCK_WMI(wmip);
953
954 switch (id) {
955 case (WMI_GET_BITRATE_CMDID):
956 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_BITRATE_CMDID\n", DBGARG));
957 status = wmi_bitrate_reply_rx(wmip, datap, len);
958 break;
959 case (WMI_GET_CHANNEL_LIST_CMDID):
960 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_CHANNEL_LIST_CMDID\n", DBGARG));
961 status = wmi_channelList_reply_rx(wmip, datap, len);
962 break;
963 case (WMI_GET_TX_PWR_CMDID):
964 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_TX_PWR_CMDID\n", DBGARG));
965 status = wmi_txPwr_reply_rx(wmip, datap, len);
966 break;
967 case (WMI_READY_EVENTID):
968 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_READY_EVENTID\n", DBGARG));
969 status = wmi_ready_event_rx(wmip, datap, len);
970 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
971 A_WMI_DBGLOG_INIT_DONE(wmip->wmi_devt);
972 break;
973 case (WMI_CONNECT_EVENTID):
974 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CONNECT_EVENTID\n", DBGARG));
975 status = wmi_connect_event_rx(wmip, datap, len);
976 A_WMI_SEND_GENERIC_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
977 break;
978 case (WMI_DISCONNECT_EVENTID):
979 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_DISCONNECT_EVENTID\n", DBGARG));
980 status = wmi_disconnect_event_rx(wmip, datap, len);
981 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
982 break;
983 case (WMI_PEER_NODE_EVENTID):
984 A_DPRINTF (DBG_WMI, (DBGFMT "WMI_PEER_NODE_EVENTID\n", DBGARG));
985 status = wmi_peer_node_event_rx(wmip, datap, len);
986 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
987 break;
988 case (WMI_TKIP_MICERR_EVENTID):
989 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TKIP_MICERR_EVENTID\n", DBGARG));
990 status = wmi_tkip_micerr_event_rx(wmip, datap, len);
991 break;
992 case (WMI_BSSINFO_EVENTID):
993 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BSSINFO_EVENTID\n", DBGARG));
994 {
995
996
997
998
999
1000 WMI_BSS_INFO_HDR2 bih2;
1001 WMI_BSS_INFO_HDR *bih;
1002 A_MEMCPY(&bih2, datap, sizeof(WMI_BSS_INFO_HDR2));
1003
1004 A_NETBUF_PUSH(osbuf, 4);
1005 datap = A_NETBUF_DATA(osbuf);
1006 len = A_NETBUF_LEN(osbuf);
1007 bih = (WMI_BSS_INFO_HDR *)datap;
1008
1009 bih->channel = bih2.channel;
1010 bih->frameType = bih2.frameType;
1011 bih->snr = bih2.snr;
1012 bih->rssi = bih2.snr - 95;
1013 bih->ieMask = bih2.ieMask;
1014 A_MEMCPY(bih->bssid, bih2.bssid, ATH_MAC_LEN);
1015
1016 status = wmi_bssInfo_event_rx(wmip, datap, len);
1017 A_WMI_SEND_GENERIC_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
1018 }
1019 break;
1020 case (WMI_REGDOMAIN_EVENTID):
1021 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REGDOMAIN_EVENTID\n", DBGARG));
1022 status = wmi_regDomain_event_rx(wmip, datap, len);
1023 break;
1024 case (WMI_PSTREAM_TIMEOUT_EVENTID):
1025 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_PSTREAM_TIMEOUT_EVENTID\n", DBGARG));
1026 status = wmi_pstream_timeout_event_rx(wmip, datap, len);
1027
1028
1029
1030
1031
1032
1033 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
1034 break;
1035 case (WMI_NEIGHBOR_REPORT_EVENTID):
1036 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_NEIGHBOR_REPORT_EVENTID\n", DBGARG));
1037 status = wmi_neighborReport_event_rx(wmip, datap, len);
1038 break;
1039 case (WMI_SCAN_COMPLETE_EVENTID):
1040 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SCAN_COMPLETE_EVENTID\n", DBGARG));
1041 status = wmi_scanComplete_rx(wmip, datap, len);
1042 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
1043 break;
1044 case (WMI_CMDERROR_EVENTID):
1045 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CMDERROR_EVENTID\n", DBGARG));
1046 status = wmi_errorEvent_rx(wmip, datap, len);
1047 break;
1048 case (WMI_REPORT_STATISTICS_EVENTID):
1049 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_STATISTICS_EVENTID\n", DBGARG));
1050 status = wmi_statsEvent_rx(wmip, datap, len);
1051 break;
1052 case (WMI_RSSI_THRESHOLD_EVENTID):
1053 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_RSSI_THRESHOLD_EVENTID\n", DBGARG));
1054 status = wmi_rssiThresholdEvent_rx(wmip, datap, len);
1055 break;
1056 case (WMI_ERROR_REPORT_EVENTID):
1057 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_ERROR_REPORT_EVENTID\n", DBGARG));
1058 status = wmi_reportErrorEvent_rx(wmip, datap, len);
1059 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
1060 break;
1061 case (WMI_OPT_RX_FRAME_EVENTID):
1062 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_OPT_RX_FRAME_EVENTID\n", DBGARG));
1063 status = wmi_opt_frame_event_rx(wmip, datap, len);
1064 break;
1065 case (WMI_REPORT_ROAM_TBL_EVENTID):
1066 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_ROAM_TBL_EVENTID\n", DBGARG));
1067 status = wmi_roam_tbl_event_rx(wmip, datap, len);
1068 break;
1069 case (WMI_EXTENSION_EVENTID):
1070 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_EXTENSION_EVENTID\n", DBGARG));
1071 status = wmi_control_rx_xtnd(wmip, osbuf);
1072 break;
1073 case (WMI_CAC_EVENTID):
1074 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CAC_EVENTID\n", DBGARG));
1075 status = wmi_cac_event_rx(wmip, datap, len);
1076 break;
1077 case (WMI_CHANNEL_CHANGE_EVENTID):
1078 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CHANNEL_CHANGE_EVENTID\n", DBGARG));
1079 status = wmi_channel_change_event_rx(wmip, datap, len);
1080 break;
1081 case (WMI_REPORT_ROAM_DATA_EVENTID):
1082 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_ROAM_DATA_EVENTID\n", DBGARG));
1083 status = wmi_roam_data_event_rx(wmip, datap, len);
1084 break;
1085#ifdef CONFIG_HOST_TCMD_SUPPORT
1086 case (WMI_TEST_EVENTID):
1087 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TEST_EVENTID\n", DBGARG));
1088 status = wmi_tcmd_test_report_rx(wmip, datap, len);
1089 break;
1090#endif
1091 case (WMI_GET_FIXRATES_CMDID):
1092 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_FIXRATES_CMDID\n", DBGARG));
1093 status = wmi_ratemask_reply_rx(wmip, datap, len);
1094 break;
1095 case (WMI_TX_RETRY_ERR_EVENTID):
1096 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TX_RETRY_ERR_EVENTID\n", DBGARG));
1097 status = wmi_txRetryErrEvent_rx(wmip, datap, len);
1098 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
1099 break;
1100 case (WMI_SNR_THRESHOLD_EVENTID):
1101 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SNR_THRESHOLD_EVENTID\n", DBGARG));
1102 status = wmi_snrThresholdEvent_rx(wmip, datap, len);
1103 break;
1104 case (WMI_LQ_THRESHOLD_EVENTID):
1105 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_LQ_THRESHOLD_EVENTID\n", DBGARG));
1106 status = wmi_lqThresholdEvent_rx(wmip, datap, len);
1107 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
1108 break;
1109 case (WMI_APLIST_EVENTID):
1110 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Received APLIST Event\n"));
1111 status = wmi_aplistEvent_rx(wmip, datap, len);
1112 break;
1113 case (WMI_GET_KEEPALIVE_CMDID):
1114 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_KEEPALIVE_CMDID\n", DBGARG));
1115 status = wmi_keepalive_reply_rx(wmip, datap, len);
1116 break;
1117 case (WMI_GET_WOW_LIST_EVENTID):
1118 status = wmi_get_wow_list_event_rx(wmip, datap, len);
1119 break;
1120 case (WMI_GET_PMKID_LIST_EVENTID):
1121 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_PMKID_LIST Event\n", DBGARG));
1122 status = wmi_get_pmkid_list_event_rx(wmip, datap, len);
1123 break;
1124 case (WMI_PSPOLL_EVENTID):
1125 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_PSPOLL_EVENT\n", DBGARG));
1126 status = wmi_pspoll_event_rx(wmip, datap, len);
1127 break;
1128 case (WMI_DTIMEXPIRY_EVENTID):
1129 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_DTIMEXPIRY_EVENT\n", DBGARG));
1130 status = wmi_dtimexpiry_event_rx(wmip, datap, len);
1131 break;
1132 case (WMI_SET_PARAMS_REPLY_EVENTID):
1133 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SET_PARAMS_REPLY Event\n", DBGARG));
1134 status = wmi_set_params_event_rx(wmip, datap, len);
1135 break;
1136 case (WMI_ACM_REJECT_EVENTID):
1137 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SET_PARAMS_REPLY Event\n", DBGARG));
1138 status = wmi_acm_reject_event_rx(wmip, datap, len);
1139 break;
1140#ifdef ATH_AR6K_11N_SUPPORT
1141 case (WMI_ADDBA_REQ_EVENTID):
1142 status = wmi_addba_req_event_rx(wmip, datap, len);
1143 break;
1144 case (WMI_ADDBA_RESP_EVENTID):
1145 status = wmi_addba_resp_event_rx(wmip, datap, len);
1146 break;
1147 case (WMI_DELBA_REQ_EVENTID):
1148 status = wmi_delba_req_event_rx(wmip, datap, len);
1149 break;
1150 case (WMI_REPORT_BTCOEX_CONFIG_EVENTID):
1151 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BTCOEX_CONFIG_EVENTID", DBGARG));
1152 status = wmi_btcoex_config_event_rx(wmip, datap, len);
1153 break;
1154 case (WMI_REPORT_BTCOEX_STATS_EVENTID):
1155 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BTCOEX_STATS_EVENTID", DBGARG));
1156 status = wmi_btcoex_stats_event_rx(wmip, datap, len);
1157 break;
1158#endif
1159 case (WMI_TX_COMPLETE_EVENTID):
1160 {
1161 int index;
1162 TX_COMPLETE_MSG_V1 *pV1;
1163 WMI_TX_COMPLETE_EVENT *pEv = (WMI_TX_COMPLETE_EVENT *)datap;
1164 A_PRINTF("comp: %d %d %d\n", pEv->numMessages, pEv->msgLen, pEv->msgType);
1165
1166 for(index = 0 ; index < pEv->numMessages ; index++) {
1167 pV1 = (TX_COMPLETE_MSG_V1 *)(datap + sizeof(WMI_TX_COMPLETE_EVENT) + index*sizeof(TX_COMPLETE_MSG_V1));
1168 A_PRINTF("msg: %d %d %d %d\n", pV1->status, pV1->pktID, pV1->rateIdx, pV1->ackFailures);
1169 }
1170 }
1171 break;
1172 case (WMI_HCI_EVENT_EVENTID):
1173 status = wmi_hci_event_rx(wmip, datap, len);
1174 break;
1175#ifdef WAPI_ENABLE
1176 case (WMI_WAPI_REKEY_EVENTID):
1177 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_WAPI_REKEY_EVENTID", DBGARG));
1178 status = wmi_wapi_rekey_event_rx(wmip, datap, len);
1179 break;
1180#endif
1181 default:
1182 A_DPRINTF(DBG_WMI|DBG_ERROR,
1183 (DBGFMT "Unknown id 0x%x\n", DBGARG, id));
1184 wmip->wmi_stats.cmd_id_err++;
1185 status = A_ERROR;
1186 break;
1187 }
1188
1189 A_NETBUF_FREE(osbuf);
1190
1191 return status;
1192}
1193
1194
1195static A_STATUS
1196wmi_simple_cmd(struct wmi_t *wmip, WMI_COMMAND_ID cmdid)
1197{
1198 void *osbuf;
1199
1200 osbuf = A_NETBUF_ALLOC(0);
1201 if (osbuf == NULL) {
1202 return A_NO_MEMORY;
1203 }
1204
1205 return (wmi_cmd_send(wmip, osbuf, cmdid, NO_SYNC_WMIFLAG));
1206}
1207
1208
1209
1210
1211#if defined(CONFIG_HOST_GPIO_SUPPORT) || defined(CONFIG_TARGET_PROFILE_SUPPORT)
1212static A_STATUS
1213wmi_simple_cmd_xtnd(struct wmi_t *wmip, WMIX_COMMAND_ID cmdid)
1214{
1215 void *osbuf;
1216
1217 osbuf = A_NETBUF_ALLOC(0);
1218 if (osbuf == NULL) {
1219 return A_NO_MEMORY;
1220 }
1221
1222 return (wmi_cmd_send_xtnd(wmip, osbuf, cmdid, NO_SYNC_WMIFLAG));
1223}
1224#endif
1225
1226static A_STATUS
1227wmi_ready_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1228{
1229 WMI_READY_EVENT *ev = (WMI_READY_EVENT *)datap;
1230
1231 if (len < sizeof(WMI_READY_EVENT)) {
1232 return A_EINVAL;
1233 }
1234 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1235 wmip->wmi_ready = TRUE;
1236 A_WMI_READY_EVENT(wmip->wmi_devt, ev->macaddr, ev->phyCapability,
1237 ev->sw_version, ev->abi_version);
1238
1239 return A_OK;
1240}
1241
1242#define LE_READ_4(p) \
1243 ((A_UINT32) \
1244 ((((A_UINT8 *)(p))[0] ) | (((A_UINT8 *)(p))[1] << 8) | \
1245 (((A_UINT8 *)(p))[2] << 16) | (((A_UINT8 *)(p))[3] << 24)))
1246
1247static int __inline
1248iswmmoui(const A_UINT8 *frm)
1249{
1250 return frm[1] > 3 && LE_READ_4(frm+2) == ((WMM_OUI_TYPE<<24)|WMM_OUI);
1251}
1252
1253static int __inline
1254iswmmparam(const A_UINT8 *frm)
1255{
1256 return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE;
1257}
1258
1259
1260static A_STATUS
1261wmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1262{
1263 WMI_CONNECT_EVENT *ev;
1264 A_UINT8 *pie,*peie;
1265
1266 if (len < sizeof(WMI_CONNECT_EVENT))
1267 {
1268 return A_EINVAL;
1269 }
1270 ev = (WMI_CONNECT_EVENT *)datap;
1271
1272 A_DPRINTF(DBG_WMI,
1273 (DBGFMT "freq %d bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
1274 DBGARG, ev->channel,
1275 ev->bssid[0], ev->bssid[1], ev->bssid[2],
1276 ev->bssid[3], ev->bssid[4], ev->bssid[5]));
1277
1278 A_MEMCPY(wmip->wmi_bssid, ev->bssid, ATH_MAC_LEN);
1279
1280
1281 pie = ev->assocInfo + ev->beaconIeLen + ev->assocReqLen +
1282 sizeof(A_UINT16) +
1283 sizeof(A_UINT16) +
1284 sizeof(A_UINT16) ;
1285
1286
1287 peie = ev->assocInfo + ev->beaconIeLen + ev->assocReqLen + ev->assocRespLen;
1288
1289 while (pie < peie)
1290 {
1291 switch (*pie)
1292 {
1293 case IEEE80211_ELEMID_VENDOR:
1294 if (iswmmoui(pie))
1295 {
1296 if(iswmmparam (pie))
1297 {
1298 wmip->wmi_is_wmm_enabled = TRUE;
1299 }
1300 }
1301 break;
1302 }
1303
1304 if (wmip->wmi_is_wmm_enabled)
1305 {
1306 break;
1307 }
1308 pie += pie[1] + 2;
1309 }
1310
1311 A_WMI_CONNECT_EVENT(wmip->wmi_devt, ev->channel, ev->bssid,
1312 ev->listenInterval, ev->beaconInterval,
1313 (NETWORK_TYPE) ev->networkType, ev->beaconIeLen,
1314 ev->assocReqLen, ev->assocRespLen,
1315 ev->assocInfo);
1316
1317 return A_OK;
1318}
1319
1320static A_STATUS
1321wmi_regDomain_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1322{
1323 WMI_REG_DOMAIN_EVENT *ev;
1324
1325 if (len < sizeof(*ev)) {
1326 return A_EINVAL;
1327 }
1328 ev = (WMI_REG_DOMAIN_EVENT *)datap;
1329
1330 A_WMI_REGDOMAIN_EVENT(wmip->wmi_devt, ev->regDomain);
1331
1332 return A_OK;
1333}
1334
1335static A_STATUS
1336wmi_neighborReport_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1337{
1338 WMI_NEIGHBOR_REPORT_EVENT *ev;
1339 int numAps;
1340
1341 if (len < sizeof(*ev)) {
1342 return A_EINVAL;
1343 }
1344 ev = (WMI_NEIGHBOR_REPORT_EVENT *)datap;
1345 numAps = ev->numberOfAps;
1346
1347 if (len < (int)(sizeof(*ev) + ((numAps - 1) * sizeof(WMI_NEIGHBOR_INFO)))) {
1348 return A_EINVAL;
1349 }
1350
1351 A_WMI_NEIGHBORREPORT_EVENT(wmip->wmi_devt, numAps, ev->neighbor);
1352
1353 return A_OK;
1354}
1355
1356static A_STATUS
1357wmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1358{
1359 WMI_DISCONNECT_EVENT *ev;
1360 wmip->wmi_traffic_class = 100;
1361
1362 if (len < sizeof(WMI_DISCONNECT_EVENT)) {
1363 return A_EINVAL;
1364 }
1365 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1366
1367 ev = (WMI_DISCONNECT_EVENT *)datap;
1368
1369 A_MEMZERO(wmip->wmi_bssid, sizeof(wmip->wmi_bssid));
1370
1371 wmip->wmi_is_wmm_enabled = FALSE;
1372 wmip->wmi_pair_crypto_type = NONE_CRYPT;
1373 wmip->wmi_grp_crypto_type = NONE_CRYPT;
1374
1375 A_WMI_DISCONNECT_EVENT(wmip->wmi_devt, ev->disconnectReason, ev->bssid,
1376 ev->assocRespLen, ev->assocInfo, ev->protocolReasonStatus);
1377
1378 return A_OK;
1379}
1380
1381static A_STATUS
1382wmi_peer_node_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1383{
1384 WMI_PEER_NODE_EVENT *ev;
1385
1386 if (len < sizeof(WMI_PEER_NODE_EVENT)) {
1387 return A_EINVAL;
1388 }
1389 ev = (WMI_PEER_NODE_EVENT *)datap;
1390 if (ev->eventCode == PEER_NODE_JOIN_EVENT) {
1391 A_DPRINTF (DBG_WMI, (DBGFMT "Joined node with Macaddr: ", DBGARG));
1392 } else if(ev->eventCode == PEER_NODE_LEAVE_EVENT) {
1393 A_DPRINTF (DBG_WMI, (DBGFMT "left node with Macaddr: ", DBGARG));
1394 }
1395
1396 A_WMI_PEER_EVENT (wmip->wmi_devt, ev->eventCode, ev->peerMacAddr);
1397
1398 return A_OK;
1399}
1400
1401static A_STATUS
1402wmi_tkip_micerr_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1403{
1404 WMI_TKIP_MICERR_EVENT *ev;
1405
1406 if (len < sizeof(*ev)) {
1407 return A_EINVAL;
1408 }
1409 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1410
1411 ev = (WMI_TKIP_MICERR_EVENT *)datap;
1412 A_WMI_TKIP_MICERR_EVENT(wmip->wmi_devt, ev->keyid, ev->ismcast);
1413
1414 return A_OK;
1415}
1416
1417static A_STATUS
1418wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1419{
1420 bss_t *bss = NULL;
1421 WMI_BSS_INFO_HDR *bih;
1422 A_UINT8 *buf;
1423 A_UINT32 nodeCachingAllowed = 1;
1424 A_UCHAR cached_ssid_len = 0;
1425 A_UCHAR cached_ssid_buf[IEEE80211_NWID_LEN] = {0};
1426 A_UINT8 beacon_ssid_len = 0;
1427
1428 if (len <= sizeof(WMI_BSS_INFO_HDR)) {
1429 return A_EINVAL;
1430 }
1431
1432 bih = (WMI_BSS_INFO_HDR *)datap;
1433 bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid);
1434
1435 if (bih->rssi > 0) {
1436 if (NULL == bss)
1437 return A_OK;
1438 else
1439 bih->rssi = bss->ni_rssi;
1440 }
1441
1442 A_WMI_BSSINFO_EVENT_RX(wmip->wmi_devt, datap, len);
1443
1444 if(ar6000_get_driver_cfg(wmip->wmi_devt,
1445 AR6000_DRIVER_CFG_GET_WLANNODECACHING,
1446 &nodeCachingAllowed) != A_OK) {
1447 wmi_node_return(wmip, bss);
1448 return A_EINVAL;
1449 }
1450
1451 if(!nodeCachingAllowed) {
1452 wmi_node_return(wmip, bss);
1453 return A_OK;
1454 }
1455
1456 buf = datap + sizeof(WMI_BSS_INFO_HDR);
1457 len -= sizeof(WMI_BSS_INFO_HDR);
1458
1459 A_DPRINTF(DBG_WMI2, (DBGFMT "bssInfo event - ch %u, rssi %02x, "
1460 "bssid \"%pM\"\n", DBGARG, bih->channel,
1461 (unsigned char) bih->rssi, bih->bssid));
1462
1463 if(wps_enable && (bih->frameType == PROBERESP_FTYPE) ) {
1464 wmi_node_return(wmip, bss);
1465 return A_OK;
1466 }
1467
1468 if (bss != NULL) {
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478 if ((TRUE == is_probe_ssid) && (BEACON_FTYPE == bih->frameType))
1479 {
1480 A_UCHAR *ie_ssid;
1481
1482 ie_ssid = bss->ni_cie.ie_ssid;
1483 if(ie_ssid && (ie_ssid[1] <= IEEE80211_NWID_LEN) && (ie_ssid[2] != 0))
1484 {
1485 cached_ssid_len = ie_ssid[1];
1486 memcpy(cached_ssid_buf, ie_ssid + 2, cached_ssid_len);
1487 }
1488 }
1489
1490
1491
1492
1493
1494
1495
1496
1497 if (IEEE80211_ADDR_EQ(wmip->wmi_bssid, bih->bssid)) {
1498 bih->rssi = bss->ni_rssi;
1499 bih->snr = bss->ni_snr;
1500 }
1501
1502 wlan_node_reclaim(&wmip->wmi_scan_table, bss);
1503 }
1504
1505
1506
1507
1508
1509
1510 beacon_ssid_len = buf[SSID_IE_LEN_INDEX];
1511
1512
1513 if ((TRUE == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) &&
1514 (0 != cached_ssid_len) &&
1515 (0 == beacon_ssid_len || (cached_ssid_len > beacon_ssid_len && 0 == buf[SSID_IE_LEN_INDEX + 1])))
1516 {
1517 len += (cached_ssid_len - beacon_ssid_len);
1518 }
1519
1520 bss = wlan_node_alloc(&wmip->wmi_scan_table, len);
1521 if (bss == NULL) {
1522 return A_NO_MEMORY;
1523 }
1524
1525 bss->ni_snr = bih->snr;
1526 bss->ni_rssi = bih->rssi;
1527 A_ASSERT(bss->ni_buf != NULL);
1528
1529
1530
1531
1532 if ((TRUE == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) &&
1533 (0 != cached_ssid_len) &&
1534 (0 == beacon_ssid_len || (beacon_ssid_len && 0 == buf[SSID_IE_LEN_INDEX + 1])))
1535 {
1536 A_UINT8 *ni_buf = bss->ni_buf;
1537 int buf_len = len;
1538
1539
1540
1541 A_MEMCPY(ni_buf, buf, SSID_IE_LEN_INDEX + 1);
1542
1543 ni_buf[SSID_IE_LEN_INDEX] = cached_ssid_len;
1544 ni_buf += (SSID_IE_LEN_INDEX + 1);
1545
1546 buf += (SSID_IE_LEN_INDEX + 1);
1547 buf_len -= (SSID_IE_LEN_INDEX + 1);
1548
1549
1550 A_MEMCPY(ni_buf, cached_ssid_buf, cached_ssid_len);
1551 ni_buf += cached_ssid_len;
1552
1553 buf += beacon_ssid_len;
1554 buf_len -= beacon_ssid_len;
1555
1556 if (cached_ssid_len > beacon_ssid_len)
1557 buf_len -= (cached_ssid_len - beacon_ssid_len);
1558
1559
1560 A_MEMCPY(ni_buf, buf, buf_len);
1561 }
1562 else
1563 A_MEMCPY(bss->ni_buf, buf, len);
1564
1565 bss->ni_framelen = len;
1566 if (wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie) != A_OK) {
1567 wlan_node_free(bss);
1568 return A_EINVAL;
1569 }
1570
1571
1572
1573
1574
1575 bss->ni_cie.ie_chan = bih->channel;
1576 wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid);
1577
1578 return A_OK;
1579}
1580
1581static A_STATUS
1582wmi_opt_frame_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1583{
1584 bss_t *bss;
1585 WMI_OPT_RX_INFO_HDR *bih;
1586 A_UINT8 *buf;
1587
1588 if (len <= sizeof(WMI_OPT_RX_INFO_HDR)) {
1589 return A_EINVAL;
1590 }
1591
1592 bih = (WMI_OPT_RX_INFO_HDR *)datap;
1593 buf = datap + sizeof(WMI_OPT_RX_INFO_HDR);
1594 len -= sizeof(WMI_OPT_RX_INFO_HDR);
1595
1596 A_DPRINTF(DBG_WMI2, (DBGFMT "opt frame event %2.2x:%2.2x\n", DBGARG,
1597 bih->bssid[4], bih->bssid[5]));
1598
1599 bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid);
1600 if (bss != NULL) {
1601
1602
1603
1604
1605
1606 wlan_node_reclaim(&wmip->wmi_scan_table, bss);
1607 }
1608
1609 bss = wlan_node_alloc(&wmip->wmi_scan_table, len);
1610 if (bss == NULL) {
1611 return A_NO_MEMORY;
1612 }
1613
1614 bss->ni_snr = bih->snr;
1615 bss->ni_cie.ie_chan = bih->channel;
1616 A_ASSERT(bss->ni_buf != NULL);
1617 A_MEMCPY(bss->ni_buf, buf, len);
1618 wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid);
1619
1620 return A_OK;
1621}
1622
1623
1624
1625
1626static A_STATUS
1627wmi_pstream_timeout_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1628{
1629 WMI_PSTREAM_TIMEOUT_EVENT *ev;
1630
1631 if (len < sizeof(WMI_PSTREAM_TIMEOUT_EVENT)) {
1632 return A_EINVAL;
1633 }
1634
1635 A_DPRINTF(DBG_WMI, (DBGFMT "wmi_pstream_timeout_event_rx\n", DBGARG));
1636
1637 ev = (WMI_PSTREAM_TIMEOUT_EVENT *)datap;
1638
1639
1640
1641
1642
1643
1644
1645 LOCK_WMI(wmip);
1646 wmip->wmi_streamExistsForAC[ev->trafficClass]=0;
1647 wmip->wmi_fatPipeExists &= ~(1 << ev->trafficClass);
1648 UNLOCK_WMI(wmip);
1649
1650
1651 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, ev->trafficClass);
1652
1653 return A_OK;
1654}
1655
1656static A_STATUS
1657wmi_bitrate_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1658{
1659 WMI_BIT_RATE_REPLY *reply;
1660 A_INT32 rate;
1661 A_UINT32 sgi,index;
1662
1663
1664
1665
1666
1667 if (len < sizeof(WMI_BIT_RATE_REPLY)) {
1668 return A_EINVAL;
1669 }
1670 reply = (WMI_BIT_RATE_REPLY *)datap;
1671 A_DPRINTF(DBG_WMI,
1672 (DBGFMT "Enter - rateindex %d\n", DBGARG, reply->rateIndex));
1673
1674 if (reply->rateIndex == (A_INT8) RATE_AUTO) {
1675 rate = RATE_AUTO;
1676 } else {
1677
1678 index = reply->rateIndex & 0x7f;
1679 sgi = (reply->rateIndex & 0x80)? 1:0;
1680 rate = wmi_rateTable[index][sgi];
1681 }
1682
1683 A_WMI_BITRATE_RX(wmip->wmi_devt, rate);
1684 return A_OK;
1685}
1686
1687static A_STATUS
1688wmi_ratemask_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1689{
1690 WMI_FIX_RATES_REPLY *reply;
1691
1692 if (len < sizeof(WMI_FIX_RATES_REPLY)) {
1693 return A_EINVAL;
1694 }
1695 reply = (WMI_FIX_RATES_REPLY *)datap;
1696 A_DPRINTF(DBG_WMI,
1697 (DBGFMT "Enter - fixed rate mask %x\n", DBGARG, reply->fixRateMask));
1698
1699 A_WMI_RATEMASK_RX(wmip->wmi_devt, reply->fixRateMask);
1700
1701 return A_OK;
1702}
1703
1704static A_STATUS
1705wmi_channelList_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1706{
1707 WMI_CHANNEL_LIST_REPLY *reply;
1708
1709 if (len < sizeof(WMI_CHANNEL_LIST_REPLY)) {
1710 return A_EINVAL;
1711 }
1712 reply = (WMI_CHANNEL_LIST_REPLY *)datap;
1713 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1714
1715 A_WMI_CHANNELLIST_RX(wmip->wmi_devt, reply->numChannels,
1716 reply->channelList);
1717
1718 return A_OK;
1719}
1720
1721static A_STATUS
1722wmi_txPwr_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1723{
1724 WMI_TX_PWR_REPLY *reply;
1725
1726 if (len < sizeof(*reply)) {
1727 return A_EINVAL;
1728 }
1729 reply = (WMI_TX_PWR_REPLY *)datap;
1730 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1731
1732 A_WMI_TXPWR_RX(wmip->wmi_devt, reply->dbM);
1733
1734 return A_OK;
1735}
1736static A_STATUS
1737wmi_keepalive_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1738{
1739 WMI_GET_KEEPALIVE_CMD *reply;
1740
1741 if (len < sizeof(*reply)) {
1742 return A_EINVAL;
1743 }
1744 reply = (WMI_GET_KEEPALIVE_CMD *)datap;
1745 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1746
1747 A_WMI_KEEPALIVE_RX(wmip->wmi_devt, reply->configured);
1748
1749 return A_OK;
1750}
1751
1752
1753static A_STATUS
1754wmi_dset_open_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1755{
1756 WMIX_DSETOPENREQ_EVENT *dsetopenreq;
1757
1758 if (len < sizeof(WMIX_DSETOPENREQ_EVENT)) {
1759 return A_EINVAL;
1760 }
1761 dsetopenreq = (WMIX_DSETOPENREQ_EVENT *)datap;
1762 A_DPRINTF(DBG_WMI,
1763 (DBGFMT "Enter - dset_id=0x%x\n", DBGARG, dsetopenreq->dset_id));
1764 A_WMI_DSET_OPEN_REQ(wmip->wmi_devt,
1765 dsetopenreq->dset_id,
1766 dsetopenreq->targ_dset_handle,
1767 dsetopenreq->targ_reply_fn,
1768 dsetopenreq->targ_reply_arg);
1769
1770 return A_OK;
1771}
1772
1773#ifdef CONFIG_HOST_DSET_SUPPORT
1774static A_STATUS
1775wmi_dset_close_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1776{
1777 WMIX_DSETCLOSE_EVENT *dsetclose;
1778
1779 if (len < sizeof(WMIX_DSETCLOSE_EVENT)) {
1780 return A_EINVAL;
1781 }
1782 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1783
1784 dsetclose = (WMIX_DSETCLOSE_EVENT *)datap;
1785 A_WMI_DSET_CLOSE(wmip->wmi_devt, dsetclose->access_cookie);
1786
1787 return A_OK;
1788}
1789
1790static A_STATUS
1791wmi_dset_data_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1792{
1793 WMIX_DSETDATAREQ_EVENT *dsetdatareq;
1794
1795 if (len < sizeof(WMIX_DSETDATAREQ_EVENT)) {
1796 return A_EINVAL;
1797 }
1798 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1799
1800 dsetdatareq = (WMIX_DSETDATAREQ_EVENT *)datap;
1801 A_WMI_DSET_DATA_REQ(wmip->wmi_devt,
1802 dsetdatareq->access_cookie,
1803 dsetdatareq->offset,
1804 dsetdatareq->length,
1805 dsetdatareq->targ_buf,
1806 dsetdatareq->targ_reply_fn,
1807 dsetdatareq->targ_reply_arg);
1808
1809 return A_OK;
1810}
1811#endif
1812
1813static A_STATUS
1814wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1815{
1816 WMI_SCAN_COMPLETE_EVENT *ev;
1817
1818 ev = (WMI_SCAN_COMPLETE_EVENT *)datap;
1819 if ((A_STATUS)ev->status == A_OK) {
1820 wlan_refresh_inactive_nodes(&wmip->wmi_scan_table);
1821 }
1822 A_WMI_SCANCOMPLETE_EVENT(wmip->wmi_devt, (A_STATUS) ev->status);
1823 is_probe_ssid = FALSE;
1824
1825 return A_OK;
1826}
1827
1828
1829
1830
1831
1832
1833
1834
1835static A_STATUS
1836wmi_errorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1837{
1838 WMI_CMD_ERROR_EVENT *ev;
1839
1840 ev = (WMI_CMD_ERROR_EVENT *)datap;
1841 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Programming Error: cmd=%d ", ev->commandId));
1842 switch (ev->errorCode) {
1843 case (INVALID_PARAM):
1844 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal Parameter\n"));
1845 break;
1846 case (ILLEGAL_STATE):
1847 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal State\n"));
1848 break;
1849 case (INTERNAL_ERROR):
1850 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Internal Error\n"));
1851 break;
1852 }
1853
1854 return A_OK;
1855}
1856
1857
1858static A_STATUS
1859wmi_statsEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1860{
1861 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1862
1863 A_WMI_TARGETSTATS_EVENT(wmip->wmi_devt, datap, len);
1864
1865 return A_OK;
1866}
1867
1868static A_STATUS
1869wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1870{
1871 WMI_RSSI_THRESHOLD_EVENT *reply;
1872 WMI_RSSI_THRESHOLD_VAL newThreshold;
1873 WMI_RSSI_THRESHOLD_PARAMS_CMD cmd;
1874 SQ_THRESHOLD_PARAMS *sq_thresh =
1875 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI];
1876 A_UINT8 upper_rssi_threshold, lower_rssi_threshold;
1877 A_INT16 rssi;
1878
1879 if (len < sizeof(*reply)) {
1880 return A_EINVAL;
1881 }
1882 reply = (WMI_RSSI_THRESHOLD_EVENT *)datap;
1883 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1884 newThreshold = (WMI_RSSI_THRESHOLD_VAL) reply->range;
1885 rssi = reply->rssi;
1886
1887
1888
1889
1890
1891
1892 if (newThreshold) {
1893
1894 if (rssi < sq_thresh->upper_threshold[0]) {
1895 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious upper RSSI threshold event: "
1896 " %d\n", DBGARG, rssi));
1897 } else if ((rssi < sq_thresh->upper_threshold[1]) &&
1898 (rssi >= sq_thresh->upper_threshold[0]))
1899 {
1900 newThreshold = WMI_RSSI_THRESHOLD1_ABOVE;
1901 } else if ((rssi < sq_thresh->upper_threshold[2]) &&
1902 (rssi >= sq_thresh->upper_threshold[1]))
1903 {
1904 newThreshold = WMI_RSSI_THRESHOLD2_ABOVE;
1905 } else if ((rssi < sq_thresh->upper_threshold[3]) &&
1906 (rssi >= sq_thresh->upper_threshold[2]))
1907 {
1908 newThreshold = WMI_RSSI_THRESHOLD3_ABOVE;
1909 } else if ((rssi < sq_thresh->upper_threshold[4]) &&
1910 (rssi >= sq_thresh->upper_threshold[3]))
1911 {
1912 newThreshold = WMI_RSSI_THRESHOLD4_ABOVE;
1913 } else if ((rssi < sq_thresh->upper_threshold[5]) &&
1914 (rssi >= sq_thresh->upper_threshold[4]))
1915 {
1916 newThreshold = WMI_RSSI_THRESHOLD5_ABOVE;
1917 } else if (rssi >= sq_thresh->upper_threshold[5]) {
1918 newThreshold = WMI_RSSI_THRESHOLD6_ABOVE;
1919 }
1920 } else {
1921
1922 if (rssi > sq_thresh->lower_threshold[0]) {
1923 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious lower RSSI threshold event: "
1924 "%d %d\n", DBGARG, rssi, sq_thresh->lower_threshold[0]));
1925 } else if ((rssi > sq_thresh->lower_threshold[1]) &&
1926 (rssi <= sq_thresh->lower_threshold[0]))
1927 {
1928 newThreshold = WMI_RSSI_THRESHOLD6_BELOW;
1929 } else if ((rssi > sq_thresh->lower_threshold[2]) &&
1930 (rssi <= sq_thresh->lower_threshold[1]))
1931 {
1932 newThreshold = WMI_RSSI_THRESHOLD5_BELOW;
1933 } else if ((rssi > sq_thresh->lower_threshold[3]) &&
1934 (rssi <= sq_thresh->lower_threshold[2]))
1935 {
1936 newThreshold = WMI_RSSI_THRESHOLD4_BELOW;
1937 } else if ((rssi > sq_thresh->lower_threshold[4]) &&
1938 (rssi <= sq_thresh->lower_threshold[3]))
1939 {
1940 newThreshold = WMI_RSSI_THRESHOLD3_BELOW;
1941 } else if ((rssi > sq_thresh->lower_threshold[5]) &&
1942 (rssi <= sq_thresh->lower_threshold[4]))
1943 {
1944 newThreshold = WMI_RSSI_THRESHOLD2_BELOW;
1945 } else if (rssi <= sq_thresh->lower_threshold[5]) {
1946 newThreshold = WMI_RSSI_THRESHOLD1_BELOW;
1947 }
1948 }
1949
1950 lower_rssi_threshold = ar6000_get_lower_threshold(rssi, sq_thresh,
1951 sq_thresh->lower_threshold_valid_count);
1952 upper_rssi_threshold = ar6000_get_upper_threshold(rssi, sq_thresh,
1953 sq_thresh->upper_threshold_valid_count);
1954
1955 cmd.thresholdAbove1_Val = upper_rssi_threshold;
1956 cmd.thresholdBelow1_Val = lower_rssi_threshold;
1957 cmd.weight = sq_thresh->weight;
1958 cmd.pollTime = sq_thresh->polling_interval;
1959
1960 rssi_event_value = rssi;
1961
1962 if (wmi_send_rssi_threshold_params(wmip, &cmd) != A_OK) {
1963 A_DPRINTF(DBG_WMI, (DBGFMT "Unable to configure the RSSI thresholds\n",
1964 DBGARG));
1965 }
1966
1967 A_WMI_RSSI_THRESHOLD_EVENT(wmip->wmi_devt, newThreshold, reply->rssi);
1968
1969 return A_OK;
1970}
1971
1972
1973static A_STATUS
1974wmi_reportErrorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1975{
1976 WMI_TARGET_ERROR_REPORT_EVENT *reply;
1977
1978 if (len < sizeof(*reply)) {
1979 return A_EINVAL;
1980 }
1981 reply = (WMI_TARGET_ERROR_REPORT_EVENT *)datap;
1982 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1983
1984 A_WMI_REPORT_ERROR_EVENT(wmip->wmi_devt, (WMI_TARGET_ERROR_VAL) reply->errorVal);
1985
1986 return A_OK;
1987}
1988
1989static A_STATUS
1990wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1991{
1992 WMI_CAC_EVENT *reply;
1993 WMM_TSPEC_IE *tspec_ie;
1994 A_UINT16 activeTsids;
1995
1996 if (len < sizeof(*reply)) {
1997 return A_EINVAL;
1998 }
1999 reply = (WMI_CAC_EVENT *)datap;
2000
2001 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2002
2003 if ((reply->cac_indication == CAC_INDICATION_ADMISSION_RESP) &&
2004 (reply->statusCode != TSPEC_STATUS_CODE_ADMISSION_ACCEPTED)) {
2005 tspec_ie = (WMM_TSPEC_IE *) &(reply->tspecSuggestion);
2006
2007 wmi_delete_pstream_cmd(wmip, reply->ac,
2008 (tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK);
2009 }
2010 else if (reply->cac_indication == CAC_INDICATION_NO_RESP) {
2011 A_UINT8 i;
2012
2013
2014
2015 LOCK_WMI(wmip);
2016 activeTsids = wmip->wmi_streamExistsForAC[reply->ac];
2017 UNLOCK_WMI(wmip);
2018
2019 for (i = 0; i < sizeof(activeTsids) * 8; i++) {
2020 if ((activeTsids >> i) & 1) {
2021 break;
2022 }
2023 }
2024 if (i < (sizeof(activeTsids) * 8)) {
2025 wmi_delete_pstream_cmd(wmip, reply->ac, i);
2026 }
2027 }
2028
2029
2030
2031
2032 else if (reply->cac_indication == CAC_INDICATION_DELETE) {
2033 A_UINT8 tsid = 0;
2034
2035 tspec_ie = (WMM_TSPEC_IE *) &(reply->tspecSuggestion);
2036 tsid= ((tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK);
2037 LOCK_WMI(wmip);
2038 wmip->wmi_streamExistsForAC[reply->ac] &= ~(1<<tsid);
2039 activeTsids = wmip->wmi_streamExistsForAC[reply->ac];
2040 UNLOCK_WMI(wmip);
2041
2042
2043
2044
2045
2046 if (!activeTsids) {
2047 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, reply->ac);
2048 wmip->wmi_fatPipeExists &= ~(1 << reply->ac);
2049 }
2050 }
2051
2052 A_WMI_CAC_EVENT(wmip->wmi_devt, reply->ac,
2053 reply->cac_indication, reply->statusCode,
2054 reply->tspecSuggestion);
2055
2056 return A_OK;
2057}
2058
2059static A_STATUS
2060wmi_channel_change_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2061{
2062 WMI_CHANNEL_CHANGE_EVENT *reply;
2063
2064 if (len < sizeof(*reply)) {
2065 return A_EINVAL;
2066 }
2067 reply = (WMI_CHANNEL_CHANGE_EVENT *)datap;
2068 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2069
2070 A_WMI_CHANNEL_CHANGE_EVENT(wmip->wmi_devt, reply->oldChannel,
2071 reply->newChannel);
2072
2073 return A_OK;
2074}
2075
2076static A_STATUS
2077wmi_hbChallengeResp_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2078{
2079 WMIX_HB_CHALLENGE_RESP_EVENT *reply;
2080
2081 if (len < sizeof(*reply)) {
2082 return A_EINVAL;
2083 }
2084 reply = (WMIX_HB_CHALLENGE_RESP_EVENT *)datap;
2085 A_DPRINTF(DBG_WMI, (DBGFMT "wmi: challenge response event\n", DBGARG));
2086
2087 A_WMI_HBCHALLENGERESP_EVENT(wmip->wmi_devt, reply->cookie, reply->source);
2088
2089 return A_OK;
2090}
2091
2092static A_STATUS
2093wmi_roam_tbl_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2094{
2095 WMI_TARGET_ROAM_TBL *reply;
2096
2097 if (len < sizeof(*reply)) {
2098 return A_EINVAL;
2099 }
2100 reply = (WMI_TARGET_ROAM_TBL *)datap;
2101 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2102
2103 A_WMI_ROAM_TABLE_EVENT(wmip->wmi_devt, reply);
2104
2105 return A_OK;
2106}
2107
2108static A_STATUS
2109wmi_roam_data_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2110{
2111 WMI_TARGET_ROAM_DATA *reply;
2112
2113 if (len < sizeof(*reply)) {
2114 return A_EINVAL;
2115 }
2116 reply = (WMI_TARGET_ROAM_DATA *)datap;
2117 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2118
2119 A_WMI_ROAM_DATA_EVENT(wmip->wmi_devt, reply);
2120
2121 return A_OK;
2122}
2123
2124static A_STATUS
2125wmi_txRetryErrEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2126{
2127 if (len < sizeof(WMI_TX_RETRY_ERR_EVENT)) {
2128 return A_EINVAL;
2129 }
2130 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2131
2132 A_WMI_TX_RETRY_ERR_EVENT(wmip->wmi_devt);
2133
2134 return A_OK;
2135}
2136
2137static A_STATUS
2138wmi_snrThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2139{
2140 WMI_SNR_THRESHOLD_EVENT *reply;
2141 SQ_THRESHOLD_PARAMS *sq_thresh =
2142 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_SNR];
2143 WMI_SNR_THRESHOLD_VAL newThreshold;
2144 WMI_SNR_THRESHOLD_PARAMS_CMD cmd;
2145 A_UINT8 upper_snr_threshold, lower_snr_threshold;
2146 A_INT16 snr;
2147
2148 if (len < sizeof(*reply)) {
2149 return A_EINVAL;
2150 }
2151 reply = (WMI_SNR_THRESHOLD_EVENT *)datap;
2152 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2153
2154 newThreshold = (WMI_SNR_THRESHOLD_VAL) reply->range;
2155 snr = reply->snr;
2156
2157
2158
2159
2160
2161 if (newThreshold) {
2162
2163 if (snr < sq_thresh->upper_threshold[0]) {
2164 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious upper SNR threshold event: "
2165 "%d\n", DBGARG, snr));
2166 } else if ((snr < sq_thresh->upper_threshold[1]) &&
2167 (snr >= sq_thresh->upper_threshold[0]))
2168 {
2169 newThreshold = WMI_SNR_THRESHOLD1_ABOVE;
2170 } else if ((snr < sq_thresh->upper_threshold[2]) &&
2171 (snr >= sq_thresh->upper_threshold[1]))
2172 {
2173 newThreshold = WMI_SNR_THRESHOLD2_ABOVE;
2174 } else if ((snr < sq_thresh->upper_threshold[3]) &&
2175 (snr >= sq_thresh->upper_threshold[2]))
2176 {
2177 newThreshold = WMI_SNR_THRESHOLD3_ABOVE;
2178 } else if (snr >= sq_thresh->upper_threshold[3]) {
2179 newThreshold = WMI_SNR_THRESHOLD4_ABOVE;
2180 }
2181 } else {
2182
2183 if (snr > sq_thresh->lower_threshold[0]) {
2184 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious lower SNR threshold event: "
2185 "%d %d\n", DBGARG, snr, sq_thresh->lower_threshold[0]));
2186 } else if ((snr > sq_thresh->lower_threshold[1]) &&
2187 (snr <= sq_thresh->lower_threshold[0]))
2188 {
2189 newThreshold = WMI_SNR_THRESHOLD4_BELOW;
2190 } else if ((snr > sq_thresh->lower_threshold[2]) &&
2191 (snr <= sq_thresh->lower_threshold[1]))
2192 {
2193 newThreshold = WMI_SNR_THRESHOLD3_BELOW;
2194 } else if ((snr > sq_thresh->lower_threshold[3]) &&
2195 (snr <= sq_thresh->lower_threshold[2]))
2196 {
2197 newThreshold = WMI_SNR_THRESHOLD2_BELOW;
2198 } else if (snr <= sq_thresh->lower_threshold[3]) {
2199 newThreshold = WMI_SNR_THRESHOLD1_BELOW;
2200 }
2201 }
2202
2203
2204 lower_snr_threshold = ar6000_get_lower_threshold(snr, sq_thresh,
2205 sq_thresh->lower_threshold_valid_count);
2206 upper_snr_threshold = ar6000_get_upper_threshold(snr, sq_thresh,
2207 sq_thresh->upper_threshold_valid_count);
2208
2209
2210 cmd.thresholdAbove1_Val = upper_snr_threshold;
2211 cmd.thresholdBelow1_Val = lower_snr_threshold;
2212 cmd.weight = sq_thresh->weight;
2213 cmd.pollTime = sq_thresh->polling_interval;
2214
2215 A_DPRINTF(DBG_WMI, (DBGFMT "snr: %d, threshold: %d, lower: %d, upper: %d\n"
2216 ,DBGARG, snr, newThreshold, lower_snr_threshold,
2217 upper_snr_threshold));
2218
2219 snr_event_value = snr;
2220
2221 if (wmi_send_snr_threshold_params(wmip, &cmd) != A_OK) {
2222 A_DPRINTF(DBG_WMI, (DBGFMT "Unable to configure the SNR thresholds\n",
2223 DBGARG));
2224 }
2225 A_WMI_SNR_THRESHOLD_EVENT_RX(wmip->wmi_devt, newThreshold, reply->snr);
2226
2227 return A_OK;
2228}
2229
2230static A_STATUS
2231wmi_lqThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2232{
2233 WMI_LQ_THRESHOLD_EVENT *reply;
2234
2235 if (len < sizeof(*reply)) {
2236 return A_EINVAL;
2237 }
2238 reply = (WMI_LQ_THRESHOLD_EVENT *)datap;
2239 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2240
2241 A_WMI_LQ_THRESHOLD_EVENT_RX(wmip->wmi_devt,
2242 (WMI_LQ_THRESHOLD_VAL) reply->range,
2243 reply->lq);
2244
2245 return A_OK;
2246}
2247
2248static A_STATUS
2249wmi_aplistEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2250{
2251 A_UINT16 ap_info_entry_size;
2252 WMI_APLIST_EVENT *ev = (WMI_APLIST_EVENT *)datap;
2253 WMI_AP_INFO_V1 *ap_info_v1;
2254 A_UINT8 i;
2255
2256 if (len < sizeof(WMI_APLIST_EVENT)) {
2257 return A_EINVAL;
2258 }
2259
2260 if (ev->apListVer == APLIST_VER1) {
2261 ap_info_entry_size = sizeof(WMI_AP_INFO_V1);
2262 ap_info_v1 = (WMI_AP_INFO_V1 *)ev->apList;
2263 } else {
2264 return A_EINVAL;
2265 }
2266
2267 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Number of APs in APLIST Event is %d\n", ev->numAP));
2268 if (len < (int)(sizeof(WMI_APLIST_EVENT) +
2269 (ev->numAP - 1) * ap_info_entry_size))
2270 {
2271 return A_EINVAL;
2272 }
2273
2274
2275
2276
2277 for (i = 0; i < ev->numAP; i++) {
2278 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("AP#%d BSSID %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x "\
2279 "Channel %d\n", i,
2280 ap_info_v1->bssid[0], ap_info_v1->bssid[1],
2281 ap_info_v1->bssid[2], ap_info_v1->bssid[3],
2282 ap_info_v1->bssid[4], ap_info_v1->bssid[5],
2283 ap_info_v1->channel));
2284 ap_info_v1++;
2285 }
2286 return A_OK;
2287}
2288
2289static A_STATUS
2290wmi_dbglog_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2291{
2292 A_UINT32 dropped;
2293
2294 dropped = *((A_UINT32 *)datap);
2295 datap += sizeof(dropped);
2296 len -= sizeof(dropped);
2297 A_WMI_DBGLOG_EVENT(wmip->wmi_devt, dropped, (A_INT8*)datap, len);
2298 return A_OK;
2299}
2300
2301#ifdef CONFIG_HOST_GPIO_SUPPORT
2302static A_STATUS
2303wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2304{
2305 WMIX_GPIO_INTR_EVENT *gpio_intr = (WMIX_GPIO_INTR_EVENT *)datap;
2306
2307 A_DPRINTF(DBG_WMI,
2308 (DBGFMT "Enter - intrmask=0x%x input=0x%x.\n", DBGARG,
2309 gpio_intr->intr_mask, gpio_intr->input_values));
2310
2311 A_WMI_GPIO_INTR_RX(gpio_intr->intr_mask, gpio_intr->input_values);
2312
2313 return A_OK;
2314}
2315
2316static A_STATUS
2317wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2318{
2319 WMIX_GPIO_DATA_EVENT *gpio_data = (WMIX_GPIO_DATA_EVENT *)datap;
2320
2321 A_DPRINTF(DBG_WMI,
2322 (DBGFMT "Enter - reg=%d value=0x%x\n", DBGARG,
2323 gpio_data->reg_id, gpio_data->value));
2324
2325 A_WMI_GPIO_DATA_RX(gpio_data->reg_id, gpio_data->value);
2326
2327 return A_OK;
2328}
2329
2330static A_STATUS
2331wmi_gpio_ack_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2332{
2333 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2334
2335 A_WMI_GPIO_ACK_RX();
2336
2337 return A_OK;
2338}
2339#endif
2340
2341
2342
2343
2344
2345A_STATUS
2346wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId,
2347 WMI_SYNC_FLAG syncflag)
2348{
2349 A_STATUS status;
2350#define IS_OPT_TX_CMD(cmdId) ((cmdId == WMI_OPT_TX_FRAME_CMDID))
2351 WMI_CMD_HDR *cHdr;
2352 HTC_ENDPOINT_ID eid = wmip->wmi_endpoint_id;
2353
2354 A_ASSERT(osbuf != NULL);
2355
2356 if (syncflag >= END_WMIFLAG) {
2357 A_NETBUF_FREE(osbuf);
2358 return A_EINVAL;
2359 }
2360
2361 if ((syncflag == SYNC_BEFORE_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) {
2362
2363
2364
2365
2366 wmi_sync_point(wmip);
2367 }
2368
2369 if (A_NETBUF_PUSH(osbuf, sizeof(WMI_CMD_HDR)) != A_OK) {
2370 A_NETBUF_FREE(osbuf);
2371 return A_NO_MEMORY;
2372 }
2373
2374 cHdr = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf);
2375 cHdr->commandId = (A_UINT16) cmdId;
2376 cHdr->info1 = 0;
2377
2378
2379
2380
2381 if (IS_OPT_TX_CMD(cmdId)) {
2382 if ((status=wmi_data_hdr_add(wmip, osbuf, OPT_MSGTYPE, FALSE, FALSE,0,NULL)) != A_OK) {
2383 A_NETBUF_FREE(osbuf);
2384 return status;
2385 }
2386 eid = A_WMI_Ac2EndpointID(wmip->wmi_devt, WMM_AC_BE);
2387 }
2388 A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid);
2389
2390 if ((syncflag == SYNC_AFTER_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) {
2391
2392
2393
2394
2395 wmi_sync_point(wmip);
2396 }
2397 return (A_OK);
2398#undef IS_OPT_TX_CMD
2399}
2400
2401A_STATUS
2402wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId,
2403 WMI_SYNC_FLAG syncflag)
2404{
2405 WMIX_CMD_HDR *cHdr;
2406
2407 if (A_NETBUF_PUSH(osbuf, sizeof(WMIX_CMD_HDR)) != A_OK) {
2408 A_NETBUF_FREE(osbuf);
2409 return A_NO_MEMORY;
2410 }
2411
2412 cHdr = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf);
2413 cHdr->commandId = (A_UINT32) cmdId;
2414
2415 return wmi_cmd_send(wmip, osbuf, WMI_EXTENSION_CMDID, syncflag);
2416}
2417
2418A_STATUS
2419wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType,
2420 DOT11_AUTH_MODE dot11AuthMode, AUTH_MODE authMode,
2421 CRYPTO_TYPE pairwiseCrypto, A_UINT8 pairwiseCryptoLen,
2422 CRYPTO_TYPE groupCrypto, A_UINT8 groupCryptoLen,
2423 int ssidLength, A_UCHAR *ssid,
2424 A_UINT8 *bssid, A_UINT16 channel, A_UINT32 ctrl_flags)
2425{
2426 void *osbuf;
2427 WMI_CONNECT_CMD *cc;
2428 wmip->wmi_traffic_class = 100;
2429
2430 if ((pairwiseCrypto == NONE_CRYPT) && (groupCrypto != NONE_CRYPT)) {
2431 return A_EINVAL;
2432 }
2433 if ((pairwiseCrypto != NONE_CRYPT) && (groupCrypto == NONE_CRYPT)) {
2434 return A_EINVAL;
2435 }
2436
2437 osbuf = A_NETBUF_ALLOC(sizeof(WMI_CONNECT_CMD));
2438 if (osbuf == NULL) {
2439 return A_NO_MEMORY;
2440 }
2441
2442 A_NETBUF_PUT(osbuf, sizeof(WMI_CONNECT_CMD));
2443
2444 cc = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf));
2445 A_MEMZERO(cc, sizeof(*cc));
2446
2447 if (ssidLength)
2448 {
2449 A_MEMCPY(cc->ssid, ssid, ssidLength);
2450 }
2451
2452 cc->ssidLength = ssidLength;
2453 cc->networkType = netType;
2454 cc->dot11AuthMode = dot11AuthMode;
2455 cc->authMode = authMode;
2456 cc->pairwiseCryptoType = pairwiseCrypto;
2457 cc->pairwiseCryptoLen = pairwiseCryptoLen;
2458 cc->groupCryptoType = groupCrypto;
2459 cc->groupCryptoLen = groupCryptoLen;
2460 cc->channel = channel;
2461 cc->ctrl_flags = ctrl_flags;
2462
2463 if (bssid != NULL) {
2464 A_MEMCPY(cc->bssid, bssid, ATH_MAC_LEN);
2465 }
2466
2467 wmip->wmi_pair_crypto_type = pairwiseCrypto;
2468 wmip->wmi_grp_crypto_type = groupCrypto;
2469
2470 return (wmi_cmd_send(wmip, osbuf, WMI_CONNECT_CMDID, NO_SYNC_WMIFLAG));
2471}
2472
2473A_STATUS
2474wmi_reconnect_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT16 channel)
2475{
2476 void *osbuf;
2477 WMI_RECONNECT_CMD *cc;
2478 wmip->wmi_traffic_class = 100;
2479
2480 osbuf = A_NETBUF_ALLOC(sizeof(WMI_RECONNECT_CMD));
2481 if (osbuf == NULL) {
2482 return A_NO_MEMORY;
2483 }
2484
2485 A_NETBUF_PUT(osbuf, sizeof(WMI_RECONNECT_CMD));
2486
2487 cc = (WMI_RECONNECT_CMD *)(A_NETBUF_DATA(osbuf));
2488 A_MEMZERO(cc, sizeof(*cc));
2489
2490 cc->channel = channel;
2491
2492 if (bssid != NULL) {
2493 A_MEMCPY(cc->bssid, bssid, ATH_MAC_LEN);
2494 }
2495
2496 return (wmi_cmd_send(wmip, osbuf, WMI_RECONNECT_CMDID, NO_SYNC_WMIFLAG));
2497}
2498
2499A_STATUS
2500wmi_disconnect_cmd(struct wmi_t *wmip)
2501{
2502 A_STATUS status;
2503 wmip->wmi_traffic_class = 100;
2504
2505
2506
2507 status = wmi_simple_cmd(wmip, WMI_DISCONNECT_CMDID);
2508
2509 return status;
2510}
2511
2512A_STATUS
2513wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType,
2514 A_BOOL forceFgScan, A_BOOL isLegacy,
2515 A_UINT32 homeDwellTime, A_UINT32 forceScanInterval,
2516 A_INT8 numChan, A_UINT16 *channelList)
2517{
2518 void *osbuf;
2519 WMI_START_SCAN_CMD *sc;
2520 A_INT8 size;
2521
2522 size = sizeof (*sc);
2523
2524 if ((scanType != WMI_LONG_SCAN) && (scanType != WMI_SHORT_SCAN)) {
2525 return A_EINVAL;
2526 }
2527
2528 if (numChan) {
2529 if (numChan > WMI_MAX_CHANNELS) {
2530 return A_EINVAL;
2531 }
2532 size += sizeof(A_UINT16) * (numChan - 1);
2533 }
2534
2535 osbuf = A_NETBUF_ALLOC(size);
2536 if (osbuf == NULL) {
2537 return A_NO_MEMORY;
2538 }
2539
2540 A_NETBUF_PUT(osbuf, size);
2541
2542 sc = (WMI_START_SCAN_CMD *)(A_NETBUF_DATA(osbuf));
2543 sc->scanType = scanType;
2544 sc->forceFgScan = forceFgScan;
2545 sc->isLegacy = isLegacy;
2546 sc->homeDwellTime = homeDwellTime;
2547 sc->forceScanInterval = forceScanInterval;
2548 sc->numChannels = numChan;
2549 if (numChan) {
2550 A_MEMCPY(sc->channelList, channelList, numChan * sizeof(A_UINT16));
2551 }
2552
2553 return (wmi_cmd_send(wmip, osbuf, WMI_START_SCAN_CMDID, NO_SYNC_WMIFLAG));
2554}
2555
2556A_STATUS
2557wmi_scanparams_cmd(struct wmi_t *wmip, A_UINT16 fg_start_sec,
2558 A_UINT16 fg_end_sec, A_UINT16 bg_sec,
2559 A_UINT16 minact_chdw_msec, A_UINT16 maxact_chdw_msec,
2560 A_UINT16 pas_chdw_msec,
2561 A_UINT8 shScanRatio, A_UINT8 scanCtrlFlags,
2562 A_UINT32 max_dfsch_act_time, A_UINT16 maxact_scan_per_ssid)
2563{
2564 void *osbuf;
2565 WMI_SCAN_PARAMS_CMD *sc;
2566
2567 osbuf = A_NETBUF_ALLOC(sizeof(*sc));
2568 if (osbuf == NULL) {
2569 return A_NO_MEMORY;
2570 }
2571
2572 A_NETBUF_PUT(osbuf, sizeof(*sc));
2573
2574 sc = (WMI_SCAN_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
2575 A_MEMZERO(sc, sizeof(*sc));
2576 sc->fg_start_period = fg_start_sec;
2577 sc->fg_end_period = fg_end_sec;
2578 sc->bg_period = bg_sec;
2579 sc->minact_chdwell_time = minact_chdw_msec;
2580 sc->maxact_chdwell_time = maxact_chdw_msec;
2581 sc->pas_chdwell_time = pas_chdw_msec;
2582 sc->shortScanRatio = shScanRatio;
2583 sc->scanCtrlFlags = scanCtrlFlags;
2584 sc->max_dfsch_act_time = max_dfsch_act_time;
2585 sc->maxact_scan_per_ssid = maxact_scan_per_ssid;
2586
2587 return (wmi_cmd_send(wmip, osbuf, WMI_SET_SCAN_PARAMS_CMDID,
2588 NO_SYNC_WMIFLAG));
2589}
2590
2591A_STATUS
2592wmi_bssfilter_cmd(struct wmi_t *wmip, A_UINT8 filter, A_UINT32 ieMask)
2593{
2594 void *osbuf;
2595 WMI_BSS_FILTER_CMD *cmd;
2596
2597 if (filter >= LAST_BSS_FILTER) {
2598 return A_EINVAL;
2599 }
2600
2601 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2602 if (osbuf == NULL) {
2603 return A_NO_MEMORY;
2604 }
2605
2606 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2607
2608 cmd = (WMI_BSS_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
2609 A_MEMZERO(cmd, sizeof(*cmd));
2610 cmd->bssFilter = filter;
2611 cmd->ieMask = ieMask;
2612
2613 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BSS_FILTER_CMDID,
2614 NO_SYNC_WMIFLAG));
2615}
2616
2617A_STATUS
2618wmi_probedSsid_cmd(struct wmi_t *wmip, A_UINT8 index, A_UINT8 flag,
2619 A_UINT8 ssidLength, A_UCHAR *ssid)
2620{
2621 void *osbuf;
2622 WMI_PROBED_SSID_CMD *cmd;
2623
2624 if (index > MAX_PROBED_SSID_INDEX) {
2625 return A_EINVAL;
2626 }
2627 if (ssidLength > sizeof(cmd->ssid)) {
2628 return A_EINVAL;
2629 }
2630 if ((flag & (DISABLE_SSID_FLAG | ANY_SSID_FLAG)) && (ssidLength > 0)) {
2631 return A_EINVAL;
2632 }
2633 if ((flag & SPECIFIC_SSID_FLAG) && !ssidLength) {
2634 return A_EINVAL;
2635 }
2636
2637 if (flag & SPECIFIC_SSID_FLAG) {
2638 is_probe_ssid = TRUE;
2639 }
2640
2641 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2642 if (osbuf == NULL) {
2643 return A_NO_MEMORY;
2644 }
2645
2646 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2647
2648 cmd = (WMI_PROBED_SSID_CMD *)(A_NETBUF_DATA(osbuf));
2649 A_MEMZERO(cmd, sizeof(*cmd));
2650 cmd->entryIndex = index;
2651 cmd->flag = flag;
2652 cmd->ssidLength = ssidLength;
2653 A_MEMCPY(cmd->ssid, ssid, ssidLength);
2654
2655 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PROBED_SSID_CMDID,
2656 NO_SYNC_WMIFLAG));
2657}
2658
2659A_STATUS
2660wmi_listeninterval_cmd(struct wmi_t *wmip, A_UINT16 listenInterval, A_UINT16 listenBeacons)
2661{
2662 void *osbuf;
2663 WMI_LISTEN_INT_CMD *cmd;
2664
2665 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2666 if (osbuf == NULL) {
2667 return A_NO_MEMORY;
2668 }
2669
2670 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2671
2672 cmd = (WMI_LISTEN_INT_CMD *)(A_NETBUF_DATA(osbuf));
2673 A_MEMZERO(cmd, sizeof(*cmd));
2674 cmd->listenInterval = listenInterval;
2675 cmd->numBeacons = listenBeacons;
2676
2677 return (wmi_cmd_send(wmip, osbuf, WMI_SET_LISTEN_INT_CMDID,
2678 NO_SYNC_WMIFLAG));
2679}
2680
2681A_STATUS
2682wmi_bmisstime_cmd(struct wmi_t *wmip, A_UINT16 bmissTime, A_UINT16 bmissBeacons)
2683{
2684 void *osbuf;
2685 WMI_BMISS_TIME_CMD *cmd;
2686
2687 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2688 if (osbuf == NULL) {
2689 return A_NO_MEMORY;
2690 }
2691
2692 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2693
2694 cmd = (WMI_BMISS_TIME_CMD *)(A_NETBUF_DATA(osbuf));
2695 A_MEMZERO(cmd, sizeof(*cmd));
2696 cmd->bmissTime = bmissTime;
2697 cmd->numBeacons = bmissBeacons;
2698
2699 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BMISS_TIME_CMDID,
2700 NO_SYNC_WMIFLAG));
2701}
2702
2703A_STATUS
2704wmi_associnfo_cmd(struct wmi_t *wmip, A_UINT8 ieType,
2705 A_UINT8 ieLen, A_UINT8 *ieInfo)
2706{
2707 void *osbuf;
2708 WMI_SET_ASSOC_INFO_CMD *cmd;
2709 A_UINT16 cmdLen;
2710
2711 cmdLen = sizeof(*cmd) + ieLen - 1;
2712 osbuf = A_NETBUF_ALLOC(cmdLen);
2713 if (osbuf == NULL) {
2714 return A_NO_MEMORY;
2715 }
2716
2717 A_NETBUF_PUT(osbuf, cmdLen);
2718
2719 cmd = (WMI_SET_ASSOC_INFO_CMD *)(A_NETBUF_DATA(osbuf));
2720 A_MEMZERO(cmd, cmdLen);
2721 cmd->ieType = ieType;
2722 cmd->bufferSize = ieLen;
2723 A_MEMCPY(cmd->assocInfo, ieInfo, ieLen);
2724
2725 return (wmi_cmd_send(wmip, osbuf, WMI_SET_ASSOC_INFO_CMDID,
2726 NO_SYNC_WMIFLAG));
2727}
2728
2729A_STATUS
2730wmi_powermode_cmd(struct wmi_t *wmip, A_UINT8 powerMode)
2731{
2732 void *osbuf;
2733 WMI_POWER_MODE_CMD *cmd;
2734
2735 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2736 if (osbuf == NULL) {
2737 return A_NO_MEMORY;
2738 }
2739
2740 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2741
2742 cmd = (WMI_POWER_MODE_CMD *)(A_NETBUF_DATA(osbuf));
2743 A_MEMZERO(cmd, sizeof(*cmd));
2744 cmd->powerMode = powerMode;
2745 wmip->wmi_powerMode = powerMode;
2746
2747 return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_MODE_CMDID,
2748 NO_SYNC_WMIFLAG));
2749}
2750
2751A_STATUS
2752wmi_ibsspmcaps_cmd(struct wmi_t *wmip, A_UINT8 pmEnable, A_UINT8 ttl,
2753 A_UINT16 atim_windows, A_UINT16 timeout_value)
2754{
2755 void *osbuf;
2756 WMI_IBSS_PM_CAPS_CMD *cmd;
2757
2758 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2759 if (osbuf == NULL) {
2760 return A_NO_MEMORY;
2761 }
2762
2763 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2764
2765 cmd = (WMI_IBSS_PM_CAPS_CMD *)(A_NETBUF_DATA(osbuf));
2766 A_MEMZERO(cmd, sizeof(*cmd));
2767 cmd->power_saving = pmEnable;
2768 cmd->ttl = ttl;
2769 cmd->atim_windows = atim_windows;
2770 cmd->timeout_value = timeout_value;
2771
2772 return (wmi_cmd_send(wmip, osbuf, WMI_SET_IBSS_PM_CAPS_CMDID,
2773 NO_SYNC_WMIFLAG));
2774}
2775
2776A_STATUS
2777wmi_apps_cmd(struct wmi_t *wmip, A_UINT8 psType, A_UINT32 idle_time,
2778 A_UINT32 ps_period, A_UINT8 sleep_period)
2779{
2780 void *osbuf;
2781 WMI_AP_PS_CMD *cmd;
2782
2783 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2784 if (osbuf == NULL) {
2785 return A_NO_MEMORY;
2786 }
2787
2788 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2789
2790 cmd = (WMI_AP_PS_CMD *)(A_NETBUF_DATA(osbuf));
2791 A_MEMZERO(cmd, sizeof(*cmd));
2792 cmd->psType = psType;
2793 cmd->idle_time = idle_time;
2794 cmd->ps_period = ps_period;
2795 cmd->sleep_period = sleep_period;
2796
2797 return (wmi_cmd_send(wmip, osbuf, WMI_SET_AP_PS_CMDID,
2798 NO_SYNC_WMIFLAG));
2799}
2800
2801A_STATUS
2802wmi_pmparams_cmd(struct wmi_t *wmip, A_UINT16 idlePeriod,
2803 A_UINT16 psPollNum, A_UINT16 dtimPolicy,
2804 A_UINT16 tx_wakeup_policy, A_UINT16 num_tx_to_wakeup,
2805 A_UINT16 ps_fail_event_policy)
2806{
2807 void *osbuf;
2808 WMI_POWER_PARAMS_CMD *pm;
2809
2810 osbuf = A_NETBUF_ALLOC(sizeof(*pm));
2811 if (osbuf == NULL) {
2812 return A_NO_MEMORY;
2813 }
2814
2815 A_NETBUF_PUT(osbuf, sizeof(*pm));
2816
2817 pm = (WMI_POWER_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
2818 A_MEMZERO(pm, sizeof(*pm));
2819 pm->idle_period = idlePeriod;
2820 pm->pspoll_number = psPollNum;
2821 pm->dtim_policy = dtimPolicy;
2822 pm->tx_wakeup_policy = tx_wakeup_policy;
2823 pm->num_tx_to_wakeup = num_tx_to_wakeup;
2824 pm->ps_fail_event_policy = ps_fail_event_policy;
2825
2826 return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_PARAMS_CMDID,
2827 NO_SYNC_WMIFLAG));
2828}
2829
2830A_STATUS
2831wmi_disctimeout_cmd(struct wmi_t *wmip, A_UINT8 timeout)
2832{
2833 void *osbuf;
2834 WMI_DISC_TIMEOUT_CMD *cmd;
2835
2836 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2837 if (osbuf == NULL) {
2838 return A_NO_MEMORY;
2839 }
2840
2841 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2842
2843 cmd = (WMI_DISC_TIMEOUT_CMD *)(A_NETBUF_DATA(osbuf));
2844 A_MEMZERO(cmd, sizeof(*cmd));
2845 cmd->disconnectTimeout = timeout;
2846
2847 return (wmi_cmd_send(wmip, osbuf, WMI_SET_DISC_TIMEOUT_CMDID,
2848 NO_SYNC_WMIFLAG));
2849}
2850
2851A_STATUS
2852wmi_addKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex, CRYPTO_TYPE keyType,
2853 A_UINT8 keyUsage, A_UINT8 keyLength, A_UINT8 *keyRSC,
2854 A_UINT8 *keyMaterial, A_UINT8 key_op_ctrl, A_UINT8 *macAddr,
2855 WMI_SYNC_FLAG sync_flag)
2856{
2857 void *osbuf;
2858 WMI_ADD_CIPHER_KEY_CMD *cmd;
2859
2860 if ((keyIndex > WMI_MAX_KEY_INDEX) || (keyLength > WMI_MAX_KEY_LEN) ||
2861 (keyMaterial == NULL))
2862 {
2863 return A_EINVAL;
2864 }
2865
2866 if ((WEP_CRYPT != keyType) && (NULL == keyRSC)) {
2867 return A_EINVAL;
2868 }
2869
2870 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2871 if (osbuf == NULL) {
2872 return A_NO_MEMORY;
2873 }
2874
2875 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2876
2877 cmd = (WMI_ADD_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf));
2878 A_MEMZERO(cmd, sizeof(*cmd));
2879 cmd->keyIndex = keyIndex;
2880 cmd->keyType = keyType;
2881 cmd->keyUsage = keyUsage;
2882 cmd->keyLength = keyLength;
2883 A_MEMCPY(cmd->key, keyMaterial, keyLength);
2884#ifdef WAPI_ENABLE
2885 if (NULL != keyRSC && key_op_ctrl != KEY_OP_INIT_WAPIPN) {
2886#else
2887 if (NULL != keyRSC) {
2888#endif
2889 A_MEMCPY(cmd->keyRSC, keyRSC, sizeof(cmd->keyRSC));
2890 }
2891 cmd->key_op_ctrl = key_op_ctrl;
2892
2893 if(macAddr) {
2894 A_MEMCPY(cmd->key_macaddr,macAddr,IEEE80211_ADDR_LEN);
2895 }
2896
2897 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_CIPHER_KEY_CMDID, sync_flag));
2898}
2899
2900A_STATUS
2901wmi_add_krk_cmd(struct wmi_t *wmip, A_UINT8 *krk)
2902{
2903 void *osbuf;
2904 WMI_ADD_KRK_CMD *cmd;
2905
2906 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2907 if (osbuf == NULL) {
2908 return A_NO_MEMORY;
2909 }
2910
2911 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2912
2913 cmd = (WMI_ADD_KRK_CMD *)(A_NETBUF_DATA(osbuf));
2914 A_MEMZERO(cmd, sizeof(*cmd));
2915 A_MEMCPY(cmd->krk, krk, WMI_KRK_LEN);
2916
2917 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_KRK_CMDID, NO_SYNC_WMIFLAG));
2918}
2919
2920A_STATUS
2921wmi_delete_krk_cmd(struct wmi_t *wmip)
2922{
2923 return wmi_simple_cmd(wmip, WMI_DELETE_KRK_CMDID);
2924}
2925
2926A_STATUS
2927wmi_deleteKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex)
2928{
2929 void *osbuf;
2930 WMI_DELETE_CIPHER_KEY_CMD *cmd;
2931
2932 if (keyIndex > WMI_MAX_KEY_INDEX) {
2933 return A_EINVAL;
2934 }
2935
2936 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2937 if (osbuf == NULL) {
2938 return A_NO_MEMORY;
2939 }
2940
2941 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2942
2943 cmd = (WMI_DELETE_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf));
2944 A_MEMZERO(cmd, sizeof(*cmd));
2945 cmd->keyIndex = keyIndex;
2946
2947 return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_CIPHER_KEY_CMDID,
2948 NO_SYNC_WMIFLAG));
2949}
2950
2951A_STATUS
2952wmi_setPmkid_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT8 *pmkId,
2953 A_BOOL set)
2954{
2955 void *osbuf;
2956 WMI_SET_PMKID_CMD *cmd;
2957
2958 if (bssid == NULL) {
2959 return A_EINVAL;
2960 }
2961
2962 if ((set == TRUE) && (pmkId == NULL)) {
2963 return A_EINVAL;
2964 }
2965
2966 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2967 if (osbuf == NULL) {
2968 return A_NO_MEMORY;
2969 }
2970
2971 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2972
2973 cmd = (WMI_SET_PMKID_CMD *)(A_NETBUF_DATA(osbuf));
2974 A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid));
2975 if (set == TRUE) {
2976 A_MEMCPY(cmd->pmkid, pmkId, sizeof(cmd->pmkid));
2977 cmd->enable = PMKID_ENABLE;
2978 } else {
2979 A_MEMZERO(cmd->pmkid, sizeof(cmd->pmkid));
2980 cmd->enable = PMKID_DISABLE;
2981 }
2982
2983 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_CMDID, NO_SYNC_WMIFLAG));
2984}
2985
2986A_STATUS
2987wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, A_BOOL en)
2988{
2989 void *osbuf;
2990 WMI_SET_TKIP_COUNTERMEASURES_CMD *cmd;
2991
2992 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2993 if (osbuf == NULL) {
2994 return A_NO_MEMORY;
2995 }
2996
2997 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2998
2999 cmd = (WMI_SET_TKIP_COUNTERMEASURES_CMD *)(A_NETBUF_DATA(osbuf));
3000 cmd->cm_en = (en == TRUE)? WMI_TKIP_CM_ENABLE : WMI_TKIP_CM_DISABLE;
3001
3002 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TKIP_COUNTERMEASURES_CMDID,
3003 NO_SYNC_WMIFLAG));
3004}
3005
3006A_STATUS
3007wmi_set_akmp_params_cmd(struct wmi_t *wmip,
3008 WMI_SET_AKMP_PARAMS_CMD *akmpParams)
3009{
3010 void *osbuf;
3011 WMI_SET_AKMP_PARAMS_CMD *cmd;
3012
3013 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3014 if (osbuf == NULL) {
3015 return A_NO_MEMORY;
3016 }
3017
3018 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3019 cmd = (WMI_SET_AKMP_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
3020 cmd->akmpInfo = akmpParams->akmpInfo;
3021
3022 return (wmi_cmd_send(wmip, osbuf, WMI_SET_AKMP_PARAMS_CMDID,
3023 NO_SYNC_WMIFLAG));
3024}
3025
3026A_STATUS
3027wmi_set_pmkid_list_cmd(struct wmi_t *wmip,
3028 WMI_SET_PMKID_LIST_CMD *pmkInfo)
3029{
3030 void *osbuf;
3031 WMI_SET_PMKID_LIST_CMD *cmd;
3032 A_UINT16 cmdLen;
3033 A_UINT8 i;
3034
3035 cmdLen = sizeof(pmkInfo->numPMKID) +
3036 pmkInfo->numPMKID * sizeof(WMI_PMKID);
3037
3038 osbuf = A_NETBUF_ALLOC(cmdLen);
3039 if (osbuf == NULL) {
3040 return A_NO_MEMORY;
3041 }
3042
3043 A_NETBUF_PUT(osbuf, cmdLen);
3044 cmd = (WMI_SET_PMKID_LIST_CMD *)(A_NETBUF_DATA(osbuf));
3045 cmd->numPMKID = pmkInfo->numPMKID;
3046
3047 for (i = 0; i < cmd->numPMKID; i++) {
3048 A_MEMCPY(&cmd->pmkidList[i], &pmkInfo->pmkidList[i],
3049 WMI_PMKID_LEN);
3050 }
3051
3052 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_LIST_CMDID,
3053 NO_SYNC_WMIFLAG));
3054}
3055
3056A_STATUS
3057wmi_get_pmkid_list_cmd(struct wmi_t *wmip)
3058{
3059 return wmi_simple_cmd(wmip, WMI_GET_PMKID_LIST_CMDID);
3060}
3061
3062A_STATUS
3063wmi_dataSync_send(struct wmi_t *wmip, void *osbuf, HTC_ENDPOINT_ID eid)
3064{
3065 WMI_DATA_HDR *dtHdr;
3066
3067 A_ASSERT( eid != wmip->wmi_endpoint_id);
3068 A_ASSERT(osbuf != NULL);
3069
3070 if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != A_OK) {
3071 return A_NO_MEMORY;
3072 }
3073
3074 dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf);
3075 dtHdr->info =
3076 (SYNC_MSGTYPE & WMI_DATA_HDR_MSG_TYPE_MASK) << WMI_DATA_HDR_MSG_TYPE_SHIFT;
3077
3078 A_DPRINTF(DBG_WMI, (DBGFMT "Enter - eid %d\n", DBGARG, eid));
3079
3080 return (A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid));
3081}
3082
3083typedef struct _WMI_DATA_SYNC_BUFS {
3084 A_UINT8 trafficClass;
3085 void *osbuf;
3086}WMI_DATA_SYNC_BUFS;
3087
3088static A_STATUS
3089wmi_sync_point(struct wmi_t *wmip)
3090{
3091 void *cmd_osbuf;
3092 WMI_SYNC_CMD *cmd;
3093 WMI_DATA_SYNC_BUFS dataSyncBufs[WMM_NUM_AC];
3094 A_UINT8 i,numPriStreams=0;
3095 A_STATUS status = A_OK;
3096
3097 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
3098
3099 memset(dataSyncBufs,0,sizeof(dataSyncBufs));
3100
3101
3102 LOCK_WMI(wmip);
3103
3104 for (i=0; i < WMM_NUM_AC ; i++) {
3105 if (wmip->wmi_fatPipeExists & (1 << i)) {
3106 numPriStreams++;
3107 dataSyncBufs[numPriStreams-1].trafficClass = i;
3108 }
3109 }
3110
3111 UNLOCK_WMI(wmip);
3112
3113
3114
3115 do {
3116
3117
3118
3119
3120 cmd_osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3121 if (cmd_osbuf == NULL) {
3122 status = A_NO_MEMORY;
3123 break;
3124 }
3125
3126 A_NETBUF_PUT(cmd_osbuf, sizeof(*cmd));
3127
3128 cmd = (WMI_SYNC_CMD *)(A_NETBUF_DATA(cmd_osbuf));
3129 A_MEMZERO(cmd, sizeof(*cmd));
3130
3131
3132
3133
3134 cmd->dataSyncMap = wmip->wmi_fatPipeExists;
3135
3136 for (i=0; i < numPriStreams ; i++) {
3137 dataSyncBufs[i].osbuf = A_NETBUF_ALLOC(0);
3138 if (dataSyncBufs[i].osbuf == NULL) {
3139 status = A_NO_MEMORY;
3140 break;
3141 }
3142 }
3143
3144
3145
3146
3147 if (A_FAILED(status)) {
3148 break;
3149 }
3150
3151
3152
3153
3154
3155 status = wmi_cmd_send(wmip, cmd_osbuf, WMI_SYNCHRONIZE_CMDID,
3156 NO_SYNC_WMIFLAG);
3157
3158 if (A_FAILED(status)) {
3159 break;
3160 }
3161
3162 cmd_osbuf = NULL;
3163
3164 for(i=0; i < numPriStreams; i++) {
3165 A_ASSERT(dataSyncBufs[i].osbuf != NULL);
3166 status = wmi_dataSync_send(wmip,
3167 dataSyncBufs[i].osbuf,
3168 A_WMI_Ac2EndpointID(wmip->wmi_devt,
3169 dataSyncBufs[i].
3170 trafficClass)
3171 );
3172
3173 if (A_FAILED(status)) {
3174 break;
3175 }
3176
3177
3178 dataSyncBufs[i].osbuf = NULL;
3179 }
3180
3181 } while(FALSE);
3182
3183
3184
3185 if (cmd_osbuf != NULL) {
3186 A_NETBUF_FREE(cmd_osbuf);
3187 }
3188
3189 for (i = 0; i < numPriStreams; i++) {
3190 if (dataSyncBufs[i].osbuf != NULL) {
3191 A_NETBUF_FREE(dataSyncBufs[i].osbuf);
3192 }
3193 }
3194
3195 return (status);
3196}
3197
3198A_STATUS
3199wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *params)
3200{
3201 void *osbuf;
3202 WMI_CREATE_PSTREAM_CMD *cmd;
3203 A_UINT8 fatPipeExistsForAC=0;
3204 A_INT32 minimalPHY = 0;
3205 A_INT32 nominalPHY = 0;
3206
3207
3208 if( !((params->userPriority < 8) &&
3209 (params->userPriority <= 0x7) &&
3210 (convert_userPriority_to_trafficClass(params->userPriority) == params->trafficClass) &&
3211 (params->trafficDirection == UPLINK_TRAFFIC ||
3212 params->trafficDirection == DNLINK_TRAFFIC ||
3213 params->trafficDirection == BIDIR_TRAFFIC) &&
3214 (params->trafficType == TRAFFIC_TYPE_APERIODIC ||
3215 params->trafficType == TRAFFIC_TYPE_PERIODIC ) &&
3216 (params->voicePSCapability == DISABLE_FOR_THIS_AC ||
3217 params->voicePSCapability == ENABLE_FOR_THIS_AC ||
3218 params->voicePSCapability == ENABLE_FOR_ALL_AC) &&
3219 (params->tsid == WMI_IMPLICIT_PSTREAM || params->tsid <= WMI_MAX_THINSTREAM)) )
3220 {
3221 return A_EINVAL;
3222 }
3223
3224
3225
3226
3227
3228
3229
3230 minimalPHY = ((params->minPhyRate / 1000)/1000);
3231
3232
3233
3234 if (params->nominalPHY >= minimalPHY)
3235 {
3236 nominalPHY = (params->nominalPHY * 1000)/500;
3237 A_DPRINTF(DBG_WMI,
3238 (DBGFMT "TSRS IE Enabled::MinPhy %x->NominalPhy ===> %x\n", DBGARG,
3239 minimalPHY, nominalPHY));
3240
3241 params->nominalPHY = nominalPHY;
3242 }
3243 else
3244 {
3245 params->nominalPHY = 0;
3246 }
3247
3248 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3249 if (osbuf == NULL) {
3250 return A_NO_MEMORY;
3251 }
3252
3253 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3254
3255 A_DPRINTF(DBG_WMI,
3256 (DBGFMT "Sending create_pstream_cmd: ac=%d tsid:%d\n", DBGARG,
3257 params->trafficClass, params->tsid));
3258
3259 cmd = (WMI_CREATE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf));
3260 A_MEMZERO(cmd, sizeof(*cmd));
3261 A_MEMCPY(cmd, params, sizeof(*cmd));
3262
3263
3264 if ((A_UINT32)params->tsid == (A_UINT32)WMI_IMPLICIT_PSTREAM) {
3265 LOCK_WMI(wmip);
3266 fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass));
3267 wmip->wmi_fatPipeExists |= (1<<params->trafficClass);
3268 UNLOCK_WMI(wmip);
3269 } else {
3270
3271 LOCK_WMI(wmip);
3272 fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass));
3273 wmip->wmi_streamExistsForAC[params->trafficClass] |= (1<<params->tsid);
3274
3275
3276
3277 wmip->wmi_fatPipeExists |= (1<<params->trafficClass);
3278 UNLOCK_WMI(wmip);
3279 }
3280
3281
3282
3283
3284
3285 if (!fatPipeExistsForAC) {
3286 A_WMI_STREAM_TX_ACTIVE(wmip->wmi_devt, params->trafficClass);
3287 }
3288
3289
3290 return (wmi_cmd_send(wmip, osbuf, WMI_CREATE_PSTREAM_CMDID,
3291 NO_SYNC_WMIFLAG));
3292}
3293
3294A_STATUS
3295wmi_delete_pstream_cmd(struct wmi_t *wmip, A_UINT8 trafficClass, A_UINT8 tsid)
3296{
3297 void *osbuf;
3298 WMI_DELETE_PSTREAM_CMD *cmd;
3299 A_STATUS status;
3300 A_UINT16 activeTsids=0;
3301
3302
3303 if (trafficClass > 3) {
3304 A_DPRINTF(DBG_WMI, (DBGFMT "Invalid trafficClass: %d\n", DBGARG, trafficClass));
3305 return A_EINVAL;
3306 }
3307
3308 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3309 if (osbuf == NULL) {
3310 return A_NO_MEMORY;
3311 }
3312
3313 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3314
3315 cmd = (WMI_DELETE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf));
3316 A_MEMZERO(cmd, sizeof(*cmd));
3317
3318 cmd->trafficClass = trafficClass;
3319 cmd->tsid = tsid;
3320
3321 LOCK_WMI(wmip);
3322 activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
3323 UNLOCK_WMI(wmip);
3324
3325
3326 if (!(activeTsids & (1<<tsid))) {
3327
3328 A_NETBUF_FREE(osbuf);
3329 A_DPRINTF(DBG_WMI,
3330 (DBGFMT "TSID %d does'nt exist for trafficClass: %d\n", DBGARG, tsid, trafficClass));
3331
3332 return A_ERROR;
3333 }
3334
3335 A_DPRINTF(DBG_WMI,
3336 (DBGFMT "Sending delete_pstream_cmd: trafficClass: %d tsid=%d\n", DBGARG, trafficClass, tsid));
3337
3338 status = (wmi_cmd_send(wmip, osbuf, WMI_DELETE_PSTREAM_CMDID,
3339 SYNC_BEFORE_WMIFLAG));
3340
3341 LOCK_WMI(wmip);
3342 wmip->wmi_streamExistsForAC[trafficClass] &= ~(1<<tsid);
3343 activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
3344 UNLOCK_WMI(wmip);
3345
3346
3347
3348
3349
3350 if(!activeTsids) {
3351 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, trafficClass);
3352 wmip->wmi_fatPipeExists &= ~(1<<trafficClass);
3353 }
3354
3355 return status;
3356}
3357
3358A_STATUS
3359wmi_set_framerate_cmd(struct wmi_t *wmip, A_UINT8 bEnable, A_UINT8 type, A_UINT8 subType, A_UINT16 rateMask)
3360{
3361 void *osbuf;
3362 WMI_FRAME_RATES_CMD *cmd;
3363 A_UINT8 frameType;
3364
3365 A_DPRINTF(DBG_WMI,
3366 (DBGFMT " type %02X, subType %02X, rateMask %04x\n", DBGARG, type, subType, rateMask));
3367
3368 if((type != IEEE80211_FRAME_TYPE_MGT && type != IEEE80211_FRAME_TYPE_CTL) ||
3369 (subType > 15)){
3370
3371 return A_EINVAL;
3372 }
3373
3374 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3375 if (osbuf == NULL) {
3376 return A_NO_MEMORY;
3377 }
3378
3379 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3380
3381 cmd = (WMI_FRAME_RATES_CMD *)(A_NETBUF_DATA(osbuf));
3382 A_MEMZERO(cmd, sizeof(*cmd));
3383
3384 frameType = (A_UINT8)((subType << 4) | type);
3385
3386 cmd->bEnableMask = bEnable;
3387 cmd->frameType = frameType;
3388 cmd->frameRateMask = rateMask;
3389
3390 return (wmi_cmd_send(wmip, osbuf, WMI_SET_FRAMERATES_CMDID, NO_SYNC_WMIFLAG));
3391}
3392
3393
3394
3395
3396
3397A_STATUS
3398wmi_set_bitrate_cmd(struct wmi_t *wmip, A_INT32 dataRate, A_INT32 mgmtRate, A_INT32 ctlRate)
3399{
3400 void *osbuf;
3401 WMI_BIT_RATE_CMD *cmd;
3402 A_INT8 drix, mrix, crix, ret_val;
3403
3404 if (dataRate != -1) {
3405 ret_val = wmi_validate_bitrate(wmip, dataRate, &drix);
3406 if(ret_val == A_EINVAL){
3407 return A_EINVAL;
3408 }
3409 } else {
3410 drix = -1;
3411 }
3412
3413 if (mgmtRate != -1) {
3414 ret_val = wmi_validate_bitrate(wmip, mgmtRate, &mrix);
3415 if(ret_val == A_EINVAL){
3416 return A_EINVAL;
3417 }
3418 } else {
3419 mrix = -1;
3420 }
3421 if (ctlRate != -1) {
3422 ret_val = wmi_validate_bitrate(wmip, ctlRate, &crix);
3423 if(ret_val == A_EINVAL){
3424 return A_EINVAL;
3425 }
3426 } else {
3427 crix = -1;
3428 }
3429 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3430 if (osbuf == NULL) {
3431 return A_NO_MEMORY;
3432 }
3433
3434 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3435
3436 cmd = (WMI_BIT_RATE_CMD *)(A_NETBUF_DATA(osbuf));
3437 A_MEMZERO(cmd, sizeof(*cmd));
3438
3439 cmd->rateIndex = drix;
3440 cmd->mgmtRateIndex = mrix;
3441 cmd->ctlRateIndex = crix;
3442
3443
3444 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BITRATE_CMDID, NO_SYNC_WMIFLAG));
3445}
3446
3447A_STATUS
3448wmi_get_bitrate_cmd(struct wmi_t *wmip)
3449{
3450 return wmi_simple_cmd(wmip, WMI_GET_BITRATE_CMDID);
3451}
3452
3453
3454
3455
3456A_BOOL
3457wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_INT32 rateIndex)
3458{
3459 WMI_PHY_MODE phyMode = (WMI_PHY_MODE) wmip->wmi_phyMode;
3460 A_BOOL isValid = TRUE;
3461 switch(phyMode) {
3462 case WMI_11A_MODE:
3463 if (wmip->wmi_ht_allowed[A_BAND_5GHZ]){
3464 if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
3465 isValid = FALSE;
3466 }
3467 } else {
3468 if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_A_SUPPORT_RATE_STOP)) {
3469 isValid = FALSE;
3470 }
3471 }
3472 break;
3473
3474 case WMI_11B_MODE:
3475 if ((rateIndex < MODE_B_SUPPORT_RATE_START) || (rateIndex > MODE_B_SUPPORT_RATE_STOP)) {
3476 isValid = FALSE;
3477 }
3478 break;
3479
3480 case WMI_11GONLY_MODE:
3481 if (wmip->wmi_ht_allowed[A_BAND_24GHZ]){
3482 if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
3483 isValid = FALSE;
3484 }
3485 } else {
3486 if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE_GONLY_SUPPORT_RATE_STOP)) {
3487 isValid = FALSE;
3488 }
3489 }
3490 break;
3491
3492 case WMI_11G_MODE:
3493 case WMI_11AG_MODE:
3494 if (wmip->wmi_ht_allowed[A_BAND_24GHZ]){
3495 if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
3496 isValid = FALSE;
3497 }
3498 } else {
3499 if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_G_SUPPORT_RATE_STOP)) {
3500 isValid = FALSE;
3501 }
3502 }
3503 break;
3504 default:
3505 A_ASSERT(FALSE);
3506 break;
3507 }
3508
3509 return isValid;
3510}
3511
3512A_INT8
3513wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate, A_INT8 *rate_idx)
3514{
3515 A_INT8 i;
3516
3517 for (i=0;;i++)
3518 {
3519 if (wmi_rateTable[(A_UINT32) i][0] == 0) {
3520 return A_EINVAL;
3521 }
3522 if (wmi_rateTable[(A_UINT32) i][0] == rate) {
3523 break;
3524 }
3525 }
3526
3527 if(wmi_is_bitrate_index_valid(wmip, (A_INT32) i) != TRUE) {
3528 return A_EINVAL;
3529 }
3530
3531 *rate_idx = i;
3532 return A_OK;
3533}
3534
3535A_STATUS
3536wmi_set_fixrates_cmd(struct wmi_t *wmip, A_UINT32 fixRatesMask)
3537{
3538 void *osbuf;
3539 WMI_FIX_RATES_CMD *cmd;
3540#if 0
3541 A_INT32 rateIndex;
3542
3543
3544
3545
3546
3547
3548
3549 for(rateIndex = 0; rateIndex < MAX_NUMBER_OF_SUPPORT_RATES; rateIndex++) {
3550 if((1 << rateIndex) & (A_UINT32)fixRatesMask) {
3551 if(wmi_is_bitrate_index_valid(wmip, rateIndex) != TRUE) {
3552 A_DPRINTF(DBG_WMI, (DBGFMT "Set Fix Rates command failed: Given rate is illegal in current PHY mode\n", DBGARG));
3553 return A_EINVAL;
3554 }
3555 }
3556 }
3557#endif
3558
3559
3560 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3561 if (osbuf == NULL) {
3562 return A_NO_MEMORY;
3563 }
3564
3565 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3566
3567 cmd = (WMI_FIX_RATES_CMD *)(A_NETBUF_DATA(osbuf));
3568 A_MEMZERO(cmd, sizeof(*cmd));
3569
3570 cmd->fixRateMask = fixRatesMask;
3571
3572 return (wmi_cmd_send(wmip, osbuf, WMI_SET_FIXRATES_CMDID, NO_SYNC_WMIFLAG));
3573}
3574
3575A_STATUS
3576wmi_get_ratemask_cmd(struct wmi_t *wmip)
3577{
3578 return wmi_simple_cmd(wmip, WMI_GET_FIXRATES_CMDID);
3579}
3580
3581A_STATUS
3582wmi_get_channelList_cmd(struct wmi_t *wmip)
3583{
3584 return wmi_simple_cmd(wmip, WMI_GET_CHANNEL_LIST_CMDID);
3585}
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597A_STATUS
3598wmi_set_channelParams_cmd(struct wmi_t *wmip, A_UINT8 scanParam,
3599 WMI_PHY_MODE mode, A_INT8 numChan,
3600 A_UINT16 *channelList)
3601{
3602 void *osbuf;
3603 WMI_CHANNEL_PARAMS_CMD *cmd;
3604 A_INT8 size;
3605
3606 size = sizeof (*cmd);
3607
3608 if (numChan) {
3609 if (numChan > WMI_MAX_CHANNELS) {
3610 return A_EINVAL;
3611 }
3612 size += sizeof(A_UINT16) * (numChan - 1);
3613 }
3614
3615 osbuf = A_NETBUF_ALLOC(size);
3616 if (osbuf == NULL) {
3617 return A_NO_MEMORY;
3618 }
3619
3620 A_NETBUF_PUT(osbuf, size);
3621
3622 cmd = (WMI_CHANNEL_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
3623 A_MEMZERO(cmd, size);
3624
3625 wmip->wmi_phyMode = mode;
3626 cmd->scanParam = scanParam;
3627 cmd->phyMode = mode;
3628 cmd->numChannels = numChan;
3629 A_MEMCPY(cmd->channelList, channelList, numChan * sizeof(A_UINT16));
3630
3631 return (wmi_cmd_send(wmip, osbuf, WMI_SET_CHANNEL_PARAMS_CMDID,
3632 NO_SYNC_WMIFLAG));
3633}
3634
3635void
3636wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
3637{
3638 SQ_THRESHOLD_PARAMS *sq_thresh =
3639 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI];
3640
3641
3642
3643
3644 sq_thresh->weight = rssiCmd->weight;
3645 sq_thresh->polling_interval = rssiCmd->pollTime;
3646
3647 sq_thresh->upper_threshold[0] = rssiCmd->thresholdAbove1_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3648 sq_thresh->upper_threshold[1] = rssiCmd->thresholdAbove2_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3649 sq_thresh->upper_threshold[2] = rssiCmd->thresholdAbove3_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3650 sq_thresh->upper_threshold[3] = rssiCmd->thresholdAbove4_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3651 sq_thresh->upper_threshold[4] = rssiCmd->thresholdAbove5_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3652 sq_thresh->upper_threshold[5] = rssiCmd->thresholdAbove6_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3653 sq_thresh->upper_threshold_valid_count = 6;
3654
3655
3656 sq_thresh->lower_threshold[0] = rssiCmd->thresholdBelow6_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3657 sq_thresh->lower_threshold[1] = rssiCmd->thresholdBelow5_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3658 sq_thresh->lower_threshold[2] = rssiCmd->thresholdBelow4_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3659 sq_thresh->lower_threshold[3] = rssiCmd->thresholdBelow3_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3660 sq_thresh->lower_threshold[4] = rssiCmd->thresholdBelow2_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3661 sq_thresh->lower_threshold[5] = rssiCmd->thresholdBelow1_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3662 sq_thresh->lower_threshold_valid_count = 6;
3663
3664 if (!rssi_event_value) {
3665
3666
3667
3668
3669
3670 rssiCmd->thresholdAbove1_Val = sq_thresh->upper_threshold[0];
3671 rssiCmd->thresholdBelow1_Val = sq_thresh->lower_threshold[0];
3672 } else {
3673
3674
3675
3676
3677 rssiCmd->thresholdAbove1_Val = ar6000_get_upper_threshold(rssi_event_value, sq_thresh,
3678 sq_thresh->upper_threshold_valid_count);
3679 rssiCmd->thresholdBelow1_Val = ar6000_get_lower_threshold(rssi_event_value, sq_thresh,
3680 sq_thresh->lower_threshold_valid_count);
3681}
3682}
3683
3684A_STATUS
3685wmi_set_rssi_threshold_params(struct wmi_t *wmip,
3686 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
3687{
3688
3689
3690 if( rssiCmd->thresholdAbove6_Val <= rssiCmd->thresholdAbove5_Val ||
3691 rssiCmd->thresholdAbove5_Val <= rssiCmd->thresholdAbove4_Val ||
3692 rssiCmd->thresholdAbove4_Val <= rssiCmd->thresholdAbove3_Val ||
3693 rssiCmd->thresholdAbove3_Val <= rssiCmd->thresholdAbove2_Val ||
3694 rssiCmd->thresholdAbove2_Val <= rssiCmd->thresholdAbove1_Val ||
3695 rssiCmd->thresholdBelow6_Val <= rssiCmd->thresholdBelow5_Val ||
3696 rssiCmd->thresholdBelow5_Val <= rssiCmd->thresholdBelow4_Val ||
3697 rssiCmd->thresholdBelow4_Val <= rssiCmd->thresholdBelow3_Val ||
3698 rssiCmd->thresholdBelow3_Val <= rssiCmd->thresholdBelow2_Val ||
3699 rssiCmd->thresholdBelow2_Val <= rssiCmd->thresholdBelow1_Val)
3700 {
3701 return A_EINVAL;
3702 }
3703
3704 wmi_cache_configure_rssithreshold(wmip, rssiCmd);
3705
3706 return (wmi_send_rssi_threshold_params(wmip, rssiCmd));
3707}
3708
3709A_STATUS
3710wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *ipCmd)
3711{
3712 void *osbuf;
3713 WMI_SET_IP_CMD *cmd;
3714
3715
3716 if((*((A_UINT8*)&ipCmd->ips[0]) >= 0xE0) ||
3717 (*((A_UINT8*)&ipCmd->ips[1]) >= 0xE0)) {
3718 return A_EINVAL;
3719 }
3720
3721 osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_IP_CMD));
3722 if (osbuf == NULL) {
3723 return A_NO_MEMORY;
3724 }
3725
3726 A_NETBUF_PUT(osbuf, sizeof(WMI_SET_IP_CMD));
3727 cmd = (WMI_SET_IP_CMD *)(A_NETBUF_DATA(osbuf));
3728 A_MEMCPY(cmd, ipCmd, sizeof(WMI_SET_IP_CMD));
3729
3730 return (wmi_cmd_send(wmip, osbuf, WMI_SET_IP_CMDID,
3731 NO_SYNC_WMIFLAG));
3732}
3733
3734A_STATUS
3735wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip,
3736 WMI_SET_HOST_SLEEP_MODE_CMD *hostModeCmd)
3737{
3738 void *osbuf;
3739 A_INT8 size;
3740 WMI_SET_HOST_SLEEP_MODE_CMD *cmd;
3741 A_UINT16 activeTsids=0;
3742 A_UINT8 streamExists=0;
3743 A_UINT8 i;
3744
3745 if( hostModeCmd->awake == hostModeCmd->asleep) {
3746 return A_EINVAL;
3747 }
3748
3749 size = sizeof (*cmd);
3750
3751 osbuf = A_NETBUF_ALLOC(size);
3752 if (osbuf == NULL) {
3753 return A_NO_MEMORY;
3754 }
3755
3756 A_NETBUF_PUT(osbuf, size);
3757
3758 cmd = (WMI_SET_HOST_SLEEP_MODE_CMD *)(A_NETBUF_DATA(osbuf));
3759 A_MEMZERO(cmd, size);
3760 A_MEMCPY(cmd, hostModeCmd, sizeof(WMI_SET_HOST_SLEEP_MODE_CMD));
3761
3762 if(hostModeCmd->asleep) {
3763
3764
3765
3766
3767
3768 LOCK_WMI(wmip);
3769 streamExists = wmip->wmi_fatPipeExists;
3770 UNLOCK_WMI(wmip);
3771
3772 for(i=0;i< WMM_NUM_AC;i++) {
3773 if (streamExists & (1<<i)) {
3774 LOCK_WMI(wmip);
3775 activeTsids = wmip->wmi_streamExistsForAC[i];
3776 UNLOCK_WMI(wmip);
3777
3778 if(!activeTsids) {
3779 streamExists &= ~(1<<i);
3780
3781 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt,i);
3782 }
3783 }
3784 }
3785
3786
3787 LOCK_WMI(wmip);
3788 wmip->wmi_fatPipeExists = streamExists;
3789 UNLOCK_WMI(wmip);
3790 }
3791
3792 return (wmi_cmd_send(wmip, osbuf, WMI_SET_HOST_SLEEP_MODE_CMDID,
3793 NO_SYNC_WMIFLAG));
3794}
3795
3796A_STATUS
3797wmi_set_wow_mode_cmd(struct wmi_t *wmip,
3798 WMI_SET_WOW_MODE_CMD *wowModeCmd)
3799{
3800 void *osbuf;
3801 A_INT8 size;
3802 WMI_SET_WOW_MODE_CMD *cmd;
3803
3804 size = sizeof (*cmd);
3805
3806 osbuf = A_NETBUF_ALLOC(size);
3807 if (osbuf == NULL) {
3808 return A_NO_MEMORY;
3809 }
3810
3811 A_NETBUF_PUT(osbuf, size);
3812
3813 cmd = (WMI_SET_WOW_MODE_CMD *)(A_NETBUF_DATA(osbuf));
3814 A_MEMZERO(cmd, size);
3815 A_MEMCPY(cmd, wowModeCmd, sizeof(WMI_SET_WOW_MODE_CMD));
3816
3817 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WOW_MODE_CMDID,
3818 NO_SYNC_WMIFLAG));
3819
3820}
3821
3822A_STATUS
3823wmi_get_wow_list_cmd(struct wmi_t *wmip,
3824 WMI_GET_WOW_LIST_CMD *wowListCmd)
3825{
3826 void *osbuf;
3827 A_INT8 size;
3828 WMI_GET_WOW_LIST_CMD *cmd;
3829
3830 size = sizeof (*cmd);
3831
3832 osbuf = A_NETBUF_ALLOC(size);
3833 if (osbuf == NULL) {
3834 return A_NO_MEMORY;
3835 }
3836
3837 A_NETBUF_PUT(osbuf, size);
3838
3839 cmd = (WMI_GET_WOW_LIST_CMD *)(A_NETBUF_DATA(osbuf));
3840 A_MEMZERO(cmd, size);
3841 A_MEMCPY(cmd, wowListCmd, sizeof(WMI_GET_WOW_LIST_CMD));
3842
3843 return (wmi_cmd_send(wmip, osbuf, WMI_GET_WOW_LIST_CMDID,
3844 NO_SYNC_WMIFLAG));
3845
3846}
3847
3848static A_STATUS
3849wmi_get_wow_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
3850{
3851 WMI_GET_WOW_LIST_REPLY *reply;
3852
3853 if (len < sizeof(WMI_GET_WOW_LIST_REPLY)) {
3854 return A_EINVAL;
3855 }
3856 reply = (WMI_GET_WOW_LIST_REPLY *)datap;
3857
3858 A_WMI_WOW_LIST_EVENT(wmip->wmi_devt, reply->num_filters,
3859 reply);
3860
3861 return A_OK;
3862}
3863
3864A_STATUS wmi_add_wow_pattern_cmd(struct wmi_t *wmip,
3865 WMI_ADD_WOW_PATTERN_CMD *addWowCmd,
3866 A_UINT8* pattern, A_UINT8* mask,
3867 A_UINT8 pattern_size)
3868{
3869 void *osbuf;
3870 A_INT8 size;
3871 WMI_ADD_WOW_PATTERN_CMD *cmd;
3872 A_UINT8 *filter_mask = NULL;
3873
3874 size = sizeof (*cmd);
3875
3876 size += ((2 * addWowCmd->filter_size)* sizeof(A_UINT8));
3877 osbuf = A_NETBUF_ALLOC(size);
3878 if (osbuf == NULL) {
3879 return A_NO_MEMORY;
3880 }
3881
3882 A_NETBUF_PUT(osbuf, size);
3883
3884 cmd = (WMI_ADD_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf));
3885 cmd->filter_list_id = addWowCmd->filter_list_id;
3886 cmd->filter_offset = addWowCmd->filter_offset;
3887 cmd->filter_size = addWowCmd->filter_size;
3888
3889 A_MEMCPY(cmd->filter, pattern, addWowCmd->filter_size);
3890
3891 filter_mask = (A_UINT8*)(cmd->filter + cmd->filter_size);
3892 A_MEMCPY(filter_mask, mask, addWowCmd->filter_size);
3893
3894
3895 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_WOW_PATTERN_CMDID,
3896 NO_SYNC_WMIFLAG));
3897}
3898
3899A_STATUS
3900wmi_del_wow_pattern_cmd(struct wmi_t *wmip,
3901 WMI_DEL_WOW_PATTERN_CMD *delWowCmd)
3902{
3903 void *osbuf;
3904 A_INT8 size;
3905 WMI_DEL_WOW_PATTERN_CMD *cmd;
3906
3907 size = sizeof (*cmd);
3908
3909 osbuf = A_NETBUF_ALLOC(size);
3910 if (osbuf == NULL) {
3911 return A_NO_MEMORY;
3912 }
3913
3914 A_NETBUF_PUT(osbuf, size);
3915
3916 cmd = (WMI_DEL_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf));
3917 A_MEMZERO(cmd, size);
3918 A_MEMCPY(cmd, delWowCmd, sizeof(WMI_DEL_WOW_PATTERN_CMD));
3919
3920 return (wmi_cmd_send(wmip, osbuf, WMI_DEL_WOW_PATTERN_CMDID,
3921 NO_SYNC_WMIFLAG));
3922
3923}
3924
3925void
3926wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
3927{
3928 SQ_THRESHOLD_PARAMS *sq_thresh =
3929 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_SNR];
3930
3931
3932
3933
3934 sq_thresh->weight = snrCmd->weight;
3935 sq_thresh->polling_interval = snrCmd->pollTime;
3936
3937 sq_thresh->upper_threshold[0] = snrCmd->thresholdAbove1_Val;
3938 sq_thresh->upper_threshold[1] = snrCmd->thresholdAbove2_Val;
3939 sq_thresh->upper_threshold[2] = snrCmd->thresholdAbove3_Val;
3940 sq_thresh->upper_threshold[3] = snrCmd->thresholdAbove4_Val;
3941 sq_thresh->upper_threshold_valid_count = 4;
3942
3943
3944 sq_thresh->lower_threshold[0] = snrCmd->thresholdBelow4_Val;
3945 sq_thresh->lower_threshold[1] = snrCmd->thresholdBelow3_Val;
3946 sq_thresh->lower_threshold[2] = snrCmd->thresholdBelow2_Val;
3947 sq_thresh->lower_threshold[3] = snrCmd->thresholdBelow1_Val;
3948 sq_thresh->lower_threshold_valid_count = 4;
3949
3950 if (!snr_event_value) {
3951
3952
3953
3954
3955
3956 snrCmd->thresholdAbove1_Val = (A_UINT8)sq_thresh->upper_threshold[0];
3957 snrCmd->thresholdBelow1_Val = (A_UINT8)sq_thresh->lower_threshold[0];
3958 } else {
3959
3960
3961
3962
3963 snrCmd->thresholdAbove1_Val = ar6000_get_upper_threshold(snr_event_value, sq_thresh,
3964 sq_thresh->upper_threshold_valid_count);
3965 snrCmd->thresholdBelow1_Val = ar6000_get_lower_threshold(snr_event_value, sq_thresh,
3966 sq_thresh->lower_threshold_valid_count);
3967 }
3968
3969}
3970A_STATUS
3971wmi_set_snr_threshold_params(struct wmi_t *wmip,
3972 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
3973{
3974 if( snrCmd->thresholdAbove4_Val <= snrCmd->thresholdAbove3_Val ||
3975 snrCmd->thresholdAbove3_Val <= snrCmd->thresholdAbove2_Val ||
3976 snrCmd->thresholdAbove2_Val <= snrCmd->thresholdAbove1_Val ||
3977 snrCmd->thresholdBelow4_Val <= snrCmd->thresholdBelow3_Val ||
3978 snrCmd->thresholdBelow3_Val <= snrCmd->thresholdBelow2_Val ||
3979 snrCmd->thresholdBelow2_Val <= snrCmd->thresholdBelow1_Val)
3980 {
3981 return A_EINVAL;
3982 }
3983 wmi_cache_configure_snrthreshold(wmip, snrCmd);
3984 return (wmi_send_snr_threshold_params(wmip, snrCmd));
3985}
3986
3987A_STATUS
3988wmi_clr_rssi_snr(struct wmi_t *wmip)
3989{
3990 void *osbuf;
3991
3992 osbuf = A_NETBUF_ALLOC(sizeof(int));
3993 if (osbuf == NULL) {
3994 return A_NO_MEMORY;
3995 }
3996
3997 return (wmi_cmd_send(wmip, osbuf, WMI_CLR_RSSI_SNR_CMDID,
3998 NO_SYNC_WMIFLAG));
3999}
4000
4001A_STATUS
4002wmi_set_lq_threshold_params(struct wmi_t *wmip,
4003 WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd)
4004{
4005 void *osbuf;
4006 A_INT8 size;
4007 WMI_LQ_THRESHOLD_PARAMS_CMD *cmd;
4008
4009 if( lqCmd->thresholdAbove4_Val <= lqCmd->thresholdAbove3_Val ||
4010 lqCmd->thresholdAbove3_Val <= lqCmd->thresholdAbove2_Val ||
4011 lqCmd->thresholdAbove2_Val <= lqCmd->thresholdAbove1_Val ||
4012 lqCmd->thresholdBelow4_Val <= lqCmd->thresholdBelow3_Val ||
4013 lqCmd->thresholdBelow3_Val <= lqCmd->thresholdBelow2_Val ||
4014 lqCmd->thresholdBelow2_Val <= lqCmd->thresholdBelow1_Val ) {
4015
4016 return A_EINVAL;
4017 }
4018
4019 size = sizeof (*cmd);
4020
4021 osbuf = A_NETBUF_ALLOC(size);
4022 if (osbuf == NULL) {
4023 return A_NO_MEMORY;
4024 }
4025
4026 A_NETBUF_PUT(osbuf, size);
4027
4028 cmd = (WMI_LQ_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
4029 A_MEMZERO(cmd, size);
4030 A_MEMCPY(cmd, lqCmd, sizeof(WMI_LQ_THRESHOLD_PARAMS_CMD));
4031
4032 return (wmi_cmd_send(wmip, osbuf, WMI_LQ_THRESHOLD_PARAMS_CMDID,
4033 NO_SYNC_WMIFLAG));
4034}
4035
4036A_STATUS
4037wmi_set_error_report_bitmask(struct wmi_t *wmip, A_UINT32 mask)
4038{
4039 void *osbuf;
4040 A_INT8 size;
4041 WMI_TARGET_ERROR_REPORT_BITMASK *cmd;
4042
4043 size = sizeof (*cmd);
4044
4045 osbuf = A_NETBUF_ALLOC(size);
4046 if (osbuf == NULL) {
4047 return A_NO_MEMORY;
4048 }
4049
4050 A_NETBUF_PUT(osbuf, size);
4051
4052 cmd = (WMI_TARGET_ERROR_REPORT_BITMASK *)(A_NETBUF_DATA(osbuf));
4053 A_MEMZERO(cmd, size);
4054
4055 cmd->bitmask = mask;
4056
4057 return (wmi_cmd_send(wmip, osbuf, WMI_TARGET_ERROR_REPORT_BITMASK_CMDID,
4058 NO_SYNC_WMIFLAG));
4059}
4060
4061A_STATUS
4062wmi_get_challenge_resp_cmd(struct wmi_t *wmip, A_UINT32 cookie, A_UINT32 source)
4063{
4064 void *osbuf;
4065 WMIX_HB_CHALLENGE_RESP_CMD *cmd;
4066
4067 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4068 if (osbuf == NULL) {
4069 return A_NO_MEMORY;
4070 }
4071
4072 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4073
4074 cmd = (WMIX_HB_CHALLENGE_RESP_CMD *)(A_NETBUF_DATA(osbuf));
4075 cmd->cookie = cookie;
4076 cmd->source = source;
4077
4078 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_HB_CHALLENGE_RESP_CMDID,
4079 NO_SYNC_WMIFLAG));
4080}
4081
4082A_STATUS
4083wmi_config_debug_module_cmd(struct wmi_t *wmip, A_UINT16 mmask,
4084 A_UINT16 tsr, A_BOOL rep, A_UINT16 size,
4085 A_UINT32 valid)
4086{
4087 void *osbuf;
4088 WMIX_DBGLOG_CFG_MODULE_CMD *cmd;
4089
4090 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4091 if (osbuf == NULL) {
4092 return A_NO_MEMORY;
4093 }
4094
4095 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4096
4097 cmd = (WMIX_DBGLOG_CFG_MODULE_CMD *)(A_NETBUF_DATA(osbuf));
4098 cmd->config.cfgmmask = mmask;
4099 cmd->config.cfgtsr = tsr;
4100 cmd->config.cfgrep = rep;
4101 cmd->config.cfgsize = size;
4102 cmd->config.cfgvalid = valid;
4103
4104 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DBGLOG_CFG_MODULE_CMDID,
4105 NO_SYNC_WMIFLAG));
4106}
4107
4108A_STATUS
4109wmi_get_stats_cmd(struct wmi_t *wmip)
4110{
4111 return wmi_simple_cmd(wmip, WMI_GET_STATISTICS_CMDID);
4112}
4113
4114A_STATUS
4115wmi_addBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex, A_UINT8 *bssid)
4116{
4117 void *osbuf;
4118 WMI_ADD_BAD_AP_CMD *cmd;
4119
4120 if ((bssid == NULL) || (apIndex > WMI_MAX_BAD_AP_INDEX)) {
4121 return A_EINVAL;
4122 }
4123
4124 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4125 if (osbuf == NULL) {
4126 return A_NO_MEMORY;
4127 }
4128
4129 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4130
4131 cmd = (WMI_ADD_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf));
4132 cmd->badApIndex = apIndex;
4133 A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid));
4134
4135 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_BAD_AP_CMDID, SYNC_BEFORE_WMIFLAG));
4136}
4137
4138A_STATUS
4139wmi_deleteBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex)
4140{
4141 void *osbuf;
4142 WMI_DELETE_BAD_AP_CMD *cmd;
4143
4144 if (apIndex > WMI_MAX_BAD_AP_INDEX) {
4145 return A_EINVAL;
4146 }
4147
4148 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4149 if (osbuf == NULL) {
4150 return A_NO_MEMORY;
4151 }
4152
4153 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4154
4155 cmd = (WMI_DELETE_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf));
4156 cmd->badApIndex = apIndex;
4157
4158 return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_BAD_AP_CMDID,
4159 NO_SYNC_WMIFLAG));
4160}
4161
4162A_STATUS
4163wmi_abort_scan_cmd(struct wmi_t *wmip)
4164{
4165 return wmi_simple_cmd(wmip, WMI_ABORT_SCAN_CMDID);
4166}
4167
4168A_STATUS
4169wmi_set_txPwr_cmd(struct wmi_t *wmip, A_UINT8 dbM)
4170{
4171 void *osbuf;
4172 WMI_SET_TX_PWR_CMD *cmd;
4173
4174 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4175 if (osbuf == NULL) {
4176 return A_NO_MEMORY;
4177 }
4178
4179 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4180
4181 cmd = (WMI_SET_TX_PWR_CMD *)(A_NETBUF_DATA(osbuf));
4182 cmd->dbM = dbM;
4183
4184 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_PWR_CMDID, NO_SYNC_WMIFLAG));
4185}
4186
4187A_STATUS
4188wmi_get_txPwr_cmd(struct wmi_t *wmip)
4189{
4190 return wmi_simple_cmd(wmip, WMI_GET_TX_PWR_CMDID);
4191}
4192
4193A_UINT16
4194wmi_get_mapped_qos_queue(struct wmi_t *wmip, A_UINT8 trafficClass)
4195{
4196 A_UINT16 activeTsids=0;
4197
4198 LOCK_WMI(wmip);
4199 activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
4200 UNLOCK_WMI(wmip);
4201
4202 return activeTsids;
4203}
4204
4205A_STATUS
4206wmi_get_roam_tbl_cmd(struct wmi_t *wmip)
4207{
4208 return wmi_simple_cmd(wmip, WMI_GET_ROAM_TBL_CMDID);
4209}
4210
4211A_STATUS
4212wmi_get_roam_data_cmd(struct wmi_t *wmip, A_UINT8 roamDataType)
4213{
4214 void *osbuf;
4215 A_UINT32 size = sizeof(A_UINT8);
4216 WMI_TARGET_ROAM_DATA *cmd;
4217
4218 osbuf = A_NETBUF_ALLOC(size);
4219 if (osbuf == NULL) {
4220 return A_NO_MEMORY;
4221 }
4222
4223 A_NETBUF_PUT(osbuf, size);
4224
4225 cmd = (WMI_TARGET_ROAM_DATA *)(A_NETBUF_DATA(osbuf));
4226 cmd->roamDataType = roamDataType;
4227
4228 return (wmi_cmd_send(wmip, osbuf, WMI_GET_ROAM_DATA_CMDID,
4229 NO_SYNC_WMIFLAG));
4230}
4231
4232A_STATUS
4233wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p,
4234 A_UINT8 size)
4235{
4236 void *osbuf;
4237 WMI_SET_ROAM_CTRL_CMD *cmd;
4238
4239 osbuf = A_NETBUF_ALLOC(size);
4240 if (osbuf == NULL) {
4241 return A_NO_MEMORY;
4242 }
4243
4244 A_NETBUF_PUT(osbuf, size);
4245
4246 cmd = (WMI_SET_ROAM_CTRL_CMD *)(A_NETBUF_DATA(osbuf));
4247 A_MEMZERO(cmd, size);
4248
4249 A_MEMCPY(cmd, p, size);
4250
4251 return (wmi_cmd_send(wmip, osbuf, WMI_SET_ROAM_CTRL_CMDID,
4252 NO_SYNC_WMIFLAG));
4253}
4254
4255A_STATUS
4256wmi_set_powersave_timers_cmd(struct wmi_t *wmip,
4257 WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd,
4258 A_UINT8 size)
4259{
4260 void *osbuf;
4261 WMI_POWERSAVE_TIMERS_POLICY_CMD *cmd;
4262
4263
4264 if(!pCmd->psPollTimeout || !pCmd->triggerTimeout ||
4265 !(pCmd->apsdTimPolicy == IGNORE_TIM_ALL_QUEUES_APSD ||
4266 pCmd->apsdTimPolicy == PROCESS_TIM_ALL_QUEUES_APSD) ||
4267 !(pCmd->simulatedAPSDTimPolicy == IGNORE_TIM_SIMULATED_APSD ||
4268 pCmd->simulatedAPSDTimPolicy == PROCESS_TIM_SIMULATED_APSD))
4269 return A_EINVAL;
4270
4271 osbuf = A_NETBUF_ALLOC(size);
4272 if (osbuf == NULL) {
4273 return A_NO_MEMORY;
4274 }
4275
4276 A_NETBUF_PUT(osbuf, size);
4277
4278 cmd = (WMI_POWERSAVE_TIMERS_POLICY_CMD *)(A_NETBUF_DATA(osbuf));
4279 A_MEMZERO(cmd, size);
4280
4281 A_MEMCPY(cmd, pCmd, size);
4282
4283 return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID,
4284 NO_SYNC_WMIFLAG));
4285}
4286
4287#ifdef CONFIG_HOST_GPIO_SUPPORT
4288
4289A_STATUS
4290wmi_gpio_output_set(struct wmi_t *wmip,
4291 A_UINT32 set_mask,
4292 A_UINT32 clear_mask,
4293 A_UINT32 enable_mask,
4294 A_UINT32 disable_mask)
4295{
4296 void *osbuf;
4297 WMIX_GPIO_OUTPUT_SET_CMD *output_set;
4298 int size;
4299
4300 size = sizeof(*output_set);
4301
4302 A_DPRINTF(DBG_WMI,
4303 (DBGFMT "Enter - set=0x%x clear=0x%x enb=0x%x dis=0x%x\n", DBGARG,
4304 set_mask, clear_mask, enable_mask, disable_mask));
4305
4306 osbuf = A_NETBUF_ALLOC(size);
4307 if (osbuf == NULL) {
4308 return A_NO_MEMORY;
4309 }
4310 A_NETBUF_PUT(osbuf, size);
4311 output_set = (WMIX_GPIO_OUTPUT_SET_CMD *)(A_NETBUF_DATA(osbuf));
4312
4313 output_set->set_mask = set_mask;
4314 output_set->clear_mask = clear_mask;
4315 output_set->enable_mask = enable_mask;
4316 output_set->disable_mask = disable_mask;
4317
4318 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_OUTPUT_SET_CMDID,
4319 NO_SYNC_WMIFLAG));
4320}
4321
4322
4323A_STATUS
4324wmi_gpio_input_get(struct wmi_t *wmip)
4325{
4326 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
4327
4328 return wmi_simple_cmd_xtnd(wmip, WMIX_GPIO_INPUT_GET_CMDID);
4329}
4330
4331
4332A_STATUS
4333wmi_gpio_register_set(struct wmi_t *wmip,
4334 A_UINT32 gpioreg_id,
4335 A_UINT32 value)
4336{
4337 void *osbuf;
4338 WMIX_GPIO_REGISTER_SET_CMD *register_set;
4339 int size;
4340
4341 size = sizeof(*register_set);
4342
4343 A_DPRINTF(DBG_WMI,
4344 (DBGFMT "Enter - reg=%d value=0x%x\n", DBGARG, gpioreg_id, value));
4345
4346 osbuf = A_NETBUF_ALLOC(size);
4347 if (osbuf == NULL) {
4348 return A_NO_MEMORY;
4349 }
4350 A_NETBUF_PUT(osbuf, size);
4351 register_set = (WMIX_GPIO_REGISTER_SET_CMD *)(A_NETBUF_DATA(osbuf));
4352
4353 register_set->gpioreg_id = gpioreg_id;
4354 register_set->value = value;
4355
4356 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_REGISTER_SET_CMDID,
4357 NO_SYNC_WMIFLAG));
4358}
4359
4360
4361A_STATUS
4362wmi_gpio_register_get(struct wmi_t *wmip,
4363 A_UINT32 gpioreg_id)
4364{
4365 void *osbuf;
4366 WMIX_GPIO_REGISTER_GET_CMD *register_get;
4367 int size;
4368
4369 size = sizeof(*register_get);
4370
4371 A_DPRINTF(DBG_WMI, (DBGFMT "Enter - reg=%d\n", DBGARG, gpioreg_id));
4372
4373 osbuf = A_NETBUF_ALLOC(size);
4374 if (osbuf == NULL) {
4375 return A_NO_MEMORY;
4376 }
4377 A_NETBUF_PUT(osbuf, size);
4378 register_get = (WMIX_GPIO_REGISTER_GET_CMD *)(A_NETBUF_DATA(osbuf));
4379
4380 register_get->gpioreg_id = gpioreg_id;
4381
4382 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_REGISTER_GET_CMDID,
4383 NO_SYNC_WMIFLAG));
4384}
4385
4386
4387A_STATUS
4388wmi_gpio_intr_ack(struct wmi_t *wmip,
4389 A_UINT32 ack_mask)
4390{
4391 void *osbuf;
4392 WMIX_GPIO_INTR_ACK_CMD *intr_ack;
4393 int size;
4394
4395 size = sizeof(*intr_ack);
4396
4397 A_DPRINTF(DBG_WMI, (DBGFMT "Enter ack_mask=0x%x\n", DBGARG, ack_mask));
4398
4399 osbuf = A_NETBUF_ALLOC(size);
4400 if (osbuf == NULL) {
4401 return A_NO_MEMORY;
4402 }
4403 A_NETBUF_PUT(osbuf, size);
4404 intr_ack = (WMIX_GPIO_INTR_ACK_CMD *)(A_NETBUF_DATA(osbuf));
4405
4406 intr_ack->ack_mask = ack_mask;
4407
4408 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_INTR_ACK_CMDID,
4409 NO_SYNC_WMIFLAG));
4410}
4411#endif
4412
4413A_STATUS
4414wmi_set_access_params_cmd(struct wmi_t *wmip, A_UINT8 ac, A_UINT16 txop, A_UINT8 eCWmin,
4415 A_UINT8 eCWmax, A_UINT8 aifsn)
4416{
4417 void *osbuf;
4418 WMI_SET_ACCESS_PARAMS_CMD *cmd;
4419
4420 if ((eCWmin > WMI_MAX_CW_ACPARAM) || (eCWmax > WMI_MAX_CW_ACPARAM) ||
4421 (aifsn > WMI_MAX_AIFSN_ACPARAM) || (ac >= WMM_NUM_AC))
4422 {
4423 return A_EINVAL;
4424 }
4425
4426 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4427 if (osbuf == NULL) {
4428 return A_NO_MEMORY;
4429 }
4430
4431 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4432
4433 cmd = (WMI_SET_ACCESS_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
4434 cmd->txop = txop;
4435 cmd->eCWmin = eCWmin;
4436 cmd->eCWmax = eCWmax;
4437 cmd->aifsn = aifsn;
4438 cmd->ac = ac;
4439
4440 return (wmi_cmd_send(wmip, osbuf, WMI_SET_ACCESS_PARAMS_CMDID,
4441 NO_SYNC_WMIFLAG));
4442}
4443
4444A_STATUS
4445wmi_set_retry_limits_cmd(struct wmi_t *wmip, A_UINT8 frameType,
4446 A_UINT8 trafficClass, A_UINT8 maxRetries,
4447 A_UINT8 enableNotify)
4448{
4449 void *osbuf;
4450 WMI_SET_RETRY_LIMITS_CMD *cmd;
4451
4452 if ((frameType != MGMT_FRAMETYPE) && (frameType != CONTROL_FRAMETYPE) &&
4453 (frameType != DATA_FRAMETYPE))
4454 {
4455 return A_EINVAL;
4456 }
4457
4458 if (maxRetries > WMI_MAX_RETRIES) {
4459 return A_EINVAL;
4460 }
4461
4462 if (frameType != DATA_FRAMETYPE) {
4463 trafficClass = 0;
4464 }
4465
4466 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4467 if (osbuf == NULL) {
4468 return A_NO_MEMORY;
4469 }
4470
4471 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4472
4473 cmd = (WMI_SET_RETRY_LIMITS_CMD *)(A_NETBUF_DATA(osbuf));
4474 cmd->frameType = frameType;
4475 cmd->trafficClass = trafficClass;
4476 cmd->maxRetries = maxRetries;
4477 cmd->enableNotify = enableNotify;
4478
4479 return (wmi_cmd_send(wmip, osbuf, WMI_SET_RETRY_LIMITS_CMDID,
4480 NO_SYNC_WMIFLAG));
4481}
4482
4483void
4484wmi_get_current_bssid(struct wmi_t *wmip, A_UINT8 *bssid)
4485{
4486 if (bssid != NULL) {
4487 A_MEMCPY(bssid, wmip->wmi_bssid, ATH_MAC_LEN);
4488 }
4489}
4490
4491A_STATUS
4492wmi_set_opt_mode_cmd(struct wmi_t *wmip, A_UINT8 optMode)
4493{
4494 void *osbuf;
4495 WMI_SET_OPT_MODE_CMD *cmd;
4496
4497 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4498 if (osbuf == NULL) {
4499 return A_NO_MEMORY;
4500 }
4501
4502 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4503
4504 cmd = (WMI_SET_OPT_MODE_CMD *)(A_NETBUF_DATA(osbuf));
4505 A_MEMZERO(cmd, sizeof(*cmd));
4506 cmd->optMode = optMode;
4507
4508 return (wmi_cmd_send(wmip, osbuf, WMI_SET_OPT_MODE_CMDID,
4509 SYNC_BOTH_WMIFLAG));
4510}
4511
4512A_STATUS
4513wmi_opt_tx_frame_cmd(struct wmi_t *wmip,
4514 A_UINT8 frmType,
4515 A_UINT8 *dstMacAddr,
4516 A_UINT8 *bssid,
4517 A_UINT16 optIEDataLen,
4518 A_UINT8 *optIEData)
4519{
4520 void *osbuf;
4521 WMI_OPT_TX_FRAME_CMD *cmd;
4522 osbuf = A_NETBUF_ALLOC(optIEDataLen + sizeof(*cmd));
4523 if (osbuf == NULL) {
4524 return A_NO_MEMORY;
4525 }
4526
4527 A_NETBUF_PUT(osbuf, (optIEDataLen + sizeof(*cmd)));
4528
4529 cmd = (WMI_OPT_TX_FRAME_CMD *)(A_NETBUF_DATA(osbuf));
4530 A_MEMZERO(cmd, (optIEDataLen + sizeof(*cmd)-1));
4531
4532 cmd->frmType = frmType;
4533 cmd->optIEDataLen = optIEDataLen;
4534
4535 A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid));
4536 A_MEMCPY(cmd->dstAddr, dstMacAddr, sizeof(cmd->dstAddr));
4537 A_MEMCPY(&cmd->optIEData[0], optIEData, optIEDataLen);
4538
4539 return (wmi_cmd_send(wmip, osbuf, WMI_OPT_TX_FRAME_CMDID,
4540 NO_SYNC_WMIFLAG));
4541}
4542
4543A_STATUS
4544wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, A_UINT16 intvl)
4545{
4546 void *osbuf;
4547 WMI_BEACON_INT_CMD *cmd;
4548
4549 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4550 if (osbuf == NULL) {
4551 return A_NO_MEMORY;
4552 }
4553
4554 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4555
4556 cmd = (WMI_BEACON_INT_CMD *)(A_NETBUF_DATA(osbuf));
4557 A_MEMZERO(cmd, sizeof(*cmd));
4558 cmd->beaconInterval = intvl;
4559
4560 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BEACON_INT_CMDID,
4561 NO_SYNC_WMIFLAG));
4562}
4563
4564
4565A_STATUS
4566wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, A_UINT16 voicePktSize)
4567{
4568 void *osbuf;
4569 WMI_SET_VOICE_PKT_SIZE_CMD *cmd;
4570
4571 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4572 if (osbuf == NULL) {
4573 return A_NO_MEMORY;
4574 }
4575
4576 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4577
4578 cmd = (WMI_SET_VOICE_PKT_SIZE_CMD *)(A_NETBUF_DATA(osbuf));
4579 A_MEMZERO(cmd, sizeof(*cmd));
4580 cmd->voicePktSize = voicePktSize;
4581
4582 return (wmi_cmd_send(wmip, osbuf, WMI_SET_VOICE_PKT_SIZE_CMDID,
4583 NO_SYNC_WMIFLAG));
4584}
4585
4586
4587A_STATUS
4588wmi_set_max_sp_len_cmd(struct wmi_t *wmip, A_UINT8 maxSPLen)
4589{
4590 void *osbuf;
4591 WMI_SET_MAX_SP_LEN_CMD *cmd;
4592
4593
4594
4595
4596 if(maxSPLen & ~0x03)
4597 return A_EINVAL;
4598
4599 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4600 if (osbuf == NULL) {
4601 return A_NO_MEMORY;
4602 }
4603
4604 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4605
4606 cmd = (WMI_SET_MAX_SP_LEN_CMD *)(A_NETBUF_DATA(osbuf));
4607 A_MEMZERO(cmd, sizeof(*cmd));
4608 cmd->maxSPLen = maxSPLen;
4609
4610 return (wmi_cmd_send(wmip, osbuf, WMI_SET_MAX_SP_LEN_CMDID,
4611 NO_SYNC_WMIFLAG));
4612}
4613
4614A_UINT8
4615wmi_determine_userPriority(
4616 A_UINT8 *pkt,
4617 A_UINT32 layer2Pri)
4618{
4619 A_UINT8 ipPri;
4620 iphdr *ipHdr = (iphdr *)pkt;
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631 ipPri = ipHdr->ip_tos >> 5;
4632 ipPri &= 0x7;
4633
4634 if ((layer2Pri & 0x7) > ipPri)
4635 return ((A_UINT8)layer2Pri & 0x7);
4636 else
4637 return ipPri;
4638}
4639
4640A_UINT8
4641convert_userPriority_to_trafficClass(A_UINT8 userPriority)
4642{
4643 return (up_to_ac[userPriority & 0x7]);
4644}
4645
4646A_UINT8
4647wmi_get_power_mode_cmd(struct wmi_t *wmip)
4648{
4649 return wmip->wmi_powerMode;
4650}
4651
4652A_STATUS
4653wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, A_BOOL tspecCompliance)
4654{
4655 A_STATUS ret = A_OK;
4656
4657#define TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF (~0)
4658#define TSPEC_SERVICE_START_TIME_ATHEROS_DEF 0
4659#define TSPEC_MAX_BURST_SIZE_ATHEROS_DEF 0
4660#define TSPEC_DELAY_BOUND_ATHEROS_DEF 0
4661#define TSPEC_MEDIUM_TIME_ATHEROS_DEF 0
4662#define TSPEC_SBA_ATHEROS_DEF 0x2000
4663
4664
4665 if(tspecCompliance == ATHEROS_COMPLIANCE) {
4666 if ((pCmd->suspensionInt != TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF) ||
4667 (pCmd->serviceStartTime != TSPEC_SERVICE_START_TIME_ATHEROS_DEF) ||
4668 (pCmd->minDataRate != pCmd->meanDataRate) ||
4669 (pCmd->minDataRate != pCmd->peakDataRate) ||
4670 (pCmd->maxBurstSize != TSPEC_MAX_BURST_SIZE_ATHEROS_DEF) ||
4671 (pCmd->delayBound != TSPEC_DELAY_BOUND_ATHEROS_DEF) ||
4672 (pCmd->sba != TSPEC_SBA_ATHEROS_DEF) ||
4673 (pCmd->mediumTime != TSPEC_MEDIUM_TIME_ATHEROS_DEF)) {
4674
4675 A_DPRINTF(DBG_WMI, (DBGFMT "Invalid TSPEC params\n", DBGARG));
4676
4677 ret = A_EINVAL;
4678 }
4679 }
4680
4681 return ret;
4682}
4683
4684#ifdef CONFIG_HOST_TCMD_SUPPORT
4685static A_STATUS
4686wmi_tcmd_test_report_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
4687{
4688
4689 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
4690
4691 A_WMI_TCMD_RX_REPORT_EVENT(wmip->wmi_devt, datap, len);
4692
4693 return A_OK;
4694}
4695
4696#endif
4697
4698A_STATUS
4699wmi_set_authmode_cmd(struct wmi_t *wmip, A_UINT8 mode)
4700{
4701 void *osbuf;
4702 WMI_SET_AUTH_MODE_CMD *cmd;
4703
4704 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4705 if (osbuf == NULL) {
4706 return A_NO_MEMORY;
4707 }
4708
4709 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4710
4711 cmd = (WMI_SET_AUTH_MODE_CMD *)(A_NETBUF_DATA(osbuf));
4712 A_MEMZERO(cmd, sizeof(*cmd));
4713 cmd->mode = mode;
4714
4715 return (wmi_cmd_send(wmip, osbuf, WMI_SET_AUTH_MODE_CMDID,
4716 NO_SYNC_WMIFLAG));
4717}
4718
4719A_STATUS
4720wmi_set_reassocmode_cmd(struct wmi_t *wmip, A_UINT8 mode)
4721{
4722 void *osbuf;
4723 WMI_SET_REASSOC_MODE_CMD *cmd;
4724
4725 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4726 if (osbuf == NULL) {
4727 return A_NO_MEMORY;
4728 }
4729
4730 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4731
4732 cmd = (WMI_SET_REASSOC_MODE_CMD *)(A_NETBUF_DATA(osbuf));
4733 A_MEMZERO(cmd, sizeof(*cmd));
4734 cmd->mode = mode;
4735
4736 return (wmi_cmd_send(wmip, osbuf, WMI_SET_REASSOC_MODE_CMDID,
4737 NO_SYNC_WMIFLAG));
4738}
4739
4740A_STATUS
4741wmi_set_lpreamble_cmd(struct wmi_t *wmip, A_UINT8 status, A_UINT8 preamblePolicy)
4742{
4743 void *osbuf;
4744 WMI_SET_LPREAMBLE_CMD *cmd;
4745
4746 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4747 if (osbuf == NULL) {
4748 return A_NO_MEMORY;
4749 }
4750
4751 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4752
4753 cmd = (WMI_SET_LPREAMBLE_CMD *)(A_NETBUF_DATA(osbuf));
4754 A_MEMZERO(cmd, sizeof(*cmd));
4755 cmd->status = status;
4756 cmd->preamblePolicy = preamblePolicy;
4757
4758 return (wmi_cmd_send(wmip, osbuf, WMI_SET_LPREAMBLE_CMDID,
4759 NO_SYNC_WMIFLAG));
4760}
4761
4762A_STATUS
4763wmi_set_rts_cmd(struct wmi_t *wmip, A_UINT16 threshold)
4764{
4765 void *osbuf;
4766 WMI_SET_RTS_CMD *cmd;
4767
4768 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4769 if (osbuf == NULL) {
4770 return A_NO_MEMORY;
4771 }
4772
4773 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4774
4775 cmd = (WMI_SET_RTS_CMD*)(A_NETBUF_DATA(osbuf));
4776 A_MEMZERO(cmd, sizeof(*cmd));
4777 cmd->threshold = threshold;
4778
4779 return (wmi_cmd_send(wmip, osbuf, WMI_SET_RTS_CMDID,
4780 NO_SYNC_WMIFLAG));
4781}
4782
4783A_STATUS
4784wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status)
4785{
4786 void *osbuf;
4787 WMI_SET_WMM_CMD *cmd;
4788
4789 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4790 if (osbuf == NULL) {
4791 return A_NO_MEMORY;
4792 }
4793
4794 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4795
4796 cmd = (WMI_SET_WMM_CMD*)(A_NETBUF_DATA(osbuf));
4797 A_MEMZERO(cmd, sizeof(*cmd));
4798 cmd->status = status;
4799
4800 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_CMDID,
4801 NO_SYNC_WMIFLAG));
4802
4803}
4804
4805A_STATUS
4806wmi_set_qos_supp_cmd(struct wmi_t *wmip, A_UINT8 status)
4807{
4808 void *osbuf;
4809 WMI_SET_QOS_SUPP_CMD *cmd;
4810
4811 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4812 if (osbuf == NULL) {
4813 return A_NO_MEMORY;
4814 }
4815
4816 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4817
4818 cmd = (WMI_SET_QOS_SUPP_CMD*)(A_NETBUF_DATA(osbuf));
4819 A_MEMZERO(cmd, sizeof(*cmd));
4820 cmd->status = status;
4821 return (wmi_cmd_send(wmip, osbuf, WMI_SET_QOS_SUPP_CMDID,
4822 NO_SYNC_WMIFLAG));
4823}
4824
4825
4826A_STATUS
4827wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG cfg)
4828{
4829 void *osbuf;
4830 WMI_SET_WMM_TXOP_CMD *cmd;
4831
4832 if( !((cfg == WMI_TXOP_DISABLED) || (cfg == WMI_TXOP_ENABLED)) )
4833 return A_EINVAL;
4834
4835 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4836 if (osbuf == NULL) {
4837 return A_NO_MEMORY;
4838 }
4839
4840 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4841
4842 cmd = (WMI_SET_WMM_TXOP_CMD *)(A_NETBUF_DATA(osbuf));
4843 A_MEMZERO(cmd, sizeof(*cmd));
4844 cmd->txopEnable = cfg;
4845
4846 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_TXOP_CMDID,
4847 NO_SYNC_WMIFLAG));
4848
4849}
4850
4851A_STATUS
4852wmi_set_country(struct wmi_t *wmip, A_UCHAR *countryCode)
4853{
4854 void *osbuf;
4855 WMI_AP_SET_COUNTRY_CMD *cmd;
4856
4857 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4858 if (osbuf == NULL) {
4859 return A_NO_MEMORY;
4860 }
4861
4862 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4863
4864 cmd = (WMI_AP_SET_COUNTRY_CMD *)(A_NETBUF_DATA(osbuf));
4865 A_MEMZERO(cmd, sizeof(*cmd));
4866 A_MEMCPY(cmd->countryCode,countryCode,3);
4867
4868 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_COUNTRY_CMDID,
4869 NO_SYNC_WMIFLAG));
4870}
4871
4872#ifdef CONFIG_HOST_TCMD_SUPPORT
4873
4874
4875
4876
4877A_STATUS
4878wmi_test_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT32 len)
4879{
4880 void *osbuf;
4881 char *data;
4882
4883 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
4884
4885 osbuf= A_NETBUF_ALLOC(len);
4886 if(osbuf == NULL)
4887 {
4888 return A_NO_MEMORY;
4889 }
4890 A_NETBUF_PUT(osbuf, len);
4891 data = A_NETBUF_DATA(osbuf);
4892 A_MEMCPY(data, buf, len);
4893
4894 return(wmi_cmd_send(wmip, osbuf, WMI_TEST_CMDID,
4895 NO_SYNC_WMIFLAG));
4896}
4897
4898#endif
4899
4900A_STATUS
4901wmi_set_bt_status_cmd(struct wmi_t *wmip, A_UINT8 streamType, A_UINT8 status)
4902{
4903 void *osbuf;
4904 WMI_SET_BT_STATUS_CMD *cmd;
4905
4906 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Enter - streamType=%d, status=%d\n", streamType, status));
4907
4908 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4909 if (osbuf == NULL) {
4910 return A_NO_MEMORY;
4911 }
4912
4913 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4914
4915 cmd = (WMI_SET_BT_STATUS_CMD *)(A_NETBUF_DATA(osbuf));
4916 A_MEMZERO(cmd, sizeof(*cmd));
4917 cmd->streamType = streamType;
4918 cmd->status = status;
4919
4920 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_STATUS_CMDID,
4921 NO_SYNC_WMIFLAG));
4922}
4923
4924A_STATUS
4925wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd)
4926{
4927 void *osbuf;
4928 WMI_SET_BT_PARAMS_CMD* alloc_cmd;
4929
4930 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("cmd params is %d\n", cmd->paramType));
4931
4932 if (cmd->paramType == BT_PARAM_SCO) {
4933 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("sco params %d %d %d %d %d %d %d %d %d %d %d %d\n", cmd->info.scoParams.numScoCyclesForceTrigger,
4934 cmd->info.scoParams.dataResponseTimeout,
4935 cmd->info.scoParams.stompScoRules,
4936 cmd->info.scoParams.scoOptFlags,
4937 cmd->info.scoParams.stompDutyCyleVal,
4938 cmd->info.scoParams.stompDutyCyleMaxVal,
4939 cmd->info.scoParams.psPollLatencyFraction,
4940 cmd->info.scoParams.noSCOSlots,
4941 cmd->info.scoParams.noIdleSlots,
4942 cmd->info.scoParams.scoOptOffRssi,
4943 cmd->info.scoParams.scoOptOnRssi,
4944 cmd->info.scoParams.scoOptRtsCount));
4945 }
4946 else if (cmd->paramType == BT_PARAM_A2DP) {
4947 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("A2DP params %d %d %d %d %d %d %d %d\n", cmd->info.a2dpParams.a2dpWlanUsageLimit,
4948 cmd->info.a2dpParams.a2dpBurstCntMin,
4949 cmd->info.a2dpParams.a2dpDataRespTimeout,
4950 cmd->info.a2dpParams.a2dpOptFlags,
4951 cmd->info.a2dpParams.isCoLocatedBtRoleMaster,
4952 cmd->info.a2dpParams.a2dpOptOffRssi,
4953 cmd->info.a2dpParams.a2dpOptOnRssi,
4954 cmd->info.a2dpParams.a2dpOptRtsCount));
4955 }
4956 else if (cmd->paramType == BT_PARAM_ANTENNA_CONFIG) {
4957 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Ant config %d\n", cmd->info.antType));
4958 }
4959 else if (cmd->paramType == BT_PARAM_COLOCATED_BT_DEVICE) {
4960 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("co-located BT %d\n", cmd->info.coLocatedBtDev));
4961 }
4962 else if (cmd->paramType == BT_PARAM_ACLCOEX) {
4963 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("ACL params %d %d %d\n", cmd->info.aclCoexParams.aclWlanMediumUsageTime,
4964 cmd->info.aclCoexParams.aclBtMediumUsageTime,
4965 cmd->info.aclCoexParams.aclDataRespTimeout));
4966 }
4967 else if (cmd->paramType == BT_PARAM_11A_SEPARATE_ANT) {
4968 A_DPRINTF(DBG_WMI, (DBGFMT "11A ant\n", DBGARG));
4969 }
4970
4971 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4972 if (osbuf == NULL) {
4973 return A_NO_MEMORY;
4974 }
4975
4976 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4977
4978 alloc_cmd = (WMI_SET_BT_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
4979 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4980 A_MEMCPY(alloc_cmd, cmd, sizeof(*cmd));
4981
4982 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_PARAMS_CMDID,
4983 NO_SYNC_WMIFLAG));
4984}
4985
4986A_STATUS
4987wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd)
4988{
4989 void *osbuf;
4990 WMI_SET_BTCOEX_FE_ANT_CMD *alloc_cmd;
4991
4992 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4993 if (osbuf == NULL) {
4994 return A_NO_MEMORY;
4995 }
4996 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4997 alloc_cmd = (WMI_SET_BTCOEX_FE_ANT_CMD *)(A_NETBUF_DATA(osbuf));
4998 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4999 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_FE_ANT_CMD));
5000 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_FE_ANT_CMDID,
5001 NO_SYNC_WMIFLAG));
5002
5003}
5004
5005
5006A_STATUS
5007wmi_set_btcoex_colocated_bt_dev_cmd(struct wmi_t *wmip,
5008 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD * cmd)
5009{
5010 void *osbuf;
5011 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD *alloc_cmd;
5012
5013 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5014 if (osbuf == NULL) {
5015 return A_NO_MEMORY;
5016 }
5017 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5018 alloc_cmd = (WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD *)(A_NETBUF_DATA(osbuf));
5019 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5020 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD));
5021 A_PRINTF("colocated bt = %d\n", alloc_cmd->btcoexCoLocatedBTdev);
5022 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID,
5023 NO_SYNC_WMIFLAG));
5024
5025}
5026
5027A_STATUS
5028wmi_set_btcoex_btinquiry_page_config_cmd(struct wmi_t *wmip,
5029 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD* cmd)
5030{
5031 void *osbuf;
5032 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *alloc_cmd;
5033
5034 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5035 if (osbuf == NULL) {
5036 return A_NO_MEMORY;
5037 }
5038 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5039 alloc_cmd = (WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
5040 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5041 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD));
5042 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID,
5043 NO_SYNC_WMIFLAG));
5044
5045}
5046
5047A_STATUS
5048wmi_set_btcoex_sco_config_cmd(struct wmi_t *wmip,
5049 WMI_SET_BTCOEX_SCO_CONFIG_CMD * cmd)
5050{
5051 void *osbuf;
5052 WMI_SET_BTCOEX_SCO_CONFIG_CMD *alloc_cmd;
5053
5054 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5055 if (osbuf == NULL) {
5056 return A_NO_MEMORY;
5057 }
5058 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5059 alloc_cmd = (WMI_SET_BTCOEX_SCO_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
5060 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5061 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_SCO_CONFIG_CMD));
5062 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_SCO_CONFIG_CMDID ,
5063 NO_SYNC_WMIFLAG));
5064
5065}
5066
5067A_STATUS
5068wmi_set_btcoex_a2dp_config_cmd(struct wmi_t *wmip,
5069 WMI_SET_BTCOEX_A2DP_CONFIG_CMD * cmd)
5070{
5071 void *osbuf;
5072 WMI_SET_BTCOEX_A2DP_CONFIG_CMD *alloc_cmd;
5073
5074 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5075 if (osbuf == NULL) {
5076 return A_NO_MEMORY;
5077 }
5078 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5079 alloc_cmd = (WMI_SET_BTCOEX_A2DP_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
5080 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5081 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_A2DP_CONFIG_CMD));
5082 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_A2DP_CONFIG_CMDID ,
5083 NO_SYNC_WMIFLAG));
5084
5085}
5086
5087A_STATUS
5088wmi_set_btcoex_aclcoex_config_cmd(struct wmi_t *wmip,
5089 WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD * cmd)
5090{
5091 void *osbuf;
5092 WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD *alloc_cmd;
5093
5094 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5095 if (osbuf == NULL) {
5096 return A_NO_MEMORY;
5097 }
5098 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5099 alloc_cmd = (WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
5100 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5101 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD));
5102 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID ,
5103 NO_SYNC_WMIFLAG));
5104
5105}
5106
5107A_STATUS
5108wmi_set_btcoex_debug_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_DEBUG_CMD * cmd)
5109{
5110 void *osbuf;
5111 WMI_SET_BTCOEX_DEBUG_CMD *alloc_cmd;
5112
5113 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5114 if (osbuf == NULL) {
5115 return A_NO_MEMORY;
5116 }
5117 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5118 alloc_cmd = (WMI_SET_BTCOEX_DEBUG_CMD *)(A_NETBUF_DATA(osbuf));
5119 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5120 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_DEBUG_CMD));
5121 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_DEBUG_CMDID ,
5122 NO_SYNC_WMIFLAG));
5123
5124}
5125
5126A_STATUS
5127wmi_set_btcoex_bt_operating_status_cmd(struct wmi_t * wmip,
5128 WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD * cmd)
5129{
5130 void *osbuf;
5131 WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *alloc_cmd;
5132
5133 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5134 if (osbuf == NULL) {
5135 return A_NO_MEMORY;
5136 }
5137 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5138 alloc_cmd = (WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *)(A_NETBUF_DATA(osbuf));
5139 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5140 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD));
5141 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID ,
5142 NO_SYNC_WMIFLAG));
5143
5144}
5145
5146A_STATUS
5147wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * cmd)
5148{
5149 void *osbuf;
5150 WMI_GET_BTCOEX_CONFIG_CMD *alloc_cmd;
5151
5152 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5153 if (osbuf == NULL) {
5154 return A_NO_MEMORY;
5155 }
5156 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5157 alloc_cmd = (WMI_GET_BTCOEX_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
5158 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5159 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_GET_BTCOEX_CONFIG_CMD));
5160 return (wmi_cmd_send(wmip, osbuf, WMI_GET_BTCOEX_CONFIG_CMDID ,
5161 NO_SYNC_WMIFLAG));
5162
5163}
5164
5165A_STATUS
5166wmi_get_btcoex_stats_cmd(struct wmi_t *wmip)
5167{
5168
5169 return wmi_simple_cmd(wmip, WMI_GET_BTCOEX_STATS_CMDID);
5170
5171}
5172
5173A_STATUS
5174wmi_get_keepalive_configured(struct wmi_t *wmip)
5175{
5176 void *osbuf;
5177 WMI_GET_KEEPALIVE_CMD *cmd;
5178 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5179 if (osbuf == NULL) {
5180 return A_NO_MEMORY;
5181 }
5182 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5183 cmd = (WMI_GET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf));
5184 A_MEMZERO(cmd, sizeof(*cmd));
5185 return (wmi_cmd_send(wmip, osbuf, WMI_GET_KEEPALIVE_CMDID,
5186 NO_SYNC_WMIFLAG));
5187}
5188
5189A_UINT8
5190wmi_get_keepalive_cmd(struct wmi_t *wmip)
5191{
5192 return wmip->wmi_keepaliveInterval;
5193}
5194
5195A_STATUS
5196wmi_set_keepalive_cmd(struct wmi_t *wmip, A_UINT8 keepaliveInterval)
5197{
5198 void *osbuf;
5199 WMI_SET_KEEPALIVE_CMD *cmd;
5200
5201 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5202 if (osbuf == NULL) {
5203 return A_NO_MEMORY;
5204 }
5205
5206 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5207
5208 cmd = (WMI_SET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf));
5209 A_MEMZERO(cmd, sizeof(*cmd));
5210 cmd->keepaliveInterval = keepaliveInterval;
5211 wmip->wmi_keepaliveInterval = keepaliveInterval;
5212
5213 return (wmi_cmd_send(wmip, osbuf, WMI_SET_KEEPALIVE_CMDID,
5214 NO_SYNC_WMIFLAG));
5215}
5216
5217A_STATUS
5218wmi_set_params_cmd(struct wmi_t *wmip, A_UINT32 opcode, A_UINT32 length, A_CHAR* buffer)
5219{
5220 void *osbuf;
5221 WMI_SET_PARAMS_CMD *cmd;
5222
5223 osbuf = A_NETBUF_ALLOC(sizeof(*cmd) + length);
5224 if (osbuf == NULL) {
5225 return A_NO_MEMORY;
5226 }
5227
5228 A_NETBUF_PUT(osbuf, sizeof(*cmd) + length);
5229
5230 cmd = (WMI_SET_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
5231 A_MEMZERO(cmd, sizeof(*cmd));
5232 cmd->opcode = opcode;
5233 cmd->length = length;
5234 A_MEMCPY(cmd->buffer, buffer, length);
5235
5236 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PARAMS_CMDID,
5237 NO_SYNC_WMIFLAG));
5238}
5239
5240
5241A_STATUS
5242wmi_set_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8 dot3, A_UINT8 dot4)
5243{
5244 void *osbuf;
5245 WMI_SET_MCAST_FILTER_CMD *cmd;
5246
5247 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5248 if (osbuf == NULL) {
5249 return A_NO_MEMORY;
5250 }
5251
5252 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5253
5254 cmd = (WMI_SET_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
5255 cmd->multicast_mac[0] = 0x01;
5256 cmd->multicast_mac[1] = 0x00;
5257 cmd->multicast_mac[2] = 0x5e;
5258 cmd->multicast_mac[3] = dot2&0x7F;
5259 cmd->multicast_mac[4] = dot3;
5260 cmd->multicast_mac[5] = dot4;
5261
5262 return (wmi_cmd_send(wmip, osbuf, WMI_SET_MCAST_FILTER_CMDID,
5263 NO_SYNC_WMIFLAG));
5264}
5265
5266
5267A_STATUS
5268wmi_del_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8 dot3, A_UINT8 dot4)
5269{
5270 void *osbuf;
5271 WMI_SET_MCAST_FILTER_CMD *cmd;
5272
5273 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5274 if (osbuf == NULL) {
5275 return A_NO_MEMORY;
5276 }
5277
5278 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5279
5280 cmd = (WMI_SET_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
5281 cmd->multicast_mac[0] = 0x01;
5282 cmd->multicast_mac[1] = 0x00;
5283 cmd->multicast_mac[2] = 0x5e;
5284 cmd->multicast_mac[3] = dot2&0x7F;
5285 cmd->multicast_mac[4] = dot3;
5286 cmd->multicast_mac[5] = dot4;
5287
5288 return (wmi_cmd_send(wmip, osbuf, WMI_DEL_MCAST_FILTER_CMDID,
5289 NO_SYNC_WMIFLAG));
5290}
5291
5292A_STATUS
5293wmi_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 enable)
5294{
5295 void *osbuf;
5296 WMI_MCAST_FILTER_CMD *cmd;
5297
5298 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5299 if (osbuf == NULL) {
5300 return A_NO_MEMORY;
5301 }
5302
5303 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5304
5305 cmd = (WMI_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
5306 cmd->enable = enable;
5307
5308 return (wmi_cmd_send(wmip, osbuf, WMI_MCAST_FILTER_CMDID,
5309 NO_SYNC_WMIFLAG));
5310}
5311
5312A_STATUS
5313wmi_set_appie_cmd(struct wmi_t *wmip, A_UINT8 mgmtFrmType, A_UINT8 ieLen,
5314 A_UINT8 *ieInfo)
5315{
5316 void *osbuf;
5317 WMI_SET_APPIE_CMD *cmd;
5318 A_UINT16 cmdLen;
5319
5320 cmdLen = sizeof(*cmd) + ieLen - 1;
5321 osbuf = A_NETBUF_ALLOC(cmdLen);
5322 if (osbuf == NULL) {
5323 return A_NO_MEMORY;
5324 }
5325
5326 A_NETBUF_PUT(osbuf, cmdLen);
5327
5328 cmd = (WMI_SET_APPIE_CMD *)(A_NETBUF_DATA(osbuf));
5329 A_MEMZERO(cmd, cmdLen);
5330
5331 cmd->mgmtFrmType = mgmtFrmType;
5332 cmd->ieLen = ieLen;
5333 A_MEMCPY(cmd->ieInfo, ieInfo, ieLen);
5334
5335 return (wmi_cmd_send(wmip, osbuf, WMI_SET_APPIE_CMDID, NO_SYNC_WMIFLAG));
5336}
5337
5338A_STATUS
5339wmi_set_halparam_cmd(struct wmi_t *wmip, A_UINT8 *cmd, A_UINT16 dataLen)
5340{
5341 void *osbuf;
5342 A_UINT8 *data;
5343
5344 osbuf = A_NETBUF_ALLOC(dataLen);
5345 if (osbuf == NULL) {
5346 return A_NO_MEMORY;
5347 }
5348
5349 A_NETBUF_PUT(osbuf, dataLen);
5350
5351 data = A_NETBUF_DATA(osbuf);
5352
5353 A_MEMCPY(data, cmd, dataLen);
5354
5355 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WHALPARAM_CMDID, NO_SYNC_WMIFLAG));
5356}
5357
5358A_INT32
5359wmi_get_rate(A_INT8 rateindex)
5360{
5361 if (rateindex == RATE_AUTO) {
5362 return 0;
5363 } else {
5364 return(wmi_rateTable[(A_UINT32) rateindex][0]);
5365 }
5366}
5367
5368void
5369wmi_node_return (struct wmi_t *wmip, bss_t *bss)
5370{
5371 if (NULL != bss)
5372 {
5373 wlan_node_return (&wmip->wmi_scan_table, bss);
5374 }
5375}
5376
5377void
5378wmi_set_nodeage(struct wmi_t *wmip, A_UINT32 nodeAge)
5379{
5380 wlan_set_nodeage(&wmip->wmi_scan_table,nodeAge);
5381}
5382
5383bss_t *
5384wmi_find_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid,
5385 A_UINT32 ssidLength, A_BOOL bIsWPA2, A_BOOL bMatchSSID)
5386{
5387 bss_t *node = NULL;
5388 node = wlan_find_Ssidnode (&wmip->wmi_scan_table, pSsid,
5389 ssidLength, bIsWPA2, bMatchSSID);
5390 return node;
5391}
5392
5393
5394#ifdef THREAD_X
5395void
5396wmi_refresh_scan_table (struct wmi_t *wmip)
5397{
5398 wlan_refresh_inactive_nodes (&wmip->wmi_scan_table);
5399}
5400#endif
5401
5402void
5403wmi_free_allnodes(struct wmi_t *wmip)
5404{
5405 wlan_free_allnodes(&wmip->wmi_scan_table);
5406}
5407
5408bss_t *
5409wmi_find_node(struct wmi_t *wmip, const A_UINT8 *macaddr)
5410{
5411 bss_t *ni=NULL;
5412 ni=wlan_find_node(&wmip->wmi_scan_table,macaddr);
5413 return ni;
5414}
5415
5416void
5417wmi_free_node(struct wmi_t *wmip, const A_UINT8 *macaddr)
5418{
5419 bss_t *ni=NULL;
5420
5421 ni=wlan_find_node(&wmip->wmi_scan_table,macaddr);
5422 if (ni != NULL) {
5423 wlan_node_reclaim(&wmip->wmi_scan_table, ni);
5424 }
5425
5426 return;
5427}
5428
5429A_STATUS
5430wmi_dset_open_reply(struct wmi_t *wmip,
5431 A_UINT32 status,
5432 A_UINT32 access_cookie,
5433 A_UINT32 dset_size,
5434 A_UINT32 dset_version,
5435 A_UINT32 targ_handle,
5436 A_UINT32 targ_reply_fn,
5437 A_UINT32 targ_reply_arg)
5438{
5439 void *osbuf;
5440 WMIX_DSETOPEN_REPLY_CMD *open_reply;
5441
5442 A_DPRINTF(DBG_WMI, (DBGFMT "Enter - wmip=0x%lx\n", DBGARG, (unsigned long)wmip));
5443
5444 osbuf = A_NETBUF_ALLOC(sizeof(*open_reply));
5445 if (osbuf == NULL) {
5446 return A_NO_MEMORY;
5447 }
5448
5449 A_NETBUF_PUT(osbuf, sizeof(*open_reply));
5450 open_reply = (WMIX_DSETOPEN_REPLY_CMD *)(A_NETBUF_DATA(osbuf));
5451
5452 open_reply->status = status;
5453 open_reply->targ_dset_handle = targ_handle;
5454 open_reply->targ_reply_fn = targ_reply_fn;
5455 open_reply->targ_reply_arg = targ_reply_arg;
5456 open_reply->access_cookie = access_cookie;
5457 open_reply->size = dset_size;
5458 open_reply->version = dset_version;
5459
5460 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETOPEN_REPLY_CMDID,
5461 NO_SYNC_WMIFLAG));
5462}
5463
5464static A_STATUS
5465wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len)
5466{
5467 WMI_PMKID_LIST_REPLY *reply;
5468 A_UINT32 expected_len;
5469
5470 if (len < sizeof(WMI_PMKID_LIST_REPLY)) {
5471 return A_EINVAL;
5472 }
5473 reply = (WMI_PMKID_LIST_REPLY *)datap;
5474 expected_len = sizeof(reply->numPMKID) + reply->numPMKID * WMI_PMKID_LEN;
5475
5476 if (len < expected_len) {
5477 return A_EINVAL;
5478 }
5479
5480 A_WMI_PMKID_LIST_EVENT(wmip->wmi_devt, reply->numPMKID,
5481 reply->pmkidList, reply->bssidList[0]);
5482
5483 return A_OK;
5484}
5485
5486
5487static A_STATUS
5488wmi_set_params_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len)
5489{
5490 WMI_SET_PARAMS_REPLY *reply;
5491
5492 if (len < sizeof(WMI_SET_PARAMS_REPLY)) {
5493 return A_EINVAL;
5494 }
5495 reply = (WMI_SET_PARAMS_REPLY *)datap;
5496
5497 if (A_OK == reply->status)
5498 {
5499
5500 }
5501 else
5502 {
5503
5504 }
5505
5506 return A_OK;
5507}
5508
5509
5510
5511static A_STATUS
5512wmi_acm_reject_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len)
5513{
5514 WMI_ACM_REJECT_EVENT *ev;
5515
5516 ev = (WMI_ACM_REJECT_EVENT *)datap;
5517 wmip->wmi_traffic_class = ev->trafficClass;
5518 printk("ACM REJECT %d\n",wmip->wmi_traffic_class);
5519 return A_OK;
5520}
5521
5522
5523#ifdef CONFIG_HOST_DSET_SUPPORT
5524A_STATUS
5525wmi_dset_data_reply(struct wmi_t *wmip,
5526 A_UINT32 status,
5527 A_UINT8 *user_buf,
5528 A_UINT32 length,
5529 A_UINT32 targ_buf,
5530 A_UINT32 targ_reply_fn,
5531 A_UINT32 targ_reply_arg)
5532{
5533 void *osbuf;
5534 WMIX_DSETDATA_REPLY_CMD *data_reply;
5535 A_UINT32 size;
5536
5537 size = sizeof(*data_reply) + length;
5538
5539 if (size <= length) {
5540 return A_ERROR;
5541 }
5542
5543 A_DPRINTF(DBG_WMI,
5544 (DBGFMT "Enter - length=%d status=%d\n", DBGARG, length, status));
5545
5546 osbuf = A_NETBUF_ALLOC(size);
5547 if (osbuf == NULL) {
5548 return A_NO_MEMORY;
5549 }
5550 A_NETBUF_PUT(osbuf, size);
5551 data_reply = (WMIX_DSETDATA_REPLY_CMD *)(A_NETBUF_DATA(osbuf));
5552
5553 data_reply->status = status;
5554 data_reply->targ_buf = targ_buf;
5555 data_reply->targ_reply_fn = targ_reply_fn;
5556 data_reply->targ_reply_arg = targ_reply_arg;
5557 data_reply->length = length;
5558
5559 if (status == A_OK) {
5560 if (a_copy_from_user(data_reply->buf, user_buf, length)) {
5561 A_NETBUF_FREE(osbuf);
5562 return A_ERROR;
5563 }
5564 }
5565
5566 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETDATA_REPLY_CMDID,
5567 NO_SYNC_WMIFLAG));
5568}
5569#endif
5570
5571A_STATUS
5572wmi_set_wsc_status_cmd(struct wmi_t *wmip, A_UINT32 status)
5573{
5574 void *osbuf;
5575 char *cmd;
5576
5577 wps_enable = status;
5578
5579 osbuf = a_netbuf_alloc(sizeof(1));
5580 if (osbuf == NULL) {
5581 return A_NO_MEMORY;
5582 }
5583
5584 a_netbuf_put(osbuf, sizeof(1));
5585
5586 cmd = (char *)(a_netbuf_to_data(osbuf));
5587
5588 A_MEMZERO(cmd, sizeof(*cmd));
5589 cmd[0] = (status?1:0);
5590 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WSC_STATUS_CMDID,
5591 NO_SYNC_WMIFLAG));
5592}
5593
5594#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
5595A_STATUS
5596wmi_prof_cfg_cmd(struct wmi_t *wmip,
5597 A_UINT32 period,
5598 A_UINT32 nbins)
5599{
5600 void *osbuf;
5601 WMIX_PROF_CFG_CMD *cmd;
5602
5603 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5604 if (osbuf == NULL) {
5605 return A_NO_MEMORY;
5606 }
5607
5608 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5609
5610 cmd = (WMIX_PROF_CFG_CMD *)(A_NETBUF_DATA(osbuf));
5611 A_MEMZERO(cmd, sizeof(*cmd));
5612 cmd->period = period;
5613 cmd->nbins = nbins;
5614
5615 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_PROF_CFG_CMDID, NO_SYNC_WMIFLAG));
5616}
5617
5618A_STATUS
5619wmi_prof_addr_set_cmd(struct wmi_t *wmip, A_UINT32 addr)
5620{
5621 void *osbuf;
5622 WMIX_PROF_ADDR_SET_CMD *cmd;
5623
5624 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5625 if (osbuf == NULL) {
5626 return A_NO_MEMORY;
5627 }
5628
5629 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5630
5631 cmd = (WMIX_PROF_ADDR_SET_CMD *)(A_NETBUF_DATA(osbuf));
5632 A_MEMZERO(cmd, sizeof(*cmd));
5633 cmd->addr = addr;
5634
5635 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_PROF_ADDR_SET_CMDID, NO_SYNC_WMIFLAG));
5636}
5637
5638A_STATUS
5639wmi_prof_start_cmd(struct wmi_t *wmip)
5640{
5641 return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_START_CMDID);
5642}
5643
5644A_STATUS
5645wmi_prof_stop_cmd(struct wmi_t *wmip)
5646{
5647 return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_STOP_CMDID);
5648}
5649
5650A_STATUS
5651wmi_prof_count_get_cmd(struct wmi_t *wmip)
5652{
5653 return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_COUNT_GET_CMDID);
5654}
5655
5656
5657static A_STATUS
5658wmi_prof_count_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
5659{
5660 WMIX_PROF_COUNT_EVENT *prof_data = (WMIX_PROF_COUNT_EVENT *)datap;
5661
5662 A_DPRINTF(DBG_WMI,
5663 (DBGFMT "Enter - addr=0x%x count=%d\n", DBGARG,
5664 prof_data->addr, prof_data->count));
5665
5666 A_WMI_PROF_COUNT_RX(prof_data->addr, prof_data->count);
5667
5668 return A_OK;
5669}
5670#endif
5671
5672#ifdef OS_ROAM_MANAGEMENT
5673
5674#define ETHERNET_MAC_ADDRESS_LENGTH 6
5675
5676void
5677wmi_scan_indication (struct wmi_t *wmip)
5678{
5679 struct ieee80211_node_table *nt;
5680 A_UINT32 gen;
5681 A_UINT32 size;
5682 A_UINT32 bsssize;
5683 bss_t *bss;
5684 A_UINT32 numbss;
5685 PNDIS_802_11_BSSID_SCAN_INFO psi;
5686 PBYTE pie;
5687 NDIS_802_11_FIXED_IEs *pFixed;
5688 NDIS_802_11_VARIABLE_IEs *pVar;
5689 A_UINT32 RateSize;
5690
5691 struct ar6kScanIndication
5692 {
5693 NDIS_802_11_STATUS_INDICATION ind;
5694 NDIS_802_11_BSSID_SCAN_INFO_LIST slist;
5695 } *pAr6kScanIndEvent;
5696
5697 nt = &wmip->wmi_scan_table;
5698
5699 ++nt->nt_si_gen;
5700
5701
5702 gen = nt->nt_si_gen;
5703
5704 size = offsetof(struct ar6kScanIndication, slist) +
5705 offsetof(NDIS_802_11_BSSID_SCAN_INFO_LIST, BssidScanInfo);
5706
5707 numbss = 0;
5708
5709 IEEE80211_NODE_LOCK(nt);
5710
5711
5712 for (bss = nt->nt_node_first; bss; bss = bss->ni_list_next) {
5713 if (bss->ni_si_gen != gen) {
5714 bsssize = offsetof(NDIS_802_11_BSSID_SCAN_INFO, Bssid) + offsetof(NDIS_WLAN_BSSID_EX, IEs);
5715 bsssize = bsssize + sizeof(NDIS_802_11_FIXED_IEs);
5716
5717#ifdef SUPPORT_WPA2
5718 if (bss->ni_cie.ie_rsn) {
5719 bsssize = bsssize + bss->ni_cie.ie_rsn[1] + 2;
5720 }
5721#endif
5722 if (bss->ni_cie.ie_wpa) {
5723 bsssize = bsssize + bss->ni_cie.ie_wpa[1] + 2;
5724 }
5725
5726
5727 bsssize = (bsssize + 3) & ~3;
5728
5729 size += bsssize;
5730
5731 numbss++;
5732 }
5733 }
5734
5735 if (0 == numbss)
5736 {
5737
5738 ar6000_scan_indication (wmip->wmi_devt, NULL, 0);
5739 IEEE80211_NODE_UNLOCK (nt);
5740 return;
5741 }
5742
5743 pAr6kScanIndEvent = A_MALLOC(size);
5744
5745 if (NULL == pAr6kScanIndEvent)
5746 {
5747 IEEE80211_NODE_UNLOCK(nt);
5748 return;
5749 }
5750
5751 A_MEMZERO(pAr6kScanIndEvent, size);
5752
5753
5754 pAr6kScanIndEvent->ind.StatusType = Ndis802_11StatusType_BssidScanInfoList;
5755 pAr6kScanIndEvent->slist.Version = 1;
5756 pAr6kScanIndEvent->slist.NumItems = numbss;
5757
5758 psi = &pAr6kScanIndEvent->slist.BssidScanInfo[0];
5759
5760 for (bss = nt->nt_node_first; bss; bss = bss->ni_list_next) {
5761 if (bss->ni_si_gen != gen) {
5762
5763 bss->ni_si_gen = gen;
5764
5765
5766 psi->ScanTime = bss->ni_tstamp - WLAN_NODE_INACT_TIMEOUT_MSEC;
5767
5768
5769 bsssize = offsetof(NDIS_WLAN_BSSID_EX, IEs);
5770 bsssize = bsssize + sizeof(NDIS_802_11_FIXED_IEs);
5771
5772#ifdef SUPPORT_WPA2
5773 if (bss->ni_cie.ie_rsn) {
5774 bsssize = bsssize + bss->ni_cie.ie_rsn[1] + 2;
5775 }
5776#endif
5777 if (bss->ni_cie.ie_wpa) {
5778 bsssize = bsssize + bss->ni_cie.ie_wpa[1] + 2;
5779 }
5780
5781
5782 bsssize = (bsssize + 3) & ~3;
5783
5784 psi->Bssid.Length = bsssize;
5785
5786 memcpy (psi->Bssid.MacAddress, bss->ni_macaddr, ETHERNET_MAC_ADDRESS_LENGTH);
5787
5788
5789
5790
5791
5792
5793 psi->Bssid.Ssid.SsidLength = 0;
5794 pie = bss->ni_cie.ie_ssid;
5795
5796 if (pie) {
5797
5798
5799
5800
5801
5802
5803
5804 if (pie[1] <= 32) {
5805 psi->Bssid.Ssid.SsidLength = pie[1];
5806 memcpy(psi->Bssid.Ssid.Ssid, &pie[2], psi->Bssid.Ssid.SsidLength);
5807 }
5808 }
5809 psi->Bssid.Privacy = (bss->ni_cie.ie_capInfo & 0x10) ? 1 : 0;
5810
5811
5812 psi->Bssid.Rssi = bss->ni_rssi;
5813
5814 if (bss->ni_cie.ie_chan >= 2412 && bss->ni_cie.ie_chan <= 2484) {
5815
5816 if (bss->ni_cie.ie_rates && bss->ni_cie.ie_xrates) {
5817 psi->Bssid.NetworkTypeInUse = Ndis802_11OFDM24;
5818 }
5819 else {
5820 psi->Bssid.NetworkTypeInUse = Ndis802_11DS;
5821 }
5822 }
5823 else {
5824 psi->Bssid.NetworkTypeInUse = Ndis802_11OFDM5;
5825 }
5826
5827 psi->Bssid.Configuration.Length = sizeof(psi->Bssid.Configuration);
5828 psi->Bssid.Configuration.BeaconPeriod = bss->ni_cie.ie_beaconInt;
5829 psi->Bssid.Configuration.ATIMWindow = 0;
5830 psi->Bssid.Configuration.DSConfig = bss->ni_cie.ie_chan * 1000;
5831 psi->Bssid.InfrastructureMode = ((bss->ni_cie.ie_capInfo & 0x03) == 0x01 ) ? Ndis802_11Infrastructure : Ndis802_11IBSS;
5832
5833 RateSize = 0;
5834 pie = bss->ni_cie.ie_rates;
5835 if (pie) {
5836 RateSize = (pie[1] < NDIS_802_11_LENGTH_RATES_EX) ? pie[1] : NDIS_802_11_LENGTH_RATES_EX;
5837 memcpy(psi->Bssid.SupportedRates, &pie[2], RateSize);
5838 }
5839 pie = bss->ni_cie.ie_xrates;
5840 if (pie && RateSize < NDIS_802_11_LENGTH_RATES_EX) {
5841 memcpy(psi->Bssid.SupportedRates + RateSize, &pie[2],
5842 (pie[1] < (NDIS_802_11_LENGTH_RATES_EX - RateSize)) ? pie[1] : (NDIS_802_11_LENGTH_RATES_EX - RateSize));
5843 }
5844
5845
5846 psi->Bssid.IELength = sizeof(NDIS_802_11_FIXED_IEs);
5847
5848 pFixed = (NDIS_802_11_FIXED_IEs *)psi->Bssid.IEs;
5849 memcpy(pFixed->Timestamp, bss->ni_cie.ie_tstamp, sizeof(pFixed->Timestamp));
5850 pFixed->BeaconInterval = bss->ni_cie.ie_beaconInt;
5851 pFixed->Capabilities = bss->ni_cie.ie_capInfo;
5852
5853
5854
5855 pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pFixed + sizeof(NDIS_802_11_FIXED_IEs));
5856
5857#ifdef SUPPORT_WPA2
5858
5859 if (bss->ni_cie.ie_rsn) {
5860 pie = bss->ni_cie.ie_rsn;
5861 psi->Bssid.IELength += pie[1] + 2;
5862 memcpy(pVar, pie, pie[1] + 2);
5863 pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pVar + pie[1] + 2);
5864 }
5865#endif
5866
5867 if (bss->ni_cie.ie_wpa) {
5868 pie = bss->ni_cie.ie_wpa;
5869 psi->Bssid.IELength += pie[1] + 2;
5870 memcpy(pVar, pie, pie[1] + 2);
5871 pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pVar + pie[1] + 2);
5872 }
5873
5874
5875 psi = (PNDIS_802_11_BSSID_SCAN_INFO)((BYTE*)psi + bsssize + FIELD_OFFSET(NDIS_802_11_BSSID_SCAN_INFO, Bssid));
5876 }
5877 }
5878
5879 IEEE80211_NODE_UNLOCK(nt);
5880
5881
5882
5883
5884
5885 ar6000_scan_indication (wmip->wmi_devt, pAr6kScanIndEvent, size);
5886
5887 A_FREE(pAr6kScanIndEvent);
5888}
5889#endif
5890
5891A_UINT8
5892ar6000_get_upper_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh,
5893 A_UINT32 size)
5894{
5895 A_UINT32 index;
5896 A_UINT8 threshold = (A_UINT8)sq_thresh->upper_threshold[size - 1];
5897
5898
5899 for (index = 0; index < size; index ++) {
5900 if (rssi < sq_thresh->upper_threshold[index]) {
5901 threshold = (A_UINT8)sq_thresh->upper_threshold[index];
5902 break;
5903 }
5904 }
5905
5906 return threshold;
5907}
5908
5909A_UINT8
5910ar6000_get_lower_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh,
5911 A_UINT32 size)
5912{
5913 A_UINT32 index;
5914 A_UINT8 threshold = (A_UINT8)sq_thresh->lower_threshold[size - 1];
5915
5916
5917 for (index = 0; index < size; index ++) {
5918 if (rssi > sq_thresh->lower_threshold[index]) {
5919 threshold = (A_UINT8)sq_thresh->lower_threshold[index];
5920 break;
5921 }
5922 }
5923
5924 return threshold;
5925}
5926static A_STATUS
5927wmi_send_rssi_threshold_params(struct wmi_t *wmip,
5928 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
5929{
5930 void *osbuf;
5931 A_INT8 size;
5932 WMI_RSSI_THRESHOLD_PARAMS_CMD *cmd;
5933
5934 size = sizeof (*cmd);
5935
5936 osbuf = A_NETBUF_ALLOC(size);
5937 if (osbuf == NULL) {
5938 return A_NO_MEMORY;
5939 }
5940
5941 A_NETBUF_PUT(osbuf, size);
5942
5943 cmd = (WMI_RSSI_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
5944 A_MEMZERO(cmd, size);
5945 A_MEMCPY(cmd, rssiCmd, sizeof(WMI_RSSI_THRESHOLD_PARAMS_CMD));
5946
5947 return (wmi_cmd_send(wmip, osbuf, WMI_RSSI_THRESHOLD_PARAMS_CMDID,
5948 NO_SYNC_WMIFLAG));
5949}
5950static A_STATUS
5951wmi_send_snr_threshold_params(struct wmi_t *wmip,
5952 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
5953{
5954 void *osbuf;
5955 A_INT8 size;
5956 WMI_SNR_THRESHOLD_PARAMS_CMD *cmd;
5957
5958 size = sizeof (*cmd);
5959
5960 osbuf = A_NETBUF_ALLOC(size);
5961 if (osbuf == NULL) {
5962 return A_NO_MEMORY;
5963 }
5964
5965 A_NETBUF_PUT(osbuf, size);
5966 cmd = (WMI_SNR_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
5967 A_MEMZERO(cmd, size);
5968 A_MEMCPY(cmd, snrCmd, sizeof(WMI_SNR_THRESHOLD_PARAMS_CMD));
5969
5970 return (wmi_cmd_send(wmip, osbuf, WMI_SNR_THRESHOLD_PARAMS_CMDID,
5971 NO_SYNC_WMIFLAG));
5972}
5973
5974A_STATUS
5975wmi_set_target_event_report_cmd(struct wmi_t *wmip, WMI_SET_TARGET_EVENT_REPORT_CMD* cmd)
5976{
5977 void *osbuf;
5978 WMI_SET_TARGET_EVENT_REPORT_CMD* alloc_cmd;
5979
5980 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5981 if (osbuf == NULL) {
5982 return A_NO_MEMORY;
5983 }
5984
5985 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5986
5987 alloc_cmd = (WMI_SET_TARGET_EVENT_REPORT_CMD *)(A_NETBUF_DATA(osbuf));
5988 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5989 A_MEMCPY(alloc_cmd, cmd, sizeof(*cmd));
5990
5991 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TARGET_EVENT_REPORT_CMDID,
5992 NO_SYNC_WMIFLAG));
5993}
5994
5995bss_t *wmi_rm_current_bss (struct wmi_t *wmip, A_UINT8 *id)
5996{
5997 wmi_get_current_bssid (wmip, id);
5998 return wlan_node_remove (&wmip->wmi_scan_table, id);
5999}
6000
6001A_STATUS wmi_add_current_bss (struct wmi_t *wmip, A_UINT8 *id, bss_t *bss)
6002{
6003 wlan_setup_node (&wmip->wmi_scan_table, bss, id);
6004 return A_OK;
6005}
6006
6007#ifdef ATH_AR6K_11N_SUPPORT
6008static A_STATUS
6009wmi_addba_req_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
6010{
6011 WMI_ADDBA_REQ_EVENT *cmd = (WMI_ADDBA_REQ_EVENT *)datap;
6012
6013 A_WMI_AGGR_RECV_ADDBA_REQ_EVT(wmip->wmi_devt, cmd);
6014
6015 return A_OK;
6016}
6017
6018
6019static A_STATUS
6020wmi_addba_resp_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
6021{
6022 WMI_ADDBA_RESP_EVENT *cmd = (WMI_ADDBA_RESP_EVENT *)datap;
6023
6024 A_WMI_AGGR_RECV_ADDBA_RESP_EVT(wmip->wmi_devt, cmd);
6025
6026 return A_OK;
6027}
6028
6029static A_STATUS
6030wmi_delba_req_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
6031{
6032 WMI_DELBA_EVENT *cmd = (WMI_DELBA_EVENT *)datap;
6033
6034 A_WMI_AGGR_RECV_DELBA_REQ_EVT(wmip->wmi_devt, cmd);
6035
6036 return A_OK;
6037}
6038
6039A_STATUS
6040wmi_btcoex_config_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
6041{
6042 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
6043
6044 A_WMI_BTCOEX_CONFIG_EVENT(wmip->wmi_devt, datap, len);
6045
6046 return A_OK;
6047}
6048
6049
6050A_STATUS
6051wmi_btcoex_stats_event_rx(struct wmi_t * wmip,A_UINT8 * datap,int len)
6052{
6053 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
6054
6055 A_WMI_BTCOEX_STATS_EVENT(wmip->wmi_devt, datap, len);
6056
6057 return A_OK;
6058
6059}
6060#endif
6061
6062static A_STATUS
6063wmi_hci_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
6064{
6065 WMI_HCI_EVENT *cmd = (WMI_HCI_EVENT *)datap;
6066 A_WMI_HCI_EVENT_EVT(wmip->wmi_devt, cmd);
6067
6068 return A_OK;
6069}
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086A_STATUS
6087wmi_ap_profile_commit(struct wmi_t *wmip, WMI_CONNECT_CMD *p)
6088{
6089 void *osbuf;
6090 WMI_CONNECT_CMD *cm;
6091
6092 osbuf = A_NETBUF_ALLOC(sizeof(*cm));
6093 if (osbuf == NULL) {
6094 return A_NO_MEMORY;
6095 }
6096
6097 A_NETBUF_PUT(osbuf, sizeof(*cm));
6098 cm = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf));
6099 A_MEMZERO(cm, sizeof(*cm));
6100
6101 A_MEMCPY(cm,p,sizeof(*cm));
6102
6103 return (wmi_cmd_send(wmip, osbuf, WMI_AP_CONFIG_COMMIT_CMDID, NO_SYNC_WMIFLAG));
6104}
6105
6106
6107
6108
6109
6110
6111
6112A_STATUS
6113wmi_ap_set_hidden_ssid(struct wmi_t *wmip, A_UINT8 hidden_ssid)
6114{
6115 void *osbuf;
6116 WMI_AP_HIDDEN_SSID_CMD *hs;
6117
6118 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_HIDDEN_SSID_CMD));
6119 if (osbuf == NULL) {
6120 return A_NO_MEMORY;
6121 }
6122
6123 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_HIDDEN_SSID_CMD));
6124 hs = (WMI_AP_HIDDEN_SSID_CMD *)(A_NETBUF_DATA(osbuf));
6125 A_MEMZERO(hs, sizeof(*hs));
6126
6127 hs->hidden_ssid = hidden_ssid;
6128
6129 A_DPRINTF(DBG_WMI, (DBGFMT "AR6000_XIOCTL_AP_HIDDEN_SSID %d\n", DBGARG , hidden_ssid));
6130 return (wmi_cmd_send(wmip, osbuf, WMI_AP_HIDDEN_SSID_CMDID, NO_SYNC_WMIFLAG));
6131}
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141A_STATUS
6142wmi_ap_set_num_sta(struct wmi_t *wmip, A_UINT8 num_sta)
6143{
6144 void *osbuf;
6145 WMI_AP_SET_NUM_STA_CMD *ns;
6146
6147 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_NUM_STA_CMD));
6148 if (osbuf == NULL) {
6149 return A_NO_MEMORY;
6150 }
6151
6152 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_NUM_STA_CMD));
6153 ns = (WMI_AP_SET_NUM_STA_CMD *)(A_NETBUF_DATA(osbuf));
6154 A_MEMZERO(ns, sizeof(*ns));
6155
6156 ns->num_sta = num_sta;
6157
6158 A_DPRINTF(DBG_WMI, (DBGFMT "AR6000_XIOCTL_AP_SET_MAX_NUM_STA %d\n", DBGARG , num_sta));
6159 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_NUM_STA_CMDID, NO_SYNC_WMIFLAG));
6160}
6161
6162
6163
6164
6165
6166
6167
6168
6169A_STATUS
6170wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *acl)
6171{
6172 void *osbuf;
6173 WMI_AP_ACL_MAC_CMD *a;
6174
6175 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_ACL_MAC_CMD));
6176 if (osbuf == NULL) {
6177 return A_NO_MEMORY;
6178 }
6179
6180 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_ACL_MAC_CMD));
6181 a = (WMI_AP_ACL_MAC_CMD *)(A_NETBUF_DATA(osbuf));
6182 A_MEMZERO(a, sizeof(*a));
6183 A_MEMCPY(a,acl,sizeof(*acl));
6184
6185 return (wmi_cmd_send(wmip, osbuf, WMI_AP_ACL_MAC_LIST_CMDID, NO_SYNC_WMIFLAG));
6186}
6187
6188
6189
6190
6191
6192
6193
6194
6195A_STATUS
6196wmi_ap_set_mlme(struct wmi_t *wmip, A_UINT8 cmd, A_UINT8 *mac, A_UINT16 reason)
6197{
6198 void *osbuf;
6199 WMI_AP_SET_MLME_CMD *mlme;
6200
6201 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_MLME_CMD));
6202 if (osbuf == NULL) {
6203 return A_NO_MEMORY;
6204 }
6205
6206 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_MLME_CMD));
6207 mlme = (WMI_AP_SET_MLME_CMD *)(A_NETBUF_DATA(osbuf));
6208 A_MEMZERO(mlme, sizeof(*mlme));
6209
6210 mlme->cmd = cmd;
6211 A_MEMCPY(mlme->mac, mac, ATH_MAC_LEN);
6212 mlme->reason = reason;
6213
6214 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_MLME_CMDID, NO_SYNC_WMIFLAG));
6215}
6216
6217static A_STATUS
6218wmi_pspoll_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
6219{
6220 WMI_PSPOLL_EVENT *ev;
6221
6222 if (len < sizeof(WMI_PSPOLL_EVENT)) {
6223 return A_EINVAL;
6224 }
6225 ev = (WMI_PSPOLL_EVENT *)datap;
6226
6227 A_WMI_PSPOLL_EVENT(wmip->wmi_devt, ev->aid);
6228 return A_OK;
6229}
6230
6231static A_STATUS
6232wmi_dtimexpiry_event_rx(struct wmi_t *wmip, A_UINT8 *datap,int len)
6233{
6234 A_WMI_DTIMEXPIRY_EVENT(wmip->wmi_devt);
6235 return A_OK;
6236}
6237
6238#ifdef WAPI_ENABLE
6239static A_STATUS
6240wmi_wapi_rekey_event_rx(struct wmi_t *wmip, A_UINT8 *datap,int len)
6241{
6242 A_UINT8 *ev;
6243
6244 if (len < 7) {
6245 return A_EINVAL;
6246 }
6247 ev = (A_UINT8 *)datap;
6248
6249 A_WMI_WAPI_REKEY_EVENT(wmip->wmi_devt, *ev, &ev[1]);
6250 return A_OK;
6251}
6252#endif
6253
6254A_STATUS
6255wmi_set_pvb_cmd(struct wmi_t *wmip, A_UINT16 aid, A_BOOL flag)
6256{
6257 WMI_AP_SET_PVB_CMD *cmd;
6258 void *osbuf = NULL;
6259
6260 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_PVB_CMD));
6261 if (osbuf == NULL) {
6262 return A_NO_MEMORY;
6263 }
6264
6265 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_PVB_CMD));
6266 cmd = (WMI_AP_SET_PVB_CMD *)(A_NETBUF_DATA(osbuf));
6267 A_MEMZERO(cmd, sizeof(*cmd));
6268
6269 cmd->aid = aid;
6270 cmd->flag = flag;
6271
6272 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_PVB_CMDID, NO_SYNC_WMIFLAG));
6273}
6274
6275A_STATUS
6276wmi_ap_conn_inact_time(struct wmi_t *wmip, A_UINT32 period)
6277{
6278 WMI_AP_CONN_INACT_CMD *cmd;
6279 void *osbuf = NULL;
6280
6281 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_CONN_INACT_CMD));
6282 if (osbuf == NULL) {
6283 return A_NO_MEMORY;
6284 }
6285
6286 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_CONN_INACT_CMD));
6287 cmd = (WMI_AP_CONN_INACT_CMD *)(A_NETBUF_DATA(osbuf));
6288 A_MEMZERO(cmd, sizeof(*cmd));
6289
6290 cmd->period = period;
6291
6292 return (wmi_cmd_send(wmip, osbuf, WMI_AP_CONN_INACT_CMDID, NO_SYNC_WMIFLAG));
6293}
6294
6295A_STATUS
6296wmi_ap_bgscan_time(struct wmi_t *wmip, A_UINT32 period, A_UINT32 dwell)
6297{
6298 WMI_AP_PROT_SCAN_TIME_CMD *cmd;
6299 void *osbuf = NULL;
6300
6301 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_PROT_SCAN_TIME_CMD));
6302 if (osbuf == NULL) {
6303 return A_NO_MEMORY;
6304 }
6305
6306 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_PROT_SCAN_TIME_CMD));
6307 cmd = (WMI_AP_PROT_SCAN_TIME_CMD *)(A_NETBUF_DATA(osbuf));
6308 A_MEMZERO(cmd, sizeof(*cmd));
6309
6310 cmd->period_min = period;
6311 cmd->dwell_ms = dwell;
6312
6313 return (wmi_cmd_send(wmip, osbuf, WMI_AP_PROT_SCAN_TIME_CMDID, NO_SYNC_WMIFLAG));
6314}
6315
6316A_STATUS
6317wmi_ap_set_dtim(struct wmi_t *wmip, A_UINT8 dtim)
6318{
6319 WMI_AP_SET_DTIM_CMD *cmd;
6320 void *osbuf = NULL;
6321
6322 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_DTIM_CMD));
6323 if (osbuf == NULL) {
6324 return A_NO_MEMORY;
6325 }
6326
6327 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_DTIM_CMD));
6328 cmd = (WMI_AP_SET_DTIM_CMD *)(A_NETBUF_DATA(osbuf));
6329 A_MEMZERO(cmd, sizeof(*cmd));
6330
6331 cmd->dtim = dtim;
6332
6333 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_DTIM_CMDID, NO_SYNC_WMIFLAG));
6334}
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344A_STATUS
6345wmi_ap_set_acl_policy(struct wmi_t *wmip, A_UINT8 policy)
6346{
6347 void *osbuf;
6348 WMI_AP_ACL_POLICY_CMD *po;
6349
6350 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_ACL_POLICY_CMD));
6351 if (osbuf == NULL) {
6352 return A_NO_MEMORY;
6353}
6354
6355 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_ACL_POLICY_CMD));
6356 po = (WMI_AP_ACL_POLICY_CMD *)(A_NETBUF_DATA(osbuf));
6357 A_MEMZERO(po, sizeof(*po));
6358
6359 po->policy = policy;
6360
6361 return (wmi_cmd_send(wmip, osbuf, WMI_AP_ACL_POLICY_CMDID, NO_SYNC_WMIFLAG));
6362}
6363
6364A_STATUS
6365wmi_ap_set_rateset(struct wmi_t *wmip, A_UINT8 rateset)
6366{
6367 void *osbuf;
6368 WMI_AP_SET_11BG_RATESET_CMD *rs;
6369
6370 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_11BG_RATESET_CMD));
6371 if (osbuf == NULL) {
6372 return A_NO_MEMORY;
6373 }
6374
6375 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_11BG_RATESET_CMD));
6376 rs = (WMI_AP_SET_11BG_RATESET_CMD *)(A_NETBUF_DATA(osbuf));
6377 A_MEMZERO(rs, sizeof(*rs));
6378
6379 rs->rateset = rateset;
6380
6381 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_11BG_RATESET_CMDID, NO_SYNC_WMIFLAG));
6382}
6383
6384#ifdef ATH_AR6K_11N_SUPPORT
6385A_STATUS
6386wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd)
6387{
6388 void *osbuf;
6389 WMI_SET_HT_CAP_CMD *htCap;
6390 A_UINT8 band;
6391
6392 osbuf = A_NETBUF_ALLOC(sizeof(*htCap));
6393 if (osbuf == NULL) {
6394 return A_NO_MEMORY;
6395 }
6396
6397 A_NETBUF_PUT(osbuf, sizeof(*htCap));
6398
6399 band = (cmd->band)? A_BAND_5GHZ : A_BAND_24GHZ;
6400 wmip->wmi_ht_allowed[band] = (cmd->enable)? 1:0;
6401
6402 htCap = (WMI_SET_HT_CAP_CMD *)(A_NETBUF_DATA(osbuf));
6403 A_MEMZERO(htCap, sizeof(*htCap));
6404 A_MEMCPY(htCap, cmd, sizeof(*htCap));
6405
6406 return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_CAP_CMDID,
6407 NO_SYNC_WMIFLAG));
6408}
6409
6410A_STATUS
6411wmi_set_ht_op_cmd(struct wmi_t *wmip, A_UINT8 sta_chan_width)
6412{
6413 void *osbuf;
6414 WMI_SET_HT_OP_CMD *htInfo;
6415
6416 osbuf = A_NETBUF_ALLOC(sizeof(*htInfo));
6417 if (osbuf == NULL) {
6418 return A_NO_MEMORY;
6419 }
6420
6421 A_NETBUF_PUT(osbuf, sizeof(*htInfo));
6422
6423 htInfo = (WMI_SET_HT_OP_CMD *)(A_NETBUF_DATA(osbuf));
6424 A_MEMZERO(htInfo, sizeof(*htInfo));
6425 htInfo->sta_chan_width = sta_chan_width;
6426
6427 return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_OP_CMDID,
6428 NO_SYNC_WMIFLAG));
6429}
6430#endif
6431
6432A_STATUS
6433wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, A_UINT32 *pMaskArray)
6434{
6435 void *osbuf;
6436 WMI_SET_TX_SELECT_RATES_CMD *pData;
6437
6438 osbuf = A_NETBUF_ALLOC(sizeof(*pData));
6439 if (osbuf == NULL) {
6440 return A_NO_MEMORY;
6441 }
6442
6443 A_NETBUF_PUT(osbuf, sizeof(*pData));
6444
6445 pData = (WMI_SET_TX_SELECT_RATES_CMD *)(A_NETBUF_DATA(osbuf));
6446 A_MEMCPY(pData, pMaskArray, sizeof(*pData));
6447
6448 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_SELECT_RATES_CMDID,
6449 NO_SYNC_WMIFLAG));
6450}
6451
6452
6453A_STATUS
6454wmi_send_hci_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT16 sz)
6455{
6456 void *osbuf;
6457 WMI_HCI_CMD *cmd;
6458
6459 osbuf = A_NETBUF_ALLOC(sizeof(*cmd) + sz);
6460 if (osbuf == NULL) {
6461 return A_NO_MEMORY;
6462 }
6463
6464 A_NETBUF_PUT(osbuf, sizeof(*cmd) + sz);
6465 cmd = (WMI_HCI_CMD *)(A_NETBUF_DATA(osbuf));
6466
6467 cmd->cmd_buf_sz = sz;
6468 A_MEMCPY(cmd->buf, buf, sz);
6469 return (wmi_cmd_send(wmip, osbuf, WMI_HCI_CMD_CMDID, NO_SYNC_WMIFLAG));
6470}
6471
6472#ifdef ATH_AR6K_11N_SUPPORT
6473A_STATUS
6474wmi_allow_aggr_cmd(struct wmi_t *wmip, A_UINT16 tx_tidmask, A_UINT16 rx_tidmask)
6475{
6476 void *osbuf;
6477 WMI_ALLOW_AGGR_CMD *cmd;
6478
6479 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6480 if (osbuf == NULL) {
6481 return A_NO_MEMORY;
6482 }
6483
6484 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6485
6486 cmd = (WMI_ALLOW_AGGR_CMD *)(A_NETBUF_DATA(osbuf));
6487 cmd->tx_allow_aggr = tx_tidmask;
6488 cmd->rx_allow_aggr = rx_tidmask;
6489
6490 return (wmi_cmd_send(wmip, osbuf, WMI_ALLOW_AGGR_CMDID, NO_SYNC_WMIFLAG));
6491}
6492
6493A_STATUS
6494wmi_setup_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid)
6495{
6496 void *osbuf;
6497 WMI_ADDBA_REQ_CMD *cmd;
6498
6499 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6500 if (osbuf == NULL) {
6501 return A_NO_MEMORY;
6502 }
6503
6504 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6505
6506 cmd = (WMI_ADDBA_REQ_CMD *)(A_NETBUF_DATA(osbuf));
6507 cmd->tid = tid;
6508
6509 return (wmi_cmd_send(wmip, osbuf, WMI_ADDBA_REQ_CMDID, NO_SYNC_WMIFLAG));
6510}
6511
6512A_STATUS
6513wmi_delete_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid, A_BOOL uplink)
6514{
6515 void *osbuf;
6516 WMI_DELBA_REQ_CMD *cmd;
6517
6518 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6519 if (osbuf == NULL) {
6520 return A_NO_MEMORY;
6521 }
6522
6523 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6524
6525 cmd = (WMI_DELBA_REQ_CMD *)(A_NETBUF_DATA(osbuf));
6526 cmd->tid = tid;
6527 cmd->is_sender_initiator = uplink;
6528
6529
6530 return (wmi_cmd_send(wmip, osbuf, WMI_DELBA_REQ_CMDID, NO_SYNC_WMIFLAG));
6531}
6532#endif
6533
6534A_STATUS
6535wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, A_UINT8 rxMetaVersion,
6536 A_BOOL rxDot11Hdr, A_BOOL defragOnHost)
6537{
6538 void *osbuf;
6539 WMI_RX_FRAME_FORMAT_CMD *cmd;
6540
6541 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6542 if (osbuf == NULL) {
6543 return A_NO_MEMORY;
6544 }
6545
6546 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6547
6548 cmd = (WMI_RX_FRAME_FORMAT_CMD *)(A_NETBUF_DATA(osbuf));
6549 cmd->dot11Hdr = (rxDot11Hdr==TRUE)? 1:0;
6550 cmd->defragOnHost = (defragOnHost==TRUE)? 1:0;
6551 cmd->metaVersion = rxMetaVersion;
6552
6553
6554 return (wmi_cmd_send(wmip, osbuf, WMI_RX_FRAME_FORMAT_CMDID, NO_SYNC_WMIFLAG));
6555}
6556
6557
6558A_STATUS
6559wmi_set_thin_mode_cmd(struct wmi_t *wmip, A_BOOL bThinMode)
6560{
6561 void *osbuf;
6562 WMI_SET_THIN_MODE_CMD *cmd;
6563
6564 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6565 if (osbuf == NULL) {
6566 return A_NO_MEMORY;
6567 }
6568
6569 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6570
6571 cmd = (WMI_SET_THIN_MODE_CMD *)(A_NETBUF_DATA(osbuf));
6572 cmd->enable = (bThinMode==TRUE)? 1:0;
6573
6574
6575 return (wmi_cmd_send(wmip, osbuf, WMI_SET_THIN_MODE_CMDID, NO_SYNC_WMIFLAG));
6576}
6577
6578
6579A_STATUS
6580wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE precedence)
6581{
6582 void *osbuf;
6583 WMI_SET_BT_WLAN_CONN_PRECEDENCE *cmd;
6584
6585 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6586 if (osbuf == NULL) {
6587 return A_NO_MEMORY;
6588 }
6589
6590 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6591
6592 cmd = (WMI_SET_BT_WLAN_CONN_PRECEDENCE *)(A_NETBUF_DATA(osbuf));
6593 A_MEMZERO(cmd, sizeof(*cmd));
6594 cmd->precedence = precedence;
6595
6596 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID,
6597 NO_SYNC_WMIFLAG));
6598}
6599
6600A_STATUS
6601wmi_set_pmk_cmd(struct wmi_t *wmip, A_UINT8 *pmk)
6602{
6603 void *osbuf;
6604 WMI_SET_PMK_CMD *p;
6605
6606 osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_PMK_CMD));
6607 if (osbuf == NULL) {
6608 return A_NO_MEMORY;
6609 }
6610
6611 A_NETBUF_PUT(osbuf, sizeof(WMI_SET_PMK_CMD));
6612
6613 p = (WMI_SET_PMK_CMD *)(A_NETBUF_DATA(osbuf));
6614 A_MEMZERO(p, sizeof(*p));
6615
6616 A_MEMCPY(p->pmk, pmk, WMI_PMK_LEN);
6617
6618 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMK_CMDID, NO_SYNC_WMIFLAG));
6619}
6620
6621A_STATUS
6622wmi_SGI_cmd(struct wmi_t *wmip, A_UINT32 sgiMask, A_UINT8 sgiPERThreshold)
6623{
6624 void *osbuf;
6625 WMI_SET_TX_SGI_PARAM_CMD *cmd;
6626
6627 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6628 if (osbuf == NULL) {
6629 return A_NO_MEMORY ;
6630 }
6631
6632 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6633
6634 cmd = (WMI_SET_TX_SGI_PARAM_CMD *)(A_NETBUF_DATA(osbuf));
6635 A_MEMZERO(cmd, sizeof(*cmd));
6636 cmd->sgiMask = sgiMask;
6637 cmd->sgiPERThreshold = sgiPERThreshold;
6638 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_SGI_PARAM_CMDID,
6639 NO_SYNC_WMIFLAG));
6640}
6641
6642bss_t *
6643wmi_find_matching_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid,
6644 A_UINT32 ssidLength,
6645 A_UINT32 dot11AuthMode, A_UINT32 authMode,
6646 A_UINT32 pairwiseCryptoType, A_UINT32 grpwiseCryptoTyp)
6647{
6648 bss_t *node = NULL;
6649 node = wlan_find_matching_Ssidnode (&wmip->wmi_scan_table, pSsid,
6650 ssidLength, dot11AuthMode, authMode, pairwiseCryptoType, grpwiseCryptoTyp);
6651
6652 return node;
6653}
6654
6655A_UINT16
6656wmi_ieee2freq (int chan)
6657{
6658 A_UINT16 freq = 0;
6659 freq = wlan_ieee2freq (chan);
6660 return freq;
6661
6662}
6663
6664A_UINT32
6665wmi_freq2ieee (A_UINT16 freq)
6666{
6667 A_UINT16 chan = 0;
6668 chan = wlan_freq2ieee (freq);
6669 return chan;
6670}
6671