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