d14bad28bdfba4e41d2a3194c0083bc7fd4d0bf3
[pandora-kernel.git] / drivers / staging / ath6kl / wmi / wmi.c
1 //------------------------------------------------------------------------------
2 // Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
3 // 
4 //
5 // Permission to use, copy, modify, and/or distribute this software for any
6 // purpose with or without fee is hereby granted, provided that the above
7 // copyright notice and this permission notice appear in all copies.
8 //
9 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 //
17 //
18 //------------------------------------------------------------------------------
19 //==============================================================================
20 // This module implements the hardware independent layer of the
21 // Wireless Module Interface (WMI) protocol.
22 //
23 // Author(s): ="Atheros"
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
51 static ATH_DEBUG_MASK_DESCRIPTION wmi_debug_desc[] = {
52     { ATH_DEBUG_WMI , "General WMI Tracing"},
53 };
54
55 ATH_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
73 static A_STATUS wmi_ready_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
74
75 static A_STATUS wmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
76                                      int len);
77 static A_STATUS wmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
78                                         int len);
79
80 static A_STATUS wmi_tkip_micerr_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
81                                         int len);
82 static A_STATUS wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
83                                      int len);
84 static A_STATUS wmi_opt_frame_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
85                                        int len);
86 static A_STATUS wmi_pstream_timeout_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
87                                      int len);
88 static A_STATUS wmi_sync_point(struct wmi_t *wmip);
89
90 static A_STATUS wmi_bitrate_reply_rx(struct wmi_t *wmip, A_UINT8 *datap,
91                                      int len);
92 static A_STATUS wmi_ratemask_reply_rx(struct wmi_t *wmip, A_UINT8 *datap,
93                                      int len);
94 static A_STATUS wmi_channelList_reply_rx(struct wmi_t *wmip, A_UINT8 *datap,
95                                          int len);
96 static A_STATUS wmi_regDomain_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
97                                        int len);
98 static A_STATUS wmi_txPwr_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
99 static A_STATUS wmi_neighborReport_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
100                                              int len);
101
102 static A_STATUS wmi_dset_open_req_rx(struct wmi_t *wmip, A_UINT8 *datap,
103                                      int len);
104 #ifdef CONFIG_HOST_DSET_SUPPORT
105 static A_STATUS wmi_dset_close_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
106 static A_STATUS wmi_dset_data_req_rx(struct wmi_t *wmip, A_UINT8 *datap,
107                                      int len);
108 #endif /* CONFIG_HOST_DSET_SUPPORT */
109
110
111 static A_STATUS wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap,
112                                      int len);
113 static A_STATUS wmi_errorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
114 static A_STATUS wmi_statsEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
115 static A_STATUS wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
116 static A_STATUS wmi_hbChallengeResp_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
117 static A_STATUS wmi_reportErrorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
118 static A_STATUS wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
119 static A_STATUS wmi_channel_change_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
120 static A_STATUS wmi_roam_tbl_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
121                                       int len);
122 static A_STATUS wmi_roam_data_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
123                                       int len);
124 static A_STATUS wmi_get_wow_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
125                                       int len);
126 static A_STATUS
127 wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len);
128
129 static A_STATUS
130 wmi_set_params_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len);
131
132 static A_STATUS
133 wmi_acm_reject_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len);
134
135 #ifdef CONFIG_HOST_GPIO_SUPPORT
136 static A_STATUS wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
137 static A_STATUS wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
138 static A_STATUS wmi_gpio_ack_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
139 #endif /* CONFIG_HOST_GPIO_SUPPORT */
140
141 #ifdef CONFIG_HOST_TCMD_SUPPORT
142 static A_STATUS
143 wmi_tcmd_test_report_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
144 #endif
145
146 static A_STATUS
147 wmi_txRetryErrEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
148
149 static A_STATUS
150 wmi_snrThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
151
152 static A_STATUS
153 wmi_lqThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
154
155 static A_BOOL
156 wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_INT32 rateIndex);
157
158 static A_STATUS
159 wmi_aplistEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
160
161 static A_STATUS
162 wmi_dbglog_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
163
164 static A_STATUS wmi_keepalive_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
165
166 A_STATUS wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId,
167                   WMI_SYNC_FLAG syncflag);
168
169 A_UINT8 ar6000_get_upper_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, A_UINT32 size);
170 A_UINT8 ar6000_get_lower_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, A_UINT32 size);
171
172 void wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd);
173 void wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd);
174 static A_STATUS wmi_send_rssi_threshold_params(struct wmi_t *wmip,
175                               WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd);
176 static 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)
179 static A_STATUS
180 wmi_prof_count_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
181 #endif /* CONFIG_TARGET_PROFILE_SUPPORT */
182
183 static A_STATUS wmi_pspoll_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
184                                      int len);
185 static A_STATUS wmi_dtimexpiry_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
186                                      int len);
187
188 static A_STATUS wmi_peer_node_event_rx (struct wmi_t *wmip, A_UINT8 *datap,
189                                         int len);
190 #ifdef ATH_AR6K_11N_SUPPORT
191 static A_STATUS wmi_addba_req_event_rx(struct wmi_t *, A_UINT8 *, int);
192 static A_STATUS wmi_addba_resp_event_rx(struct wmi_t *, A_UINT8 *, int);
193 static A_STATUS wmi_delba_req_event_rx(struct wmi_t *, A_UINT8 *, int);
194 static A_STATUS wmi_btcoex_config_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
195 static A_STATUS wmi_btcoex_stats_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
196 #endif
197 static A_STATUS wmi_hci_event_rx(struct wmi_t *, A_UINT8 *, int);
198
199 #ifdef WAPI_ENABLE
200 static 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)
206 unsigned int processDot11Hdr = 0;
207 #else
208 unsigned int processDot11Hdr = 1;
209 #endif
210 #else
211 extern unsigned int processDot11Hdr;
212 #endif
213
214 int wps_enable;
215 static const A_INT32 wmi_rateTable[][2] = {
216   //{W/O SGI, with SGI}
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 /* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */
265 const 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 /* This stuff is used when we want a simple layer-3 visibility */
279 typedef PREPACK struct _iphdr {
280     A_UINT8     ip_ver_hdrlen;          /* version and hdr length */
281     A_UINT8     ip_tos;                 /* type of service */
282     A_UINT16    ip_len;                 /* total length */
283     A_UINT16    ip_id;                  /* identification */
284     A_INT16     ip_off;                 /* fragment offset field */
285 #define IP_DF 0x4000                    /* dont fragment flag */
286 #define IP_MF 0x2000                    /* more fragments flag */
287 #define IP_OFFMASK 0x1fff               /* mask for fragmenting bits */
288     A_UINT8     ip_ttl;                 /* time to live */
289     A_UINT8     ip_p;                   /* protocol */
290     A_UINT16    ip_sum;                 /* checksum */
291     A_UINT8     ip_src[4];              /* source and dest address */
292     A_UINT8     ip_dst[4];
293 } POSTPACK iphdr;
294
295 #include "athendpack.h"
296
297 static A_INT16 rssi_event_value = 0;
298 static A_INT16 snr_event_value = 0;
299
300 A_BOOL is_probe_ssid = FALSE;
301
302 void *
303 wmi_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
335 void
336 wmi_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     /* Initialize QoS States */
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
359 void
360 wmi_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
366 HTC_ENDPOINT_ID
367 wmi_get_control_ep(struct wmi_t * wmip)
368 {
369     return(wmip->wmi_endpoint_id);
370 }
371
372 void
373 wmi_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  *  performs DIX to 802.3 encapsulation for transmit packets.
390  *  uses passed in buffer.  Returns buffer or NULL if failed.
391  *  Assumes the entire DIX header is contigous and that there is
392  *  enough room in the buffer for a 802.3 mac header and LLC+SNAP headers.
393  */
394 A_STATUS
395 wmi_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          * packet is already in 802.3 format - return success
417          */
418         A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG));
419         return (A_OK);
420     }
421
422     /*
423      * Save mac fields and length to be inserted later
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      * Make room for LLC+SNAP headers
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
452 A_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                 /* the pktID is used in conjunction with txComplete messages
467                 * allowing the target to notify which tx requests have been
468                 * completed and how. */
469                 pV1->pktID = 0;
470                 /* the ratePolicyID allows the host to specify which rate policy
471                 * to use for transmitting this packet. 0 means use default behavior. */
472                 pV1->ratePolicyID = 0;
473                 A_ASSERT(pVersion != NULL);
474                 /* the version must be used to populate the meta field of the WMI_DATA_HDR */
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 /* Adds a WMI data header */
497 A_STATUS
498 wmi_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 //    A_UINT8 metaVersion = 0;
503     A_STATUS status;
504
505     A_ASSERT(osbuf != NULL);
506
507     /* adds the meta data field after the wmi data hdr. If metaVersion
508      * is returns 0 then no meta field was added. */
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     //dtHdr->rssi = 0;
529
530     return (A_OK);
531 }
532
533
534 A_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     // Initialize header size
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             /* If WMM is disabled all traffic goes as BE traffic */
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             /* Extract the endpoint info from the TOS field in the IP header */
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     /* workaround for WMM S5 */
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     /* lower 3-bits are 802.1d priority */
602     //dtHdr->info |= (userPriority & WMI_DATA_HDR_UP_MASK) << WMI_DATA_HDR_UP_SHIFT;
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             /* Implicit streams are created with TSID 0xFF */
616
617         cmd.tsid = WMI_IMPLICIT_PSTREAM;
618         wmi_create_pstream_cmd(wmip, &cmd);
619     }
620
621     return trafficClass;
622 }
623
624 A_STATUS
625 wmi_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          * packet is already in 802.3 format - return success
649          */
650         A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG));
651         goto AddDot11Hdr;
652     }
653
654     /*
655      * Save mac fields and length to be inserted later
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     // Remove the Ethernet hdr
663     A_NETBUF_PULL(osbuf, sizeof(ATH_MAC_HDR));
664     /*
665      * Make room for LLC+SNAP headers
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
681 AddDot11Hdr:
682     /* Make room for 802.11 hdr */
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     /* Setup the SA & DA */
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
716 A_STATUS
717 wmi_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     /* strip off the 802.11 hdr*/
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     // Remove the LLC Hdr.
768     A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR));
769
770     // Insert the ATH MAC hdr.
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  *  performs 802.3 to DIX encapsulation for received packets.
782  *  Assumes the entire 802.3 header is contigous.
783  */
784 A_STATUS
785 wmi_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  * Removes a WMI data header
811  */
812 A_STATUS
813 wmi_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
820 void
821 wmi_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  * WMI Extended Event received from Target.
828  */
829 A_STATUS
830 wmi_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 /* CONFIG_HOST_DSET_SUPPORT */
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 /* CONFIG_HOST_GPIO_SUPPORT */
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 /* CONFIG_TARGET_PROFILE_SUPPORT */
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  * Control Path
903  */
904 A_UINT32 cmdRecvNum;
905
906 A_STATUS
907 wmi_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              * convert WMI_BSS_INFO_HDR2 to WMI_BSS_INFO_HDR
997              * Take a local copy of the WMI_BSS_INFO_HDR2 from the wmi buffer
998              * and reconstruct the WMI_BSS_INFO_HDR in its place
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             /* pstreams are fatpipe abstractions that get implicitly created.
1028              * User apps only deal with thinstreams. creation of a thinstream
1029              * by the user or data traffic flow in an AC triggers implicit
1030              * pstream creation. Do we need to send this event to App..?
1031              * no harm in sending it.
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 /* Send a "simple" wmi command -- one with no arguments */
1195 static A_STATUS
1196 wmi_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 /* Send a "simple" extended wmi command -- one with no arguments.
1209    Enabling this command only if GPIO or profiling support is enabled.
1210    This is to suppress warnings on some platforms */
1211 #if defined(CONFIG_HOST_GPIO_SUPPORT) || defined(CONFIG_TARGET_PROFILE_SUPPORT)
1212 static A_STATUS
1213 wmi_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
1226 static A_STATUS
1227 wmi_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
1247 static int __inline
1248 iswmmoui(const A_UINT8 *frm)
1249 {
1250     return frm[1] > 3 && LE_READ_4(frm+2) == ((WMM_OUI_TYPE<<24)|WMM_OUI);
1251 }
1252
1253 static int __inline
1254 iswmmparam(const A_UINT8 *frm)
1255 {
1256     return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE;
1257 }
1258
1259
1260 static A_STATUS
1261 wmi_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     /* initialize pointer to start of assoc rsp IEs */
1281     pie = ev->assocInfo + ev->beaconIeLen + ev->assocReqLen +
1282                             sizeof(A_UINT16)  +  /* capinfo*/
1283                             sizeof(A_UINT16)  +  /* status Code */
1284                             sizeof(A_UINT16)  ;  /* associd */
1285
1286     /* initialize pointer to end of assoc rsp IEs */
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
1320 static A_STATUS
1321 wmi_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
1335 static A_STATUS
1336 wmi_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
1356 static A_STATUS
1357 wmi_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
1381 static A_STATUS
1382 wmi_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
1401 static A_STATUS
1402 wmi_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
1417 static A_STATUS
1418 wmi_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;  //no node found in the table, just drop the node with incorrect RSSI
1438         else
1439             bih->rssi = bss->ni_rssi; //Adjust RSSI in datap in case it is used in A_WMI_BSSINFO_EVENT_RX
1440     }
1441
1442     A_WMI_BSSINFO_EVENT_RX(wmip->wmi_devt, datap, len);
1443     /* What is driver config for wlan node caching? */
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 \"%02x:%02x:%02x:%02x:%02x:%02x\"\n", DBGARG,
1461               bih->channel, (unsigned char) bih->rssi, bih->bssid[0],
1462               bih->bssid[1], bih->bssid[2], bih->bssid[3], bih->bssid[4],
1463               bih->bssid[5]));
1464
1465     if(wps_enable && (bih->frameType == PROBERESP_FTYPE) ) {
1466         wmi_node_return(wmip, bss);
1467         return A_OK;
1468     }
1469
1470     if (bss != NULL) {
1471         /*
1472          * Free up the node.  Not the most efficient process given
1473          * we are about to allocate a new node but it is simple and should be
1474          * adequate.
1475          */
1476
1477         /* In case of hidden AP, beacon will not have ssid,
1478          * but a directed probe response will have it,
1479          * so cache the probe-resp-ssid if already present. */
1480         if ((TRUE == is_probe_ssid) && (BEACON_FTYPE == bih->frameType))
1481         {
1482             A_UCHAR *ie_ssid;
1483
1484             ie_ssid = bss->ni_cie.ie_ssid;
1485             if(ie_ssid && (ie_ssid[1] <= IEEE80211_NWID_LEN) && (ie_ssid[2] != 0))
1486             {
1487                 cached_ssid_len = ie_ssid[1];
1488                 memcpy(cached_ssid_buf, ie_ssid + 2, cached_ssid_len);
1489             }
1490         }
1491
1492         /*
1493          * Use the current average rssi of associated AP base on assumpiton
1494          * 1. Most os with GUI will update RSSI by wmi_get_stats_cmd() periodically
1495          * 2. wmi_get_stats_cmd(..) will be called when calling wmi_startscan_cmd(...)
1496          * The average value of RSSI give end-user better feeling for instance value of scan result
1497          * It also sync up RSSI info in GUI between scan result and RSSI signal icon
1498          */
1499         if (IEEE80211_ADDR_EQ(wmip->wmi_bssid, bih->bssid)) {
1500             bih->rssi = bss->ni_rssi;
1501             bih->snr  = bss->ni_snr;
1502         }
1503
1504         wlan_node_reclaim(&wmip->wmi_scan_table, bss);
1505     }
1506
1507     /*  beacon/probe response frame format
1508      *  [8] time stamp
1509      *  [2] beacon interval
1510      *  [2] capability information
1511      *  [tlv] ssid */
1512     beacon_ssid_len = buf[SSID_IE_LEN_INDEX];
1513
1514     /* If ssid is cached for this hidden AP, then change buffer len accordingly. */
1515     if ((TRUE == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) &&
1516         (0 != cached_ssid_len) &&
1517         (0 == beacon_ssid_len || (cached_ssid_len > beacon_ssid_len && 0 == buf[SSID_IE_LEN_INDEX + 1])))
1518     {
1519         len += (cached_ssid_len - beacon_ssid_len);
1520     }
1521
1522     bss = wlan_node_alloc(&wmip->wmi_scan_table, len);
1523     if (bss == NULL) {
1524         return A_NO_MEMORY;
1525     }
1526
1527     bss->ni_snr        = bih->snr;
1528     bss->ni_rssi       = bih->rssi;
1529     A_ASSERT(bss->ni_buf != NULL);
1530
1531     /* In case of hidden AP, beacon will not have ssid,
1532      * but a directed probe response will have it,
1533      * so place the cached-ssid(probe-resp) in the bssinfo. */
1534     if ((TRUE == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) &&
1535          (0 != cached_ssid_len) &&
1536          (0 == beacon_ssid_len || (beacon_ssid_len && 0 == buf[SSID_IE_LEN_INDEX + 1])))
1537     {
1538         A_UINT8 *ni_buf = bss->ni_buf;
1539         int buf_len = len;
1540
1541         /* copy the first 14 bytes such as
1542          * time-stamp(8), beacon-interval(2), cap-info(2), ssid-id(1), ssid-len(1). */
1543         A_MEMCPY(ni_buf, buf, SSID_IE_LEN_INDEX + 1);
1544
1545         ni_buf[SSID_IE_LEN_INDEX] = cached_ssid_len;
1546         ni_buf += (SSID_IE_LEN_INDEX + 1);
1547
1548         buf += (SSID_IE_LEN_INDEX + 1);
1549         buf_len -= (SSID_IE_LEN_INDEX + 1);
1550
1551         /* copy the cached ssid */
1552         A_MEMCPY(ni_buf, cached_ssid_buf, cached_ssid_len);
1553         ni_buf += cached_ssid_len;
1554
1555         buf += beacon_ssid_len;
1556         buf_len -= beacon_ssid_len;
1557
1558         if (cached_ssid_len > beacon_ssid_len)
1559             buf_len -= (cached_ssid_len - beacon_ssid_len);
1560
1561         /* now copy the rest of bytes */
1562         A_MEMCPY(ni_buf, buf, buf_len);
1563     }
1564     else
1565         A_MEMCPY(bss->ni_buf, buf, len);
1566
1567     bss->ni_framelen = len;
1568     if (wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie) != A_OK) {
1569         wlan_node_free(bss);
1570         return A_EINVAL;
1571     }
1572
1573     /*
1574      * Update the frequency in ie_chan, overwriting of channel number
1575      * which is done in wlan_parse_beacon
1576      */
1577     bss->ni_cie.ie_chan = bih->channel;
1578     wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid);
1579
1580     return A_OK;
1581 }
1582
1583 static A_STATUS
1584 wmi_opt_frame_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1585 {
1586     bss_t *bss;
1587     WMI_OPT_RX_INFO_HDR *bih;
1588     A_UINT8 *buf;
1589
1590     if (len <= sizeof(WMI_OPT_RX_INFO_HDR)) {
1591         return A_EINVAL;
1592     }
1593
1594     bih = (WMI_OPT_RX_INFO_HDR *)datap;
1595     buf = datap + sizeof(WMI_OPT_RX_INFO_HDR);
1596     len -= sizeof(WMI_OPT_RX_INFO_HDR);
1597
1598     A_DPRINTF(DBG_WMI2, (DBGFMT "opt frame event %2.2x:%2.2x\n", DBGARG,
1599         bih->bssid[4], bih->bssid[5]));
1600
1601     bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid);
1602     if (bss != NULL) {
1603         /*
1604          * Free up the node.  Not the most efficient process given
1605          * we are about to allocate a new node but it is simple and should be
1606          * adequate.
1607          */
1608         wlan_node_reclaim(&wmip->wmi_scan_table, bss);
1609     }
1610
1611     bss = wlan_node_alloc(&wmip->wmi_scan_table, len);
1612     if (bss == NULL) {
1613         return A_NO_MEMORY;
1614     }
1615
1616     bss->ni_snr        = bih->snr;
1617     bss->ni_cie.ie_chan = bih->channel;
1618     A_ASSERT(bss->ni_buf != NULL);
1619     A_MEMCPY(bss->ni_buf, buf, len);
1620     wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid);
1621
1622     return A_OK;
1623 }
1624
1625     /* This event indicates inactivity timeout of a fatpipe(pstream)
1626      * at the target
1627      */
1628 static A_STATUS
1629 wmi_pstream_timeout_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1630 {
1631     WMI_PSTREAM_TIMEOUT_EVENT *ev;
1632
1633     if (len < sizeof(WMI_PSTREAM_TIMEOUT_EVENT)) {
1634         return A_EINVAL;
1635     }
1636
1637     A_DPRINTF(DBG_WMI, (DBGFMT "wmi_pstream_timeout_event_rx\n", DBGARG));
1638
1639     ev = (WMI_PSTREAM_TIMEOUT_EVENT *)datap;
1640
1641         /* When the pstream (fat pipe == AC) timesout, it means there were no
1642          * thinStreams within this pstream & it got implicitly created due to
1643          * data flow on this AC. We start the inactivity timer only for
1644          * implicitly created pstream. Just reset the host state.
1645      */
1646         /* Set the activeTsids for this AC to 0 */
1647     LOCK_WMI(wmip);
1648     wmip->wmi_streamExistsForAC[ev->trafficClass]=0;
1649     wmip->wmi_fatPipeExists &= ~(1 << ev->trafficClass);
1650     UNLOCK_WMI(wmip);
1651
1652         /*Indicate inactivity to driver layer for this fatpipe (pstream)*/
1653     A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, ev->trafficClass);
1654
1655     return A_OK;
1656 }
1657
1658 static A_STATUS
1659 wmi_bitrate_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1660 {
1661     WMI_BIT_RATE_REPLY *reply;
1662     A_INT32 rate;
1663     A_UINT32 sgi,index;
1664     /* 54149:
1665      * WMI_BIT_RATE_CMD structure is changed to WMI_BIT_RATE_REPLY.
1666      * since there is difference in the length and to avoid returning
1667      * error value.
1668      */
1669     if (len < sizeof(WMI_BIT_RATE_REPLY)) {
1670         return A_EINVAL;
1671     }
1672     reply = (WMI_BIT_RATE_REPLY *)datap;
1673     A_DPRINTF(DBG_WMI,
1674         (DBGFMT "Enter - rateindex %d\n", DBGARG, reply->rateIndex));
1675
1676     if (reply->rateIndex == (A_INT8) RATE_AUTO) {
1677         rate = RATE_AUTO;
1678     } else {
1679         // the SGI state is stored as the MSb of the rateIndex
1680         index = reply->rateIndex & 0x7f;
1681         sgi = (reply->rateIndex & 0x80)? 1:0;
1682         rate = wmi_rateTable[index][sgi];
1683     }
1684
1685     A_WMI_BITRATE_RX(wmip->wmi_devt, rate);
1686     return A_OK;
1687 }
1688
1689 static A_STATUS
1690 wmi_ratemask_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1691 {
1692     WMI_FIX_RATES_REPLY *reply;
1693
1694     if (len < sizeof(WMI_FIX_RATES_REPLY)) {
1695         return A_EINVAL;
1696     }
1697     reply = (WMI_FIX_RATES_REPLY *)datap;
1698     A_DPRINTF(DBG_WMI,
1699         (DBGFMT "Enter - fixed rate mask %x\n", DBGARG, reply->fixRateMask));
1700
1701     A_WMI_RATEMASK_RX(wmip->wmi_devt, reply->fixRateMask);
1702
1703     return A_OK;
1704 }
1705
1706 static A_STATUS
1707 wmi_channelList_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1708 {
1709     WMI_CHANNEL_LIST_REPLY *reply;
1710
1711     if (len < sizeof(WMI_CHANNEL_LIST_REPLY)) {
1712         return A_EINVAL;
1713     }
1714     reply = (WMI_CHANNEL_LIST_REPLY *)datap;
1715     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1716
1717     A_WMI_CHANNELLIST_RX(wmip->wmi_devt, reply->numChannels,
1718                           reply->channelList);
1719
1720     return A_OK;
1721 }
1722
1723 static A_STATUS
1724 wmi_txPwr_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1725 {
1726     WMI_TX_PWR_REPLY *reply;
1727
1728     if (len < sizeof(*reply)) {
1729         return A_EINVAL;
1730     }
1731     reply = (WMI_TX_PWR_REPLY *)datap;
1732     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1733
1734     A_WMI_TXPWR_RX(wmip->wmi_devt, reply->dbM);
1735
1736     return A_OK;
1737 }
1738 static A_STATUS
1739 wmi_keepalive_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1740 {
1741     WMI_GET_KEEPALIVE_CMD *reply;
1742
1743     if (len < sizeof(*reply)) {
1744         return A_EINVAL;
1745     }
1746     reply = (WMI_GET_KEEPALIVE_CMD *)datap;
1747     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1748
1749     A_WMI_KEEPALIVE_RX(wmip->wmi_devt, reply->configured);
1750
1751     return A_OK;
1752 }
1753
1754
1755 static A_STATUS
1756 wmi_dset_open_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1757 {
1758     WMIX_DSETOPENREQ_EVENT *dsetopenreq;
1759
1760     if (len < sizeof(WMIX_DSETOPENREQ_EVENT)) {
1761         return A_EINVAL;
1762     }
1763     dsetopenreq = (WMIX_DSETOPENREQ_EVENT *)datap;
1764     A_DPRINTF(DBG_WMI,
1765         (DBGFMT "Enter - dset_id=0x%x\n", DBGARG, dsetopenreq->dset_id));
1766     A_WMI_DSET_OPEN_REQ(wmip->wmi_devt,
1767                         dsetopenreq->dset_id,
1768                         dsetopenreq->targ_dset_handle,
1769                         dsetopenreq->targ_reply_fn,
1770                         dsetopenreq->targ_reply_arg);
1771
1772     return A_OK;
1773 }
1774
1775 #ifdef CONFIG_HOST_DSET_SUPPORT
1776 static A_STATUS
1777 wmi_dset_close_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1778 {
1779     WMIX_DSETCLOSE_EVENT *dsetclose;
1780
1781     if (len < sizeof(WMIX_DSETCLOSE_EVENT)) {
1782         return A_EINVAL;
1783     }
1784     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1785
1786     dsetclose = (WMIX_DSETCLOSE_EVENT *)datap;
1787     A_WMI_DSET_CLOSE(wmip->wmi_devt, dsetclose->access_cookie);
1788
1789     return A_OK;
1790 }
1791
1792 static A_STATUS
1793 wmi_dset_data_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1794 {
1795     WMIX_DSETDATAREQ_EVENT *dsetdatareq;
1796
1797     if (len < sizeof(WMIX_DSETDATAREQ_EVENT)) {
1798         return A_EINVAL;
1799     }
1800     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1801
1802     dsetdatareq = (WMIX_DSETDATAREQ_EVENT *)datap;
1803     A_WMI_DSET_DATA_REQ(wmip->wmi_devt,
1804                          dsetdatareq->access_cookie,
1805                          dsetdatareq->offset,
1806                          dsetdatareq->length,
1807                          dsetdatareq->targ_buf,
1808                          dsetdatareq->targ_reply_fn,
1809                          dsetdatareq->targ_reply_arg);
1810
1811     return A_OK;
1812 }
1813 #endif /* CONFIG_HOST_DSET_SUPPORT */
1814
1815 static A_STATUS
1816 wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1817 {
1818     WMI_SCAN_COMPLETE_EVENT *ev;
1819
1820     ev = (WMI_SCAN_COMPLETE_EVENT *)datap;
1821     if ((A_STATUS)ev->status == A_OK) {
1822         wlan_refresh_inactive_nodes(&wmip->wmi_scan_table);
1823     }
1824     A_WMI_SCANCOMPLETE_EVENT(wmip->wmi_devt, (A_STATUS) ev->status);
1825     is_probe_ssid = FALSE;
1826
1827     return A_OK;
1828 }
1829
1830 /*
1831  * Target is reporting a programming error.  This is for
1832  * developer aid only.  Target only checks a few common violations
1833  * and it is responsibility of host to do all error checking.
1834  * Behavior of target after wmi error event is undefined.
1835  * A reset is recommended.
1836  */
1837 static A_STATUS
1838 wmi_errorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1839 {
1840     WMI_CMD_ERROR_EVENT *ev;
1841
1842     ev = (WMI_CMD_ERROR_EVENT *)datap;
1843     AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Programming Error: cmd=%d ", ev->commandId));
1844     switch (ev->errorCode) {
1845     case (INVALID_PARAM):
1846         AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal Parameter\n"));
1847         break;
1848     case (ILLEGAL_STATE):
1849         AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal State\n"));
1850         break;
1851     case (INTERNAL_ERROR):
1852         AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Internal Error\n"));
1853         break;
1854     }
1855
1856     return A_OK;
1857 }
1858
1859
1860 static A_STATUS
1861 wmi_statsEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1862 {
1863     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1864
1865     A_WMI_TARGETSTATS_EVENT(wmip->wmi_devt, datap, len);
1866
1867     return A_OK;
1868 }
1869
1870 static A_STATUS
1871 wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1872 {
1873     WMI_RSSI_THRESHOLD_EVENT *reply;
1874     WMI_RSSI_THRESHOLD_VAL newThreshold;
1875     WMI_RSSI_THRESHOLD_PARAMS_CMD cmd;
1876     SQ_THRESHOLD_PARAMS *sq_thresh =
1877            &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI];
1878     A_UINT8 upper_rssi_threshold, lower_rssi_threshold;
1879     A_INT16 rssi;
1880
1881     if (len < sizeof(*reply)) {
1882         return A_EINVAL;
1883     }
1884     reply = (WMI_RSSI_THRESHOLD_EVENT *)datap;
1885     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1886     newThreshold = (WMI_RSSI_THRESHOLD_VAL) reply->range;
1887     rssi = reply->rssi;
1888
1889     /*
1890      * Identify the threshold breached and communicate that to the app. After
1891      * that install a new set of thresholds based on the signal quality
1892      * reported by the target
1893      */
1894     if (newThreshold) {
1895         /* Upper threshold breached */
1896         if (rssi < sq_thresh->upper_threshold[0]) {
1897             A_DPRINTF(DBG_WMI, (DBGFMT "Spurious upper RSSI threshold event: "
1898                       " %d\n", DBGARG, rssi));
1899         } else if ((rssi < sq_thresh->upper_threshold[1]) &&
1900                    (rssi >= sq_thresh->upper_threshold[0]))
1901         {
1902             newThreshold = WMI_RSSI_THRESHOLD1_ABOVE;
1903         } else if ((rssi < sq_thresh->upper_threshold[2]) &&
1904                    (rssi >= sq_thresh->upper_threshold[1]))
1905         {
1906             newThreshold = WMI_RSSI_THRESHOLD2_ABOVE;
1907         } else if ((rssi < sq_thresh->upper_threshold[3]) &&
1908                    (rssi >= sq_thresh->upper_threshold[2]))
1909         {
1910             newThreshold = WMI_RSSI_THRESHOLD3_ABOVE;
1911         } else if ((rssi < sq_thresh->upper_threshold[4]) &&
1912                    (rssi >= sq_thresh->upper_threshold[3]))
1913         {
1914             newThreshold = WMI_RSSI_THRESHOLD4_ABOVE;
1915         } else if ((rssi < sq_thresh->upper_threshold[5]) &&
1916                    (rssi >= sq_thresh->upper_threshold[4]))
1917         {
1918             newThreshold = WMI_RSSI_THRESHOLD5_ABOVE;
1919         } else if (rssi >= sq_thresh->upper_threshold[5]) {
1920             newThreshold = WMI_RSSI_THRESHOLD6_ABOVE;
1921         }
1922     } else {
1923         /* Lower threshold breached */
1924         if (rssi > sq_thresh->lower_threshold[0]) {
1925             A_DPRINTF(DBG_WMI, (DBGFMT "Spurious lower RSSI threshold event: "
1926                       "%d %d\n", DBGARG, rssi, sq_thresh->lower_threshold[0]));
1927         } else if ((rssi > sq_thresh->lower_threshold[1]) &&
1928                    (rssi <= sq_thresh->lower_threshold[0]))
1929         {
1930             newThreshold = WMI_RSSI_THRESHOLD6_BELOW;
1931         } else if ((rssi > sq_thresh->lower_threshold[2]) &&
1932                    (rssi <= sq_thresh->lower_threshold[1]))
1933         {
1934             newThreshold = WMI_RSSI_THRESHOLD5_BELOW;
1935         } else if ((rssi > sq_thresh->lower_threshold[3]) &&
1936                    (rssi <= sq_thresh->lower_threshold[2]))
1937         {
1938             newThreshold = WMI_RSSI_THRESHOLD4_BELOW;
1939         } else if ((rssi > sq_thresh->lower_threshold[4]) &&
1940                    (rssi <= sq_thresh->lower_threshold[3]))
1941         {
1942             newThreshold = WMI_RSSI_THRESHOLD3_BELOW;
1943         } else if ((rssi > sq_thresh->lower_threshold[5]) &&
1944                    (rssi <= sq_thresh->lower_threshold[4]))
1945         {
1946             newThreshold = WMI_RSSI_THRESHOLD2_BELOW;
1947         } else if (rssi <= sq_thresh->lower_threshold[5]) {
1948             newThreshold = WMI_RSSI_THRESHOLD1_BELOW;
1949         }
1950     }
1951     /* Calculate and install the next set of thresholds */
1952     lower_rssi_threshold = ar6000_get_lower_threshold(rssi, sq_thresh,
1953                                       sq_thresh->lower_threshold_valid_count);
1954     upper_rssi_threshold = ar6000_get_upper_threshold(rssi, sq_thresh,
1955                                       sq_thresh->upper_threshold_valid_count);
1956     /* Issue a wmi command to install the thresholds */
1957     cmd.thresholdAbove1_Val = upper_rssi_threshold;
1958     cmd.thresholdBelow1_Val = lower_rssi_threshold;
1959     cmd.weight = sq_thresh->weight;
1960     cmd.pollTime = sq_thresh->polling_interval;
1961
1962     rssi_event_value = rssi;
1963
1964     if (wmi_send_rssi_threshold_params(wmip, &cmd) != A_OK) {
1965         A_DPRINTF(DBG_WMI, (DBGFMT "Unable to configure the RSSI thresholds\n",
1966                   DBGARG));
1967     }
1968
1969     A_WMI_RSSI_THRESHOLD_EVENT(wmip->wmi_devt, newThreshold, reply->rssi);
1970
1971     return A_OK;
1972 }
1973
1974
1975 static A_STATUS
1976 wmi_reportErrorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1977 {
1978     WMI_TARGET_ERROR_REPORT_EVENT *reply;
1979
1980     if (len < sizeof(*reply)) {
1981         return A_EINVAL;
1982     }
1983     reply = (WMI_TARGET_ERROR_REPORT_EVENT *)datap;
1984     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1985
1986     A_WMI_REPORT_ERROR_EVENT(wmip->wmi_devt, (WMI_TARGET_ERROR_VAL) reply->errorVal);
1987
1988     return A_OK;
1989 }
1990
1991 static A_STATUS
1992 wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1993 {
1994     WMI_CAC_EVENT *reply;
1995     WMM_TSPEC_IE *tspec_ie;
1996     A_UINT16 activeTsids;
1997
1998     if (len < sizeof(*reply)) {
1999         return A_EINVAL;
2000     }
2001     reply = (WMI_CAC_EVENT *)datap;
2002
2003     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2004
2005     if ((reply->cac_indication == CAC_INDICATION_ADMISSION_RESP) &&
2006         (reply->statusCode != TSPEC_STATUS_CODE_ADMISSION_ACCEPTED)) {
2007         tspec_ie = (WMM_TSPEC_IE *) &(reply->tspecSuggestion);
2008
2009         wmi_delete_pstream_cmd(wmip, reply->ac,
2010                 (tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK);
2011     }
2012     else if (reply->cac_indication == CAC_INDICATION_NO_RESP) {
2013         A_UINT8 i;
2014
2015         /* following assumes that there is only one outstanding ADDTS request
2016            when this event is received */
2017         LOCK_WMI(wmip);
2018         activeTsids = wmip->wmi_streamExistsForAC[reply->ac];
2019         UNLOCK_WMI(wmip);
2020
2021         for (i = 0; i < sizeof(activeTsids) * 8; i++) {
2022             if ((activeTsids >> i) & 1) {
2023                 break;
2024             }
2025         }
2026         if (i < (sizeof(activeTsids) * 8)) {
2027             wmi_delete_pstream_cmd(wmip, reply->ac, i);
2028         }
2029     }
2030         /*
2031          * Ev#72990: Clear active tsids and Add missing handling
2032          * for delete qos stream from AP
2033          */
2034     else if (reply->cac_indication == CAC_INDICATION_DELETE) {
2035         A_UINT8 tsid = 0;
2036
2037         tspec_ie = (WMM_TSPEC_IE *) &(reply->tspecSuggestion);
2038         tsid= ((tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK);
2039         LOCK_WMI(wmip);
2040         wmip->wmi_streamExistsForAC[reply->ac] &= ~(1<<tsid);
2041         activeTsids = wmip->wmi_streamExistsForAC[reply->ac];
2042         UNLOCK_WMI(wmip);
2043
2044
2045         /* Indicate stream inactivity to driver layer only if all tsids
2046          * within this AC are deleted.
2047          */
2048        if (!activeTsids) {
2049            A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, reply->ac);
2050            wmip->wmi_fatPipeExists &= ~(1 << reply->ac);
2051         }
2052     }
2053
2054     A_WMI_CAC_EVENT(wmip->wmi_devt, reply->ac,
2055                 reply->cac_indication, reply->statusCode,
2056                 reply->tspecSuggestion);
2057
2058     return A_OK;
2059 }
2060
2061 static A_STATUS
2062 wmi_channel_change_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2063 {
2064     WMI_CHANNEL_CHANGE_EVENT *reply;
2065
2066     if (len < sizeof(*reply)) {
2067         return A_EINVAL;
2068     }
2069     reply = (WMI_CHANNEL_CHANGE_EVENT *)datap;
2070     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2071
2072     A_WMI_CHANNEL_CHANGE_EVENT(wmip->wmi_devt, reply->oldChannel,
2073                                reply->newChannel);
2074
2075     return A_OK;
2076 }
2077
2078 static A_STATUS
2079 wmi_hbChallengeResp_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2080 {
2081     WMIX_HB_CHALLENGE_RESP_EVENT *reply;
2082
2083     if (len < sizeof(*reply)) {
2084         return A_EINVAL;
2085     }
2086     reply = (WMIX_HB_CHALLENGE_RESP_EVENT *)datap;
2087     A_DPRINTF(DBG_WMI, (DBGFMT "wmi: challenge response event\n", DBGARG));
2088
2089     A_WMI_HBCHALLENGERESP_EVENT(wmip->wmi_devt, reply->cookie, reply->source);
2090
2091     return A_OK;
2092 }
2093
2094 static A_STATUS
2095 wmi_roam_tbl_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2096 {
2097     WMI_TARGET_ROAM_TBL *reply;
2098
2099     if (len < sizeof(*reply)) {
2100         return A_EINVAL;
2101     }
2102     reply = (WMI_TARGET_ROAM_TBL *)datap;
2103     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2104
2105     A_WMI_ROAM_TABLE_EVENT(wmip->wmi_devt, reply);
2106
2107     return A_OK;
2108 }
2109
2110 static A_STATUS
2111 wmi_roam_data_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2112 {
2113     WMI_TARGET_ROAM_DATA *reply;
2114
2115     if (len < sizeof(*reply)) {
2116         return A_EINVAL;
2117     }
2118     reply = (WMI_TARGET_ROAM_DATA *)datap;
2119     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2120
2121     A_WMI_ROAM_DATA_EVENT(wmip->wmi_devt, reply);
2122
2123     return A_OK;
2124 }
2125
2126 static A_STATUS
2127 wmi_txRetryErrEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2128 {
2129     if (len < sizeof(WMI_TX_RETRY_ERR_EVENT)) {
2130         return A_EINVAL;
2131     }
2132     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2133
2134     A_WMI_TX_RETRY_ERR_EVENT(wmip->wmi_devt);
2135
2136     return A_OK;
2137 }
2138
2139 static A_STATUS
2140 wmi_snrThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2141 {
2142     WMI_SNR_THRESHOLD_EVENT *reply;
2143     SQ_THRESHOLD_PARAMS *sq_thresh =
2144            &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_SNR];
2145     WMI_SNR_THRESHOLD_VAL newThreshold;
2146     WMI_SNR_THRESHOLD_PARAMS_CMD cmd;
2147     A_UINT8 upper_snr_threshold, lower_snr_threshold;
2148     A_INT16 snr;
2149
2150     if (len < sizeof(*reply)) {
2151         return A_EINVAL;
2152     }
2153     reply = (WMI_SNR_THRESHOLD_EVENT *)datap;
2154     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2155
2156     newThreshold = (WMI_SNR_THRESHOLD_VAL) reply->range;
2157     snr = reply->snr;
2158     /*
2159      * Identify the threshold breached and communicate that to the app. After
2160      * that install a new set of thresholds based on the signal quality
2161      * reported by the target
2162      */
2163     if (newThreshold) {
2164         /* Upper threshold breached */
2165         if (snr < sq_thresh->upper_threshold[0]) {
2166             A_DPRINTF(DBG_WMI, (DBGFMT "Spurious upper SNR threshold event: "
2167                      "%d\n", DBGARG, snr));
2168         } else if ((snr < sq_thresh->upper_threshold[1]) &&
2169                    (snr >= sq_thresh->upper_threshold[0]))
2170         {
2171             newThreshold = WMI_SNR_THRESHOLD1_ABOVE;
2172         } else if ((snr < sq_thresh->upper_threshold[2]) &&
2173                    (snr >= sq_thresh->upper_threshold[1]))
2174         {
2175             newThreshold = WMI_SNR_THRESHOLD2_ABOVE;
2176         } else if ((snr < sq_thresh->upper_threshold[3]) &&
2177                    (snr >= sq_thresh->upper_threshold[2]))
2178         {
2179             newThreshold = WMI_SNR_THRESHOLD3_ABOVE;
2180         } else if (snr >= sq_thresh->upper_threshold[3]) {
2181             newThreshold = WMI_SNR_THRESHOLD4_ABOVE;
2182         }
2183     } else {
2184         /* Lower threshold breached */
2185         if (snr > sq_thresh->lower_threshold[0]) {
2186             A_DPRINTF(DBG_WMI, (DBGFMT "Spurious lower SNR threshold event: "
2187                       "%d %d\n", DBGARG, snr, sq_thresh->lower_threshold[0]));
2188         } else if ((snr > sq_thresh->lower_threshold[1]) &&
2189                    (snr <= sq_thresh->lower_threshold[0]))
2190         {
2191             newThreshold = WMI_SNR_THRESHOLD4_BELOW;
2192         } else if ((snr > sq_thresh->lower_threshold[2]) &&
2193                    (snr <= sq_thresh->lower_threshold[1]))
2194         {
2195             newThreshold = WMI_SNR_THRESHOLD3_BELOW;
2196         } else if ((snr > sq_thresh->lower_threshold[3]) &&
2197                    (snr <= sq_thresh->lower_threshold[2]))
2198         {
2199             newThreshold = WMI_SNR_THRESHOLD2_BELOW;
2200         } else if (snr <= sq_thresh->lower_threshold[3]) {
2201             newThreshold = WMI_SNR_THRESHOLD1_BELOW;
2202         }
2203     }
2204
2205     /* Calculate and install the next set of thresholds */
2206     lower_snr_threshold = ar6000_get_lower_threshold(snr, sq_thresh,
2207                                       sq_thresh->lower_threshold_valid_count);
2208     upper_snr_threshold = ar6000_get_upper_threshold(snr, sq_thresh,
2209                                       sq_thresh->upper_threshold_valid_count);
2210
2211     /* Issue a wmi command to install the thresholds */
2212     cmd.thresholdAbove1_Val = upper_snr_threshold;
2213     cmd.thresholdBelow1_Val = lower_snr_threshold;
2214     cmd.weight = sq_thresh->weight;
2215     cmd.pollTime = sq_thresh->polling_interval;
2216
2217     A_DPRINTF(DBG_WMI, (DBGFMT "snr: %d, threshold: %d, lower: %d, upper: %d\n"
2218               ,DBGARG, snr, newThreshold, lower_snr_threshold,
2219               upper_snr_threshold));
2220
2221     snr_event_value = snr;
2222
2223     if (wmi_send_snr_threshold_params(wmip, &cmd) != A_OK) {
2224         A_DPRINTF(DBG_WMI, (DBGFMT "Unable to configure the SNR thresholds\n",
2225                   DBGARG));
2226     }
2227     A_WMI_SNR_THRESHOLD_EVENT_RX(wmip->wmi_devt, newThreshold, reply->snr);
2228
2229     return A_OK;
2230 }
2231
2232 static A_STATUS
2233 wmi_lqThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2234 {
2235     WMI_LQ_THRESHOLD_EVENT *reply;
2236
2237     if (len < sizeof(*reply)) {
2238         return A_EINVAL;
2239     }
2240     reply = (WMI_LQ_THRESHOLD_EVENT *)datap;
2241     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2242
2243     A_WMI_LQ_THRESHOLD_EVENT_RX(wmip->wmi_devt,
2244                                 (WMI_LQ_THRESHOLD_VAL) reply->range,
2245                                 reply->lq);
2246
2247     return A_OK;
2248 }
2249
2250 static A_STATUS
2251 wmi_aplistEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2252 {
2253     A_UINT16 ap_info_entry_size;
2254     WMI_APLIST_EVENT *ev = (WMI_APLIST_EVENT *)datap;
2255     WMI_AP_INFO_V1 *ap_info_v1;
2256     A_UINT8 i;
2257
2258     if (len < sizeof(WMI_APLIST_EVENT)) {
2259         return A_EINVAL;
2260     }
2261
2262     if (ev->apListVer == APLIST_VER1) {
2263         ap_info_entry_size = sizeof(WMI_AP_INFO_V1);
2264         ap_info_v1 = (WMI_AP_INFO_V1 *)ev->apList;
2265     } else {
2266         return A_EINVAL;
2267     }
2268
2269     AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Number of APs in APLIST Event is %d\n", ev->numAP));
2270     if (len < (int)(sizeof(WMI_APLIST_EVENT) +
2271               (ev->numAP - 1) * ap_info_entry_size))
2272     {
2273         return A_EINVAL;
2274     }
2275
2276     /*
2277      * AP List Ver1 Contents
2278      */
2279     for (i = 0; i < ev->numAP; i++) {
2280         AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("AP#%d BSSID %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x "\
2281                     "Channel %d\n", i,
2282                    ap_info_v1->bssid[0], ap_info_v1->bssid[1],
2283                    ap_info_v1->bssid[2], ap_info_v1->bssid[3],
2284                    ap_info_v1->bssid[4], ap_info_v1->bssid[5],
2285                    ap_info_v1->channel));
2286         ap_info_v1++;
2287     }
2288     return A_OK;
2289 }
2290
2291 static A_STATUS
2292 wmi_dbglog_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2293 {
2294     A_UINT32 dropped;
2295
2296     dropped = *((A_UINT32 *)datap);
2297     datap += sizeof(dropped);
2298     len -= sizeof(dropped);
2299     A_WMI_DBGLOG_EVENT(wmip->wmi_devt, dropped, (A_INT8*)datap, len);
2300     return A_OK;
2301 }
2302
2303 #ifdef CONFIG_HOST_GPIO_SUPPORT
2304 static A_STATUS
2305 wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2306 {
2307     WMIX_GPIO_INTR_EVENT *gpio_intr = (WMIX_GPIO_INTR_EVENT *)datap;
2308
2309     A_DPRINTF(DBG_WMI,
2310         (DBGFMT "Enter - intrmask=0x%x input=0x%x.\n", DBGARG,
2311         gpio_intr->intr_mask, gpio_intr->input_values));
2312
2313     A_WMI_GPIO_INTR_RX(gpio_intr->intr_mask, gpio_intr->input_values);
2314
2315     return A_OK;
2316 }
2317
2318 static A_STATUS
2319 wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2320 {
2321     WMIX_GPIO_DATA_EVENT *gpio_data = (WMIX_GPIO_DATA_EVENT *)datap;
2322
2323     A_DPRINTF(DBG_WMI,
2324         (DBGFMT "Enter - reg=%d value=0x%x\n", DBGARG,
2325         gpio_data->reg_id, gpio_data->value));
2326
2327     A_WMI_GPIO_DATA_RX(gpio_data->reg_id, gpio_data->value);
2328
2329     return A_OK;
2330 }
2331
2332 static A_STATUS
2333 wmi_gpio_ack_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2334 {
2335     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2336
2337     A_WMI_GPIO_ACK_RX();
2338
2339     return A_OK;
2340 }
2341 #endif /* CONFIG_HOST_GPIO_SUPPORT */
2342
2343 /*
2344  * Called to send a wmi command. Command specific data is already built
2345  * on osbuf and current osbuf->data points to it.
2346  */
2347 A_STATUS
2348 wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId,
2349                WMI_SYNC_FLAG syncflag)
2350 {
2351     A_STATUS status;
2352 #define IS_OPT_TX_CMD(cmdId) ((cmdId == WMI_OPT_TX_FRAME_CMDID))
2353     WMI_CMD_HDR         *cHdr;
2354     HTC_ENDPOINT_ID     eid  = wmip->wmi_endpoint_id;
2355
2356     A_ASSERT(osbuf != NULL);
2357
2358     if (syncflag >= END_WMIFLAG) {
2359         A_NETBUF_FREE(osbuf);
2360         return A_EINVAL;
2361     }
2362
2363     if ((syncflag == SYNC_BEFORE_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) {
2364         /*
2365          * We want to make sure all data currently queued is transmitted before
2366          * the cmd execution.  Establish a new sync point.
2367          */
2368         wmi_sync_point(wmip);
2369     }
2370
2371     if (A_NETBUF_PUSH(osbuf, sizeof(WMI_CMD_HDR)) != A_OK) {
2372         A_NETBUF_FREE(osbuf);
2373         return A_NO_MEMORY;
2374     }
2375
2376     cHdr = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf);
2377     cHdr->commandId = (A_UINT16) cmdId;
2378     cHdr->info1 = 0; // added for virtual interface
2379
2380     /*
2381      * Only for OPT_TX_CMD, use BE endpoint.
2382      */
2383     if (IS_OPT_TX_CMD(cmdId)) {
2384         if ((status=wmi_data_hdr_add(wmip, osbuf, OPT_MSGTYPE, FALSE, FALSE,0,NULL)) != A_OK) {
2385             A_NETBUF_FREE(osbuf);
2386             return status;
2387         }
2388         eid = A_WMI_Ac2EndpointID(wmip->wmi_devt, WMM_AC_BE);
2389     }
2390     A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid);
2391
2392     if ((syncflag == SYNC_AFTER_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) {
2393         /*
2394          * We want to make sure all new data queued waits for the command to
2395          * execute. Establish a new sync point.
2396          */
2397         wmi_sync_point(wmip);
2398     }
2399     return (A_OK);
2400 #undef IS_OPT_TX_CMD
2401 }
2402
2403 A_STATUS
2404 wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId,
2405                   WMI_SYNC_FLAG syncflag)
2406 {
2407     WMIX_CMD_HDR     *cHdr;
2408
2409     if (A_NETBUF_PUSH(osbuf, sizeof(WMIX_CMD_HDR)) != A_OK) {
2410         A_NETBUF_FREE(osbuf);
2411         return A_NO_MEMORY;
2412     }
2413
2414     cHdr = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf);
2415     cHdr->commandId = (A_UINT32) cmdId;
2416
2417     return wmi_cmd_send(wmip, osbuf, WMI_EXTENSION_CMDID, syncflag);
2418 }
2419
2420 A_STATUS
2421 wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType,
2422                 DOT11_AUTH_MODE dot11AuthMode, AUTH_MODE authMode,
2423                 CRYPTO_TYPE pairwiseCrypto, A_UINT8 pairwiseCryptoLen,
2424                 CRYPTO_TYPE groupCrypto, A_UINT8 groupCryptoLen,
2425                 int ssidLength, A_UCHAR *ssid,
2426                 A_UINT8 *bssid, A_UINT16 channel, A_UINT32 ctrl_flags)
2427 {
2428     void *osbuf;
2429     WMI_CONNECT_CMD *cc;
2430     wmip->wmi_traffic_class = 100;
2431
2432     if ((pairwiseCrypto == NONE_CRYPT) && (groupCrypto != NONE_CRYPT)) {
2433         return A_EINVAL;
2434     }
2435     if ((pairwiseCrypto != NONE_CRYPT) && (groupCrypto == NONE_CRYPT)) {
2436         return A_EINVAL;
2437     }
2438
2439     osbuf = A_NETBUF_ALLOC(sizeof(WMI_CONNECT_CMD));
2440     if (osbuf == NULL) {
2441         return A_NO_MEMORY;
2442     }
2443
2444     A_NETBUF_PUT(osbuf, sizeof(WMI_CONNECT_CMD));
2445
2446     cc = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf));
2447     A_MEMZERO(cc, sizeof(*cc));
2448
2449     if (ssidLength)
2450     {
2451         A_MEMCPY(cc->ssid, ssid, ssidLength);
2452     }
2453
2454     cc->ssidLength          = ssidLength;
2455     cc->networkType         = netType;
2456     cc->dot11AuthMode       = dot11AuthMode;
2457     cc->authMode            = authMode;
2458     cc->pairwiseCryptoType  = pairwiseCrypto;
2459     cc->pairwiseCryptoLen   = pairwiseCryptoLen;
2460     cc->groupCryptoType     = groupCrypto;
2461     cc->groupCryptoLen      = groupCryptoLen;
2462     cc->channel             = channel;
2463     cc->ctrl_flags          = ctrl_flags;
2464
2465     if (bssid != NULL) {
2466         A_MEMCPY(cc->bssid, bssid, ATH_MAC_LEN);
2467     }
2468
2469     wmip->wmi_pair_crypto_type  = pairwiseCrypto;
2470     wmip->wmi_grp_crypto_type   = groupCrypto;
2471
2472     return (wmi_cmd_send(wmip, osbuf, WMI_CONNECT_CMDID, NO_SYNC_WMIFLAG));
2473 }
2474
2475 A_STATUS
2476 wmi_reconnect_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT16 channel)
2477 {
2478     void *osbuf;
2479     WMI_RECONNECT_CMD *cc;
2480     wmip->wmi_traffic_class = 100;
2481
2482     osbuf = A_NETBUF_ALLOC(sizeof(WMI_RECONNECT_CMD));
2483     if (osbuf == NULL) {
2484         return A_NO_MEMORY;
2485     }
2486
2487     A_NETBUF_PUT(osbuf, sizeof(WMI_RECONNECT_CMD));
2488
2489     cc = (WMI_RECONNECT_CMD *)(A_NETBUF_DATA(osbuf));
2490     A_MEMZERO(cc, sizeof(*cc));
2491
2492     cc->channel = channel;
2493
2494     if (bssid != NULL) {
2495         A_MEMCPY(cc->bssid, bssid, ATH_MAC_LEN);
2496     }
2497
2498     return (wmi_cmd_send(wmip, osbuf, WMI_RECONNECT_CMDID, NO_SYNC_WMIFLAG));
2499 }
2500
2501 A_STATUS
2502 wmi_disconnect_cmd(struct wmi_t *wmip)
2503 {
2504     A_STATUS status;
2505     wmip->wmi_traffic_class = 100;
2506
2507     /* Bug fix for 24817(elevator bug) - the disconnect command does not
2508        need to do a SYNC before.*/
2509     status = wmi_simple_cmd(wmip, WMI_DISCONNECT_CMDID);
2510
2511     return status;
2512 }
2513
2514 A_STATUS
2515 wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType,
2516                   A_BOOL forceFgScan, A_BOOL isLegacy,
2517                   A_UINT32 homeDwellTime, A_UINT32 forceScanInterval,
2518                   A_INT8 numChan, A_UINT16 *channelList)
2519 {
2520     void *osbuf;
2521     WMI_START_SCAN_CMD *sc;
2522     A_INT8 size;
2523
2524     size = sizeof (*sc);
2525
2526     if ((scanType != WMI_LONG_SCAN) && (scanType != WMI_SHORT_SCAN)) {
2527         return A_EINVAL;
2528     }
2529
2530     if (numChan) {
2531         if (numChan > WMI_MAX_CHANNELS) {
2532             return A_EINVAL;
2533         }
2534         size += sizeof(A_UINT16) * (numChan - 1);
2535     }
2536
2537     osbuf = A_NETBUF_ALLOC(size);
2538     if (osbuf == NULL) {
2539         return A_NO_MEMORY;
2540     }
2541
2542     A_NETBUF_PUT(osbuf, size);
2543
2544     sc = (WMI_START_SCAN_CMD *)(A_NETBUF_DATA(osbuf));
2545     sc->scanType = scanType;
2546     sc->forceFgScan = forceFgScan;
2547     sc->isLegacy = isLegacy;
2548     sc->homeDwellTime = homeDwellTime;
2549     sc->forceScanInterval = forceScanInterval;
2550     sc->numChannels = numChan;
2551     if (numChan) {
2552         A_MEMCPY(sc->channelList, channelList, numChan * sizeof(A_UINT16));
2553     }
2554
2555     return (wmi_cmd_send(wmip, osbuf, WMI_START_SCAN_CMDID, NO_SYNC_WMIFLAG));
2556 }
2557
2558 A_STATUS
2559 wmi_scanparams_cmd(struct wmi_t *wmip, A_UINT16 fg_start_sec,
2560                    A_UINT16 fg_end_sec, A_UINT16 bg_sec,
2561                    A_UINT16 minact_chdw_msec, A_UINT16 maxact_chdw_msec,
2562                    A_UINT16 pas_chdw_msec,
2563                    A_UINT8 shScanRatio, A_UINT8 scanCtrlFlags,
2564                    A_UINT32 max_dfsch_act_time, A_UINT16 maxact_scan_per_ssid)
2565 {
2566     void *osbuf;
2567     WMI_SCAN_PARAMS_CMD *sc;
2568
2569     osbuf = A_NETBUF_ALLOC(sizeof(*sc));
2570     if (osbuf == NULL) {
2571         return A_NO_MEMORY;
2572     }
2573
2574     A_NETBUF_PUT(osbuf, sizeof(*sc));
2575
2576     sc = (WMI_SCAN_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
2577     A_MEMZERO(sc, sizeof(*sc));
2578     sc->fg_start_period  = fg_start_sec;
2579     sc->fg_end_period    = fg_end_sec;
2580     sc->bg_period        = bg_sec;
2581     sc->minact_chdwell_time = minact_chdw_msec;
2582     sc->maxact_chdwell_time = maxact_chdw_msec;
2583     sc->pas_chdwell_time = pas_chdw_msec;
2584     sc->shortScanRatio   = shScanRatio;
2585     sc->scanCtrlFlags    = scanCtrlFlags;
2586     sc->max_dfsch_act_time = max_dfsch_act_time;
2587     sc->maxact_scan_per_ssid = maxact_scan_per_ssid;
2588
2589     return (wmi_cmd_send(wmip, osbuf, WMI_SET_SCAN_PARAMS_CMDID,
2590                          NO_SYNC_WMIFLAG));
2591 }
2592
2593 A_STATUS
2594 wmi_bssfilter_cmd(struct wmi_t *wmip, A_UINT8 filter, A_UINT32 ieMask)
2595 {
2596     void *osbuf;
2597     WMI_BSS_FILTER_CMD *cmd;
2598
2599     if (filter >= LAST_BSS_FILTER) {
2600         return A_EINVAL;
2601     }
2602
2603     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2604     if (osbuf == NULL) {
2605         return A_NO_MEMORY;
2606     }
2607
2608     A_NETBUF_PUT(osbuf, sizeof(*cmd));
2609
2610     cmd = (WMI_BSS_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
2611     A_MEMZERO(cmd, sizeof(*cmd));
2612     cmd->bssFilter = filter;
2613     cmd->ieMask = ieMask;
2614
2615     return (wmi_cmd_send(wmip, osbuf, WMI_SET_BSS_FILTER_CMDID,
2616                          NO_SYNC_WMIFLAG));
2617 }
2618
2619 A_STATUS
2620 wmi_probedSsid_cmd(struct wmi_t *wmip, A_UINT8 index, A_UINT8 flag,
2621                    A_UINT8 ssidLength, A_UCHAR *ssid)
2622 {
2623     void *osbuf;
2624     WMI_PROBED_SSID_CMD *cmd;
2625
2626     if (index > MAX_PROBED_SSID_INDEX) {
2627         return A_EINVAL;
2628     }
2629     if (ssidLength > sizeof(cmd->ssid)) {
2630         return A_EINVAL;
2631     }
2632     if ((flag & (DISABLE_SSID_FLAG | ANY_SSID_FLAG)) && (ssidLength > 0)) {
2633         return A_EINVAL;
2634     }
2635     if ((flag & SPECIFIC_SSID_FLAG) && !ssidLength) {
2636         return A_EINVAL;
2637     }
2638
2639     if (flag & SPECIFIC_SSID_FLAG) {
2640         is_probe_ssid = TRUE;
2641     }
2642
2643     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2644     if (osbuf == NULL) {
2645         return A_NO_MEMORY;
2646     }
2647
2648     A_NETBUF_PUT(osbuf, sizeof(*cmd));
2649
2650     cmd = (WMI_PROBED_SSID_CMD *)(A_NETBUF_DATA(osbuf));
2651     A_MEMZERO(cmd, sizeof(*cmd));
2652     cmd->entryIndex = index;
2653     cmd->flag       = flag;
2654     cmd->ssidLength = ssidLength;
2655     A_MEMCPY(cmd->ssid, ssid, ssidLength);
2656
2657     return (wmi_cmd_send(wmip, osbuf, WMI_SET_PROBED_SSID_CMDID,
2658                          NO_SYNC_WMIFLAG));
2659 }
2660
2661 A_STATUS
2662 wmi_listeninterval_cmd(struct wmi_t *wmip, A_UINT16 listenInterval, A_UINT16 listenBeacons)
2663 {
2664     void *osbuf;
2665     WMI_LISTEN_INT_CMD *cmd;
2666
2667     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2668     if (osbuf == NULL) {
2669         return A_NO_MEMORY;
2670     }
2671
2672     A_NETBUF_PUT(osbuf, sizeof(*cmd));
2673
2674     cmd = (WMI_LISTEN_INT_CMD *)(A_NETBUF_DATA(osbuf));
2675     A_MEMZERO(cmd, sizeof(*cmd));
2676     cmd->listenInterval = listenInterval;
2677     cmd->numBeacons = listenBeacons;
2678
2679     return (wmi_cmd_send(wmip, osbuf, WMI_SET_LISTEN_INT_CMDID,
2680                          NO_SYNC_WMIFLAG));
2681 }
2682
2683 A_STATUS
2684 wmi_bmisstime_cmd(struct wmi_t *wmip, A_UINT16 bmissTime, A_UINT16 bmissBeacons)
2685 {
2686     void *osbuf;
2687     WMI_BMISS_TIME_CMD *cmd;
2688
2689     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2690     if (osbuf == NULL) {
2691         return A_NO_MEMORY;
2692     }
2693
2694     A_NETBUF_PUT(osbuf, sizeof(*cmd));
2695
2696     cmd = (WMI_BMISS_TIME_CMD *)(A_NETBUF_DATA(osbuf));
2697     A_MEMZERO(cmd, sizeof(*cmd));
2698     cmd->bmissTime = bmissTime;
2699     cmd->numBeacons =  bmissBeacons;
2700
2701     return (wmi_cmd_send(wmip, osbuf, WMI_SET_BMISS_TIME_CMDID,
2702                          NO_SYNC_WMIFLAG));
2703 }
2704
2705 A_STATUS
2706 wmi_associnfo_cmd(struct wmi_t *wmip, A_UINT8 ieType,
2707                      A_UINT8 ieLen, A_UINT8 *ieInfo)
2708 {
2709     void *osbuf;
2710     WMI_SET_ASSOC_INFO_CMD *cmd;
2711     A_UINT16 cmdLen;
2712
2713     cmdLen = sizeof(*cmd) + ieLen - 1;
2714     osbuf = A_NETBUF_ALLOC(cmdLen);
2715     if (osbuf == NULL) {
2716         return A_NO_MEMORY;
2717     }
2718
2719     A_NETBUF_PUT(osbuf, cmdLen);
2720
2721     cmd = (WMI_SET_ASSOC_INFO_CMD *)(A_NETBUF_DATA(osbuf));
2722     A_MEMZERO(cmd, cmdLen);
2723     cmd->ieType = ieType;
2724     cmd->bufferSize = ieLen;
2725     A_MEMCPY(cmd->assocInfo, ieInfo, ieLen);
2726
2727     return (wmi_cmd_send(wmip, osbuf, WMI_SET_ASSOC_INFO_CMDID,
2728                          NO_SYNC_WMIFLAG));
2729 }
2730
2731 A_STATUS
2732 wmi_powermode_cmd(struct wmi_t *wmip, A_UINT8 powerMode)
2733 {
2734     void *osbuf;
2735     WMI_POWER_MODE_CMD *cmd;
2736
2737     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2738     if (osbuf == NULL) {
2739         return A_NO_MEMORY;
2740     }
2741
2742     A_NETBUF_PUT(osbuf, sizeof(*cmd));
2743
2744     cmd = (WMI_POWER_MODE_CMD *)(A_NETBUF_DATA(osbuf));
2745     A_MEMZERO(cmd, sizeof(*cmd));
2746     cmd->powerMode = powerMode;
2747     wmip->wmi_powerMode = powerMode;
2748
2749     return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_MODE_CMDID,
2750                          NO_SYNC_WMIFLAG));
2751 }
2752
2753 A_STATUS
2754 wmi_ibsspmcaps_cmd(struct wmi_t *wmip, A_UINT8 pmEnable, A_UINT8 ttl,
2755                    A_UINT16 atim_windows, A_UINT16 timeout_value)
2756 {
2757     void *osbuf;
2758     WMI_IBSS_PM_CAPS_CMD *cmd;
2759
2760     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2761     if (osbuf == NULL) {
2762         return A_NO_MEMORY;
2763     }
2764
2765     A_NETBUF_PUT(osbuf, sizeof(*cmd));
2766
2767     cmd = (WMI_IBSS_PM_CAPS_CMD *)(A_NETBUF_DATA(osbuf));
2768     A_MEMZERO(cmd, sizeof(*cmd));
2769     cmd->power_saving = pmEnable;
2770     cmd->ttl = ttl;
2771     cmd->atim_windows = atim_windows;
2772     cmd->timeout_value = timeout_value;
2773
2774     return (wmi_cmd_send(wmip, osbuf, WMI_SET_IBSS_PM_CAPS_CMDID,
2775                          NO_SYNC_WMIFLAG));
2776 }
2777
2778 A_STATUS
2779 wmi_apps_cmd(struct wmi_t *wmip, A_UINT8 psType, A_UINT32 idle_time,
2780                    A_UINT32 ps_period, A_UINT8 sleep_period)
2781 {
2782     void *osbuf;
2783     WMI_AP_PS_CMD *cmd;
2784
2785     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2786     if (osbuf == NULL) {
2787         return A_NO_MEMORY;
2788     }
2789
2790     A_NETBUF_PUT(osbuf, sizeof(*cmd));
2791
2792     cmd = (WMI_AP_PS_CMD *)(A_NETBUF_DATA(osbuf));
2793     A_MEMZERO(cmd, sizeof(*cmd));
2794     cmd->psType = psType;
2795     cmd->idle_time = idle_time;
2796     cmd->ps_period = ps_period;
2797     cmd->sleep_period = sleep_period;
2798
2799     return (wmi_cmd_send(wmip, osbuf, WMI_SET_AP_PS_CMDID,
2800                          NO_SYNC_WMIFLAG));
2801 }
2802
2803 A_STATUS
2804 wmi_pmparams_cmd(struct wmi_t *wmip, A_UINT16 idlePeriod,
2805                  A_UINT16 psPollNum, A_UINT16 dtimPolicy,
2806                  A_UINT16 tx_wakeup_policy, A_UINT16 num_tx_to_wakeup,
2807                  A_UINT16 ps_fail_event_policy)
2808 {
2809     void *osbuf;
2810     WMI_POWER_PARAMS_CMD *pm;
2811
2812     osbuf = A_NETBUF_ALLOC(sizeof(*pm));
2813     if (osbuf == NULL) {
2814         return A_NO_MEMORY;
2815     }
2816
2817     A_NETBUF_PUT(osbuf, sizeof(*pm));
2818
2819     pm = (WMI_POWER_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
2820     A_MEMZERO(pm, sizeof(*pm));
2821     pm->idle_period   = idlePeriod;
2822     pm->pspoll_number = psPollNum;
2823     pm->dtim_policy   = dtimPolicy;
2824     pm->tx_wakeup_policy = tx_wakeup_policy;
2825     pm->num_tx_to_wakeup = num_tx_to_wakeup;
2826     pm->ps_fail_event_policy = ps_fail_event_policy;
2827
2828     return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_PARAMS_CMDID,
2829                          NO_SYNC_WMIFLAG));
2830 }
2831
2832 A_STATUS
2833 wmi_disctimeout_cmd(struct wmi_t *wmip, A_UINT8 timeout)
2834 {
2835     void *osbuf;
2836     WMI_DISC_TIMEOUT_CMD *cmd;
2837
2838     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2839     if (osbuf == NULL) {
2840         return A_NO_MEMORY;
2841     }
2842
2843     A_NETBUF_PUT(osbuf, sizeof(*cmd));
2844
2845     cmd = (WMI_DISC_TIMEOUT_CMD *)(A_NETBUF_DATA(osbuf));
2846     A_MEMZERO(cmd, sizeof(*cmd));
2847     cmd->disconnectTimeout = timeout;
2848
2849     return (wmi_cmd_send(wmip, osbuf, WMI_SET_DISC_TIMEOUT_CMDID,
2850                          NO_SYNC_WMIFLAG));
2851 }
2852
2853 A_STATUS
2854 wmi_addKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex, CRYPTO_TYPE keyType,
2855                A_UINT8 keyUsage, A_UINT8 keyLength, A_UINT8 *keyRSC,
2856                A_UINT8 *keyMaterial, A_UINT8 key_op_ctrl, A_UINT8 *macAddr,
2857                WMI_SYNC_FLAG sync_flag)
2858 {
2859     void *osbuf;
2860     WMI_ADD_CIPHER_KEY_CMD *cmd;
2861
2862     if ((keyIndex > WMI_MAX_KEY_INDEX) || (keyLength > WMI_MAX_KEY_LEN) ||
2863         (keyMaterial == NULL))
2864     {
2865         return A_EINVAL;
2866     }
2867
2868     if ((WEP_CRYPT != keyType) && (NULL == keyRSC)) {
2869         return A_EINVAL;
2870     }
2871
2872     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2873     if (osbuf == NULL) {
2874         return A_NO_MEMORY;
2875     }
2876
2877     A_NETBUF_PUT(osbuf, sizeof(*cmd));
2878
2879     cmd = (WMI_ADD_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf));
2880     A_MEMZERO(cmd, sizeof(*cmd));
2881     cmd->keyIndex = keyIndex;
2882     cmd->keyType  = keyType;
2883     cmd->keyUsage = keyUsage;
2884     cmd->keyLength = keyLength;
2885     A_MEMCPY(cmd->key, keyMaterial, keyLength);
2886 #ifdef WAPI_ENABLE
2887     if (NULL != keyRSC && key_op_ctrl != KEY_OP_INIT_WAPIPN) {
2888 #else
2889     if (NULL != keyRSC) {
2890 #endif // WAPI_ENABLE
2891         A_MEMCPY(cmd->keyRSC, keyRSC, sizeof(cmd->keyRSC));
2892     }
2893     cmd->key_op_ctrl = key_op_ctrl;
2894
2895     if(macAddr) {
2896         A_MEMCPY(cmd->key_macaddr,macAddr,IEEE80211_ADDR_LEN);
2897     }
2898
2899     return (wmi_cmd_send(wmip, osbuf, WMI_ADD_CIPHER_KEY_CMDID, sync_flag));
2900 }
2901
2902 A_STATUS
2903 wmi_add_krk_cmd(struct wmi_t *wmip, A_UINT8 *krk)
2904 {
2905     void *osbuf;
2906     WMI_ADD_KRK_CMD *cmd;
2907
2908     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2909     if (osbuf == NULL) {
2910         return A_NO_MEMORY;
2911     }
2912
2913     A_NETBUF_PUT(osbuf, sizeof(*cmd));
2914
2915     cmd = (WMI_ADD_KRK_CMD *)(A_NETBUF_DATA(osbuf));
2916     A_MEMZERO(cmd, sizeof(*cmd));
2917     A_MEMCPY(cmd->krk, krk, WMI_KRK_LEN);
2918
2919     return (wmi_cmd_send(wmip, osbuf, WMI_ADD_KRK_CMDID, NO_SYNC_WMIFLAG));
2920 }
2921
2922 A_STATUS
2923 wmi_delete_krk_cmd(struct wmi_t *wmip)
2924 {
2925     return wmi_simple_cmd(wmip, WMI_DELETE_KRK_CMDID);
2926 }
2927
2928 A_STATUS
2929 wmi_deleteKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex)
2930 {
2931     void *osbuf;
2932     WMI_DELETE_CIPHER_KEY_CMD *cmd;
2933
2934     if (keyIndex > WMI_MAX_KEY_INDEX) {
2935         return A_EINVAL;
2936     }
2937
2938     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2939     if (osbuf == NULL) {
2940         return A_NO_MEMORY;
2941     }
2942
2943     A_NETBUF_PUT(osbuf, sizeof(*cmd));
2944
2945     cmd = (WMI_DELETE_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf));
2946     A_MEMZERO(cmd, sizeof(*cmd));
2947     cmd->keyIndex = keyIndex;
2948
2949     return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_CIPHER_KEY_CMDID,
2950                          NO_SYNC_WMIFLAG));
2951 }
2952
2953 A_STATUS
2954 wmi_setPmkid_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT8 *pmkId,
2955                  A_BOOL set)
2956 {
2957     void *osbuf;
2958     WMI_SET_PMKID_CMD *cmd;
2959
2960     if (bssid == NULL) {
2961         return A_EINVAL;
2962     }
2963
2964     if ((set == TRUE) && (pmkId == NULL)) {
2965         return A_EINVAL;
2966     }
2967
2968     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2969     if (osbuf == NULL) {
2970         return A_NO_MEMORY;
2971     }
2972
2973     A_NETBUF_PUT(osbuf, sizeof(*cmd));
2974
2975     cmd = (WMI_SET_PMKID_CMD *)(A_NETBUF_DATA(osbuf));
2976     A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid));
2977     if (set == TRUE) {
2978         A_MEMCPY(cmd->pmkid, pmkId, sizeof(cmd->pmkid));
2979         cmd->enable = PMKID_ENABLE;
2980     } else {
2981         A_MEMZERO(cmd->pmkid, sizeof(cmd->pmkid));
2982         cmd->enable = PMKID_DISABLE;
2983     }
2984
2985     return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_CMDID, NO_SYNC_WMIFLAG));
2986 }
2987
2988 A_STATUS
2989 wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, A_BOOL en)
2990 {
2991     void *osbuf;
2992     WMI_SET_TKIP_COUNTERMEASURES_CMD *cmd;
2993
2994     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2995     if (osbuf == NULL) {
2996         return A_NO_MEMORY;
2997     }
2998
2999     A_NETBUF_PUT(osbuf, sizeof(*cmd));
3000
3001     cmd = (WMI_SET_TKIP_COUNTERMEASURES_CMD *)(A_NETBUF_DATA(osbuf));
3002     cmd->cm_en = (en == TRUE)? WMI_TKIP_CM_ENABLE : WMI_TKIP_CM_DISABLE;
3003
3004     return (wmi_cmd_send(wmip, osbuf, WMI_SET_TKIP_COUNTERMEASURES_CMDID,
3005             NO_SYNC_WMIFLAG));
3006 }
3007
3008 A_STATUS
3009 wmi_set_akmp_params_cmd(struct wmi_t *wmip,
3010                         WMI_SET_AKMP_PARAMS_CMD *akmpParams)
3011 {
3012     void *osbuf;
3013     WMI_SET_AKMP_PARAMS_CMD *cmd;
3014
3015     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3016     if (osbuf == NULL) {
3017         return A_NO_MEMORY;
3018     }
3019
3020     A_NETBUF_PUT(osbuf, sizeof(*cmd));
3021     cmd = (WMI_SET_AKMP_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
3022     cmd->akmpInfo = akmpParams->akmpInfo;
3023
3024     return (wmi_cmd_send(wmip, osbuf, WMI_SET_AKMP_PARAMS_CMDID,
3025             NO_SYNC_WMIFLAG));
3026 }
3027
3028 A_STATUS
3029 wmi_set_pmkid_list_cmd(struct wmi_t *wmip,
3030                        WMI_SET_PMKID_LIST_CMD *pmkInfo)
3031 {
3032     void *osbuf;
3033     WMI_SET_PMKID_LIST_CMD *cmd;
3034     A_UINT16 cmdLen;
3035     A_UINT8 i;
3036
3037     cmdLen = sizeof(pmkInfo->numPMKID) +
3038              pmkInfo->numPMKID * sizeof(WMI_PMKID);
3039
3040     osbuf = A_NETBUF_ALLOC(cmdLen);
3041     if (osbuf == NULL) {
3042         return A_NO_MEMORY;
3043     }
3044
3045     A_NETBUF_PUT(osbuf, cmdLen);
3046     cmd = (WMI_SET_PMKID_LIST_CMD *)(A_NETBUF_DATA(osbuf));
3047     cmd->numPMKID = pmkInfo->numPMKID;
3048
3049     for (i = 0; i < cmd->numPMKID; i++) {
3050         A_MEMCPY(&cmd->pmkidList[i], &pmkInfo->pmkidList[i],
3051                  WMI_PMKID_LEN);
3052     }
3053
3054     return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_LIST_CMDID,
3055             NO_SYNC_WMIFLAG));
3056 }
3057
3058 A_STATUS
3059 wmi_get_pmkid_list_cmd(struct wmi_t *wmip)
3060 {
3061     return wmi_simple_cmd(wmip, WMI_GET_PMKID_LIST_CMDID);
3062 }
3063
3064 A_STATUS
3065 wmi_dataSync_send(struct wmi_t *wmip, void *osbuf, HTC_ENDPOINT_ID eid)
3066 {
3067     WMI_DATA_HDR     *dtHdr;
3068
3069     A_ASSERT( eid != wmip->wmi_endpoint_id);
3070     A_ASSERT(osbuf != NULL);
3071
3072     if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != A_OK) {
3073         return A_NO_MEMORY;
3074     }
3075
3076     dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf);
3077     dtHdr->info =
3078       (SYNC_MSGTYPE & WMI_DATA_HDR_MSG_TYPE_MASK) << WMI_DATA_HDR_MSG_TYPE_SHIFT;
3079
3080     A_DPRINTF(DBG_WMI, (DBGFMT "Enter - eid %d\n", DBGARG, eid));
3081
3082     return (A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid));
3083 }
3084
3085 typedef struct _WMI_DATA_SYNC_BUFS {
3086     A_UINT8            trafficClass;
3087     void               *osbuf;
3088 }WMI_DATA_SYNC_BUFS;
3089
3090 static A_STATUS
3091 wmi_sync_point(struct wmi_t *wmip)
3092 {
3093     void *cmd_osbuf;
3094     WMI_SYNC_CMD *cmd;
3095     WMI_DATA_SYNC_BUFS dataSyncBufs[WMM_NUM_AC];
3096     A_UINT8 i,numPriStreams=0;
3097     A_STATUS status = A_OK;
3098
3099     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
3100
3101     memset(dataSyncBufs,0,sizeof(dataSyncBufs));
3102
3103     /* lock out while we walk through the priority list and assemble our local array */
3104     LOCK_WMI(wmip);
3105
3106     for (i=0; i < WMM_NUM_AC ; i++) {
3107         if (wmip->wmi_fatPipeExists & (1 << i)) {
3108             numPriStreams++;
3109             dataSyncBufs[numPriStreams-1].trafficClass = i;
3110         }
3111     }
3112
3113     UNLOCK_WMI(wmip);
3114
3115     /* dataSyncBufs is now filled with entries (starting at index 0) containing valid streamIDs */
3116
3117     do {
3118         /*
3119          * We allocate all network buffers needed so we will be able to
3120          * send all required frames.
3121          */
3122         cmd_osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3123         if (cmd_osbuf == NULL) {
3124             status = A_NO_MEMORY;
3125             break;
3126     }
3127
3128         A_NETBUF_PUT(cmd_osbuf, sizeof(*cmd));
3129
3130         cmd = (WMI_SYNC_CMD *)(A_NETBUF_DATA(cmd_osbuf));
3131         A_MEMZERO(cmd, sizeof(*cmd));
3132
3133         /* In the SYNC cmd sent on the control Ep, send a bitmap of the data
3134          * eps on which the Data Sync will be sent
3135          */
3136         cmd->dataSyncMap = wmip->wmi_fatPipeExists;
3137
3138         for (i=0; i < numPriStreams ; i++) {
3139             dataSyncBufs[i].osbuf = A_NETBUF_ALLOC(0);
3140             if (dataSyncBufs[i].osbuf == NULL) {
3141                 status = A_NO_MEMORY;
3142                 break;
3143             }
3144         } //end for
3145
3146         /* if Buffer allocation for any of the dataSync fails, then do not
3147          * send the Synchronize cmd on the control ep
3148          */
3149         if (A_FAILED(status)) {
3150             break;
3151         }
3152
3153     /*
3154      * Send sync cmd followed by sync data messages on all endpoints being
3155      * used
3156      */
3157     status = wmi_cmd_send(wmip, cmd_osbuf, WMI_SYNCHRONIZE_CMDID,
3158                           NO_SYNC_WMIFLAG);
3159
3160         if (A_FAILED(status)) {
3161             break;
3162     }
3163             /* cmd buffer sent, we no longer own it */
3164         cmd_osbuf = NULL;
3165
3166         for(i=0; i < numPriStreams; i++) {
3167             A_ASSERT(dataSyncBufs[i].osbuf != NULL);
3168             status = wmi_dataSync_send(wmip,
3169                                        dataSyncBufs[i].osbuf,
3170                                        A_WMI_Ac2EndpointID(wmip->wmi_devt,
3171                                                             dataSyncBufs[i].
3172                                                             trafficClass)
3173                                       );
3174
3175             if (A_FAILED(status)) {
3176                 break;
3177             }
3178             /* we don't own this buffer anymore, NULL it out of the array so it
3179              * won't get cleaned up */
3180             dataSyncBufs[i].osbuf = NULL;
3181         } //end for
3182
3183     } while(FALSE);
3184
3185     /* free up any resources left over (possibly due to an error) */
3186
3187     if (cmd_osbuf != NULL) {
3188         A_NETBUF_FREE(cmd_osbuf);
3189             }
3190
3191     for (i = 0; i < numPriStreams; i++) {
3192         if (dataSyncBufs[i].osbuf != NULL) {
3193             A_NETBUF_FREE(dataSyncBufs[i].osbuf);
3194         }
3195     }
3196
3197     return (status);
3198 }
3199
3200 A_STATUS
3201 wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *params)
3202 {
3203     void *osbuf;
3204     WMI_CREATE_PSTREAM_CMD *cmd;
3205     A_UINT8 fatPipeExistsForAC=0;
3206     A_INT32 minimalPHY = 0;
3207     A_INT32 nominalPHY = 0;
3208
3209     /* Validate all the parameters. */
3210     if( !((params->userPriority < 8) &&
3211          (params->userPriority <= 0x7) &&
3212          (convert_userPriority_to_trafficClass(params->userPriority) == params->trafficClass)  &&
3213          (params->trafficDirection == UPLINK_TRAFFIC ||
3214             params->trafficDirection == DNLINK_TRAFFIC ||
3215             params->trafficDirection == BIDIR_TRAFFIC) &&
3216          (params->trafficType == TRAFFIC_TYPE_APERIODIC ||
3217             params->trafficType == TRAFFIC_TYPE_PERIODIC ) &&
3218          (params->voicePSCapability == DISABLE_FOR_THIS_AC  ||
3219             params->voicePSCapability == ENABLE_FOR_THIS_AC ||
3220             params->voicePSCapability == ENABLE_FOR_ALL_AC) &&
3221          (params->tsid == WMI_IMPLICIT_PSTREAM || params->tsid <= WMI_MAX_THINSTREAM)) )
3222     {
3223         return  A_EINVAL;
3224     }
3225
3226     //
3227     // check nominal PHY rate is >= minimalPHY, so that DUT
3228     // can allow TSRS IE
3229     //
3230
3231     // get the physical rate
3232     minimalPHY = ((params->minPhyRate / 1000)/1000); // unit of bps
3233
3234     // check minimal phy < nominal phy rate
3235     //
3236     if (params->nominalPHY >= minimalPHY)
3237     {
3238         nominalPHY = (params->nominalPHY * 1000)/500; // unit of 500 kbps
3239         A_DPRINTF(DBG_WMI,
3240                   (DBGFMT "TSRS IE Enabled::MinPhy %x->NominalPhy ===> %x\n", DBGARG,
3241                   minimalPHY, nominalPHY));
3242
3243         params->nominalPHY = nominalPHY;
3244     }
3245     else
3246     {
3247         params->nominalPHY = 0;
3248     }
3249
3250     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3251     if (osbuf == NULL) {
3252         return A_NO_MEMORY;
3253     }
3254
3255     A_NETBUF_PUT(osbuf, sizeof(*cmd));
3256
3257     A_DPRINTF(DBG_WMI,
3258         (DBGFMT "Sending create_pstream_cmd: ac=%d    tsid:%d\n", DBGARG,
3259         params->trafficClass, params->tsid));
3260
3261     cmd = (WMI_CREATE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf));
3262     A_MEMZERO(cmd, sizeof(*cmd));
3263     A_MEMCPY(cmd, params, sizeof(*cmd));
3264
3265         /* this is an implicitly created Fat pipe */
3266     if ((A_UINT32)params->tsid == (A_UINT32)WMI_IMPLICIT_PSTREAM) {
3267         LOCK_WMI(wmip);
3268         fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass));
3269         wmip->wmi_fatPipeExists |= (1<<params->trafficClass);
3270         UNLOCK_WMI(wmip);
3271     } else {
3272             /* this is an explicitly created thin stream within a fat pipe */
3273     LOCK_WMI(wmip);
3274         fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass));
3275     wmip->wmi_streamExistsForAC[params->trafficClass] |= (1<<params->tsid);
3276             /* if a thinstream becomes active, the fat pipe automatically
3277             * becomes active
3278             */
3279         wmip->wmi_fatPipeExists |= (1<<params->trafficClass);
3280     UNLOCK_WMI(wmip);
3281     }
3282
3283         /* Indicate activty change to driver layer only if this is the
3284          * first TSID to get created in this AC explicitly or an implicit
3285          * fat pipe is getting created.
3286          */
3287     if (!fatPipeExistsForAC) {
3288         A_WMI_STREAM_TX_ACTIVE(wmip->wmi_devt, params->trafficClass);
3289     }
3290
3291     /* mike: should be SYNC_BEFORE_WMIFLAG */
3292     return (wmi_cmd_send(wmip, osbuf, WMI_CREATE_PSTREAM_CMDID,
3293                          NO_SYNC_WMIFLAG));
3294 }
3295
3296 A_STATUS
3297 wmi_delete_pstream_cmd(struct wmi_t *wmip, A_UINT8 trafficClass, A_UINT8 tsid)
3298 {
3299     void *osbuf;
3300     WMI_DELETE_PSTREAM_CMD *cmd;
3301     A_STATUS status;
3302     A_UINT16 activeTsids=0;
3303
3304     /* validate the parameters */
3305     if (trafficClass > 3) {
3306         A_DPRINTF(DBG_WMI, (DBGFMT "Invalid trafficClass: %d\n", DBGARG, trafficClass));
3307         return A_EINVAL;
3308     }
3309
3310     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3311     if (osbuf == NULL) {
3312         return A_NO_MEMORY;
3313     }
3314
3315     A_NETBUF_PUT(osbuf, sizeof(*cmd));
3316
3317     cmd = (WMI_DELETE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf));
3318     A_MEMZERO(cmd, sizeof(*cmd));
3319
3320     cmd->trafficClass = trafficClass;
3321     cmd->tsid = tsid;
3322
3323     LOCK_WMI(wmip);
3324     activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
3325     UNLOCK_WMI(wmip);
3326
3327         /* Check if the tsid was created & exists */
3328     if (!(activeTsids & (1<<tsid))) {
3329
3330         A_NETBUF_FREE(osbuf);
3331         A_DPRINTF(DBG_WMI,
3332         (DBGFMT "TSID %d does'nt exist for trafficClass: %d\n", DBGARG, tsid, trafficClass));
3333             /* TODO: return a more appropriate err code */
3334         return A_ERROR;
3335     }
3336
3337     A_DPRINTF(DBG_WMI,
3338         (DBGFMT "Sending delete_pstream_cmd: trafficClass: %d tsid=%d\n", DBGARG, trafficClass, tsid));
3339
3340     status = (wmi_cmd_send(wmip, osbuf, WMI_DELETE_PSTREAM_CMDID,
3341                          SYNC_BEFORE_WMIFLAG));
3342
3343     LOCK_WMI(wmip);
3344     wmip->wmi_streamExistsForAC[trafficClass] &= ~(1<<tsid);
3345     activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
3346     UNLOCK_WMI(wmip);
3347
3348
3349         /* Indicate stream inactivity to driver layer only if all tsids
3350          * within this AC are deleted.
3351          */
3352     if(!activeTsids) {
3353         A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, trafficClass);
3354         wmip->wmi_fatPipeExists &= ~(1<<trafficClass);
3355     }
3356
3357     return status;
3358 }
3359
3360 A_STATUS
3361 wmi_set_framerate_cmd(struct wmi_t *wmip, A_UINT8 bEnable, A_UINT8 type, A_UINT8 subType, A_UINT16 rateMask)
3362 {
3363     void *osbuf;
3364     WMI_FRAME_RATES_CMD *cmd;
3365     A_UINT8 frameType;
3366
3367     A_DPRINTF(DBG_WMI,
3368         (DBGFMT " type %02X, subType %02X, rateMask %04x\n", DBGARG, type, subType, rateMask));
3369
3370     if((type != IEEE80211_FRAME_TYPE_MGT && type != IEEE80211_FRAME_TYPE_CTL) ||
3371         (subType > 15)){
3372
3373         return A_EINVAL;
3374     }
3375
3376     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3377     if (osbuf == NULL) {
3378         return A_NO_MEMORY;
3379     }
3380
3381     A_NETBUF_PUT(osbuf, sizeof(*cmd));
3382
3383     cmd = (WMI_FRAME_RATES_CMD *)(A_NETBUF_DATA(osbuf));
3384     A_MEMZERO(cmd, sizeof(*cmd));
3385
3386     frameType = (A_UINT8)((subType << 4) | type);
3387
3388     cmd->bEnableMask = bEnable;
3389     cmd->frameType = frameType;
3390     cmd->frameRateMask = rateMask;
3391
3392     return (wmi_cmd_send(wmip, osbuf, WMI_SET_FRAMERATES_CMDID, NO_SYNC_WMIFLAG));
3393 }
3394
3395 /*
3396  * used to set the bit rate.  rate is in Kbps.  If rate == -1
3397  * then auto selection is used.
3398  */
3399 A_STATUS
3400 wmi_set_bitrate_cmd(struct wmi_t *wmip, A_INT32 dataRate, A_INT32 mgmtRate, A_INT32 ctlRate)
3401 {
3402     void *osbuf;
3403     WMI_BIT_RATE_CMD *cmd;
3404     A_INT8 drix, mrix, crix, ret_val;
3405
3406     if (dataRate != -1) {
3407         ret_val = wmi_validate_bitrate(wmip, dataRate, &drix);
3408         if(ret_val == A_EINVAL){
3409             return A_EINVAL;
3410         }
3411     } else {
3412         drix = -1;
3413     }
3414
3415     if (mgmtRate != -1) {
3416         ret_val = wmi_validate_bitrate(wmip, mgmtRate, &mrix);
3417         if(ret_val == A_EINVAL){
3418             return A_EINVAL;
3419         }
3420     } else {
3421         mrix = -1;
3422     }
3423     if (ctlRate != -1) {
3424         ret_val = wmi_validate_bitrate(wmip, ctlRate, &crix);
3425         if(ret_val == A_EINVAL){
3426             return A_EINVAL;
3427         }
3428     } else {
3429         crix = -1;
3430     }
3431     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3432     if (osbuf == NULL) {
3433         return A_NO_MEMORY;
3434     }
3435
3436     A_NETBUF_PUT(osbuf, sizeof(*cmd));
3437
3438     cmd = (WMI_BIT_RATE_CMD *)(A_NETBUF_DATA(osbuf));
3439     A_MEMZERO(cmd, sizeof(*cmd));
3440
3441     cmd->rateIndex = drix;
3442     cmd->mgmtRateIndex = mrix;
3443     cmd->ctlRateIndex  = crix;
3444
3445
3446     return (wmi_cmd_send(wmip, osbuf, WMI_SET_BITRATE_CMDID, NO_SYNC_WMIFLAG));
3447 }
3448
3449 A_STATUS
3450 wmi_get_bitrate_cmd(struct wmi_t *wmip)
3451 {
3452     return wmi_simple_cmd(wmip, WMI_GET_BITRATE_CMDID);
3453 }
3454
3455 /*
3456  * Returns TRUE iff the given rate index is legal in the current PHY mode.
3457  */
3458 A_BOOL
3459 wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_INT32 rateIndex)
3460 {
3461     WMI_PHY_MODE phyMode = (WMI_PHY_MODE) wmip->wmi_phyMode;
3462     A_BOOL isValid = TRUE;
3463     switch(phyMode) {
3464         case WMI_11A_MODE:
3465             if (wmip->wmi_ht_allowed[A_BAND_5GHZ]){
3466                 if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
3467                     isValid = FALSE;
3468                 }
3469             } else {
3470                 if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_A_SUPPORT_RATE_STOP)) {
3471                     isValid = FALSE;
3472                 }
3473             }
3474             break;
3475
3476         case WMI_11B_MODE:
3477             if ((rateIndex < MODE_B_SUPPORT_RATE_START) || (rateIndex > MODE_B_SUPPORT_RATE_STOP)) {
3478                 isValid = FALSE;
3479             }
3480             break;
3481
3482         case WMI_11GONLY_MODE:
3483             if (wmip->wmi_ht_allowed[A_BAND_24GHZ]){
3484                 if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
3485                     isValid = FALSE;
3486                 }
3487             } else {
3488                 if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE_GONLY_SUPPORT_RATE_STOP)) {
3489                     isValid = FALSE;
3490                 }
3491             }
3492             break;
3493
3494         case WMI_11G_MODE:
3495         case WMI_11AG_MODE:
3496             if (wmip->wmi_ht_allowed[A_BAND_24GHZ]){
3497                 if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
3498                     isValid = FALSE;
3499                 }
3500             } else {
3501                 if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_G_SUPPORT_RATE_STOP)) {
3502                     isValid = FALSE;
3503                 }
3504             }
3505             break;
3506         default:
3507             A_ASSERT(FALSE);
3508             break;
3509     }
3510
3511     return isValid;
3512 }
3513
3514 A_INT8
3515 wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate, A_INT8 *rate_idx)
3516 {
3517     A_INT8 i;
3518
3519     for (i=0;;i++)
3520     {
3521         if (wmi_rateTable[(A_UINT32) i][0] == 0) {
3522             return A_EINVAL;
3523         }
3524         if (wmi_rateTable[(A_UINT32) i][0] == rate) {
3525             break;
3526         }
3527     }
3528
3529     if(wmi_is_bitrate_index_valid(wmip, (A_INT32) i) != TRUE) {
3530         return A_EINVAL;
3531     }
3532
3533     *rate_idx = i;
3534     return A_OK;
3535 }
3536
3537 A_STATUS
3538 wmi_set_fixrates_cmd(struct wmi_t *wmip, A_UINT32 fixRatesMask)
3539 {
3540     void *osbuf;
3541     WMI_FIX_RATES_CMD *cmd;
3542 #if 0
3543     A_INT32 rateIndex;
3544 /* This check does not work for AR6003 as the HT modes are enabled only when
3545  * the STA is connected to a HT_BSS and is not based only on channel. It is
3546  * safe to skip this check however because rate control will only use rates
3547  * that are permitted by the valid rate mask and the fix rate mask. Meaning
3548  * the fix rate mask is not sufficient by itself to cause an invalid rate
3549  * to be used. */
3550     /* Make sure all rates in the mask are valid in the current PHY mode */
3551     for(rateIndex = 0; rateIndex < MAX_NUMBER_OF_SUPPORT_RATES; rateIndex++) {
3552        if((1 << rateIndex) & (A_UINT32)fixRatesMask) {
3553             if(wmi_is_bitrate_index_valid(wmip, rateIndex) != TRUE) {
3554                 A_DPRINTF(DBG_WMI, (DBGFMT "Set Fix Rates command failed: Given rate is illegal in current PHY mode\n", DBGARG));
3555                 return A_EINVAL;
3556             }
3557        }
3558     }
3559 #endif
3560
3561
3562     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3563     if (osbuf == NULL) {
3564         return A_NO_MEMORY;
3565     }
3566
3567     A_NETBUF_PUT(osbuf, sizeof(*cmd));
3568
3569     cmd = (WMI_FIX_RATES_CMD *)(A_NETBUF_DATA(osbuf));
3570     A_MEMZERO(cmd, sizeof(*cmd));
3571
3572     cmd->fixRateMask = fixRatesMask;
3573
3574     return (wmi_cmd_send(wmip, osbuf, WMI_SET_FIXRATES_CMDID, NO_SYNC_WMIFLAG));
3575 }
3576
3577 A_STATUS
3578 wmi_get_ratemask_cmd(struct wmi_t *wmip)
3579 {
3580     return wmi_simple_cmd(wmip, WMI_GET_FIXRATES_CMDID);
3581 }
3582
3583 A_STATUS
3584 wmi_get_channelList_cmd(struct wmi_t *wmip)
3585 {
3586     return wmi_simple_cmd(wmip, WMI_GET_CHANNEL_LIST_CMDID);
3587 }
3588
3589 /*
3590  * used to generate a wmi sey channel Parameters cmd.
3591  * mode should always be specified and corresponds to the phy mode of the
3592  * wlan.
3593  * numChan should alway sbe specified. If zero indicates that all available
3594  * channels should be used.
3595  * channelList is an array of channel frequencies (in Mhz) which the radio
3596  * should limit its operation to.  It should be NULL if numChan == 0.  Size of
3597  * array should correspond to numChan entries.
3598  */
3599 A_STATUS
3600 wmi_set_channelParams_cmd(struct wmi_t *wmip, A_UINT8 scanParam,
3601                           WMI_PHY_MODE mode, A_INT8 numChan,
3602                           A_UINT16 *channelList)
3603 {
3604     void *osbuf;
3605     WMI_CHANNEL_PARAMS_CMD *cmd;
3606     A_INT8 size;
3607
3608     size = sizeof (*cmd);
3609
3610     if (numChan) {
3611         if (numChan > WMI_MAX_CHANNELS) {
3612             return A_EINVAL;
3613         }
3614         size += sizeof(A_UINT16) * (numChan - 1);
3615     }
3616
3617     osbuf = A_NETBUF_ALLOC(size);
3618     if (osbuf == NULL) {
3619         return A_NO_MEMORY;
3620     }
3621
3622     A_NETBUF_PUT(osbuf, size);
3623
3624     cmd = (WMI_CHANNEL_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
3625     A_MEMZERO(cmd, size);
3626
3627     wmip->wmi_phyMode = mode;
3628     cmd->scanParam   = scanParam;
3629     cmd->phyMode     = mode;
3630     cmd->numChannels = numChan;
3631     A_MEMCPY(cmd->channelList, channelList, numChan * sizeof(A_UINT16));
3632
3633     return (wmi_cmd_send(wmip, osbuf, WMI_SET_CHANNEL_PARAMS_CMDID,
3634                          NO_SYNC_WMIFLAG));
3635 }
3636
3637 void
3638 wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
3639 {
3640     SQ_THRESHOLD_PARAMS *sq_thresh =
3641            &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI];
3642     /*
3643      * Parse the command and store the threshold values here. The checks
3644      * for valid values can be put here
3645      */
3646     sq_thresh->weight = rssiCmd->weight;
3647     sq_thresh->polling_interval = rssiCmd->pollTime;
3648
3649     sq_thresh->upper_threshold[0] = rssiCmd->thresholdAbove1_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3650     sq_thresh->upper_threshold[1] = rssiCmd->thresholdAbove2_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3651     sq_thresh->upper_threshold[2] = rssiCmd->thresholdAbove3_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3652     sq_thresh->upper_threshold[3] = rssiCmd->thresholdAbove4_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3653     sq_thresh->upper_threshold[4] = rssiCmd->thresholdAbove5_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3654     sq_thresh->upper_threshold[5] = rssiCmd->thresholdAbove6_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3655     sq_thresh->upper_threshold_valid_count = 6;
3656
3657     /* List sorted in descending order */
3658     sq_thresh->lower_threshold[0] = rssiCmd->thresholdBelow6_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3659     sq_thresh->lower_threshold[1] = rssiCmd->thresholdBelow5_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3660     sq_thresh->lower_threshold[2] = rssiCmd->thresholdBelow4_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3661     sq_thresh->lower_threshold[3] = rssiCmd->thresholdBelow3_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3662     sq_thresh->lower_threshold[4] = rssiCmd->thresholdBelow2_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3663     sq_thresh->lower_threshold[5] = rssiCmd->thresholdBelow1_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3664     sq_thresh->lower_threshold_valid_count = 6;
3665
3666     if (!rssi_event_value) {
3667     /*
3668      * Configuring the thresholds to their extremes allows the host to get an
3669      * event from the target which is used for the configuring the correct
3670      * thresholds
3671      */
3672     rssiCmd->thresholdAbove1_Val = sq_thresh->upper_threshold[0];
3673     rssiCmd->thresholdBelow1_Val = sq_thresh->lower_threshold[0];
3674     } else {
3675         /*
3676          * In case the user issues multiple times of rssi_threshold_setting,
3677          * we should not use the extreames anymore, the target does not expect that.
3678          */
3679         rssiCmd->thresholdAbove1_Val = ar6000_get_upper_threshold(rssi_event_value, sq_thresh,
3680                                               sq_thresh->upper_threshold_valid_count);
3681         rssiCmd->thresholdBelow1_Val = ar6000_get_lower_threshold(rssi_event_value, sq_thresh,
3682                                               sq_thresh->lower_threshold_valid_count);
3683 }
3684 }
3685
3686 A_STATUS
3687 wmi_set_rssi_threshold_params(struct wmi_t *wmip,
3688                               WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
3689 {
3690
3691      /* Check these values are in ascending order */
3692     if( rssiCmd->thresholdAbove6_Val <= rssiCmd->thresholdAbove5_Val ||
3693         rssiCmd->thresholdAbove5_Val <= rssiCmd->thresholdAbove4_Val ||
3694         rssiCmd->thresholdAbove4_Val <= rssiCmd->thresholdAbove3_Val ||
3695         rssiCmd->thresholdAbove3_Val <= rssiCmd->thresholdAbove2_Val ||
3696         rssiCmd->thresholdAbove2_Val <= rssiCmd->thresholdAbove1_Val ||
3697         rssiCmd->thresholdBelow6_Val <= rssiCmd->thresholdBelow5_Val ||
3698         rssiCmd->thresholdBelow5_Val <= rssiCmd->thresholdBelow4_Val ||
3699         rssiCmd->thresholdBelow4_Val <= rssiCmd->thresholdBelow3_Val ||
3700         rssiCmd->thresholdBelow3_Val <= rssiCmd->thresholdBelow2_Val ||
3701         rssiCmd->thresholdBelow2_Val <= rssiCmd->thresholdBelow1_Val)
3702     {
3703         return A_EINVAL;
3704     }
3705
3706     wmi_cache_configure_rssithreshold(wmip, rssiCmd);
3707
3708     return (wmi_send_rssi_threshold_params(wmip, rssiCmd));
3709 }
3710
3711 A_STATUS
3712 wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *ipCmd)
3713 {
3714     void    *osbuf;
3715     WMI_SET_IP_CMD *cmd;
3716
3717     /* Multicast address are not valid */
3718     if((*((A_UINT8*)&ipCmd->ips[0]) >= 0xE0) ||
3719        (*((A_UINT8*)&ipCmd->ips[1]) >= 0xE0)) {
3720         return A_EINVAL;
3721     }
3722
3723     osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_IP_CMD));
3724     if (osbuf == NULL) {
3725         return A_NO_MEMORY;
3726     }
3727
3728     A_NETBUF_PUT(osbuf, sizeof(WMI_SET_IP_CMD));
3729     cmd = (WMI_SET_IP_CMD *)(A_NETBUF_DATA(osbuf));
3730     A_MEMCPY(cmd, ipCmd, sizeof(WMI_SET_IP_CMD));
3731
3732     return (wmi_cmd_send(wmip, osbuf, WMI_SET_IP_CMDID,
3733                             NO_SYNC_WMIFLAG));
3734 }
3735
3736 A_STATUS
3737 wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip,
3738                               WMI_SET_HOST_SLEEP_MODE_CMD *hostModeCmd)
3739 {
3740     void    *osbuf;
3741     A_INT8  size;
3742     WMI_SET_HOST_SLEEP_MODE_CMD *cmd;
3743     A_UINT16 activeTsids=0;
3744     A_UINT8 streamExists=0;
3745     A_UINT8 i;
3746
3747     if( hostModeCmd->awake == hostModeCmd->asleep) {
3748         return A_EINVAL;
3749     }
3750
3751     size = sizeof (*cmd);
3752
3753     osbuf = A_NETBUF_ALLOC(size);
3754     if (osbuf == NULL) {
3755         return A_NO_MEMORY;
3756     }
3757
3758     A_NETBUF_PUT(osbuf, size);
3759
3760     cmd = (WMI_SET_HOST_SLEEP_MODE_CMD *)(A_NETBUF_DATA(osbuf));
3761     A_MEMZERO(cmd, size);
3762     A_MEMCPY(cmd, hostModeCmd, sizeof(WMI_SET_HOST_SLEEP_MODE_CMD));
3763
3764     if(hostModeCmd->asleep) {
3765         /*
3766          * Relinquish credits from all implicitly created pstreams since when we
3767          * go to sleep. If user created explicit thinstreams exists with in a
3768          * fatpipe leave them intact for the user to delete
3769          */
3770         LOCK_WMI(wmip);
3771         streamExists = wmip->wmi_fatPipeExists;
3772         UNLOCK_WMI(wmip);
3773
3774         for(i=0;i< WMM_NUM_AC;i++) {
3775             if (streamExists & (1<<i)) {
3776                 LOCK_WMI(wmip);
3777                 activeTsids = wmip->wmi_streamExistsForAC[i];
3778                 UNLOCK_WMI(wmip);
3779                 /* If there are no user created thin streams delete the fatpipe */
3780                 if(!activeTsids) {
3781                     streamExists &= ~(1<<i);
3782                     /*Indicate inactivity to drv layer for this fatpipe(pstream)*/
3783                     A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt,i);
3784                 }
3785             }
3786         }
3787
3788         /* Update the fatpipes that exists*/
3789         LOCK_WMI(wmip);
3790         wmip->wmi_fatPipeExists = streamExists;
3791         UNLOCK_WMI(wmip);
3792     }
3793
3794     return (wmi_cmd_send(wmip, osbuf, WMI_SET_HOST_SLEEP_MODE_CMDID,
3795                             NO_SYNC_WMIFLAG));
3796 }
3797
3798 A_STATUS
3799 wmi_set_wow_mode_cmd(struct wmi_t *wmip,
3800                               WMI_SET_WOW_MODE_CMD *wowModeCmd)
3801 {
3802     void    *osbuf;
3803     A_INT8  size;
3804     WMI_SET_WOW_MODE_CMD *cmd;
3805
3806     size = sizeof (*cmd);
3807
3808     osbuf = A_NETBUF_ALLOC(size);
3809     if (osbuf == NULL) {
3810         return A_NO_MEMORY;
3811     }
3812
3813     A_NETBUF_PUT(osbuf, size);
3814
3815     cmd = (WMI_SET_WOW_MODE_CMD *)(A_NETBUF_DATA(osbuf));
3816     A_MEMZERO(cmd, size);
3817     A_MEMCPY(cmd, wowModeCmd, sizeof(WMI_SET_WOW_MODE_CMD));
3818
3819     return (wmi_cmd_send(wmip, osbuf, WMI_SET_WOW_MODE_CMDID,
3820                             NO_SYNC_WMIFLAG));
3821
3822 }
3823
3824 A_STATUS
3825 wmi_get_wow_list_cmd(struct wmi_t *wmip,
3826                               WMI_GET_WOW_LIST_CMD *wowListCmd)
3827 {
3828     void    *osbuf;
3829     A_INT8  size;
3830     WMI_GET_WOW_LIST_CMD *cmd;
3831
3832     size = sizeof (*cmd);
3833
3834     osbuf = A_NETBUF_ALLOC(size);
3835     if (osbuf == NULL) {
3836         return A_NO_MEMORY;
3837     }
3838
3839     A_NETBUF_PUT(osbuf, size);
3840
3841     cmd = (WMI_GET_WOW_LIST_CMD *)(A_NETBUF_DATA(osbuf));
3842     A_MEMZERO(cmd, size);
3843     A_MEMCPY(cmd, wowListCmd, sizeof(WMI_GET_WOW_LIST_CMD));
3844
3845     return (wmi_cmd_send(wmip, osbuf, WMI_GET_WOW_LIST_CMDID,
3846                             NO_SYNC_WMIFLAG));
3847
3848 }
3849
3850 static A_STATUS
3851 wmi_get_wow_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
3852 {
3853     WMI_GET_WOW_LIST_REPLY *reply;
3854
3855     if (len < sizeof(WMI_GET_WOW_LIST_REPLY)) {
3856         return A_EINVAL;
3857     }
3858     reply = (WMI_GET_WOW_LIST_REPLY *)datap;
3859
3860     A_WMI_WOW_LIST_EVENT(wmip->wmi_devt, reply->num_filters,
3861                           reply);
3862
3863     return A_OK;
3864 }
3865
3866 A_STATUS wmi_add_wow_pattern_cmd(struct wmi_t *wmip,
3867                                  WMI_ADD_WOW_PATTERN_CMD *addWowCmd,
3868                                  A_UINT8* pattern, A_UINT8* mask,
3869                                  A_UINT8 pattern_size)
3870 {
3871     void    *osbuf;
3872     A_INT8  size;
3873     WMI_ADD_WOW_PATTERN_CMD *cmd;
3874     A_UINT8 *filter_mask = NULL;
3875
3876     size = sizeof (*cmd);
3877
3878     size += ((2 * addWowCmd->filter_size)* sizeof(A_UINT8));
3879     osbuf = A_NETBUF_ALLOC(size);
3880     if (osbuf == NULL) {
3881         return A_NO_MEMORY;
3882     }
3883
3884     A_NETBUF_PUT(osbuf, size);
3885
3886     cmd = (WMI_ADD_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf));
3887     cmd->filter_list_id = addWowCmd->filter_list_id;
3888     cmd->filter_offset = addWowCmd->filter_offset;
3889     cmd->filter_size = addWowCmd->filter_size;
3890
3891     A_MEMCPY(cmd->filter, pattern, addWowCmd->filter_size);
3892
3893     filter_mask = (A_UINT8*)(cmd->filter + cmd->filter_size);
3894     A_MEMCPY(filter_mask, mask, addWowCmd->filter_size);
3895
3896
3897     return (wmi_cmd_send(wmip, osbuf, WMI_ADD_WOW_PATTERN_CMDID,
3898                             NO_SYNC_WMIFLAG));
3899 }
3900
3901 A_STATUS
3902 wmi_del_wow_pattern_cmd(struct wmi_t *wmip,
3903                               WMI_DEL_WOW_PATTERN_CMD *delWowCmd)
3904 {
3905     void    *osbuf;
3906     A_INT8  size;
3907     WMI_DEL_WOW_PATTERN_CMD *cmd;
3908
3909     size = sizeof (*cmd);
3910
3911     osbuf = A_NETBUF_ALLOC(size);
3912     if (osbuf == NULL) {
3913         return A_NO_MEMORY;
3914     }
3915
3916     A_NETBUF_PUT(osbuf, size);
3917
3918     cmd = (WMI_DEL_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf));
3919     A_MEMZERO(cmd, size);
3920     A_MEMCPY(cmd, delWowCmd, sizeof(WMI_DEL_WOW_PATTERN_CMD));
3921
3922     return (wmi_cmd_send(wmip, osbuf, WMI_DEL_WOW_PATTERN_CMDID,
3923                             NO_SYNC_WMIFLAG));
3924
3925 }
3926
3927 void
3928 wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
3929 {
3930     SQ_THRESHOLD_PARAMS *sq_thresh =
3931            &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_SNR];
3932     /*
3933      * Parse the command and store the threshold values here. The checks
3934      * for valid values can be put here
3935      */
3936     sq_thresh->weight = snrCmd->weight;
3937     sq_thresh->polling_interval = snrCmd->pollTime;
3938
3939     sq_thresh->upper_threshold[0] = snrCmd->thresholdAbove1_Val;
3940     sq_thresh->upper_threshold[1] = snrCmd->thresholdAbove2_Val;
3941     sq_thresh->upper_threshold[2] = snrCmd->thresholdAbove3_Val;
3942     sq_thresh->upper_threshold[3] = snrCmd->thresholdAbove4_Val;
3943     sq_thresh->upper_threshold_valid_count = 4;
3944
3945     /* List sorted in descending order */
3946     sq_thresh->lower_threshold[0] = snrCmd->thresholdBelow4_Val;
3947     sq_thresh->lower_threshold[1] = snrCmd->thresholdBelow3_Val;
3948     sq_thresh->lower_threshold[2] = snrCmd->thresholdBelow2_Val;
3949     sq_thresh->lower_threshold[3] = snrCmd->thresholdBelow1_Val;
3950     sq_thresh->lower_threshold_valid_count = 4;
3951
3952     if (!snr_event_value) {
3953     /*
3954      * Configuring the thresholds to their extremes allows the host to get an
3955      * event from the target which is used for the configuring the correct
3956      * thresholds
3957      */
3958     snrCmd->thresholdAbove1_Val = (A_UINT8)sq_thresh->upper_threshold[0];
3959     snrCmd->thresholdBelow1_Val = (A_UINT8)sq_thresh->lower_threshold[0];
3960     } else {
3961         /*
3962          * In case the user issues multiple times of snr_threshold_setting,
3963          * we should not use the extreames anymore, the target does not expect that.
3964          */
3965         snrCmd->thresholdAbove1_Val = ar6000_get_upper_threshold(snr_event_value, sq_thresh,
3966                                               sq_thresh->upper_threshold_valid_count);
3967         snrCmd->thresholdBelow1_Val = ar6000_get_lower_threshold(snr_event_value, sq_thresh,
3968                                               sq_thresh->lower_threshold_valid_count);
3969     }
3970
3971 }
3972 A_STATUS
3973 wmi_set_snr_threshold_params(struct wmi_t *wmip,
3974                              WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
3975 {
3976     if( snrCmd->thresholdAbove4_Val <= snrCmd->thresholdAbove3_Val ||
3977         snrCmd->thresholdAbove3_Val <= snrCmd->thresholdAbove2_Val ||
3978         snrCmd->thresholdAbove2_Val <= snrCmd->thresholdAbove1_Val ||
3979         snrCmd->thresholdBelow4_Val <= snrCmd->thresholdBelow3_Val ||
3980         snrCmd->thresholdBelow3_Val <= snrCmd->thresholdBelow2_Val ||
3981         snrCmd->thresholdBelow2_Val <= snrCmd->thresholdBelow1_Val)
3982     {
3983         return A_EINVAL;
3984     }
3985     wmi_cache_configure_snrthreshold(wmip, snrCmd);
3986     return (wmi_send_snr_threshold_params(wmip, snrCmd));
3987 }
3988
3989 A_STATUS
3990 wmi_clr_rssi_snr(struct wmi_t *wmip)
3991 {
3992     void    *osbuf;
3993
3994     osbuf = A_NETBUF_ALLOC(sizeof(int));
3995     if (osbuf == NULL) {
3996         return A_NO_MEMORY;
3997     }
3998
3999     return (wmi_cmd_send(wmip, osbuf, WMI_CLR_RSSI_SNR_CMDID,
4000                             NO_SYNC_WMIFLAG));
4001 }
4002
4003 A_STATUS
4004 wmi_set_lq_threshold_params(struct wmi_t *wmip,
4005                              WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd)
4006 {
4007     void    *osbuf;
4008     A_INT8  size;
4009     WMI_LQ_THRESHOLD_PARAMS_CMD *cmd;
4010     /* These values are in ascending order */
4011     if( lqCmd->thresholdAbove4_Val <= lqCmd->thresholdAbove3_Val ||
4012         lqCmd->thresholdAbove3_Val <= lqCmd->thresholdAbove2_Val ||
4013         lqCmd->thresholdAbove2_Val <= lqCmd->thresholdAbove1_Val ||
4014         lqCmd->thresholdBelow4_Val <= lqCmd->thresholdBelow3_Val ||
4015         lqCmd->thresholdBelow3_Val <= lqCmd->thresholdBelow2_Val ||
4016         lqCmd->thresholdBelow2_Val <= lqCmd->thresholdBelow1_Val ) {
4017
4018         return A_EINVAL;
4019     }
4020
4021     size = sizeof (*cmd);
4022
4023     osbuf = A_NETBUF_ALLOC(size);
4024     if (osbuf == NULL) {
4025         return A_NO_MEMORY;
4026     }
4027
4028     A_NETBUF_PUT(osbuf, size);
4029
4030     cmd = (WMI_LQ_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
4031     A_MEMZERO(cmd, size);
4032     A_MEMCPY(cmd, lqCmd, sizeof(WMI_LQ_THRESHOLD_PARAMS_CMD));
4033
4034     return (wmi_cmd_send(wmip, osbuf, WMI_LQ_THRESHOLD_PARAMS_CMDID,
4035                             NO_SYNC_WMIFLAG));
4036 }
4037
4038 A_STATUS
4039 wmi_set_error_report_bitmask(struct wmi_t *wmip, A_UINT32 mask)
4040 {
4041     void    *osbuf;
4042     A_INT8  size;
4043     WMI_TARGET_ERROR_REPORT_BITMASK *cmd;
4044
4045     size = sizeof (*cmd);
4046
4047     osbuf = A_NETBUF_ALLOC(size);
4048     if (osbuf == NULL) {
4049         return A_NO_MEMORY;
4050     }
4051
4052     A_NETBUF_PUT(osbuf, size);
4053
4054     cmd = (WMI_TARGET_ERROR_REPORT_BITMASK *)(A_NETBUF_DATA(osbuf));
4055     A_MEMZERO(cmd, size);
4056
4057     cmd->bitmask = mask;
4058
4059     return (wmi_cmd_send(wmip, osbuf, WMI_TARGET_ERROR_REPORT_BITMASK_CMDID,
4060                             NO_SYNC_WMIFLAG));
4061 }
4062
4063 A_STATUS
4064 wmi_get_challenge_resp_cmd(struct wmi_t *wmip, A_UINT32 cookie, A_UINT32 source)
4065 {
4066     void *osbuf;
4067     WMIX_HB_CHALLENGE_RESP_CMD *cmd;
4068
4069     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4070     if (osbuf == NULL) {
4071         return A_NO_MEMORY;
4072     }
4073
4074     A_NETBUF_PUT(osbuf, sizeof(*cmd));
4075
4076     cmd = (WMIX_HB_CHALLENGE_RESP_CMD *)(A_NETBUF_DATA(osbuf));
4077     cmd->cookie = cookie;
4078     cmd->source = source;
4079
4080     return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_HB_CHALLENGE_RESP_CMDID,
4081                               NO_SYNC_WMIFLAG));
4082 }
4083
4084 A_STATUS
4085 wmi_config_debug_module_cmd(struct wmi_t *wmip, A_UINT16 mmask,
4086                             A_UINT16 tsr, A_BOOL rep, A_UINT16 size,
4087                             A_UINT32 valid)
4088 {
4089     void *osbuf;
4090     WMIX_DBGLOG_CFG_MODULE_CMD *cmd;
4091
4092     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4093     if (osbuf == NULL) {
4094         return A_NO_MEMORY;
4095     }
4096
4097     A_NETBUF_PUT(osbuf, sizeof(*cmd));
4098
4099     cmd = (WMIX_DBGLOG_CFG_MODULE_CMD *)(A_NETBUF_DATA(osbuf));
4100     cmd->config.cfgmmask = mmask;
4101     cmd->config.cfgtsr = tsr;
4102     cmd->config.cfgrep = rep;
4103     cmd->config.cfgsize = size;
4104     cmd->config.cfgvalid = valid;
4105
4106     return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DBGLOG_CFG_MODULE_CMDID,
4107                               NO_SYNC_WMIFLAG));
4108 }
4109
4110 A_STATUS
4111 wmi_get_stats_cmd(struct wmi_t *wmip)
4112 {
4113     return wmi_simple_cmd(wmip, WMI_GET_STATISTICS_CMDID);
4114 }
4115
4116 A_STATUS
4117 wmi_addBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex, A_UINT8 *bssid)
4118 {
4119     void *osbuf;
4120     WMI_ADD_BAD_AP_CMD *cmd;
4121
4122     if ((bssid == NULL) || (apIndex > WMI_MAX_BAD_AP_INDEX)) {
4123         return A_EINVAL;
4124     }
4125
4126     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4127     if (osbuf == NULL) {
4128         return A_NO_MEMORY;
4129     }
4130
4131     A_NETBUF_PUT(osbuf, sizeof(*cmd));
4132
4133     cmd = (WMI_ADD_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf));
4134     cmd->badApIndex = apIndex;
4135     A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid));
4136
4137     return (wmi_cmd_send(wmip, osbuf, WMI_ADD_BAD_AP_CMDID, SYNC_BEFORE_WMIFLAG));
4138 }
4139
4140 A_STATUS
4141 wmi_deleteBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex)
4142 {
4143     void *osbuf;
4144     WMI_DELETE_BAD_AP_CMD *cmd;
4145
4146     if (apIndex > WMI_MAX_BAD_AP_INDEX) {
4147         return A_EINVAL;
4148     }
4149
4150     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4151     if (osbuf == NULL) {
4152         return A_NO_MEMORY;
4153     }
4154
4155     A_NETBUF_PUT(osbuf, sizeof(*cmd));
4156
4157     cmd = (WMI_DELETE_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf));
4158     cmd->badApIndex = apIndex;
4159
4160     return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_BAD_AP_CMDID,
4161                          NO_SYNC_WMIFLAG));
4162 }
4163
4164 A_STATUS
4165 wmi_abort_scan_cmd(struct wmi_t *wmip)
4166 {
4167     return wmi_simple_cmd(wmip, WMI_ABORT_SCAN_CMDID);
4168 }
4169
4170 A_STATUS
4171 wmi_set_txPwr_cmd(struct wmi_t *wmip, A_UINT8 dbM)
4172 {
4173     void *osbuf;
4174     WMI_SET_TX_PWR_CMD *cmd;
4175
4176     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4177     if (osbuf == NULL) {
4178         return A_NO_MEMORY;
4179     }
4180
4181     A_NETBUF_PUT(osbuf, sizeof(*cmd));
4182
4183     cmd = (WMI_SET_TX_PWR_CMD *)(A_NETBUF_DATA(osbuf));
4184     cmd->dbM = dbM;
4185
4186     return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_PWR_CMDID, NO_SYNC_WMIFLAG));
4187 }
4188
4189 A_STATUS
4190 wmi_get_txPwr_cmd(struct wmi_t *wmip)
4191 {
4192     return wmi_simple_cmd(wmip, WMI_GET_TX_PWR_CMDID);
4193 }
4194
4195 A_UINT16
4196 wmi_get_mapped_qos_queue(struct wmi_t *wmip, A_UINT8 trafficClass)
4197 {
4198     A_UINT16 activeTsids=0;
4199
4200     LOCK_WMI(wmip);
4201     activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
4202     UNLOCK_WMI(wmip);
4203
4204     return activeTsids;
4205 }
4206
4207 A_STATUS
4208 wmi_get_roam_tbl_cmd(struct wmi_t *wmip)
4209 {
4210     return wmi_simple_cmd(wmip, WMI_GET_ROAM_TBL_CMDID);
4211 }
4212
4213 A_STATUS
4214 wmi_get_roam_data_cmd(struct wmi_t *wmip, A_UINT8 roamDataType)
4215 {
4216     void *osbuf;
4217     A_UINT32 size = sizeof(A_UINT8);
4218     WMI_TARGET_ROAM_DATA *cmd;
4219
4220     osbuf = A_NETBUF_ALLOC(size);      /* no payload */
4221     if (osbuf == NULL) {
4222         return A_NO_MEMORY;
4223     }
4224
4225     A_NETBUF_PUT(osbuf, size);
4226
4227     cmd = (WMI_TARGET_ROAM_DATA *)(A_NETBUF_DATA(osbuf));
4228     cmd->roamDataType = roamDataType;
4229
4230     return (wmi_cmd_send(wmip, osbuf, WMI_GET_ROAM_DATA_CMDID,
4231                          NO_SYNC_WMIFLAG));
4232 }
4233
4234 A_STATUS
4235 wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p,
4236                       A_UINT8 size)
4237 {
4238     void *osbuf;
4239     WMI_SET_ROAM_CTRL_CMD *cmd;
4240
4241     osbuf = A_NETBUF_ALLOC(size);
4242     if (osbuf == NULL) {
4243         return A_NO_MEMORY;
4244     }
4245
4246     A_NETBUF_PUT(osbuf, size);
4247
4248     cmd = (WMI_SET_ROAM_CTRL_CMD *)(A_NETBUF_DATA(osbuf));
4249     A_MEMZERO(cmd, size);
4250
4251     A_MEMCPY(cmd, p, size);
4252
4253     return (wmi_cmd_send(wmip, osbuf, WMI_SET_ROAM_CTRL_CMDID,
4254                          NO_SYNC_WMIFLAG));
4255 }
4256
4257 A_STATUS
4258 wmi_set_powersave_timers_cmd(struct wmi_t *wmip,
4259                             WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd,
4260                             A_UINT8 size)
4261 {
4262     void *osbuf;
4263     WMI_POWERSAVE_TIMERS_POLICY_CMD *cmd;
4264
4265     /* These timers can't be zero */
4266     if(!pCmd->psPollTimeout || !pCmd->triggerTimeout ||
4267        !(pCmd->apsdTimPolicy == IGNORE_TIM_ALL_QUEUES_APSD ||
4268          pCmd->apsdTimPolicy == PROCESS_TIM_ALL_QUEUES_APSD) ||
4269        !(pCmd->simulatedAPSDTimPolicy == IGNORE_TIM_SIMULATED_APSD ||
4270          pCmd->simulatedAPSDTimPolicy == PROCESS_TIM_SIMULATED_APSD))
4271         return A_EINVAL;
4272
4273     osbuf = A_NETBUF_ALLOC(size);
4274     if (osbuf == NULL) {
4275         return A_NO_MEMORY;
4276     }
4277
4278     A_NETBUF_PUT(osbuf, size);
4279
4280     cmd = (WMI_POWERSAVE_TIMERS_POLICY_CMD *)(A_NETBUF_DATA(osbuf));
4281     A_MEMZERO(cmd, size);
4282
4283     A_MEMCPY(cmd, pCmd, size);
4284
4285     return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID,
4286                          NO_SYNC_WMIFLAG));
4287 }
4288
4289 #ifdef CONFIG_HOST_GPIO_SUPPORT
4290 /* Send a command to Target to change GPIO output pins. */
4291 A_STATUS
4292 wmi_gpio_output_set(struct wmi_t *wmip,
4293                     A_UINT32 set_mask,
4294                     A_UINT32 clear_mask,
4295                     A_UINT32 enable_mask,
4296                     A_UINT32 disable_mask)
4297 {
4298     void *osbuf;
4299     WMIX_GPIO_OUTPUT_SET_CMD *output_set;
4300     int size;
4301
4302     size = sizeof(*output_set);
4303
4304     A_DPRINTF(DBG_WMI,
4305         (DBGFMT "Enter - set=0x%x clear=0x%x enb=0x%x dis=0x%x\n", DBGARG,
4306         set_mask, clear_mask, enable_mask, disable_mask));
4307
4308     osbuf = A_NETBUF_ALLOC(size);
4309     if (osbuf == NULL) {
4310         return A_NO_MEMORY;
4311     }
4312     A_NETBUF_PUT(osbuf, size);
4313     output_set = (WMIX_GPIO_OUTPUT_SET_CMD *)(A_NETBUF_DATA(osbuf));
4314
4315     output_set->set_mask                   = set_mask;
4316     output_set->clear_mask                 = clear_mask;
4317     output_set->enable_mask                = enable_mask;
4318     output_set->disable_mask               = disable_mask;
4319
4320     return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_OUTPUT_SET_CMDID,
4321                              NO_SYNC_WMIFLAG));
4322 }
4323
4324 /* Send a command to the Target requesting state of the GPIO input pins */
4325 A_STATUS
4326 wmi_gpio_input_get(struct wmi_t *wmip)
4327 {
4328     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
4329
4330     return wmi_simple_cmd_xtnd(wmip, WMIX_GPIO_INPUT_GET_CMDID);
4331 }
4332
4333 /* Send a command to the Target that changes the value of a GPIO register. */
4334 A_STATUS
4335 wmi_gpio_register_set(struct wmi_t *wmip,
4336                       A_UINT32 gpioreg_id,
4337                       A_UINT32 value)
4338 {
4339     void *osbuf;
4340     WMIX_GPIO_REGISTER_SET_CMD *register_set;
4341     int size;
4342
4343     size = sizeof(*register_set);
4344
4345     A_DPRINTF(DBG_WMI,
4346         (DBGFMT "Enter - reg=%d value=0x%x\n", DBGARG, gpioreg_id, value));
4347
4348     osbuf = A_NETBUF_ALLOC(size);
4349     if (osbuf == NULL) {
4350         return A_NO_MEMORY;
4351     }
4352     A_NETBUF_PUT(osbuf, size);
4353     register_set = (WMIX_GPIO_REGISTER_SET_CMD *)(A_NETBUF_DATA(osbuf));
4354
4355     register_set->gpioreg_id               = gpioreg_id;
4356     register_set->value                    = value;
4357
4358     return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_REGISTER_SET_CMDID,
4359                              NO_SYNC_WMIFLAG));
4360 }
4361
4362 /* Send a command to the Target to fetch the value of a GPIO register. */
4363 A_STATUS
4364 wmi_gpio_register_get(struct wmi_t *wmip,
4365                       A_UINT32 gpioreg_id)
4366 {
4367     void *osbuf;
4368     WMIX_GPIO_REGISTER_GET_CMD *register_get;
4369     int size;
4370
4371     size = sizeof(*register_get);
4372
4373     A_DPRINTF(DBG_WMI, (DBGFMT "Enter - reg=%d\n", DBGARG, gpioreg_id));
4374
4375     osbuf = A_NETBUF_ALLOC(size);
4376     if (osbuf == NULL) {
4377         return A_NO_MEMORY;
4378     }
4379     A_NETBUF_PUT(osbuf, size);
4380     register_get = (WMIX_GPIO_REGISTER_GET_CMD *)(A_NETBUF_DATA(osbuf));
4381
4382     register_get->gpioreg_id               = gpioreg_id;
4383
4384     return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_REGISTER_GET_CMDID,
4385                              NO_SYNC_WMIFLAG));
4386 }
4387
4388 /* Send a command to the Target acknowledging some GPIO interrupts. */
4389 A_STATUS
4390 wmi_gpio_intr_ack(struct wmi_t *wmip,
4391                   A_UINT32 ack_mask)
4392 {
4393     void *osbuf;
4394     WMIX_GPIO_INTR_ACK_CMD *intr_ack;
4395     int size;
4396
4397     size = sizeof(*intr_ack);
4398
4399     A_DPRINTF(DBG_WMI, (DBGFMT "Enter ack_mask=0x%x\n", DBGARG, ack_mask));
4400
4401     osbuf = A_NETBUF_ALLOC(size);
4402     if (osbuf == NULL) {
4403         return A_NO_MEMORY;
4404     }
4405     A_NETBUF_PUT(osbuf, size);
4406     intr_ack = (WMIX_GPIO_INTR_ACK_CMD *)(A_NETBUF_DATA(osbuf));
4407
4408     intr_ack->ack_mask               = ack_mask;
4409
4410     return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_INTR_ACK_CMDID,
4411                              NO_SYNC_WMIFLAG));
4412 }
4413 #endif /* CONFIG_HOST_GPIO_SUPPORT */
4414
4415 A_STATUS
4416 wmi_set_access_params_cmd(struct wmi_t *wmip, A_UINT8 ac,  A_UINT16 txop, A_UINT8 eCWmin,
4417                           A_UINT8 eCWmax, A_UINT8 aifsn)
4418 {
4419     void *osbuf;
4420     WMI_SET_ACCESS_PARAMS_CMD *cmd;
4421
4422     if ((eCWmin > WMI_MAX_CW_ACPARAM) || (eCWmax > WMI_MAX_CW_ACPARAM) ||
4423         (aifsn > WMI_MAX_AIFSN_ACPARAM) || (ac >= WMM_NUM_AC))
4424     {
4425         return A_EINVAL;
4426     }
4427
4428     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4429     if (osbuf == NULL) {
4430         return A_NO_MEMORY;
4431     }
4432
4433     A_NETBUF_PUT(osbuf, sizeof(*cmd));
4434
4435     cmd = (WMI_SET_ACCESS_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
4436     cmd->txop   = txop;
4437     cmd->eCWmin = eCWmin;
4438     cmd->eCWmax = eCWmax;
4439     cmd->aifsn  = aifsn;
4440     cmd->ac = ac;
4441
4442     return (wmi_cmd_send(wmip, osbuf, WMI_SET_ACCESS_PARAMS_CMDID,
4443                          NO_SYNC_WMIFLAG));
4444 }
4445
4446 A_STATUS
4447 wmi_set_retry_limits_cmd(struct wmi_t *wmip, A_UINT8 frameType,
4448                          A_UINT8 trafficClass, A_UINT8 maxRetries,
4449                          A_UINT8 enableNotify)
4450 {
4451     void *osbuf;
4452     WMI_SET_RETRY_LIMITS_CMD *cmd;
4453
4454     if ((frameType != MGMT_FRAMETYPE) && (frameType != CONTROL_FRAMETYPE) &&
4455         (frameType != DATA_FRAMETYPE))
4456     {
4457         return A_EINVAL;
4458     }
4459
4460     if (maxRetries > WMI_MAX_RETRIES) {
4461         return A_EINVAL;
4462     }
4463
4464     if (frameType != DATA_FRAMETYPE) {
4465         trafficClass = 0;
4466     }
4467
4468     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4469     if (osbuf == NULL) {
4470         return A_NO_MEMORY;
4471     }
4472
4473     A_NETBUF_PUT(osbuf, sizeof(*cmd));
4474
4475     cmd = (WMI_SET_RETRY_LIMITS_CMD *)(A_NETBUF_DATA(osbuf));
4476     cmd->frameType    = frameType;
4477     cmd->trafficClass = trafficClass;
4478     cmd->maxRetries   = maxRetries;
4479     cmd->enableNotify = enableNotify;
4480
4481     return (wmi_cmd_send(wmip, osbuf, WMI_SET_RETRY_LIMITS_CMDID,
4482                          NO_SYNC_WMIFLAG));
4483 }
4484
4485 void
4486 wmi_get_current_bssid(struct wmi_t *wmip, A_UINT8 *bssid)
4487 {
4488     if (bssid != NULL) {
4489         A_MEMCPY(bssid, wmip->wmi_bssid, ATH_MAC_LEN);
4490     }
4491 }
4492
4493 A_STATUS
4494 wmi_set_opt_mode_cmd(struct wmi_t *wmip, A_UINT8 optMode)
4495 {
4496     void *osbuf;
4497     WMI_SET_OPT_MODE_CMD *cmd;
4498
4499     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4500     if (osbuf == NULL) {
4501         return A_NO_MEMORY;
4502     }
4503
4504     A_NETBUF_PUT(osbuf, sizeof(*cmd));
4505
4506     cmd = (WMI_SET_OPT_MODE_CMD *)(A_NETBUF_DATA(osbuf));
4507     A_MEMZERO(cmd, sizeof(*cmd));
4508     cmd->optMode = optMode;
4509
4510     return (wmi_cmd_send(wmip, osbuf, WMI_SET_OPT_MODE_CMDID,
4511                          SYNC_BOTH_WMIFLAG));
4512 }
4513
4514 A_STATUS
4515 wmi_opt_tx_frame_cmd(struct wmi_t *wmip,
4516                       A_UINT8 frmType,
4517                       A_UINT8 *dstMacAddr,
4518                       A_UINT8 *bssid,
4519                       A_UINT16 optIEDataLen,
4520                       A_UINT8 *optIEData)
4521 {
4522     void *osbuf;
4523     WMI_OPT_TX_FRAME_CMD *cmd;
4524     osbuf = A_NETBUF_ALLOC(optIEDataLen + sizeof(*cmd));
4525     if (osbuf == NULL) {
4526         return A_NO_MEMORY;
4527     }
4528
4529     A_NETBUF_PUT(osbuf, (optIEDataLen + sizeof(*cmd)));
4530
4531     cmd = (WMI_OPT_TX_FRAME_CMD *)(A_NETBUF_DATA(osbuf));
4532     A_MEMZERO(cmd, (optIEDataLen + sizeof(*cmd)-1));
4533
4534     cmd->frmType    = frmType;
4535     cmd->optIEDataLen   = optIEDataLen;
4536     //cmd->optIEData     = (A_UINT8 *)((int)cmd + sizeof(*cmd));
4537     A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid));
4538     A_MEMCPY(cmd->dstAddr, dstMacAddr, sizeof(cmd->dstAddr));
4539     A_MEMCPY(&cmd->optIEData[0], optIEData, optIEDataLen);
4540
4541     return (wmi_cmd_send(wmip, osbuf, WMI_OPT_TX_FRAME_CMDID,
4542                          NO_SYNC_WMIFLAG));
4543 }
4544
4545 A_STATUS
4546 wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, A_UINT16 intvl)
4547 {
4548     void *osbuf;
4549     WMI_BEACON_INT_CMD *cmd;
4550
4551     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4552     if (osbuf == NULL) {
4553         return A_NO_MEMORY;
4554     }
4555
4556     A_NETBUF_PUT(osbuf, sizeof(*cmd));
4557
4558     cmd = (WMI_BEACON_INT_CMD *)(A_NETBUF_DATA(osbuf));
4559     A_MEMZERO(cmd, sizeof(*cmd));
4560     cmd->beaconInterval = intvl;
4561
4562     return (wmi_cmd_send(wmip, osbuf, WMI_SET_BEACON_INT_CMDID,
4563             NO_SYNC_WMIFLAG));
4564 }
4565
4566
4567 A_STATUS
4568 wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, A_UINT16 voicePktSize)
4569 {
4570     void *osbuf;
4571     WMI_SET_VOICE_PKT_SIZE_CMD *cmd;
4572
4573     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4574     if (osbuf == NULL) {
4575         return A_NO_MEMORY;
4576     }
4577
4578     A_NETBUF_PUT(osbuf, sizeof(*cmd));
4579
4580     cmd = (WMI_SET_VOICE_PKT_SIZE_CMD *)(A_NETBUF_DATA(osbuf));
4581     A_MEMZERO(cmd, sizeof(*cmd));
4582     cmd->voicePktSize = voicePktSize;
4583
4584     return (wmi_cmd_send(wmip, osbuf, WMI_SET_VOICE_PKT_SIZE_CMDID,
4585             NO_SYNC_WMIFLAG));
4586 }
4587
4588
4589 A_STATUS
4590 wmi_set_max_sp_len_cmd(struct wmi_t *wmip, A_UINT8 maxSPLen)
4591 {
4592     void *osbuf;
4593     WMI_SET_MAX_SP_LEN_CMD *cmd;
4594
4595     /* maxSPLen is a two-bit value. If user trys to set anything
4596      * other than this, then its invalid
4597      */
4598     if(maxSPLen & ~0x03)
4599         return  A_EINVAL;
4600
4601     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4602     if (osbuf == NULL) {
4603         return A_NO_MEMORY;
4604     }
4605
4606     A_NETBUF_PUT(osbuf, sizeof(*cmd));
4607
4608     cmd = (WMI_SET_MAX_SP_LEN_CMD *)(A_NETBUF_DATA(osbuf));
4609     A_MEMZERO(cmd, sizeof(*cmd));
4610     cmd->maxSPLen = maxSPLen;
4611
4612     return (wmi_cmd_send(wmip, osbuf, WMI_SET_MAX_SP_LEN_CMDID,
4613             NO_SYNC_WMIFLAG));
4614 }
4615
4616 A_UINT8
4617 wmi_determine_userPriority(
4618     A_UINT8 *pkt,
4619     A_UINT32 layer2Pri)
4620 {
4621     A_UINT8 ipPri;
4622     iphdr *ipHdr = (iphdr *)pkt;
4623
4624     /* Determine IPTOS priority */
4625     /*
4626      * IP Tos format :
4627      *      (Refer Pg 57 WMM-test-plan-v1.2)
4628      * IP-TOS - 8bits
4629      *          : DSCP(6-bits) ECN(2-bits)
4630      *          : DSCP - P2 P1 P0 X X X
4631      *              where (P2 P1 P0) form 802.1D
4632      */
4633     ipPri = ipHdr->ip_tos >> 5;
4634     ipPri &= 0x7;
4635
4636     if ((layer2Pri & 0x7) > ipPri)
4637         return ((A_UINT8)layer2Pri & 0x7);
4638     else
4639         return ipPri;
4640 }
4641
4642 A_UINT8
4643 convert_userPriority_to_trafficClass(A_UINT8 userPriority)
4644 {
4645     return  (up_to_ac[userPriority & 0x7]);
4646 }
4647
4648 A_UINT8
4649 wmi_get_power_mode_cmd(struct wmi_t *wmip)
4650 {
4651     return wmip->wmi_powerMode;
4652 }
4653
4654 A_STATUS
4655 wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, A_BOOL tspecCompliance)
4656 {
4657     A_STATUS ret = A_OK;
4658
4659 #define TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF (~0)
4660 #define TSPEC_SERVICE_START_TIME_ATHEROS_DEF  0
4661 #define TSPEC_MAX_BURST_SIZE_ATHEROS_DEF      0
4662 #define TSPEC_DELAY_BOUND_ATHEROS_DEF         0
4663 #define TSPEC_MEDIUM_TIME_ATHEROS_DEF         0
4664 #define TSPEC_SBA_ATHEROS_DEF                 0x2000  /* factor is 1 */
4665
4666     /* Verify TSPEC params for ATHEROS compliance */
4667     if(tspecCompliance == ATHEROS_COMPLIANCE) {
4668         if ((pCmd->suspensionInt != TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF) ||
4669             (pCmd->serviceStartTime != TSPEC_SERVICE_START_TIME_ATHEROS_DEF) ||
4670             (pCmd->minDataRate != pCmd->meanDataRate) ||
4671             (pCmd->minDataRate != pCmd->peakDataRate) ||
4672             (pCmd->maxBurstSize != TSPEC_MAX_BURST_SIZE_ATHEROS_DEF) ||
4673             (pCmd->delayBound != TSPEC_DELAY_BOUND_ATHEROS_DEF) ||
4674             (pCmd->sba != TSPEC_SBA_ATHEROS_DEF) ||
4675             (pCmd->mediumTime != TSPEC_MEDIUM_TIME_ATHEROS_DEF)) {
4676
4677             A_DPRINTF(DBG_WMI, (DBGFMT "Invalid TSPEC params\n", DBGARG));
4678             //A_PRINTF("%s: Invalid TSPEC params\n", __func__);
4679             ret = A_EINVAL;
4680         }
4681     }
4682
4683     return ret;
4684 }
4685
4686 #ifdef CONFIG_HOST_TCMD_SUPPORT
4687 static A_STATUS
4688 wmi_tcmd_test_report_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
4689 {
4690
4691    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
4692
4693    A_WMI_TCMD_RX_REPORT_EVENT(wmip->wmi_devt, datap, len);
4694
4695    return A_OK;
4696 }
4697
4698 #endif /* CONFIG_HOST_TCMD_SUPPORT*/
4699
4700 A_STATUS
4701 wmi_set_authmode_cmd(struct wmi_t *wmip, A_UINT8 mode)
4702 {
4703     void *osbuf;
4704     WMI_SET_AUTH_MODE_CMD *cmd;
4705
4706     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4707     if (osbuf == NULL) {
4708         return A_NO_MEMORY;
4709     }
4710
4711     A_NETBUF_PUT(osbuf, sizeof(*cmd));
4712
4713     cmd = (WMI_SET_AUTH_MODE_CMD *)(A_NETBUF_DATA(osbuf));
4714     A_MEMZERO(cmd, sizeof(*cmd));
4715     cmd->mode = mode;
4716
4717     return (wmi_cmd_send(wmip, osbuf, WMI_SET_AUTH_MODE_CMDID,
4718             NO_SYNC_WMIFLAG));
4719 }
4720
4721 A_STATUS
4722 wmi_set_reassocmode_cmd(struct wmi_t *wmip, A_UINT8 mode)
4723 {
4724     void *osbuf;
4725     WMI_SET_REASSOC_MODE_CMD *cmd;
4726
4727     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4728     if (osbuf == NULL) {
4729         return A_NO_MEMORY;
4730     }
4731
4732     A_NETBUF_PUT(osbuf, sizeof(*cmd));
4733
4734     cmd = (WMI_SET_REASSOC_MODE_CMD *)(A_NETBUF_DATA(osbuf));
4735     A_MEMZERO(cmd, sizeof(*cmd));
4736     cmd->mode = mode;
4737
4738     return (wmi_cmd_send(wmip, osbuf, WMI_SET_REASSOC_MODE_CMDID,
4739             NO_SYNC_WMIFLAG));
4740 }
4741
4742 A_STATUS
4743 wmi_set_lpreamble_cmd(struct wmi_t *wmip, A_UINT8 status, A_UINT8 preamblePolicy)
4744 {
4745     void *osbuf;
4746     WMI_SET_LPREAMBLE_CMD *cmd;
4747
4748     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4749     if (osbuf == NULL) {
4750         return A_NO_MEMORY;
4751     }
4752
4753     A_NETBUF_PUT(osbuf, sizeof(*cmd));
4754
4755     cmd = (WMI_SET_LPREAMBLE_CMD *)(A_NETBUF_DATA(osbuf));
4756     A_MEMZERO(cmd, sizeof(*cmd));
4757     cmd->status = status;
4758     cmd->preamblePolicy = preamblePolicy;
4759
4760     return (wmi_cmd_send(wmip, osbuf, WMI_SET_LPREAMBLE_CMDID,
4761             NO_SYNC_WMIFLAG));
4762 }
4763
4764 A_STATUS
4765 wmi_set_rts_cmd(struct wmi_t *wmip, A_UINT16 threshold)
4766 {
4767     void *osbuf;
4768     WMI_SET_RTS_CMD *cmd;
4769
4770     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4771     if (osbuf == NULL) {
4772         return A_NO_MEMORY;
4773     }
4774
4775     A_NETBUF_PUT(osbuf, sizeof(*cmd));
4776
4777     cmd = (WMI_SET_RTS_CMD*)(A_NETBUF_DATA(osbuf));
4778     A_MEMZERO(cmd, sizeof(*cmd));
4779     cmd->threshold = threshold;
4780
4781     return (wmi_cmd_send(wmip, osbuf, WMI_SET_RTS_CMDID,
4782             NO_SYNC_WMIFLAG));
4783 }
4784
4785 A_STATUS
4786 wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status)
4787 {
4788     void *osbuf;
4789     WMI_SET_WMM_CMD *cmd;
4790
4791     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4792     if (osbuf == NULL) {
4793         return A_NO_MEMORY;
4794     }
4795
4796     A_NETBUF_PUT(osbuf, sizeof(*cmd));
4797
4798     cmd = (WMI_SET_WMM_CMD*)(A_NETBUF_DATA(osbuf));
4799     A_MEMZERO(cmd, sizeof(*cmd));
4800     cmd->status = status;
4801
4802     return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_CMDID,
4803             NO_SYNC_WMIFLAG));
4804
4805 }
4806
4807 A_STATUS
4808 wmi_set_qos_supp_cmd(struct wmi_t *wmip, A_UINT8 status)
4809 {
4810     void *osbuf;
4811     WMI_SET_QOS_SUPP_CMD *cmd;
4812
4813     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4814     if (osbuf == NULL) {
4815         return A_NO_MEMORY;
4816     }
4817
4818     A_NETBUF_PUT(osbuf, sizeof(*cmd));
4819
4820     cmd = (WMI_SET_QOS_SUPP_CMD*)(A_NETBUF_DATA(osbuf));
4821     A_MEMZERO(cmd, sizeof(*cmd));
4822     cmd->status = status;
4823     return (wmi_cmd_send(wmip, osbuf, WMI_SET_QOS_SUPP_CMDID,
4824             NO_SYNC_WMIFLAG));
4825 }
4826
4827
4828 A_STATUS
4829 wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG cfg)
4830 {
4831     void *osbuf;
4832     WMI_SET_WMM_TXOP_CMD *cmd;
4833
4834     if( !((cfg == WMI_TXOP_DISABLED) || (cfg == WMI_TXOP_ENABLED)) )
4835         return A_EINVAL;
4836
4837     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4838     if (osbuf == NULL) {
4839         return A_NO_MEMORY;
4840     }
4841
4842     A_NETBUF_PUT(osbuf, sizeof(*cmd));
4843
4844     cmd = (WMI_SET_WMM_TXOP_CMD *)(A_NETBUF_DATA(osbuf));
4845     A_MEMZERO(cmd, sizeof(*cmd));
4846     cmd->txopEnable = cfg;
4847
4848     return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_TXOP_CMDID,
4849             NO_SYNC_WMIFLAG));
4850
4851 }
4852
4853 A_STATUS
4854 wmi_set_country(struct wmi_t *wmip, A_UCHAR *countryCode)
4855 {
4856     void *osbuf;
4857     WMI_AP_SET_COUNTRY_CMD *cmd;
4858
4859     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4860     if (osbuf == NULL) {
4861         return A_NO_MEMORY;
4862     }
4863
4864     A_NETBUF_PUT(osbuf, sizeof(*cmd));
4865
4866     cmd = (WMI_AP_SET_COUNTRY_CMD *)(A_NETBUF_DATA(osbuf));
4867     A_MEMZERO(cmd, sizeof(*cmd));
4868     A_MEMCPY(cmd->countryCode,countryCode,3);
4869
4870     return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_COUNTRY_CMDID,
4871             NO_SYNC_WMIFLAG));
4872 }
4873
4874 #ifdef CONFIG_HOST_TCMD_SUPPORT
4875 /* WMI  layer doesn't need to know the data type of the test cmd.
4876    This would be beneficial for customers like Qualcomm, who might
4877    have different test command requirements from differnt manufacturers
4878  */
4879 A_STATUS
4880 wmi_test_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT32  len)
4881 {
4882     void *osbuf;
4883     char *data;
4884
4885     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
4886
4887     osbuf= A_NETBUF_ALLOC(len);
4888     if(osbuf == NULL)
4889     {
4890         return A_NO_MEMORY;
4891     }
4892     A_NETBUF_PUT(osbuf, len);
4893     data = A_NETBUF_DATA(osbuf);
4894     A_MEMCPY(data, buf, len);
4895
4896     return(wmi_cmd_send(wmip, osbuf, WMI_TEST_CMDID,
4897          NO_SYNC_WMIFLAG));
4898 }
4899
4900 #endif
4901
4902 A_STATUS
4903 wmi_set_bt_status_cmd(struct wmi_t *wmip, A_UINT8 streamType, A_UINT8 status)
4904 {
4905     void *osbuf;
4906     WMI_SET_BT_STATUS_CMD *cmd;
4907
4908     AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Enter - streamType=%d, status=%d\n", streamType, status));
4909
4910     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4911     if (osbuf == NULL) {
4912         return A_NO_MEMORY;
4913     }
4914
4915     A_NETBUF_PUT(osbuf, sizeof(*cmd));
4916
4917     cmd = (WMI_SET_BT_STATUS_CMD *)(A_NETBUF_DATA(osbuf));
4918     A_MEMZERO(cmd, sizeof(*cmd));
4919     cmd->streamType = streamType;
4920     cmd->status = status;
4921
4922     return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_STATUS_CMDID,
4923             NO_SYNC_WMIFLAG));
4924 }
4925
4926 A_STATUS
4927 wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd)
4928 {
4929     void *osbuf;
4930     WMI_SET_BT_PARAMS_CMD* alloc_cmd;
4931
4932     AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("cmd params is %d\n", cmd->paramType));
4933
4934     if (cmd->paramType == BT_PARAM_SCO) {
4935       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,
4936         cmd->info.scoParams.dataResponseTimeout,
4937         cmd->info.scoParams.stompScoRules,
4938         cmd->info.scoParams.scoOptFlags,
4939         cmd->info.scoParams.stompDutyCyleVal,
4940         cmd->info.scoParams.stompDutyCyleMaxVal,
4941         cmd->info.scoParams.psPollLatencyFraction,
4942         cmd->info.scoParams.noSCOSlots,
4943         cmd->info.scoParams.noIdleSlots,
4944         cmd->info.scoParams.scoOptOffRssi,
4945         cmd->info.scoParams.scoOptOnRssi,
4946         cmd->info.scoParams.scoOptRtsCount));
4947     }
4948     else if (cmd->paramType == BT_PARAM_A2DP) {
4949       AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("A2DP params %d %d %d %d %d %d %d %d\n", cmd->info.a2dpParams.a2dpWlanUsageLimit,
4950         cmd->info.a2dpParams.a2dpBurstCntMin,
4951         cmd->info.a2dpParams.a2dpDataRespTimeout,
4952         cmd->info.a2dpParams.a2dpOptFlags,
4953         cmd->info.a2dpParams.isCoLocatedBtRoleMaster,
4954         cmd->info.a2dpParams.a2dpOptOffRssi,
4955         cmd->info.a2dpParams.a2dpOptOnRssi,
4956         cmd->info.a2dpParams.a2dpOptRtsCount));
4957     }
4958     else if (cmd->paramType == BT_PARAM_ANTENNA_CONFIG) {
4959       AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Ant config %d\n", cmd->info.antType));
4960     }
4961     else if (cmd->paramType == BT_PARAM_COLOCATED_BT_DEVICE) {
4962       AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("co-located BT %d\n", cmd->info.coLocatedBtDev));
4963     }
4964     else if (cmd->paramType == BT_PARAM_ACLCOEX) {
4965       AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("ACL params %d %d %d\n", cmd->info.aclCoexParams.aclWlanMediumUsageTime,
4966         cmd->info.aclCoexParams.aclBtMediumUsageTime,
4967         cmd->info.aclCoexParams.aclDataRespTimeout));
4968     }
4969     else if (cmd->paramType == BT_PARAM_11A_SEPARATE_ANT) {
4970       A_DPRINTF(DBG_WMI, (DBGFMT "11A ant\n", DBGARG));
4971     }
4972
4973     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4974     if (osbuf == NULL) {
4975         return A_NO_MEMORY;
4976     }
4977
4978     A_NETBUF_PUT(osbuf, sizeof(*cmd));
4979
4980     alloc_cmd = (WMI_SET_BT_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
4981     A_MEMZERO(alloc_cmd, sizeof(*cmd));
4982     A_MEMCPY(alloc_cmd, cmd, sizeof(*cmd));
4983
4984     return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_PARAMS_CMDID,
4985             NO_SYNC_WMIFLAG));
4986 }
4987
4988 A_STATUS
4989 wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd)
4990 {
4991         void *osbuf;
4992     WMI_SET_BTCOEX_FE_ANT_CMD *alloc_cmd;
4993
4994     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4995     if (osbuf == NULL) {
4996         return A_NO_MEMORY;
4997     }
4998     A_NETBUF_PUT(osbuf, sizeof(*cmd));
4999     alloc_cmd = (WMI_SET_BTCOEX_FE_ANT_CMD *)(A_NETBUF_DATA(osbuf));
5000     A_MEMZERO(alloc_cmd, sizeof(*cmd));
5001         A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_FE_ANT_CMD));
5002     return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_FE_ANT_CMDID,
5003                          NO_SYNC_WMIFLAG));
5004
5005 }
5006
5007
5008 A_STATUS
5009 wmi_set_btcoex_colocated_bt_dev_cmd(struct wmi_t *wmip,
5010                                                 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD * cmd)
5011 {
5012         void *osbuf;
5013     WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD *alloc_cmd;
5014
5015     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5016     if (osbuf == NULL) {
5017         return A_NO_MEMORY;
5018     }
5019     A_NETBUF_PUT(osbuf, sizeof(*cmd));
5020     alloc_cmd = (WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD *)(A_NETBUF_DATA(osbuf));
5021     A_MEMZERO(alloc_cmd, sizeof(*cmd));
5022     A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD));
5023     A_PRINTF("colocated bt = %d\n", alloc_cmd->btcoexCoLocatedBTdev);
5024     return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID,
5025                          NO_SYNC_WMIFLAG));
5026
5027 }
5028
5029 A_STATUS
5030 wmi_set_btcoex_btinquiry_page_config_cmd(struct wmi_t *wmip,
5031                                                 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD* cmd)
5032 {
5033         void *osbuf;
5034     WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *alloc_cmd;
5035
5036     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5037     if (osbuf == NULL) {
5038         return A_NO_MEMORY;
5039     }
5040     A_NETBUF_PUT(osbuf, sizeof(*cmd));
5041     alloc_cmd = (WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
5042     A_MEMZERO(alloc_cmd, sizeof(*cmd));
5043         A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD));
5044     return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID,
5045                          NO_SYNC_WMIFLAG));
5046
5047 }
5048
5049 A_STATUS
5050 wmi_set_btcoex_sco_config_cmd(struct wmi_t *wmip,
5051                                                 WMI_SET_BTCOEX_SCO_CONFIG_CMD * cmd)
5052 {
5053         void *osbuf;
5054     WMI_SET_BTCOEX_SCO_CONFIG_CMD *alloc_cmd;
5055
5056     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5057     if (osbuf == NULL) {
5058         return A_NO_MEMORY;
5059     }
5060     A_NETBUF_PUT(osbuf, sizeof(*cmd));
5061     alloc_cmd = (WMI_SET_BTCOEX_SCO_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
5062     A_MEMZERO(alloc_cmd, sizeof(*cmd));
5063         A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_SCO_CONFIG_CMD));
5064     return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_SCO_CONFIG_CMDID ,
5065                          NO_SYNC_WMIFLAG));
5066
5067 }
5068
5069 A_STATUS
5070 wmi_set_btcoex_a2dp_config_cmd(struct wmi_t *wmip,
5071                                                 WMI_SET_BTCOEX_A2DP_CONFIG_CMD * cmd)
5072 {
5073         void *osbuf;
5074     WMI_SET_BTCOEX_A2DP_CONFIG_CMD *alloc_cmd;
5075
5076     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5077     if (osbuf == NULL) {
5078         return A_NO_MEMORY;
5079     }
5080     A_NETBUF_PUT(osbuf, sizeof(*cmd));
5081     alloc_cmd = (WMI_SET_BTCOEX_A2DP_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
5082     A_MEMZERO(alloc_cmd, sizeof(*cmd));
5083         A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_A2DP_CONFIG_CMD));
5084     return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_A2DP_CONFIG_CMDID ,
5085                          NO_SYNC_WMIFLAG));
5086
5087 }
5088
5089 A_STATUS
5090 wmi_set_btcoex_aclcoex_config_cmd(struct wmi_t *wmip,
5091                                                 WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD * cmd)
5092 {
5093         void *osbuf;
5094     WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD *alloc_cmd;
5095
5096     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5097     if (osbuf == NULL) {
5098         return A_NO_MEMORY;
5099     }
5100     A_NETBUF_PUT(osbuf, sizeof(*cmd));
5101     alloc_cmd = (WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
5102     A_MEMZERO(alloc_cmd, sizeof(*cmd));
5103         A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD));
5104     return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID ,
5105                          NO_SYNC_WMIFLAG));
5106
5107 }
5108
5109 A_STATUS
5110 wmi_set_btcoex_debug_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_DEBUG_CMD * cmd)
5111 {
5112         void *osbuf;
5113         WMI_SET_BTCOEX_DEBUG_CMD *alloc_cmd;
5114
5115         osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5116         if (osbuf == NULL) {
5117                         return A_NO_MEMORY;
5118         }
5119         A_NETBUF_PUT(osbuf, sizeof(*cmd));
5120         alloc_cmd = (WMI_SET_BTCOEX_DEBUG_CMD *)(A_NETBUF_DATA(osbuf));
5121         A_MEMZERO(alloc_cmd, sizeof(*cmd));
5122         A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_DEBUG_CMD));
5123         return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_DEBUG_CMDID ,
5124                                                          NO_SYNC_WMIFLAG));
5125
5126 }
5127
5128 A_STATUS
5129 wmi_set_btcoex_bt_operating_status_cmd(struct wmi_t * wmip,
5130                                         WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD * cmd)
5131 {
5132         void *osbuf;
5133         WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *alloc_cmd;
5134
5135         osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5136         if (osbuf == NULL) {
5137                         return A_NO_MEMORY;
5138         }
5139         A_NETBUF_PUT(osbuf, sizeof(*cmd));
5140         alloc_cmd = (WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *)(A_NETBUF_DATA(osbuf));
5141         A_MEMZERO(alloc_cmd, sizeof(*cmd));
5142         A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD));
5143         return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID ,
5144                                                                  NO_SYNC_WMIFLAG));
5145
5146 }
5147
5148 A_STATUS
5149 wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * cmd)
5150 {
5151         void *osbuf;
5152         WMI_GET_BTCOEX_CONFIG_CMD *alloc_cmd;
5153
5154         osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5155         if (osbuf == NULL) {
5156                         return A_NO_MEMORY;
5157         }
5158         A_NETBUF_PUT(osbuf, sizeof(*cmd));
5159         alloc_cmd = (WMI_GET_BTCOEX_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
5160         A_MEMZERO(alloc_cmd, sizeof(*cmd));
5161         A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_GET_BTCOEX_CONFIG_CMD));
5162         return (wmi_cmd_send(wmip, osbuf, WMI_GET_BTCOEX_CONFIG_CMDID ,
5163                                                          NO_SYNC_WMIFLAG));
5164
5165 }
5166
5167 A_STATUS
5168 wmi_get_btcoex_stats_cmd(struct wmi_t *wmip)
5169 {
5170
5171     return wmi_simple_cmd(wmip, WMI_GET_BTCOEX_STATS_CMDID);
5172
5173 }
5174
5175 A_STATUS
5176 wmi_get_keepalive_configured(struct wmi_t *wmip)
5177 {
5178     void *osbuf;
5179     WMI_GET_KEEPALIVE_CMD *cmd;
5180     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5181     if (osbuf == NULL) {
5182         return A_NO_MEMORY;
5183     }
5184     A_NETBUF_PUT(osbuf, sizeof(*cmd));
5185     cmd = (WMI_GET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf));
5186     A_MEMZERO(cmd, sizeof(*cmd));
5187     return (wmi_cmd_send(wmip, osbuf, WMI_GET_KEEPALIVE_CMDID,
5188                          NO_SYNC_WMIFLAG));
5189 }
5190
5191 A_UINT8
5192 wmi_get_keepalive_cmd(struct wmi_t *wmip)
5193 {
5194     return wmip->wmi_keepaliveInterval;
5195 }
5196
5197 A_STATUS
5198 wmi_set_keepalive_cmd(struct wmi_t *wmip, A_UINT8 keepaliveInterval)
5199 {
5200     void *osbuf;
5201     WMI_SET_KEEPALIVE_CMD *cmd;
5202
5203     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5204     if (osbuf == NULL) {
5205         return A_NO_MEMORY;
5206     }
5207
5208     A_NETBUF_PUT(osbuf, sizeof(*cmd));
5209
5210     cmd = (WMI_SET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf));
5211     A_MEMZERO(cmd, sizeof(*cmd));
5212     cmd->keepaliveInterval = keepaliveInterval;
5213     wmip->wmi_keepaliveInterval = keepaliveInterval;
5214
5215     return (wmi_cmd_send(wmip, osbuf, WMI_SET_KEEPALIVE_CMDID,
5216                          NO_SYNC_WMIFLAG));
5217 }
5218
5219 A_STATUS
5220 wmi_set_params_cmd(struct wmi_t *wmip, A_UINT32 opcode, A_UINT32 length, A_CHAR* buffer)
5221 {
5222     void *osbuf;
5223     WMI_SET_PARAMS_CMD *cmd;
5224
5225     osbuf = A_NETBUF_ALLOC(sizeof(*cmd) + length);
5226     if (osbuf == NULL) {
5227         return A_NO_MEMORY;
5228     }
5229
5230     A_NETBUF_PUT(osbuf, sizeof(*cmd) + length);
5231
5232     cmd = (WMI_SET_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
5233     A_MEMZERO(cmd, sizeof(*cmd));
5234     cmd->opcode = opcode;
5235     cmd->length = length;
5236     A_MEMCPY(cmd->buffer, buffer, length);
5237
5238     return (wmi_cmd_send(wmip, osbuf, WMI_SET_PARAMS_CMDID,
5239                          NO_SYNC_WMIFLAG));
5240 }
5241
5242
5243 A_STATUS
5244 wmi_set_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8 dot3, A_UINT8 dot4)
5245 {
5246     void *osbuf;
5247     WMI_SET_MCAST_FILTER_CMD *cmd;
5248
5249     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5250     if (osbuf == NULL) {
5251         return A_NO_MEMORY;
5252     }
5253
5254     A_NETBUF_PUT(osbuf, sizeof(*cmd));
5255
5256     cmd = (WMI_SET_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
5257     cmd->multicast_mac[0] = 0x01;
5258     cmd->multicast_mac[1] = 0x00;
5259     cmd->multicast_mac[2] = 0x5e;
5260     cmd->multicast_mac[3] = dot2&0x7F;
5261     cmd->multicast_mac[4] = dot3;
5262     cmd->multicast_mac[5] = dot4;
5263
5264     return (wmi_cmd_send(wmip, osbuf, WMI_SET_MCAST_FILTER_CMDID,
5265                          NO_SYNC_WMIFLAG));
5266 }
5267
5268
5269 A_STATUS
5270 wmi_del_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8 dot3, A_UINT8 dot4)
5271 {
5272     void *osbuf;
5273     WMI_SET_MCAST_FILTER_CMD *cmd;
5274
5275     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5276     if (osbuf == NULL) {
5277         return A_NO_MEMORY;
5278     }
5279
5280     A_NETBUF_PUT(osbuf, sizeof(*cmd));
5281
5282     cmd = (WMI_SET_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
5283     cmd->multicast_mac[0] = 0x01;
5284     cmd->multicast_mac[1] = 0x00;
5285     cmd->multicast_mac[2] = 0x5e;
5286     cmd->multicast_mac[3] = dot2&0x7F;
5287     cmd->multicast_mac[4] = dot3;
5288     cmd->multicast_mac[5] = dot4;
5289
5290     return (wmi_cmd_send(wmip, osbuf, WMI_DEL_MCAST_FILTER_CMDID,
5291                          NO_SYNC_WMIFLAG));
5292 }
5293
5294 A_STATUS
5295 wmi_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 enable)
5296 {
5297     void *osbuf;
5298     WMI_MCAST_FILTER_CMD *cmd;
5299
5300     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5301     if (osbuf == NULL) {
5302         return A_NO_MEMORY;
5303     }
5304
5305     A_NETBUF_PUT(osbuf, sizeof(*cmd));
5306
5307     cmd = (WMI_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
5308     cmd->enable = enable;
5309
5310     return (wmi_cmd_send(wmip, osbuf, WMI_MCAST_FILTER_CMDID,
5311                          NO_SYNC_WMIFLAG));
5312 }
5313
5314 A_STATUS
5315 wmi_set_appie_cmd(struct wmi_t *wmip, A_UINT8 mgmtFrmType, A_UINT8 ieLen,
5316                   A_UINT8 *ieInfo)
5317 {
5318     void *osbuf;
5319     WMI_SET_APPIE_CMD *cmd;
5320     A_UINT16 cmdLen;
5321
5322     cmdLen = sizeof(*cmd) + ieLen - 1;
5323     osbuf = A_NETBUF_ALLOC(cmdLen);
5324     if (osbuf == NULL) {
5325         return A_NO_MEMORY;
5326     }
5327
5328     A_NETBUF_PUT(osbuf, cmdLen);
5329
5330     cmd = (WMI_SET_APPIE_CMD *)(A_NETBUF_DATA(osbuf));
5331     A_MEMZERO(cmd, cmdLen);
5332
5333     cmd->mgmtFrmType = mgmtFrmType;
5334     cmd->ieLen = ieLen;
5335     A_MEMCPY(cmd->ieInfo, ieInfo, ieLen);
5336
5337     return (wmi_cmd_send(wmip, osbuf, WMI_SET_APPIE_CMDID, NO_SYNC_WMIFLAG));
5338 }
5339
5340 A_STATUS
5341 wmi_set_halparam_cmd(struct wmi_t *wmip, A_UINT8 *cmd, A_UINT16 dataLen)
5342 {
5343     void *osbuf;
5344     A_UINT8 *data;
5345
5346     osbuf = A_NETBUF_ALLOC(dataLen);
5347     if (osbuf == NULL) {
5348         return A_NO_MEMORY;
5349     }
5350
5351     A_NETBUF_PUT(osbuf, dataLen);
5352
5353     data = A_NETBUF_DATA(osbuf);
5354
5355     A_MEMCPY(data, cmd, dataLen);
5356
5357     return (wmi_cmd_send(wmip, osbuf, WMI_SET_WHALPARAM_CMDID, NO_SYNC_WMIFLAG));
5358 }
5359
5360 A_INT32
5361 wmi_get_rate(A_INT8 rateindex)
5362 {
5363     if (rateindex == RATE_AUTO) {
5364         return 0;
5365     } else {
5366         return(wmi_rateTable[(A_UINT32) rateindex][0]);
5367     }
5368 }
5369
5370 void
5371 wmi_node_return (struct wmi_t *wmip, bss_t *bss)
5372 {
5373     if (NULL != bss)
5374     {
5375         wlan_node_return (&wmip->wmi_scan_table, bss);
5376     }
5377 }
5378
5379 void
5380 wmi_set_nodeage(struct wmi_t *wmip, A_UINT32 nodeAge)
5381 {
5382     wlan_set_nodeage(&wmip->wmi_scan_table,nodeAge);
5383 }
5384
5385 bss_t *
5386 wmi_find_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid,
5387                    A_UINT32 ssidLength, A_BOOL bIsWPA2, A_BOOL bMatchSSID)
5388 {
5389     bss_t *node = NULL;
5390     node = wlan_find_Ssidnode (&wmip->wmi_scan_table, pSsid,
5391                                ssidLength, bIsWPA2, bMatchSSID);
5392     return node;
5393 }
5394
5395
5396 #ifdef THREAD_X
5397 void
5398 wmi_refresh_scan_table (struct wmi_t *wmip)
5399 {
5400         wlan_refresh_inactive_nodes (&wmip->wmi_scan_table);
5401 }
5402 #endif
5403
5404 void
5405 wmi_free_allnodes(struct wmi_t *wmip)
5406 {
5407     wlan_free_allnodes(&wmip->wmi_scan_table);
5408 }
5409
5410 bss_t *
5411 wmi_find_node(struct wmi_t *wmip, const A_UINT8 *macaddr)
5412 {
5413     bss_t *ni=NULL;
5414     ni=wlan_find_node(&wmip->wmi_scan_table,macaddr);
5415     return ni;
5416 }
5417
5418 void
5419 wmi_free_node(struct wmi_t *wmip, const A_UINT8 *macaddr)
5420 {
5421     bss_t *ni=NULL;
5422
5423     ni=wlan_find_node(&wmip->wmi_scan_table,macaddr);
5424     if (ni != NULL) {
5425         wlan_node_reclaim(&wmip->wmi_scan_table, ni);
5426     }
5427
5428     return;
5429 }
5430
5431 A_STATUS
5432 wmi_dset_open_reply(struct wmi_t *wmip,
5433                     A_UINT32 status,
5434                     A_UINT32 access_cookie,
5435                     A_UINT32 dset_size,
5436                     A_UINT32 dset_version,
5437                     A_UINT32 targ_handle,
5438                     A_UINT32 targ_reply_fn,
5439                     A_UINT32 targ_reply_arg)
5440 {
5441     void *osbuf;
5442     WMIX_DSETOPEN_REPLY_CMD *open_reply;
5443
5444     A_DPRINTF(DBG_WMI, (DBGFMT "Enter - wmip=0x%lx\n", DBGARG, (unsigned long)wmip));
5445
5446     osbuf = A_NETBUF_ALLOC(sizeof(*open_reply));
5447     if (osbuf == NULL) {
5448         return A_NO_MEMORY;
5449     }
5450
5451     A_NETBUF_PUT(osbuf, sizeof(*open_reply));
5452     open_reply = (WMIX_DSETOPEN_REPLY_CMD *)(A_NETBUF_DATA(osbuf));
5453
5454     open_reply->status                   = status;
5455     open_reply->targ_dset_handle         = targ_handle;
5456     open_reply->targ_reply_fn            = targ_reply_fn;
5457     open_reply->targ_reply_arg           = targ_reply_arg;
5458     open_reply->access_cookie            = access_cookie;
5459     open_reply->size                     = dset_size;
5460     open_reply->version                  = dset_version;
5461
5462     return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETOPEN_REPLY_CMDID,
5463                              NO_SYNC_WMIFLAG));
5464 }
5465
5466 static A_STATUS
5467 wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len)
5468 {
5469     WMI_PMKID_LIST_REPLY *reply;
5470     A_UINT32 expected_len;
5471
5472     if (len < sizeof(WMI_PMKID_LIST_REPLY)) {
5473         return A_EINVAL;
5474     }
5475     reply = (WMI_PMKID_LIST_REPLY *)datap;
5476     expected_len = sizeof(reply->numPMKID) + reply->numPMKID * WMI_PMKID_LEN;
5477
5478     if (len < expected_len) {
5479         return A_EINVAL;
5480     }
5481
5482     A_WMI_PMKID_LIST_EVENT(wmip->wmi_devt, reply->numPMKID,
5483                            reply->pmkidList, reply->bssidList[0]);
5484
5485     return A_OK;
5486 }
5487
5488
5489 static A_STATUS
5490 wmi_set_params_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len)
5491 {
5492     WMI_SET_PARAMS_REPLY *reply;
5493
5494     if (len < sizeof(WMI_SET_PARAMS_REPLY)) {
5495         return A_EINVAL;
5496     }
5497     reply = (WMI_SET_PARAMS_REPLY *)datap;
5498
5499     if (A_OK == reply->status)
5500     {
5501
5502     }
5503     else
5504     {
5505
5506     }
5507
5508     return A_OK;
5509 }
5510
5511
5512
5513 static A_STATUS
5514 wmi_acm_reject_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len)
5515 {
5516     WMI_ACM_REJECT_EVENT *ev;
5517
5518     ev = (WMI_ACM_REJECT_EVENT *)datap;
5519     wmip->wmi_traffic_class = ev->trafficClass;
5520     printk("ACM REJECT %d\n",wmip->wmi_traffic_class);
5521     return A_OK;
5522 }
5523
5524
5525 #ifdef CONFIG_HOST_DSET_SUPPORT
5526 A_STATUS
5527 wmi_dset_data_reply(struct wmi_t *wmip,
5528                     A_UINT32 status,
5529                     A_UINT8 *user_buf,
5530                     A_UINT32 length,
5531                     A_UINT32 targ_buf,
5532                     A_UINT32 targ_reply_fn,
5533                     A_UINT32 targ_reply_arg)
5534 {
5535     void *osbuf;
5536     WMIX_DSETDATA_REPLY_CMD *data_reply;
5537     A_UINT32 size;
5538
5539     size = sizeof(*data_reply) + length;
5540
5541     if (size <= length) {
5542         return A_ERROR;
5543     }
5544
5545     A_DPRINTF(DBG_WMI,
5546         (DBGFMT "Enter - length=%d status=%d\n", DBGARG, length, status));
5547
5548     osbuf = A_NETBUF_ALLOC(size);
5549     if (osbuf == NULL) {
5550         return A_NO_MEMORY;
5551     }
5552     A_NETBUF_PUT(osbuf, size);
5553     data_reply = (WMIX_DSETDATA_REPLY_CMD *)(A_NETBUF_DATA(osbuf));
5554
5555     data_reply->status                     = status;
5556     data_reply->targ_buf                   = targ_buf;
5557     data_reply->targ_reply_fn              = targ_reply_fn;
5558     data_reply->targ_reply_arg             = targ_reply_arg;
5559     data_reply->length                     = length;
5560
5561     if (status == A_OK) {
5562         if (a_copy_from_user(data_reply->buf, user_buf, length)) {
5563             A_NETBUF_FREE(osbuf);
5564             return A_ERROR;
5565         }
5566     }
5567
5568     return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETDATA_REPLY_CMDID,
5569                              NO_SYNC_WMIFLAG));
5570 }
5571 #endif /* CONFIG_HOST_DSET_SUPPORT */
5572
5573 A_STATUS
5574 wmi_set_wsc_status_cmd(struct wmi_t *wmip, A_UINT32 status)
5575 {
5576     void *osbuf;
5577     char *cmd;
5578
5579     wps_enable = status;
5580
5581     osbuf = a_netbuf_alloc(sizeof(1));
5582     if (osbuf == NULL) {
5583         return A_NO_MEMORY;
5584     }
5585
5586     a_netbuf_put(osbuf, sizeof(1));
5587
5588     cmd = (char *)(a_netbuf_to_data(osbuf));
5589
5590     A_MEMZERO(cmd, sizeof(*cmd));
5591     cmd[0] = (status?1:0);
5592     return (wmi_cmd_send(wmip, osbuf, WMI_SET_WSC_STATUS_CMDID,
5593                          NO_SYNC_WMIFLAG));
5594 }
5595
5596 #if defined(CONFIG_TARGET_PROFILE_SUPPORT)
5597 A_STATUS
5598 wmi_prof_cfg_cmd(struct wmi_t *wmip,
5599                  A_UINT32 period,
5600                  A_UINT32 nbins)
5601 {
5602     void *osbuf;
5603     WMIX_PROF_CFG_CMD *cmd;
5604
5605     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5606     if (osbuf == NULL) {
5607         return A_NO_MEMORY;
5608     }
5609
5610     A_NETBUF_PUT(osbuf, sizeof(*cmd));
5611
5612     cmd = (WMIX_PROF_CFG_CMD *)(A_NETBUF_DATA(osbuf));
5613     A_MEMZERO(cmd, sizeof(*cmd));
5614     cmd->period = period;
5615     cmd->nbins  = nbins;
5616
5617     return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_PROF_CFG_CMDID, NO_SYNC_WMIFLAG));
5618 }
5619
5620 A_STATUS
5621 wmi_prof_addr_set_cmd(struct wmi_t *wmip, A_UINT32 addr)
5622 {
5623     void *osbuf;
5624     WMIX_PROF_ADDR_SET_CMD *cmd;
5625
5626     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5627     if (osbuf == NULL) {
5628         return A_NO_MEMORY;
5629     }
5630
5631     A_NETBUF_PUT(osbuf, sizeof(*cmd));
5632
5633     cmd = (WMIX_PROF_ADDR_SET_CMD *)(A_NETBUF_DATA(osbuf));
5634     A_MEMZERO(cmd, sizeof(*cmd));
5635     cmd->addr = addr;
5636
5637     return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_PROF_ADDR_SET_CMDID, NO_SYNC_WMIFLAG));
5638 }
5639
5640 A_STATUS
5641 wmi_prof_start_cmd(struct wmi_t *wmip)
5642 {
5643     return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_START_CMDID);
5644 }
5645
5646 A_STATUS
5647 wmi_prof_stop_cmd(struct wmi_t *wmip)
5648 {
5649     return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_STOP_CMDID);
5650 }
5651
5652 A_STATUS
5653 wmi_prof_count_get_cmd(struct wmi_t *wmip)
5654 {
5655     return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_COUNT_GET_CMDID);
5656 }
5657
5658 /* Called to handle WMIX_PROF_CONT_EVENTID */
5659 static A_STATUS
5660 wmi_prof_count_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
5661 {
5662     WMIX_PROF_COUNT_EVENT *prof_data = (WMIX_PROF_COUNT_EVENT *)datap;
5663
5664     A_DPRINTF(DBG_WMI,
5665         (DBGFMT "Enter - addr=0x%x count=%d\n", DBGARG,
5666         prof_data->addr, prof_data->count));
5667
5668     A_WMI_PROF_COUNT_RX(prof_data->addr, prof_data->count);
5669
5670     return A_OK;
5671 }
5672 #endif /* CONFIG_TARGET_PROFILE_SUPPORT */
5673
5674 #ifdef OS_ROAM_MANAGEMENT
5675
5676 #define ETHERNET_MAC_ADDRESS_LENGTH    6
5677
5678 void
5679 wmi_scan_indication (struct wmi_t *wmip)
5680 {
5681     struct ieee80211_node_table *nt;
5682     A_UINT32 gen;
5683     A_UINT32 size;
5684     A_UINT32 bsssize;
5685     bss_t *bss;
5686     A_UINT32 numbss;
5687     PNDIS_802_11_BSSID_SCAN_INFO psi;
5688     PBYTE  pie;
5689     NDIS_802_11_FIXED_IEs *pFixed;
5690     NDIS_802_11_VARIABLE_IEs *pVar;
5691     A_UINT32  RateSize;
5692
5693     struct ar6kScanIndication
5694     {
5695         NDIS_802_11_STATUS_INDICATION     ind;
5696         NDIS_802_11_BSSID_SCAN_INFO_LIST  slist;
5697     } *pAr6kScanIndEvent;
5698
5699     nt = &wmip->wmi_scan_table;
5700
5701     ++nt->nt_si_gen;
5702
5703
5704     gen = nt->nt_si_gen;
5705
5706     size = offsetof(struct ar6kScanIndication, slist) +
5707            offsetof(NDIS_802_11_BSSID_SCAN_INFO_LIST, BssidScanInfo);
5708
5709     numbss = 0;
5710
5711     IEEE80211_NODE_LOCK(nt);
5712
5713     //calc size
5714     for (bss = nt->nt_node_first; bss; bss = bss->ni_list_next) {
5715         if (bss->ni_si_gen != gen) {
5716             bsssize = offsetof(NDIS_802_11_BSSID_SCAN_INFO, Bssid) + offsetof(NDIS_WLAN_BSSID_EX, IEs);
5717             bsssize = bsssize + sizeof(NDIS_802_11_FIXED_IEs);
5718
5719 #ifdef SUPPORT_WPA2
5720             if (bss->ni_cie.ie_rsn) {
5721                 bsssize = bsssize + bss->ni_cie.ie_rsn[1] + 2;
5722             }
5723 #endif
5724             if (bss->ni_cie.ie_wpa) {
5725                 bsssize = bsssize + bss->ni_cie.ie_wpa[1] + 2;
5726             }
5727
5728             // bsssize must be a multiple of 4 to maintain alignment.
5729             bsssize = (bsssize + 3) & ~3;
5730
5731             size += bsssize;
5732
5733             numbss++;
5734         }
5735     }
5736
5737     if (0 == numbss)
5738     {
5739 //        RETAILMSG(1, (L"AR6K: scan indication: 0 bss\n"));
5740         ar6000_scan_indication (wmip->wmi_devt, NULL, 0);
5741         IEEE80211_NODE_UNLOCK (nt);
5742         return;
5743     }
5744
5745     pAr6kScanIndEvent = A_MALLOC(size);
5746
5747     if (NULL == pAr6kScanIndEvent)
5748     {
5749         IEEE80211_NODE_UNLOCK(nt);
5750         return;
5751     }
5752
5753     A_MEMZERO(pAr6kScanIndEvent, size);
5754
5755     //copy data
5756     pAr6kScanIndEvent->ind.StatusType = Ndis802_11StatusType_BssidScanInfoList;
5757     pAr6kScanIndEvent->slist.Version = 1;
5758     pAr6kScanIndEvent->slist.NumItems = numbss;
5759
5760     psi = &pAr6kScanIndEvent->slist.BssidScanInfo[0];
5761
5762     for (bss = nt->nt_node_first; bss; bss = bss->ni_list_next) {
5763         if (bss->ni_si_gen != gen) {
5764
5765             bss->ni_si_gen = gen;
5766
5767             //Set scan time
5768             psi->ScanTime = bss->ni_tstamp - WLAN_NODE_INACT_TIMEOUT_MSEC;
5769
5770             // Copy data to bssid_ex
5771             bsssize = offsetof(NDIS_WLAN_BSSID_EX, IEs);
5772             bsssize = bsssize + sizeof(NDIS_802_11_FIXED_IEs);
5773
5774 #ifdef SUPPORT_WPA2
5775             if (bss->ni_cie.ie_rsn) {
5776                 bsssize = bsssize + bss->ni_cie.ie_rsn[1] + 2;
5777             }
5778 #endif
5779             if (bss->ni_cie.ie_wpa) {
5780                 bsssize = bsssize + bss->ni_cie.ie_wpa[1] + 2;
5781             }
5782
5783             // bsssize must be a multiple of 4 to maintain alignment.
5784             bsssize = (bsssize + 3) & ~3;
5785
5786             psi->Bssid.Length = bsssize;
5787
5788             memcpy (psi->Bssid.MacAddress, bss->ni_macaddr, ETHERNET_MAC_ADDRESS_LENGTH);
5789
5790
5791 //if (((bss->ni_macaddr[3] == 0xCE) && (bss->ni_macaddr[4] == 0xF0) && (bss->ni_macaddr[5] == 0xE7)) ||
5792 //  ((bss->ni_macaddr[3] == 0x03) && (bss->ni_macaddr[4] == 0xE2) && (bss->ni_macaddr[5] == 0x70)))
5793 //            RETAILMSG (1, (L"%x\n",bss->ni_macaddr[5]));
5794
5795             psi->Bssid.Ssid.SsidLength = 0;
5796             pie = bss->ni_cie.ie_ssid;
5797
5798             if (pie) {
5799                 // Format of SSID IE is:
5800                 //  Type   (1 octet)
5801                 //  Length (1 octet)
5802                 //  SSID (Length octets)
5803                 //
5804                 //  Validation of the IE should have occurred within WMI.
5805                 //
5806                 if (pie[1] <= 32) {
5807                     psi->Bssid.Ssid.SsidLength = pie[1];
5808                     memcpy(psi->Bssid.Ssid.Ssid, &pie[2], psi->Bssid.Ssid.SsidLength);
5809                 }
5810             }
5811             psi->Bssid.Privacy = (bss->ni_cie.ie_capInfo & 0x10) ? 1 : 0;
5812
5813             //Post the RSSI value relative to the Standard Noise floor value.
5814             psi->Bssid.Rssi = bss->ni_rssi;
5815
5816             if (bss->ni_cie.ie_chan >= 2412 && bss->ni_cie.ie_chan <= 2484) {
5817
5818                 if (bss->ni_cie.ie_rates && bss->ni_cie.ie_xrates) {
5819                     psi->Bssid.NetworkTypeInUse = Ndis802_11OFDM24;
5820                 }
5821                 else {
5822                     psi->Bssid.NetworkTypeInUse = Ndis802_11DS;
5823                 }
5824             }
5825             else {
5826                 psi->Bssid.NetworkTypeInUse = Ndis802_11OFDM5;
5827             }
5828
5829             psi->Bssid.Configuration.Length = sizeof(psi->Bssid.Configuration);
5830             psi->Bssid.Configuration.BeaconPeriod = bss->ni_cie.ie_beaconInt; // Units are Kmicroseconds (1024 us)
5831             psi->Bssid.Configuration.ATIMWindow =  0;
5832             psi->Bssid.Configuration.DSConfig =  bss->ni_cie.ie_chan * 1000;
5833             psi->Bssid.InfrastructureMode = ((bss->ni_cie.ie_capInfo & 0x03) == 0x01 ) ? Ndis802_11Infrastructure : Ndis802_11IBSS;
5834
5835             RateSize = 0;
5836             pie = bss->ni_cie.ie_rates;
5837             if (pie) {
5838                 RateSize = (pie[1] < NDIS_802_11_LENGTH_RATES_EX) ? pie[1] : NDIS_802_11_LENGTH_RATES_EX;
5839                 memcpy(psi->Bssid.SupportedRates, &pie[2], RateSize);
5840             }
5841             pie = bss->ni_cie.ie_xrates;
5842             if (pie && RateSize < NDIS_802_11_LENGTH_RATES_EX) {
5843                 memcpy(psi->Bssid.SupportedRates + RateSize, &pie[2],
5844                        (pie[1] < (NDIS_802_11_LENGTH_RATES_EX - RateSize)) ? pie[1] : (NDIS_802_11_LENGTH_RATES_EX - RateSize));
5845             }
5846
5847             // Copy the fixed IEs
5848             psi->Bssid.IELength = sizeof(NDIS_802_11_FIXED_IEs);
5849
5850             pFixed = (NDIS_802_11_FIXED_IEs *)psi->Bssid.IEs;
5851             memcpy(pFixed->Timestamp, bss->ni_cie.ie_tstamp, sizeof(pFixed->Timestamp));
5852             pFixed->BeaconInterval = bss->ni_cie.ie_beaconInt;
5853             pFixed->Capabilities = bss->ni_cie.ie_capInfo;
5854
5855             // Copy selected variable IEs
5856
5857             pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pFixed + sizeof(NDIS_802_11_FIXED_IEs));
5858
5859 #ifdef SUPPORT_WPA2
5860             // Copy the WPAv2 IE
5861             if (bss->ni_cie.ie_rsn) {
5862                 pie = bss->ni_cie.ie_rsn;
5863                 psi->Bssid.IELength += pie[1] + 2;
5864                 memcpy(pVar, pie, pie[1] + 2);
5865                 pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pVar + pie[1] + 2);
5866             }
5867 #endif
5868             // Copy the WPAv1 IE
5869             if (bss->ni_cie.ie_wpa) {
5870                 pie = bss->ni_cie.ie_wpa;
5871                 psi->Bssid.IELength += pie[1] + 2;
5872                 memcpy(pVar, pie, pie[1] + 2);
5873                 pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pVar + pie[1] + 2);
5874             }
5875
5876             // Advance buffer pointer
5877             psi = (PNDIS_802_11_BSSID_SCAN_INFO)((BYTE*)psi + bsssize + FIELD_OFFSET(NDIS_802_11_BSSID_SCAN_INFO, Bssid));
5878         }
5879     }
5880
5881     IEEE80211_NODE_UNLOCK(nt);
5882
5883 //    wmi_free_allnodes(wmip);
5884
5885 //    RETAILMSG(1, (L"AR6K: scan indication: %u bss\n", numbss));
5886
5887     ar6000_scan_indication (wmip->wmi_devt, pAr6kScanIndEvent, size);
5888
5889     A_FREE(pAr6kScanIndEvent);
5890 }
5891 #endif
5892
5893 A_UINT8
5894 ar6000_get_upper_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh,
5895                            A_UINT32 size)
5896 {
5897     A_UINT32 index;
5898     A_UINT8 threshold = (A_UINT8)sq_thresh->upper_threshold[size - 1];
5899
5900     /* The list is already in sorted order. Get the next lower value */
5901     for (index = 0; index < size; index ++) {
5902         if (rssi < sq_thresh->upper_threshold[index]) {
5903             threshold = (A_UINT8)sq_thresh->upper_threshold[index];
5904             break;
5905         }
5906     }
5907
5908     return threshold;
5909 }
5910
5911 A_UINT8
5912 ar6000_get_lower_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh,
5913                            A_UINT32 size)
5914 {
5915     A_UINT32 index;
5916     A_UINT8 threshold = (A_UINT8)sq_thresh->lower_threshold[size - 1];
5917
5918     /* The list is already in sorted order. Get the next lower value */
5919     for (index = 0; index < size; index ++) {
5920         if (rssi > sq_thresh->lower_threshold[index]) {
5921             threshold = (A_UINT8)sq_thresh->lower_threshold[index];
5922             break;
5923         }
5924     }
5925
5926     return threshold;
5927 }
5928 static A_STATUS
5929 wmi_send_rssi_threshold_params(struct wmi_t *wmip,
5930                               WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
5931 {
5932     void    *osbuf;
5933     A_INT8  size;
5934     WMI_RSSI_THRESHOLD_PARAMS_CMD *cmd;
5935
5936     size = sizeof (*cmd);
5937
5938     osbuf = A_NETBUF_ALLOC(size);
5939     if (osbuf == NULL) {
5940         return A_NO_MEMORY;
5941     }
5942
5943     A_NETBUF_PUT(osbuf, size);
5944
5945     cmd = (WMI_RSSI_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
5946     A_MEMZERO(cmd, size);
5947     A_MEMCPY(cmd, rssiCmd, sizeof(WMI_RSSI_THRESHOLD_PARAMS_CMD));
5948
5949     return (wmi_cmd_send(wmip, osbuf, WMI_RSSI_THRESHOLD_PARAMS_CMDID,
5950                             NO_SYNC_WMIFLAG));
5951 }
5952 static A_STATUS
5953 wmi_send_snr_threshold_params(struct wmi_t *wmip,
5954                              WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
5955 {
5956     void    *osbuf;
5957     A_INT8  size;
5958     WMI_SNR_THRESHOLD_PARAMS_CMD *cmd;
5959
5960     size = sizeof (*cmd);
5961
5962     osbuf = A_NETBUF_ALLOC(size);
5963     if (osbuf == NULL) {
5964         return A_NO_MEMORY;
5965     }
5966
5967     A_NETBUF_PUT(osbuf, size);
5968     cmd = (WMI_SNR_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
5969     A_MEMZERO(cmd, size);
5970     A_MEMCPY(cmd, snrCmd, sizeof(WMI_SNR_THRESHOLD_PARAMS_CMD));
5971
5972     return (wmi_cmd_send(wmip, osbuf, WMI_SNR_THRESHOLD_PARAMS_CMDID,
5973                             NO_SYNC_WMIFLAG));
5974 }
5975
5976 A_STATUS
5977 wmi_set_target_event_report_cmd(struct wmi_t *wmip, WMI_SET_TARGET_EVENT_REPORT_CMD* cmd)
5978 {
5979     void *osbuf;
5980     WMI_SET_TARGET_EVENT_REPORT_CMD* alloc_cmd;
5981
5982     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5983     if (osbuf == NULL) {
5984         return A_NO_MEMORY;
5985     }
5986
5987     A_NETBUF_PUT(osbuf, sizeof(*cmd));
5988
5989     alloc_cmd = (WMI_SET_TARGET_EVENT_REPORT_CMD *)(A_NETBUF_DATA(osbuf));
5990     A_MEMZERO(alloc_cmd, sizeof(*cmd));
5991     A_MEMCPY(alloc_cmd, cmd, sizeof(*cmd));
5992
5993     return (wmi_cmd_send(wmip, osbuf, WMI_SET_TARGET_EVENT_REPORT_CMDID,
5994             NO_SYNC_WMIFLAG));
5995 }
5996
5997 bss_t *wmi_rm_current_bss (struct wmi_t *wmip, A_UINT8 *id)
5998 {
5999     wmi_get_current_bssid (wmip, id);
6000     return wlan_node_remove (&wmip->wmi_scan_table, id);
6001 }
6002
6003 A_STATUS wmi_add_current_bss (struct wmi_t *wmip, A_UINT8 *id, bss_t *bss)
6004 {
6005     wlan_setup_node (&wmip->wmi_scan_table, bss, id);
6006     return A_OK;
6007 }
6008
6009 #ifdef ATH_AR6K_11N_SUPPORT
6010 static A_STATUS
6011 wmi_addba_req_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
6012 {
6013     WMI_ADDBA_REQ_EVENT *cmd = (WMI_ADDBA_REQ_EVENT *)datap;
6014
6015     A_WMI_AGGR_RECV_ADDBA_REQ_EVT(wmip->wmi_devt, cmd);
6016
6017     return A_OK;
6018 }
6019
6020
6021 static A_STATUS
6022 wmi_addba_resp_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
6023 {
6024     WMI_ADDBA_RESP_EVENT *cmd = (WMI_ADDBA_RESP_EVENT *)datap;
6025
6026     A_WMI_AGGR_RECV_ADDBA_RESP_EVT(wmip->wmi_devt, cmd);
6027
6028     return A_OK;
6029 }
6030
6031 static A_STATUS
6032 wmi_delba_req_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
6033 {
6034     WMI_DELBA_EVENT *cmd = (WMI_DELBA_EVENT *)datap;
6035
6036     A_WMI_AGGR_RECV_DELBA_REQ_EVT(wmip->wmi_devt, cmd);
6037
6038     return A_OK;
6039 }
6040
6041 A_STATUS
6042 wmi_btcoex_config_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
6043 {
6044         A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
6045
6046     A_WMI_BTCOEX_CONFIG_EVENT(wmip->wmi_devt, datap, len);
6047
6048      return A_OK;
6049 }
6050
6051
6052 A_STATUS
6053 wmi_btcoex_stats_event_rx(struct wmi_t * wmip,A_UINT8 * datap,int len)
6054 {
6055         A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
6056
6057     A_WMI_BTCOEX_STATS_EVENT(wmip->wmi_devt, datap, len);
6058
6059      return A_OK;
6060
6061 }
6062 #endif
6063
6064 static A_STATUS
6065 wmi_hci_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
6066 {
6067     WMI_HCI_EVENT *cmd = (WMI_HCI_EVENT *)datap;
6068     A_WMI_HCI_EVENT_EVT(wmip->wmi_devt, cmd);
6069
6070     return A_OK;
6071 }
6072
6073 ////////////////////////////////////////////////////////////////////////////////
6074 ////                                                                        ////
6075 ////                AP mode functions                                       ////
6076 ////                                                                        ////
6077 ////////////////////////////////////////////////////////////////////////////////
6078 /*
6079  * IOCTL: AR6000_XIOCTL_AP_COMMIT_CONFIG
6080  *
6081  * When AR6K in AP mode, This command will be called after
6082  * changing ssid, channel etc. It will pass the profile to
6083  * target with a flag which will indicate which parameter changed,
6084  * also if this flag is 0, there was no change in parametes, so
6085  * commit cmd will not be sent to target. Without calling this IOCTL
6086  * the changes will not take effect.
6087  */
6088 A_STATUS
6089 wmi_ap_profile_commit(struct wmi_t *wmip, WMI_CONNECT_CMD *p)
6090 {
6091     void *osbuf;
6092     WMI_CONNECT_CMD *cm;
6093
6094     osbuf = A_NETBUF_ALLOC(sizeof(*cm));
6095     if (osbuf == NULL) {
6096         return A_NO_MEMORY;
6097     }
6098
6099     A_NETBUF_PUT(osbuf, sizeof(*cm));
6100     cm = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf));
6101     A_MEMZERO(cm, sizeof(*cm));
6102
6103     A_MEMCPY(cm,p,sizeof(*cm));
6104
6105     return (wmi_cmd_send(wmip, osbuf, WMI_AP_CONFIG_COMMIT_CMDID, NO_SYNC_WMIFLAG));
6106 }
6107
6108 /*
6109  * IOCTL: AR6000_XIOCTL_AP_HIDDEN_SSID
6110  *
6111  * This command will be used to enable/disable hidden ssid functioanlity of
6112  * beacon. If it is enabled, ssid will be NULL in beacon.
6113  */
6114 A_STATUS
6115 wmi_ap_set_hidden_ssid(struct wmi_t *wmip, A_UINT8 hidden_ssid)
6116 {
6117     void *osbuf;
6118     WMI_AP_HIDDEN_SSID_CMD *hs;
6119
6120     osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_HIDDEN_SSID_CMD));
6121     if (osbuf == NULL) {
6122         return A_NO_MEMORY;
6123     }
6124
6125     A_NETBUF_PUT(osbuf, sizeof(WMI_AP_HIDDEN_SSID_CMD));
6126     hs = (WMI_AP_HIDDEN_SSID_CMD *)(A_NETBUF_DATA(osbuf));
6127     A_MEMZERO(hs, sizeof(*hs));
6128
6129     hs->hidden_ssid          = hidden_ssid;
6130
6131     A_DPRINTF(DBG_WMI, (DBGFMT "AR6000_XIOCTL_AP_HIDDEN_SSID %d\n", DBGARG , hidden_ssid));
6132     return (wmi_cmd_send(wmip, osbuf, WMI_AP_HIDDEN_SSID_CMDID, NO_SYNC_WMIFLAG));
6133 }
6134
6135 /*
6136  * IOCTL: AR6000_XIOCTL_AP_SET_MAX_NUM_STA
6137  *
6138  * This command is used to limit max num of STA that can connect
6139  * with this AP. This value should not exceed AP_MAX_NUM_STA (this
6140  * is max num of STA supported by AP). Value was already validated
6141  * in ioctl.c
6142  */
6143 A_STATUS
6144 wmi_ap_set_num_sta(struct wmi_t *wmip, A_UINT8 num_sta)
6145 {
6146     void *osbuf;
6147     WMI_AP_SET_NUM_STA_CMD *ns;
6148
6149     osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_NUM_STA_CMD));
6150     if (osbuf == NULL) {
6151         return A_NO_MEMORY;
6152     }
6153
6154     A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_NUM_STA_CMD));
6155     ns = (WMI_AP_SET_NUM_STA_CMD *)(A_NETBUF_DATA(osbuf));
6156     A_MEMZERO(ns, sizeof(*ns));
6157
6158     ns->num_sta          = num_sta;
6159
6160     A_DPRINTF(DBG_WMI, (DBGFMT "AR6000_XIOCTL_AP_SET_MAX_NUM_STA %d\n", DBGARG , num_sta));
6161     return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_NUM_STA_CMDID, NO_SYNC_WMIFLAG));
6162 }
6163
6164 /*
6165  * IOCTL: AR6000_XIOCTL_AP_SET_ACL_MAC
6166  *
6167  * This command is used to send list of mac of STAs which will
6168  * be allowed to connect with this AP. When this list is empty
6169  * firware will allow all STAs till the count reaches AP_MAX_NUM_STA.
6170  */
6171 A_STATUS
6172 wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *acl)
6173 {
6174     void *osbuf;
6175     WMI_AP_ACL_MAC_CMD *a;
6176
6177     osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_ACL_MAC_CMD));
6178     if (osbuf == NULL) {
6179         return A_NO_MEMORY;
6180     }
6181
6182     A_NETBUF_PUT(osbuf, sizeof(WMI_AP_ACL_MAC_CMD));
6183     a = (WMI_AP_ACL_MAC_CMD *)(A_NETBUF_DATA(osbuf));
6184     A_MEMZERO(a, sizeof(*a));
6185     A_MEMCPY(a,acl,sizeof(*acl));
6186
6187     return (wmi_cmd_send(wmip, osbuf, WMI_AP_ACL_MAC_LIST_CMDID, NO_SYNC_WMIFLAG));
6188 }
6189
6190 /*
6191  * IOCTL: AR6000_XIOCTL_AP_SET_MLME
6192  *
6193  * This command is used to send list of mac of STAs which will
6194  * be allowed to connect with this AP. When this list is empty
6195  * firware will allow all STAs till the count reaches AP_MAX_NUM_STA.
6196  */
6197 A_STATUS
6198 wmi_ap_set_mlme(struct wmi_t *wmip, A_UINT8 cmd, A_UINT8 *mac, A_UINT16 reason)
6199 {
6200     void *osbuf;
6201     WMI_AP_SET_MLME_CMD *mlme;
6202
6203     osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_MLME_CMD));
6204     if (osbuf == NULL) {
6205         return A_NO_MEMORY;
6206     }
6207
6208     A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_MLME_CMD));
6209     mlme = (WMI_AP_SET_MLME_CMD *)(A_NETBUF_DATA(osbuf));
6210     A_MEMZERO(mlme, sizeof(*mlme));
6211
6212     mlme->cmd = cmd;
6213     A_MEMCPY(mlme->mac, mac, ATH_MAC_LEN);
6214     mlme->reason = reason;
6215
6216     return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_MLME_CMDID, NO_SYNC_WMIFLAG));
6217 }
6218
6219 static A_STATUS
6220 wmi_pspoll_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
6221 {
6222     WMI_PSPOLL_EVENT *ev;
6223
6224     if (len < sizeof(WMI_PSPOLL_EVENT)) {
6225         return A_EINVAL;
6226     }
6227     ev = (WMI_PSPOLL_EVENT *)datap;
6228
6229     A_WMI_PSPOLL_EVENT(wmip->wmi_devt, ev->aid);
6230     return A_OK;
6231 }
6232
6233 static A_STATUS
6234 wmi_dtimexpiry_event_rx(struct wmi_t *wmip, A_UINT8 *datap,int len)
6235 {
6236     A_WMI_DTIMEXPIRY_EVENT(wmip->wmi_devt);
6237     return A_OK;
6238 }
6239
6240 #ifdef WAPI_ENABLE
6241 static A_STATUS
6242 wmi_wapi_rekey_event_rx(struct wmi_t *wmip, A_UINT8 *datap,int len)
6243 {
6244     A_UINT8 *ev;
6245
6246     if (len < 7) {
6247         return A_EINVAL;
6248     }
6249     ev = (A_UINT8 *)datap;
6250
6251     A_WMI_WAPI_REKEY_EVENT(wmip->wmi_devt, *ev, &ev[1]);
6252     return A_OK;
6253 }
6254 #endif
6255
6256 A_STATUS
6257 wmi_set_pvb_cmd(struct wmi_t *wmip, A_UINT16 aid, A_BOOL flag)
6258 {
6259     WMI_AP_SET_PVB_CMD *cmd;
6260     void *osbuf = NULL;
6261
6262     osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_PVB_CMD));
6263     if (osbuf == NULL) {
6264         return A_NO_MEMORY;
6265     }
6266
6267     A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_PVB_CMD));
6268     cmd = (WMI_AP_SET_PVB_CMD *)(A_NETBUF_DATA(osbuf));
6269     A_MEMZERO(cmd, sizeof(*cmd));
6270
6271     cmd->aid = aid;
6272     cmd->flag = flag;
6273
6274     return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_PVB_CMDID, NO_SYNC_WMIFLAG));
6275 }
6276
6277 A_STATUS
6278 wmi_ap_conn_inact_time(struct wmi_t *wmip, A_UINT32 period)
6279 {
6280     WMI_AP_CONN_INACT_CMD *cmd;
6281     void *osbuf = NULL;
6282
6283     osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_CONN_INACT_CMD));
6284     if (osbuf == NULL) {
6285         return A_NO_MEMORY;
6286     }
6287
6288     A_NETBUF_PUT(osbuf, sizeof(WMI_AP_CONN_INACT_CMD));
6289     cmd = (WMI_AP_CONN_INACT_CMD *)(A_NETBUF_DATA(osbuf));
6290     A_MEMZERO(cmd, sizeof(*cmd));
6291
6292     cmd->period = period;
6293
6294     return (wmi_cmd_send(wmip, osbuf, WMI_AP_CONN_INACT_CMDID, NO_SYNC_WMIFLAG));
6295 }
6296
6297 A_STATUS
6298 wmi_ap_bgscan_time(struct wmi_t *wmip, A_UINT32 period, A_UINT32 dwell)
6299 {
6300     WMI_AP_PROT_SCAN_TIME_CMD *cmd;
6301     void *osbuf = NULL;
6302
6303     osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_PROT_SCAN_TIME_CMD));
6304     if (osbuf == NULL) {
6305         return A_NO_MEMORY;
6306     }
6307
6308     A_NETBUF_PUT(osbuf, sizeof(WMI_AP_PROT_SCAN_TIME_CMD));
6309     cmd = (WMI_AP_PROT_SCAN_TIME_CMD *)(A_NETBUF_DATA(osbuf));
6310     A_MEMZERO(cmd, sizeof(*cmd));
6311
6312     cmd->period_min = period;
6313     cmd->dwell_ms   = dwell;
6314
6315     return (wmi_cmd_send(wmip, osbuf, WMI_AP_PROT_SCAN_TIME_CMDID, NO_SYNC_WMIFLAG));
6316 }
6317
6318 A_STATUS
6319 wmi_ap_set_dtim(struct wmi_t *wmip, A_UINT8 dtim)
6320 {
6321     WMI_AP_SET_DTIM_CMD *cmd;
6322     void *osbuf = NULL;
6323
6324     osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_DTIM_CMD));
6325     if (osbuf == NULL) {
6326         return A_NO_MEMORY;
6327     }
6328
6329     A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_DTIM_CMD));
6330     cmd = (WMI_AP_SET_DTIM_CMD *)(A_NETBUF_DATA(osbuf));
6331     A_MEMZERO(cmd, sizeof(*cmd));
6332
6333     cmd->dtim = dtim;
6334
6335     return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_DTIM_CMDID, NO_SYNC_WMIFLAG));
6336 }
6337
6338 /*
6339  * IOCTL: AR6000_XIOCTL_AP_SET_ACL_POLICY
6340  *
6341  * This command is used to set ACL policay. While changing policy, if you
6342  * want to retain the existing MAC addresses in the ACL list, policy should be
6343  * OR with AP_ACL_RETAIN_LIST_MASK, else the existing list will be cleared.
6344  * If there is no chage in policy, the list will be intact.
6345  */
6346 A_STATUS
6347 wmi_ap_set_acl_policy(struct wmi_t *wmip, A_UINT8 policy)
6348 {
6349     void *osbuf;
6350     WMI_AP_ACL_POLICY_CMD *po;
6351
6352     osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_ACL_POLICY_CMD));
6353     if (osbuf == NULL) {
6354         return A_NO_MEMORY;
6355 }
6356
6357     A_NETBUF_PUT(osbuf, sizeof(WMI_AP_ACL_POLICY_CMD));
6358     po = (WMI_AP_ACL_POLICY_CMD *)(A_NETBUF_DATA(osbuf));
6359     A_MEMZERO(po, sizeof(*po));
6360
6361     po->policy = policy;
6362
6363     return (wmi_cmd_send(wmip, osbuf, WMI_AP_ACL_POLICY_CMDID, NO_SYNC_WMIFLAG));
6364 }
6365
6366 A_STATUS
6367 wmi_ap_set_rateset(struct wmi_t *wmip, A_UINT8 rateset)
6368 {
6369     void *osbuf;
6370     WMI_AP_SET_11BG_RATESET_CMD *rs;
6371
6372     osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_11BG_RATESET_CMD));
6373     if (osbuf == NULL) {
6374         return A_NO_MEMORY;
6375     }
6376
6377     A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_11BG_RATESET_CMD));
6378     rs = (WMI_AP_SET_11BG_RATESET_CMD *)(A_NETBUF_DATA(osbuf));
6379     A_MEMZERO(rs, sizeof(*rs));
6380
6381     rs->rateset = rateset;
6382
6383     return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_11BG_RATESET_CMDID, NO_SYNC_WMIFLAG));
6384 }
6385
6386 #ifdef ATH_AR6K_11N_SUPPORT
6387 A_STATUS
6388 wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd)
6389 {
6390     void *osbuf;
6391     WMI_SET_HT_CAP_CMD *htCap;
6392     A_UINT8 band;
6393
6394     osbuf = A_NETBUF_ALLOC(sizeof(*htCap));
6395     if (osbuf == NULL) {
6396         return A_NO_MEMORY;
6397     }
6398
6399     A_NETBUF_PUT(osbuf, sizeof(*htCap));
6400
6401     band = (cmd->band)? A_BAND_5GHZ : A_BAND_24GHZ;
6402     wmip->wmi_ht_allowed[band] = (cmd->enable)? 1:0;
6403
6404     htCap = (WMI_SET_HT_CAP_CMD *)(A_NETBUF_DATA(osbuf));
6405     A_MEMZERO(htCap, sizeof(*htCap));
6406     A_MEMCPY(htCap, cmd, sizeof(*htCap));
6407
6408     return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_CAP_CMDID,
6409                          NO_SYNC_WMIFLAG));
6410 }
6411
6412 A_STATUS
6413 wmi_set_ht_op_cmd(struct wmi_t *wmip, A_UINT8 sta_chan_width)
6414 {
6415     void *osbuf;
6416     WMI_SET_HT_OP_CMD *htInfo;
6417
6418     osbuf = A_NETBUF_ALLOC(sizeof(*htInfo));
6419     if (osbuf == NULL) {
6420         return A_NO_MEMORY;
6421     }
6422
6423     A_NETBUF_PUT(osbuf, sizeof(*htInfo));
6424
6425     htInfo = (WMI_SET_HT_OP_CMD *)(A_NETBUF_DATA(osbuf));
6426     A_MEMZERO(htInfo, sizeof(*htInfo));
6427     htInfo->sta_chan_width = sta_chan_width;
6428
6429     return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_OP_CMDID,
6430                          NO_SYNC_WMIFLAG));
6431 }
6432 #endif
6433
6434 A_STATUS
6435 wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, A_UINT32 *pMaskArray)
6436 {
6437     void *osbuf;
6438     WMI_SET_TX_SELECT_RATES_CMD *pData;
6439
6440     osbuf = A_NETBUF_ALLOC(sizeof(*pData));
6441     if (osbuf == NULL) {
6442         return A_NO_MEMORY;
6443     }
6444
6445     A_NETBUF_PUT(osbuf, sizeof(*pData));
6446
6447     pData = (WMI_SET_TX_SELECT_RATES_CMD *)(A_NETBUF_DATA(osbuf));
6448     A_MEMCPY(pData, pMaskArray, sizeof(*pData));
6449
6450     return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_SELECT_RATES_CMDID,
6451                          NO_SYNC_WMIFLAG));
6452 }
6453
6454
6455 A_STATUS
6456 wmi_send_hci_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT16 sz)
6457 {
6458     void *osbuf;
6459     WMI_HCI_CMD *cmd;
6460
6461     osbuf = A_NETBUF_ALLOC(sizeof(*cmd) + sz);
6462     if (osbuf == NULL) {
6463         return A_NO_MEMORY;
6464     }
6465
6466     A_NETBUF_PUT(osbuf, sizeof(*cmd) + sz);
6467     cmd = (WMI_HCI_CMD *)(A_NETBUF_DATA(osbuf));
6468
6469     cmd->cmd_buf_sz = sz;
6470     A_MEMCPY(cmd->buf, buf, sz);
6471     return (wmi_cmd_send(wmip, osbuf, WMI_HCI_CMD_CMDID, NO_SYNC_WMIFLAG));
6472 }
6473
6474 #ifdef ATH_AR6K_11N_SUPPORT
6475 A_STATUS
6476 wmi_allow_aggr_cmd(struct wmi_t *wmip, A_UINT16 tx_tidmask, A_UINT16 rx_tidmask)
6477 {
6478     void *osbuf;
6479     WMI_ALLOW_AGGR_CMD *cmd;
6480
6481     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6482     if (osbuf == NULL) {
6483         return A_NO_MEMORY;
6484     }
6485
6486     A_NETBUF_PUT(osbuf, sizeof(*cmd));
6487
6488     cmd = (WMI_ALLOW_AGGR_CMD *)(A_NETBUF_DATA(osbuf));
6489     cmd->tx_allow_aggr = tx_tidmask;
6490     cmd->rx_allow_aggr = rx_tidmask;
6491
6492     return (wmi_cmd_send(wmip, osbuf, WMI_ALLOW_AGGR_CMDID, NO_SYNC_WMIFLAG));
6493 }
6494
6495 A_STATUS
6496 wmi_setup_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid)
6497 {
6498     void *osbuf;
6499     WMI_ADDBA_REQ_CMD *cmd;
6500
6501     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6502     if (osbuf == NULL) {
6503         return A_NO_MEMORY;
6504     }
6505
6506     A_NETBUF_PUT(osbuf, sizeof(*cmd));
6507
6508     cmd = (WMI_ADDBA_REQ_CMD *)(A_NETBUF_DATA(osbuf));
6509     cmd->tid = tid;
6510
6511     return (wmi_cmd_send(wmip, osbuf, WMI_ADDBA_REQ_CMDID, NO_SYNC_WMIFLAG));
6512 }
6513
6514 A_STATUS
6515 wmi_delete_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid, A_BOOL uplink)
6516 {
6517     void *osbuf;
6518     WMI_DELBA_REQ_CMD *cmd;
6519
6520     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6521     if (osbuf == NULL) {
6522         return A_NO_MEMORY;
6523     }
6524
6525     A_NETBUF_PUT(osbuf, sizeof(*cmd));
6526
6527     cmd = (WMI_DELBA_REQ_CMD *)(A_NETBUF_DATA(osbuf));
6528     cmd->tid = tid;
6529     cmd->is_sender_initiator = uplink;  /* uplink =1 - uplink direction, 0=downlink direction */
6530
6531     /* Delete the local aggr state, on host */
6532     return (wmi_cmd_send(wmip, osbuf, WMI_DELBA_REQ_CMDID, NO_SYNC_WMIFLAG));
6533 }
6534 #endif
6535
6536 A_STATUS
6537 wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, A_UINT8 rxMetaVersion,
6538                             A_BOOL rxDot11Hdr, A_BOOL defragOnHost)
6539 {
6540     void *osbuf;
6541     WMI_RX_FRAME_FORMAT_CMD *cmd;
6542
6543     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6544     if (osbuf == NULL) {
6545         return A_NO_MEMORY;
6546     }
6547
6548     A_NETBUF_PUT(osbuf, sizeof(*cmd));
6549
6550     cmd = (WMI_RX_FRAME_FORMAT_CMD *)(A_NETBUF_DATA(osbuf));
6551     cmd->dot11Hdr = (rxDot11Hdr==TRUE)? 1:0;
6552     cmd->defragOnHost = (defragOnHost==TRUE)? 1:0;
6553     cmd->metaVersion = rxMetaVersion;  /*  */
6554
6555     /* Delete the local aggr state, on host */
6556     return (wmi_cmd_send(wmip, osbuf, WMI_RX_FRAME_FORMAT_CMDID, NO_SYNC_WMIFLAG));
6557 }
6558
6559
6560 A_STATUS
6561 wmi_set_thin_mode_cmd(struct wmi_t *wmip, A_BOOL bThinMode)
6562 {
6563     void *osbuf;
6564     WMI_SET_THIN_MODE_CMD *cmd;
6565
6566     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6567     if (osbuf == NULL) {
6568         return A_NO_MEMORY;
6569     }
6570
6571     A_NETBUF_PUT(osbuf, sizeof(*cmd));
6572
6573     cmd = (WMI_SET_THIN_MODE_CMD *)(A_NETBUF_DATA(osbuf));
6574     cmd->enable = (bThinMode==TRUE)? 1:0;
6575
6576     /* Delete the local aggr state, on host */
6577     return (wmi_cmd_send(wmip, osbuf, WMI_SET_THIN_MODE_CMDID, NO_SYNC_WMIFLAG));
6578 }
6579
6580
6581 A_STATUS
6582 wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE precedence)
6583 {
6584     void *osbuf;
6585     WMI_SET_BT_WLAN_CONN_PRECEDENCE *cmd;
6586
6587     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6588     if (osbuf == NULL) {
6589         return A_NO_MEMORY;
6590     }
6591
6592     A_NETBUF_PUT(osbuf, sizeof(*cmd));
6593
6594     cmd = (WMI_SET_BT_WLAN_CONN_PRECEDENCE *)(A_NETBUF_DATA(osbuf));
6595     A_MEMZERO(cmd, sizeof(*cmd));
6596     cmd->precedence = precedence;
6597
6598     return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID,
6599                          NO_SYNC_WMIFLAG));
6600 }
6601
6602 A_STATUS
6603 wmi_set_pmk_cmd(struct wmi_t *wmip, A_UINT8 *pmk)
6604 {
6605     void *osbuf;
6606     WMI_SET_PMK_CMD *p;
6607
6608     osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_PMK_CMD));
6609     if (osbuf == NULL) {
6610         return A_NO_MEMORY;
6611     }
6612
6613     A_NETBUF_PUT(osbuf, sizeof(WMI_SET_PMK_CMD));
6614
6615     p = (WMI_SET_PMK_CMD *)(A_NETBUF_DATA(osbuf));
6616     A_MEMZERO(p, sizeof(*p));
6617
6618     A_MEMCPY(p->pmk, pmk, WMI_PMK_LEN);
6619
6620     return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMK_CMDID, NO_SYNC_WMIFLAG));
6621 }
6622
6623 A_STATUS
6624 wmi_SGI_cmd(struct wmi_t *wmip, A_UINT32 sgiMask, A_UINT8 sgiPERThreshold)
6625 {
6626     void *osbuf;
6627     WMI_SET_TX_SGI_PARAM_CMD *cmd;
6628
6629     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6630     if (osbuf == NULL) {
6631         return A_NO_MEMORY ;
6632     }
6633
6634     A_NETBUF_PUT(osbuf, sizeof(*cmd));
6635
6636     cmd = (WMI_SET_TX_SGI_PARAM_CMD *)(A_NETBUF_DATA(osbuf));
6637     A_MEMZERO(cmd, sizeof(*cmd));
6638     cmd->sgiMask = sgiMask;
6639     cmd->sgiPERThreshold = sgiPERThreshold;
6640     return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_SGI_PARAM_CMDID,
6641                          NO_SYNC_WMIFLAG));
6642 }
6643
6644 bss_t *
6645 wmi_find_matching_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid,
6646                    A_UINT32 ssidLength,
6647                    A_UINT32 dot11AuthMode, A_UINT32 authMode,
6648                    A_UINT32 pairwiseCryptoType, A_UINT32 grpwiseCryptoTyp)
6649 {
6650     bss_t *node = NULL;
6651     node = wlan_find_matching_Ssidnode (&wmip->wmi_scan_table, pSsid,
6652                                ssidLength, dot11AuthMode, authMode, pairwiseCryptoType, grpwiseCryptoTyp);
6653
6654     return node;
6655 }
6656
6657 A_UINT16
6658 wmi_ieee2freq (int chan)
6659 {
6660     A_UINT16 freq = 0;
6661     freq = wlan_ieee2freq (chan);
6662     return freq;
6663
6664 }
6665
6666 A_UINT32
6667 wmi_freq2ieee (A_UINT16 freq)
6668 {
6669     A_UINT16 chan = 0;
6670     chan = wlan_freq2ieee (freq);
6671     return chan;
6672 }