Add ar6000 wireless driver.
[kernel.git] / drivers / ar6000 / wmi / wmi.c
1 /*
2  * Copyright (c) 2004-2007 Atheros Communications Inc.
3  * All rights reserved.
4  *
5  * This module implements the hardware independent layer of the
6  * Wireless Module Interface (WMI) protocol.
7  *
8  * $Id: //depot/sw/releases/olca2.0-GPL/host/wmi/wmi.c#3 $
9  *
10  *
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License version 2 as
13  *  published by the Free Software Foundation;
14  *
15  *  Software distributed under the License is distributed on an "AS
16  *  IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
17  *  implied. See the License for the specific language governing
18  *  rights and limitations under the License.
19  *
20  *
21  *
22  */
23
24 #include <a_config.h>
25 #include <athdefs.h>
26 #include <a_types.h>
27 #include <a_osapi.h>
28 #include "htc.h"
29 #include "htc_api.h"
30 #include "wmi.h"
31 #include <ieee80211.h>
32 #include <ieee80211_node.h>
33 #include <wlan_api.h>
34 #include <wmi_api.h>
35 #include "dset_api.h"
36 #include "gpio_api.h"
37 #include "wmi_host.h"
38 #include "a_drv.h"
39 #include "a_drv_api.h"
40 #include "a_debug.h"
41 #include "dbglog_api.h"
42
43 static A_STATUS wmi_ready_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
44
45 static A_STATUS wmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
46                                      int len);
47 static A_STATUS wmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
48                                         int len);
49 static A_STATUS wmi_tkip_micerr_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
50                                         int len);
51 static A_STATUS wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
52                                      int len);
53 static A_STATUS wmi_opt_frame_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
54                                        int len);
55 static A_STATUS wmi_pstream_timeout_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
56                                      int len);
57 static A_STATUS wmi_sync_point(struct wmi_t *wmip);
58
59 static A_STATUS wmi_bitrate_reply_rx(struct wmi_t *wmip, A_UINT8 *datap,
60                                      int len);
61 static A_STATUS wmi_ratemask_reply_rx(struct wmi_t *wmip, A_UINT8 *datap,
62                                      int len);
63 static A_STATUS wmi_channelList_reply_rx(struct wmi_t *wmip, A_UINT8 *datap,
64                                          int len);
65 static A_STATUS wmi_regDomain_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
66                                        int len);
67 static A_STATUS wmi_txPwr_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
68 static A_STATUS wmi_neighborReport_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
69                                              int len);
70
71 static A_STATUS wmi_dset_open_req_rx(struct wmi_t *wmip, A_UINT8 *datap,
72                                      int len);
73 #ifdef CONFIG_HOST_DSET_SUPPORT
74 static A_STATUS wmi_dset_close_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
75 static A_STATUS wmi_dset_data_req_rx(struct wmi_t *wmip, A_UINT8 *datap,
76                                      int len);
77 #endif /* CONFIG_HOST_DSET_SUPPORT */
78
79
80 static A_STATUS wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap,
81                                      int len);
82 static A_STATUS wmi_errorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
83 static A_STATUS wmi_statsEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
84 static A_STATUS wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
85 static A_STATUS wmi_hbChallengeResp_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
86 static A_STATUS wmi_reportErrorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
87 static A_STATUS wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
88 static A_STATUS wmi_roam_tbl_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
89                                       int len);
90 static A_STATUS wmi_roam_data_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
91                                       int len);
92 static A_STATUS wmi_get_wow_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
93                                       int len);
94 static A_STATUS
95 wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len);
96
97 #ifdef CONFIG_HOST_GPIO_SUPPORT
98 static A_STATUS wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
99 static A_STATUS wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
100 static A_STATUS wmi_gpio_ack_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
101 #endif /* CONFIG_HOST_GPIO_SUPPORT */
102
103 #ifdef CONFIG_HOST_TCMD_SUPPORT
104 static A_STATUS
105 wmi_tcmd_test_report_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
106 #endif
107
108 static A_STATUS
109 wmi_txRetryErrEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
110
111 static A_STATUS
112 wmi_snrThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
113
114 static A_STATUS
115 wmi_lqThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
116
117 static A_BOOL
118 wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_UINT32 rateIndex);
119
120 static A_STATUS
121 wmi_aplistEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
122
123 static A_STATUS
124 wmi_dbglog_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
125
126 static A_STATUS wmi_keepalive_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
127
128 int wps_enable;
129 static const A_INT32 wmi_rateTable[] = {
130     1000,
131     2000,
132     5500,
133     11000,
134     6000,
135     9000,
136     12000,
137     18000,
138     24000,
139     36000,
140     48000,
141     54000,
142     0};
143
144 #define MODE_A_SUPPORT_RATE_START       4
145 #define MODE_A_SUPPORT_RATE_STOP        11
146
147 #define MODE_GONLY_SUPPORT_RATE_START   MODE_A_SUPPORT_RATE_START
148 #define MODE_GONLY_SUPPORT_RATE_STOP    MODE_A_SUPPORT_RATE_STOP
149
150 #define MODE_B_SUPPORT_RATE_START       0
151 #define MODE_B_SUPPORT_RATE_STOP        3
152
153 #define MODE_G_SUPPORT_RATE_START       0
154 #define MODE_G_SUPPORT_RATE_STOP        11
155
156 #define MAX_NUMBER_OF_SUPPORT_RATES     (MODE_G_SUPPORT_RATE_STOP + 1)
157
158 /* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */
159 const A_UINT8 up_to_ac[]= {
160                 WMM_AC_BE,
161                 WMM_AC_BK,
162                 WMM_AC_BK,
163                 WMM_AC_BE,
164                 WMM_AC_VI,
165                 WMM_AC_VI,
166                 WMM_AC_VO,
167                 WMM_AC_VO,
168             };
169
170 void *
171 wmi_init(void *devt)
172 {
173     struct wmi_t *wmip;
174
175     wmip = A_MALLOC(sizeof(struct wmi_t));
176     if (wmip == NULL) {
177         return (NULL);
178     }
179     A_MEMZERO(wmip, sizeof(*wmip));
180     A_MUTEX_INIT(&wmip->wmi_lock);
181     wmip->wmi_devt = devt;
182     wlan_node_table_init(wmip, &wmip->wmi_scan_table);
183     wmi_qos_state_init(wmip);
184     wmip->wmi_powerMode = REC_POWER;
185     wmip->wmi_phyMode = WMI_11G_MODE;
186
187     return (wmip);
188 }
189
190 void
191 wmi_qos_state_init(struct wmi_t *wmip)
192 {
193     A_UINT8 i;
194
195     if (wmip == NULL) {
196         return;
197     }
198     LOCK_WMI(wmip);
199
200     /* Initialize QoS States */
201     wmip->wmi_numQoSStream = 0;
202
203     wmip->wmi_fatPipeExists = 0;
204
205     for (i=0; i < WMM_NUM_AC; i++) {
206         wmip->wmi_streamExistsForAC[i]=0;
207     }
208
209         /* Initialize the static Wmi stream Pri to WMM AC mappings Arrays */
210     WMI_INIT_WMISTREAM_AC_MAP(wmip);
211
212     UNLOCK_WMI(wmip);
213
214     A_WMI_SET_NUMDATAENDPTS(wmip->wmi_devt, 1);
215 }
216
217 void
218 wmi_shutdown(struct wmi_t *wmip)
219 {
220     if (wmip != NULL) {
221         wlan_node_table_cleanup(&wmip->wmi_scan_table);
222         if (A_IS_MUTEX_VALID(&wmip->wmi_lock)) {
223             A_MUTEX_DELETE(&wmip->wmi_lock);
224         }
225         A_FREE(wmip);
226     }
227 }
228
229 /*
230  *  performs DIX to 802.3 encapsulation for transmit packets.
231  *  uses passed in buffer.  Returns buffer or NULL if failed.
232  *  Assumes the entire DIX header is contigous and that there is
233  *  enough room in the buffer for a 802.3 mac header and LLC+SNAP headers.
234  */
235 A_STATUS
236 wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf)
237 {
238     A_UINT8          *datap;
239     A_UINT16         typeorlen;
240     ATH_MAC_HDR      macHdr;
241     ATH_LLC_SNAP_HDR *llcHdr;
242
243     A_ASSERT(osbuf != NULL);
244
245     if (A_NETBUF_HEADROOM(osbuf) <
246         (sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR)))
247     {
248         return A_NO_MEMORY;
249     }
250
251     datap = A_NETBUF_DATA(osbuf);
252
253     typeorlen = *(A_UINT16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN);
254
255     if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) {
256         /*
257          * packet is already in 802.3 format - return success
258          */
259         A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG));
260         return (A_OK);
261     }
262
263     /*
264      * Save mac fields and length to be inserted later
265      */
266     A_MEMCPY(macHdr.dstMac, datap, ATH_MAC_LEN);
267     A_MEMCPY(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN);
268     macHdr.typeOrLen = A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) +
269                                   sizeof(ATH_LLC_SNAP_HDR));
270
271     /*
272      * Make room for LLC+SNAP headers
273      */
274     if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != A_OK) {
275         return A_NO_MEMORY;
276     }
277
278     datap = A_NETBUF_DATA(osbuf);
279
280     A_MEMCPY(datap, &macHdr, sizeof (ATH_MAC_HDR));
281
282     llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR));
283     llcHdr->dsap      = 0xAA;
284     llcHdr->ssap      = 0xAA;
285     llcHdr->cntl      = 0x03;
286     llcHdr->orgCode[0] = 0x0;
287     llcHdr->orgCode[1] = 0x0;
288     llcHdr->orgCode[2] = 0x0;
289     llcHdr->etherType = typeorlen;
290
291     return (A_OK);
292 }
293
294 /*
295  * Adds a WMI data header
296  * Assumes there is enough room in the buffer to add header.
297  */
298 A_STATUS
299 wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, A_UINT8 msgType)
300 {
301     WMI_DATA_HDR     *dtHdr;
302
303     A_ASSERT(osbuf != NULL);
304
305     if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != A_OK) {
306         return A_NO_MEMORY;
307     }
308
309     dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf);
310     dtHdr->info = msgType;
311     dtHdr->rssi = 0;
312
313     return (A_OK);
314 }
315
316 A_UINT8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT8 dir, A_UINT8 up)
317 {
318     A_UINT8         *datap;
319     A_UINT8         trafficClass = WMM_AC_BE, userPriority = up;
320     ATH_LLC_SNAP_HDR *llcHdr;
321     A_UINT16        ipType = IP_ETHERTYPE;
322     WMI_DATA_HDR     *dtHdr;
323     WMI_CREATE_PSTREAM_CMD  cmd;
324     A_BOOL           streamExists = FALSE;
325
326     A_ASSERT(osbuf != NULL);
327
328     datap = A_NETBUF_DATA(osbuf);
329
330     if (up == UNDEFINED_PRI) {
331     llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) +
332                                   sizeof(ATH_MAC_HDR));
333
334         if (llcHdr->etherType == A_CPU2BE16(ipType)) {
335         /* Extract the endpoint info from the TOS field in the IP header */
336         userPriority = A_WMI_IPTOS_TO_USERPRIORITY(((A_UINT8 *)llcHdr) + sizeof(ATH_LLC_SNAP_HDR));
337         }
338     }
339
340     if (userPriority < MAX_NUM_PRI) {
341         trafficClass = convert_userPriority_to_trafficClass(userPriority);
342     }
343
344     dtHdr = (WMI_DATA_HDR *)datap;
345     if(dir==UPLINK_TRAFFIC)
346         dtHdr->info |= (userPriority & WMI_DATA_HDR_UP_MASK) << WMI_DATA_HDR_UP_SHIFT;  /* lower 3-bits are 802.1d priority */
347
348     LOCK_WMI(wmip);
349     streamExists = wmip->wmi_fatPipeExists;
350     UNLOCK_WMI(wmip);
351
352     if (!(streamExists & (1 << trafficClass))) {
353
354         A_MEMZERO(&cmd, sizeof(cmd));
355             cmd.trafficClass = trafficClass;
356             cmd.userPriority = userPriority;
357                 cmd.inactivityInt = WMI_IMPLICIT_PSTREAM_INACTIVITY_INT;
358             /* Implicit streams are created with TSID 0xFF */
359         cmd.tsid = WMI_IMPLICIT_PSTREAM;
360         wmi_create_pstream_cmd(wmip, &cmd);
361     }
362
363     return trafficClass;
364 }
365
366 WMI_PRI_STREAM_ID
367 wmi_get_stream_id(struct wmi_t *wmip, A_UINT8 trafficClass)
368 {
369     return WMI_ACCESSCATEGORY_WMISTREAM(wmip, trafficClass);
370 }
371
372 /*
373  *  performs 802.3 to DIX encapsulation for received packets.
374  *  Assumes the entire 802.3 header is contigous.
375  */
376 A_STATUS
377 wmi_dot3_2_dix(struct wmi_t *wmip, void *osbuf)
378 {
379     A_UINT8          *datap;
380     ATH_MAC_HDR      macHdr;
381     ATH_LLC_SNAP_HDR *llcHdr;
382
383     A_ASSERT(osbuf != NULL);
384     datap = A_NETBUF_DATA(osbuf);
385
386     A_MEMCPY(&macHdr, datap, sizeof(ATH_MAC_HDR));
387     llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR));
388     macHdr.typeOrLen = llcHdr->etherType;
389
390     if (A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != A_OK) {
391         return A_NO_MEMORY;
392     }
393
394     datap = A_NETBUF_DATA(osbuf);
395
396     A_MEMCPY(datap, &macHdr, sizeof (ATH_MAC_HDR));
397
398     return (A_OK);
399 }
400
401 /*
402  * Removes a WMI data header
403  */
404 A_STATUS
405 wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf)
406 {
407     A_ASSERT(osbuf != NULL);
408
409     return (A_NETBUF_PULL(osbuf, sizeof(WMI_DATA_HDR)));
410 }
411
412 void
413 wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg)
414 {
415     wlan_iterate_nodes(&wmip->wmi_scan_table, f, arg);
416 }
417
418 /*
419  * WMI Extended Event received from Target.
420  */
421 A_STATUS
422 wmi_control_rx_xtnd(struct wmi_t *wmip, void *osbuf)
423 {
424     WMIX_CMD_HDR *cmd;
425     A_UINT16 id;
426     A_UINT8 *datap;
427     A_UINT32 len;
428     A_STATUS status = A_OK;
429
430     if (A_NETBUF_LEN(osbuf) < sizeof(WMIX_CMD_HDR)) {
431         A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG));
432         wmip->wmi_stats.cmd_len_err++;
433         A_NETBUF_FREE(osbuf);
434         return A_ERROR;
435     }
436
437     cmd = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf);
438     id = cmd->commandId;
439
440     if (A_NETBUF_PULL(osbuf, sizeof(WMIX_CMD_HDR)) != A_OK) {
441         A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG));
442         wmip->wmi_stats.cmd_len_err++;
443         A_NETBUF_FREE(osbuf);
444         return A_ERROR;
445     }
446
447     datap = A_NETBUF_DATA(osbuf);
448     len = A_NETBUF_LEN(osbuf);
449
450     switch (id) {
451     case (WMIX_DSETOPENREQ_EVENTID):
452         status = wmi_dset_open_req_rx(wmip, datap, len);
453         break;
454 #ifdef CONFIG_HOST_DSET_SUPPORT
455     case (WMIX_DSETCLOSE_EVENTID):
456         status = wmi_dset_close_rx(wmip, datap, len);
457         break;
458     case (WMIX_DSETDATAREQ_EVENTID):
459         status = wmi_dset_data_req_rx(wmip, datap, len);
460         break;
461 #endif /* CONFIG_HOST_DSET_SUPPORT */
462 #ifdef CONFIG_HOST_GPIO_SUPPORT
463     case (WMIX_GPIO_INTR_EVENTID):
464         wmi_gpio_intr_rx(wmip, datap, len);
465         break;
466     case (WMIX_GPIO_DATA_EVENTID):
467         wmi_gpio_data_rx(wmip, datap, len);
468         break;
469     case (WMIX_GPIO_ACK_EVENTID):
470         wmi_gpio_ack_rx(wmip, datap, len);
471         break;
472 #endif /* CONFIG_HOST_GPIO_SUPPORT */
473     case (WMIX_HB_CHALLENGE_RESP_EVENTID):
474         wmi_hbChallengeResp_rx(wmip, datap, len);
475         break;
476     case (WMIX_DBGLOG_EVENTID):
477         wmi_dbglog_event_rx(wmip, datap, len);
478         break;
479     default:
480         A_DPRINTF(DBG_WMI|DBG_ERROR,
481             (DBGFMT "Unknown id 0x%x\n", DBGARG, id));
482         wmip->wmi_stats.cmd_id_err++;
483         status = A_ERROR;
484         break;
485     }
486
487     return status;
488 }
489
490 /*
491  * Control Path
492  */
493 A_UINT32 cmdRecvNum;
494
495 A_STATUS
496 wmi_control_rx(struct wmi_t *wmip, void *osbuf)
497 {
498     WMI_CMD_HDR *cmd;
499     A_UINT16 id;
500     A_UINT8 *datap;
501     A_UINT32 len, i, loggingReq;
502     A_STATUS status = A_OK;
503
504     A_ASSERT(osbuf != NULL);
505     if (A_NETBUF_LEN(osbuf) < sizeof(WMI_CMD_HDR)) {
506         A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG));
507         wmip->wmi_stats.cmd_len_err++;
508         A_NETBUF_FREE(osbuf);
509         return A_ERROR;
510     }
511
512     cmd = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf);
513     id = cmd->commandId;
514
515     if (A_NETBUF_PULL(osbuf, sizeof(WMI_CMD_HDR)) != A_OK) {
516         A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG));
517         wmip->wmi_stats.cmd_len_err++;
518         A_NETBUF_FREE(osbuf);
519         return A_ERROR;
520     }
521
522     datap = A_NETBUF_DATA(osbuf);
523     len = A_NETBUF_LEN(osbuf);
524
525     ar6000_get_driver_cfg(wmip->wmi_devt,
526                     AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS,
527                     &loggingReq);
528
529     if(loggingReq) {
530         AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI %d \n",id));
531         AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI recv, MsgNo %d : ", cmdRecvNum));
532         for(i = 0; i < len; i++)
533             AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("%x ", datap[i]));
534         AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("\n"));
535     }
536
537     LOCK_WMI(wmip);
538     cmdRecvNum++;
539     UNLOCK_WMI(wmip);
540
541     switch (id) {
542     case (WMI_GET_BITRATE_CMDID):
543         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_BITRATE_CMDID\n", DBGARG));
544         status = wmi_bitrate_reply_rx(wmip, datap, len);
545         break;
546     case (WMI_GET_CHANNEL_LIST_CMDID):
547         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_CHANNEL_LIST_CMDID\n", DBGARG));
548         status = wmi_channelList_reply_rx(wmip, datap, len);
549         break;
550     case (WMI_GET_TX_PWR_CMDID):
551         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_TX_PWR_CMDID\n", DBGARG));
552         status = wmi_txPwr_reply_rx(wmip, datap, len);
553         break;
554     case (WMI_READY_EVENTID):
555         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_READY_EVENTID\n", DBGARG));
556         status = wmi_ready_event_rx(wmip, datap, len);
557         A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
558         A_WMI_DBGLOG_INIT_DONE(wmip->wmi_devt);
559         break;
560     case (WMI_CONNECT_EVENTID):
561         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CONNECT_EVENTID\n", DBGARG));
562         status = wmi_connect_event_rx(wmip, datap, len);
563         A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
564         break;
565     case (WMI_DISCONNECT_EVENTID):
566         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_DISCONNECT_EVENTID\n", DBGARG));
567         status = wmi_disconnect_event_rx(wmip, datap, len);
568         A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
569         break;
570     case (WMI_TKIP_MICERR_EVENTID):
571         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TKIP_MICERR_EVENTID\n", DBGARG));
572         status = wmi_tkip_micerr_event_rx(wmip, datap, len);
573         break;
574     case (WMI_BSSINFO_EVENTID):
575         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BSSINFO_EVENTID\n", DBGARG));
576         status = wmi_bssInfo_event_rx(wmip, datap, len);
577         A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
578         break;
579     case (WMI_REGDOMAIN_EVENTID):
580         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REGDOMAIN_EVENTID\n", DBGARG));
581         status = wmi_regDomain_event_rx(wmip, datap, len);
582         break;
583     case (WMI_PSTREAM_TIMEOUT_EVENTID):
584         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_PSTREAM_TIMEOUT_EVENTID\n", DBGARG));
585         status = wmi_pstream_timeout_event_rx(wmip, datap, len);
586             /* pstreams are fatpipe abstractions that get implicitly created.
587              * User apps only deal with thinstreams. creation of a thinstream
588              * by the user or data traffic flow in an AC triggers implicit
589              * pstream creation. Do we need to send this event to App..?
590              * no harm in sending it.
591              */
592         A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
593         break;
594     case (WMI_NEIGHBOR_REPORT_EVENTID):
595         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_NEIGHBOR_REPORT_EVENTID\n", DBGARG));
596         status = wmi_neighborReport_event_rx(wmip, datap, len);
597         break;
598     case (WMI_SCAN_COMPLETE_EVENTID):
599         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SCAN_COMPLETE_EVENTID\n", DBGARG));
600         status = wmi_scanComplete_rx(wmip, datap, len);
601         A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
602         break;
603     case (WMI_CMDERROR_EVENTID):
604         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CMDERROR_EVENTID\n", DBGARG));
605         status = wmi_errorEvent_rx(wmip, datap, len);
606         break;
607     case (WMI_REPORT_STATISTICS_EVENTID):
608         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_STATISTICS_EVENTID\n", DBGARG));
609         status = wmi_statsEvent_rx(wmip, datap, len);
610         break;
611     case (WMI_RSSI_THRESHOLD_EVENTID):
612         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_RSSI_THRESHOLD_EVENTID\n", DBGARG));
613         status = wmi_rssiThresholdEvent_rx(wmip, datap, len);
614         break;
615     case (WMI_ERROR_REPORT_EVENTID):
616         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_ERROR_REPORT_EVENTID\n", DBGARG));
617         status = wmi_reportErrorEvent_rx(wmip, datap, len);
618         A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
619         break;
620     case (WMI_OPT_RX_FRAME_EVENTID):
621         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_OPT_RX_FRAME_EVENTID\n", DBGARG));
622         status = wmi_opt_frame_event_rx(wmip, datap, len);
623         break;
624     case (WMI_REPORT_ROAM_TBL_EVENTID):
625         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_ROAM_TBL_EVENTID\n", DBGARG));
626         status = wmi_roam_tbl_event_rx(wmip, datap, len);
627         break;
628     case (WMI_EXTENSION_EVENTID):
629         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_EXTENSION_EVENTID\n", DBGARG));
630         status = wmi_control_rx_xtnd(wmip, osbuf);
631         break;
632     case (WMI_CAC_EVENTID):
633         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CAC_EVENTID\n", DBGARG));
634         status = wmi_cac_event_rx(wmip, datap, len);
635         break;
636     case (WMI_REPORT_ROAM_DATA_EVENTID):
637         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_ROAM_DATA_EVENTID\n", DBGARG));
638         status = wmi_roam_data_event_rx(wmip, datap, len);
639         break;
640 #ifdef CONFIG_HOST_TCMD_SUPPORT
641     case (WMI_TEST_EVENTID):
642         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TEST_EVENTID\n", DBGARG));
643         status = wmi_tcmd_test_report_rx(wmip, datap, len);
644         break;
645 #endif
646     case (WMI_GET_FIXRATES_CMDID):
647         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_FIXRATES_CMDID\n", DBGARG));
648         status = wmi_ratemask_reply_rx(wmip, datap, len);
649         break;
650     case (WMI_TX_RETRY_ERR_EVENTID):
651         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TX_RETRY_ERR_EVENTID\n", DBGARG));
652         status = wmi_txRetryErrEvent_rx(wmip, datap, len);
653         A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
654         break;
655     case (WMI_SNR_THRESHOLD_EVENTID):
656         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SNR_THRESHOLD_EVENTID\n", DBGARG));
657         status = wmi_snrThresholdEvent_rx(wmip, datap, len);
658         A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
659         break;
660     case (WMI_LQ_THRESHOLD_EVENTID):
661         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_LQ_THRESHOLD_EVENTID\n", DBGARG));
662         status = wmi_lqThresholdEvent_rx(wmip, datap, len);
663         A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
664         break;
665     case (WMI_APLIST_EVENTID):
666         AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Received APLIST Event\n"));
667         status = wmi_aplistEvent_rx(wmip, datap, len);
668         break;
669     case (WMI_GET_KEEPALIVE_CMDID):
670         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_KEEPALIVE_CMDID\n", DBGARG));
671         status = wmi_keepalive_reply_rx(wmip, datap, len);
672         break;
673     case (WMI_GET_WOW_LIST_EVENTID):
674         status = wmi_get_wow_list_event_rx(wmip, datap, len);
675         break;
676     case (WMI_GET_PMKID_LIST_EVENTID):
677         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_PMKID_LIST Event\n", DBGARG));
678         status = wmi_get_pmkid_list_event_rx(wmip, datap, len);
679         break;
680     default:
681         A_DPRINTF(DBG_WMI|DBG_ERROR,
682             (DBGFMT "Unknown id 0x%x\n", DBGARG, id));
683         wmip->wmi_stats.cmd_id_err++;
684         status = A_ERROR;
685         break;
686     }
687
688     A_NETBUF_FREE(osbuf);
689
690     return status;
691 }
692
693 static A_STATUS
694 wmi_ready_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
695 {
696     WMI_READY_EVENT *ev = (WMI_READY_EVENT *)datap;
697
698     if (len < sizeof(WMI_READY_EVENT)) {
699         return A_EINVAL;
700     }
701     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
702     wmip->wmi_ready = TRUE;
703     A_WMI_READY_EVENT(wmip->wmi_devt, ev->macaddr, ev->phyCapability);
704
705     return A_OK;
706 }
707
708 static A_STATUS
709 wmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
710 {
711     WMI_CONNECT_EVENT *ev;
712
713     if (len < sizeof(WMI_CONNECT_EVENT)) {
714         return A_EINVAL;
715     }
716     ev = (WMI_CONNECT_EVENT *)datap;
717     A_DPRINTF(DBG_WMI,
718         (DBGFMT "freq %d bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
719         DBGARG, ev->channel,
720         ev->bssid[0], ev->bssid[1], ev->bssid[2],
721         ev->bssid[3], ev->bssid[4], ev->bssid[5]));
722
723     A_MEMCPY(wmip->wmi_bssid, ev->bssid, ATH_MAC_LEN);
724
725     A_WMI_CONNECT_EVENT(wmip->wmi_devt, ev->channel, ev->bssid,
726                          ev->listenInterval, ev->beaconInterval,
727                          ev->networkType, ev->beaconIeLen,
728                          ev->assocReqLen, ev->assocRespLen,
729                          ev->assocInfo);
730
731     return A_OK;
732 }
733
734 static A_STATUS
735 wmi_regDomain_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
736 {
737     WMI_REG_DOMAIN_EVENT *ev;
738
739     if (len < sizeof(*ev)) {
740         return A_EINVAL;
741     }
742     ev = (WMI_REG_DOMAIN_EVENT *)datap;
743
744     A_WMI_REGDOMAIN_EVENT(wmip->wmi_devt, ev->regDomain);
745
746     return A_OK;
747 }
748
749 static A_STATUS
750 wmi_neighborReport_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
751 {
752     WMI_NEIGHBOR_REPORT_EVENT *ev;
753     int numAps;
754
755     if (len < sizeof(*ev)) {
756         return A_EINVAL;
757     }
758     ev = (WMI_NEIGHBOR_REPORT_EVENT *)datap;
759     numAps = ev->numberOfAps;
760
761     if (len < (int)(sizeof(*ev) + ((numAps - 1) * sizeof(WMI_NEIGHBOR_INFO)))) {
762         return A_EINVAL;
763     }
764
765     A_WMI_NEIGHBORREPORT_EVENT(wmip->wmi_devt, numAps, ev->neighbor);
766
767     return A_OK;
768 }
769
770 static A_STATUS
771 wmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
772 {
773     WMI_DISCONNECT_EVENT *ev;
774
775     if (len < sizeof(WMI_DISCONNECT_EVENT)) {
776         return A_EINVAL;
777     }
778     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
779
780     ev = (WMI_DISCONNECT_EVENT *)datap;
781
782     A_MEMZERO(wmip->wmi_bssid, sizeof(wmip->wmi_bssid));
783
784     A_WMI_DISCONNECT_EVENT(wmip->wmi_devt, ev->disconnectReason, ev->bssid,
785                             ev->assocRespLen, ev->assocInfo, ev->protocolReasonStatus);
786
787     return A_OK;
788 }
789
790 static A_STATUS
791 wmi_tkip_micerr_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
792 {
793     WMI_TKIP_MICERR_EVENT *ev;
794
795     if (len < sizeof(*ev)) {
796         return A_EINVAL;
797     }
798     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
799
800     ev = (WMI_TKIP_MICERR_EVENT *)datap;
801     A_WMI_TKIP_MICERR_EVENT(wmip->wmi_devt, ev->keyid, ev->ismcast);
802
803     return A_OK;
804 }
805
806 static A_STATUS
807 wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
808 {
809     bss_t *bss;
810     WMI_BSS_INFO_HDR *bih;
811     A_UINT8 *buf;
812     A_UINT32 nodeCachingAllowed;
813
814     if (len <= sizeof(WMI_BSS_INFO_HDR)) {
815         return A_EINVAL;
816     }
817
818     A_WMI_BSSINFO_EVENT_RX(wmip->wmi_devt, datap, len);
819     /* What is driver config for wlan node caching? */
820     if(ar6000_get_driver_cfg(wmip->wmi_devt,
821                     AR6000_DRIVER_CFG_GET_WLANNODECACHING,
822                     &nodeCachingAllowed) != A_OK) {
823         return A_EINVAL;
824     }
825
826     if(!nodeCachingAllowed) {
827         return A_OK;
828     }
829
830
831     bih = (WMI_BSS_INFO_HDR *)datap;
832     buf = datap + sizeof(WMI_BSS_INFO_HDR);
833     len -= sizeof(WMI_BSS_INFO_HDR);
834
835     A_DPRINTF(DBG_WMI2, (DBGFMT "bssInfo event - ch %u, rssi %02x, "
836               "bssid \"%02x:%02x:%02x:%02x:%02x:%02x\"\n", DBGARG,
837               bih->channel, (unsigned char) bih->rssi, bih->bssid[0],
838               bih->bssid[1], bih->bssid[2], bih->bssid[3], bih->bssid[4],
839               bih->bssid[5]));
840
841     if(wps_enable && (bih->frameType == PROBERESP_FTYPE) ) {
842             printk("%s() A_OK 2\n", __FUNCTION__);
843                 return A_OK;
844     }
845
846     bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid);
847     if (bss != NULL) {
848         /*
849          * Free up the node.  Not the most efficient process given
850          * we are about to allocate a new node but it is simple and should be
851          * adequate.
852          */
853         wlan_node_reclaim(&wmip->wmi_scan_table, bss);
854     }
855
856     bss = wlan_node_alloc(&wmip->wmi_scan_table, len);
857     if (bss == NULL) {
858         return A_NO_MEMORY;
859     }
860
861     bss->ni_snr        = bih->snr;
862     bss->ni_rssi       = bih->rssi;
863     A_ASSERT(bss->ni_buf != NULL);
864     A_MEMCPY(bss->ni_buf, buf, len);
865
866     if (wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie) != A_OK) {
867         wlan_node_free(bss);
868         return A_EINVAL;
869     }
870
871     /*
872      * Update the frequency in ie_chan, overwriting of channel number
873      * which is done in wlan_parse_beacon
874      */
875     bss->ni_cie.ie_chan = bih->channel;
876     wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid);
877
878     return A_OK;
879 }
880
881 static A_STATUS
882 wmi_opt_frame_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
883 {
884     bss_t *bss;
885     WMI_OPT_RX_INFO_HDR *bih;
886     A_UINT8 *buf;
887
888     if (len <= sizeof(WMI_OPT_RX_INFO_HDR)) {
889         return A_EINVAL;
890     }
891
892     bih = (WMI_OPT_RX_INFO_HDR *)datap;
893     buf = datap + sizeof(WMI_OPT_RX_INFO_HDR);
894     len -= sizeof(WMI_OPT_RX_INFO_HDR);
895
896     A_DPRINTF(DBG_WMI2, (DBGFMT "opt frame event %2.2x:%2.2x\n", DBGARG,
897         bih->bssid[4], bih->bssid[5]));
898
899     bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid);
900     if (bss != NULL) {
901         /*
902          * Free up the node.  Not the most efficient process given
903          * we are about to allocate a new node but it is simple and should be
904          * adequate.
905          */
906         wlan_node_reclaim(&wmip->wmi_scan_table, bss);
907     }
908
909     bss = wlan_node_alloc(&wmip->wmi_scan_table, len);
910     if (bss == NULL) {
911         return A_NO_MEMORY;
912     }
913
914     bss->ni_snr        = bih->snr;
915     bss->ni_cie.ie_chan = bih->channel;
916     A_ASSERT(bss->ni_buf != NULL);
917     A_MEMCPY(bss->ni_buf, buf, len);
918     wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid);
919
920     return A_OK;
921 }
922
923     /* This event indicates inactivity timeout of a fatpipe(pstream)
924      * at the target
925      */
926 static A_STATUS
927 wmi_pstream_timeout_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
928 {
929     WMI_PSTREAM_TIMEOUT_EVENT *ev;
930
931     if (len < sizeof(WMI_PSTREAM_TIMEOUT_EVENT)) {
932         return A_EINVAL;
933     }
934
935     A_DPRINTF(DBG_WMI, (DBGFMT "wmi_pstream_timeout_event_rx\n", DBGARG));
936
937     ev = (WMI_PSTREAM_TIMEOUT_EVENT *)datap;
938
939         /* When the pstream (fat pipe == AC) timesout, it means there were no
940          * thinStreams within this pstream & it got implicitly created due to
941          * data flow on this AC. We start the inactivity timer only for
942          * implicitly created pstream. Just reset the host state.
943          */
944         /* Set the activeTsids for this AC to 0 */
945     LOCK_WMI(wmip);
946     wmip->wmi_streamExistsForAC[ev->trafficClass]=0;
947     wmip->wmi_fatPipeExists &= ~(1 << ev->trafficClass);
948     UNLOCK_WMI(wmip);
949
950         /*Indicate inactivity to driver layer for this fatpipe (pstream)*/
951     A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, ev->trafficClass);
952
953     return A_OK;
954 }
955
956 static A_STATUS
957 wmi_bitrate_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
958 {
959     WMI_BIT_RATE_CMD *reply;
960     A_INT32 rate;
961
962     if (len < sizeof(WMI_BIT_RATE_CMD)) {
963         return A_EINVAL;
964     }
965     reply = (WMI_BIT_RATE_CMD *)datap;
966     A_DPRINTF(DBG_WMI,
967         (DBGFMT "Enter - rateindex %d\n", DBGARG, reply->rateIndex));
968
969     if (reply->rateIndex == RATE_AUTO) {
970         rate = RATE_AUTO;
971     } else {
972         rate = wmi_rateTable[(A_UINT32) reply->rateIndex];
973     }
974
975     A_WMI_BITRATE_RX(wmip->wmi_devt, rate);
976
977     return A_OK;
978 }
979
980 static A_STATUS
981 wmi_ratemask_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
982 {
983     WMI_FIX_RATES_CMD *reply;
984
985     if (len < sizeof(WMI_BIT_RATE_CMD)) {
986         return A_EINVAL;
987     }
988     reply = (WMI_FIX_RATES_CMD *)datap;
989     A_DPRINTF(DBG_WMI,
990         (DBGFMT "Enter - fixed rate mask %x\n", DBGARG, reply->fixRateMask));
991
992     A_WMI_RATEMASK_RX(wmip->wmi_devt, reply->fixRateMask);
993
994     return A_OK;
995 }
996
997 static A_STATUS
998 wmi_channelList_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
999 {
1000     WMI_CHANNEL_LIST_REPLY *reply;
1001
1002     if (len < sizeof(WMI_CHANNEL_LIST_REPLY)) {
1003         return A_EINVAL;
1004     }
1005     reply = (WMI_CHANNEL_LIST_REPLY *)datap;
1006     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1007
1008     A_WMI_CHANNELLIST_RX(wmip->wmi_devt, reply->numChannels,
1009                           reply->channelList);
1010
1011     return A_OK;
1012 }
1013
1014 static A_STATUS
1015 wmi_txPwr_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1016 {
1017     WMI_TX_PWR_REPLY *reply;
1018
1019     if (len < sizeof(*reply)) {
1020         return A_EINVAL;
1021     }
1022     reply = (WMI_TX_PWR_REPLY *)datap;
1023     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1024
1025     A_WMI_TXPWR_RX(wmip->wmi_devt, reply->dbM);
1026
1027     return A_OK;
1028 }
1029 static A_STATUS
1030 wmi_keepalive_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1031 {
1032     WMI_GET_KEEPALIVE_CMD *reply;
1033
1034     if (len < sizeof(*reply)) {
1035         return A_EINVAL;
1036     }
1037     reply = (WMI_GET_KEEPALIVE_CMD *)datap;
1038     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1039
1040     A_WMI_KEEPALIVE_RX(wmip->wmi_devt, reply->configured);
1041
1042     return A_OK;
1043 }
1044
1045
1046 static A_STATUS
1047 wmi_dset_open_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1048 {
1049     WMIX_DSETOPENREQ_EVENT *dsetopenreq;
1050
1051     if (len < sizeof(WMIX_DSETOPENREQ_EVENT)) {
1052         return A_EINVAL;
1053     }
1054     dsetopenreq = (WMIX_DSETOPENREQ_EVENT *)datap;
1055     A_DPRINTF(DBG_WMI,
1056         (DBGFMT "Enter - dset_id=0x%x\n", DBGARG, dsetopenreq->dset_id));
1057     A_WMI_DSET_OPEN_REQ(wmip->wmi_devt,
1058                         dsetopenreq->dset_id,
1059                         dsetopenreq->targ_dset_handle,
1060                         dsetopenreq->targ_reply_fn,
1061                         dsetopenreq->targ_reply_arg);
1062
1063     return A_OK;
1064 }
1065
1066 #ifdef CONFIG_HOST_DSET_SUPPORT
1067 static A_STATUS
1068 wmi_dset_close_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1069 {
1070     WMIX_DSETCLOSE_EVENT *dsetclose;
1071
1072     if (len < sizeof(WMIX_DSETCLOSE_EVENT)) {
1073         return A_EINVAL;
1074     }
1075     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1076
1077     dsetclose = (WMIX_DSETCLOSE_EVENT *)datap;
1078     A_WMI_DSET_CLOSE(wmip->wmi_devt, dsetclose->access_cookie);
1079
1080     return A_OK;
1081 }
1082
1083 static A_STATUS
1084 wmi_dset_data_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1085 {
1086     WMIX_DSETDATAREQ_EVENT *dsetdatareq;
1087
1088     if (len < sizeof(WMIX_DSETDATAREQ_EVENT)) {
1089         return A_EINVAL;
1090     }
1091     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1092
1093     dsetdatareq = (WMIX_DSETDATAREQ_EVENT *)datap;
1094     A_WMI_DSET_DATA_REQ(wmip->wmi_devt,
1095                          dsetdatareq->access_cookie,
1096                          dsetdatareq->offset,
1097                          dsetdatareq->length,
1098                          dsetdatareq->targ_buf,
1099                          dsetdatareq->targ_reply_fn,
1100                          dsetdatareq->targ_reply_arg);
1101
1102     return A_OK;
1103 }
1104 #endif /* CONFIG_HOST_DSET_SUPPORT */
1105
1106 static A_STATUS
1107 wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1108 {
1109     WMI_SCAN_COMPLETE_EVENT *ev;
1110
1111     ev = (WMI_SCAN_COMPLETE_EVENT *)datap;
1112     A_WMI_SCANCOMPLETE_EVENT(wmip->wmi_devt, ev->status);
1113
1114     return A_OK;
1115 }
1116
1117 /*
1118  * Target is reporting a programming error.  This is for
1119  * developer aid only.  Target only checks a few common violations
1120  * and it is responsibility of host to do all error checking.
1121  * Behavior of target after wmi error event is undefined.
1122  * A reset is recommended.
1123  */
1124 static A_STATUS
1125 wmi_errorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1126 {
1127     WMI_CMD_ERROR_EVENT *ev;
1128
1129     ev = (WMI_CMD_ERROR_EVENT *)datap;
1130     AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Programming Error: cmd=%d ", ev->commandId));
1131     switch (ev->errorCode) {
1132     case (INVALID_PARAM):
1133         AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal Parameter\n"));
1134         break;
1135     case (ILLEGAL_STATE):
1136         AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal State\n"));
1137         break;
1138     case (INTERNAL_ERROR):
1139         AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Internal Error\n"));
1140         break;
1141     }
1142
1143     return A_OK;
1144 }
1145
1146
1147 static A_STATUS
1148 wmi_statsEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1149 {
1150     WMI_TARGET_STATS *reply;
1151
1152     if (len < sizeof(*reply)) {
1153         return A_EINVAL;
1154     }
1155     reply = (WMI_TARGET_STATS *)datap;
1156     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1157
1158     A_WMI_TARGETSTATS_EVENT(wmip->wmi_devt, reply);
1159
1160     return A_OK;
1161 }
1162
1163 static A_STATUS
1164 wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1165 {
1166     WMI_RSSI_THRESHOLD_EVENT *reply;
1167
1168     if (len < sizeof(*reply)) {
1169         return A_EINVAL;
1170     }
1171     reply = (WMI_RSSI_THRESHOLD_EVENT *)datap;
1172     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1173
1174     A_WMI_RSSI_THRESHOLD_EVENT(wmip->wmi_devt, reply->range, reply->rssi);
1175
1176     return A_OK;
1177 }
1178
1179
1180 static A_STATUS
1181 wmi_reportErrorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1182 {
1183     WMI_TARGET_ERROR_REPORT_EVENT *reply;
1184
1185     if (len < sizeof(*reply)) {
1186         return A_EINVAL;
1187     }
1188     reply = (WMI_TARGET_ERROR_REPORT_EVENT *)datap;
1189     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1190
1191     A_WMI_REPORT_ERROR_EVENT(wmip->wmi_devt, reply->errorVal);
1192
1193     return A_OK;
1194 }
1195
1196 static A_STATUS
1197 wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1198 {
1199     WMI_CAC_EVENT *reply;
1200
1201     if (len < sizeof(*reply)) {
1202         return A_EINVAL;
1203     }
1204     reply = (WMI_CAC_EVENT *)datap;
1205     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1206
1207     A_WMI_CAC_EVENT(wmip->wmi_devt, reply->ac,
1208                 reply->cac_indication, reply->statusCode,
1209                 reply->tspecSuggestion);
1210
1211     return A_OK;
1212 }
1213
1214 static A_STATUS
1215 wmi_hbChallengeResp_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1216 {
1217     WMIX_HB_CHALLENGE_RESP_EVENT *reply;
1218
1219     if (len < sizeof(*reply)) {
1220         return A_EINVAL;
1221     }
1222     reply = (WMIX_HB_CHALLENGE_RESP_EVENT *)datap;
1223     A_DPRINTF(DBG_WMI, (DBGFMT "wmi: challenge response event\n", DBGARG));
1224
1225     A_WMI_HBCHALLENGERESP_EVENT(wmip->wmi_devt, reply->cookie, reply->source);
1226
1227     return A_OK;
1228 }
1229
1230 static A_STATUS
1231 wmi_roam_tbl_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1232 {
1233     WMI_TARGET_ROAM_TBL *reply;
1234
1235     if (len < sizeof(*reply)) {
1236         return A_EINVAL;
1237     }
1238     reply = (WMI_TARGET_ROAM_TBL *)datap;
1239     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1240
1241     A_WMI_ROAM_TABLE_EVENT(wmip->wmi_devt, reply);
1242
1243     return A_OK;
1244 }
1245
1246 static A_STATUS
1247 wmi_roam_data_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1248 {
1249     WMI_TARGET_ROAM_DATA *reply;
1250
1251     if (len < sizeof(*reply)) {
1252         return A_EINVAL;
1253     }
1254     reply = (WMI_TARGET_ROAM_DATA *)datap;
1255     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1256
1257     A_WMI_ROAM_DATA_EVENT(wmip->wmi_devt, reply);
1258
1259     return A_OK;
1260 }
1261
1262 static A_STATUS
1263 wmi_txRetryErrEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1264 {
1265     WMI_TX_RETRY_ERR_EVENT *reply;
1266
1267     if (len < sizeof(*reply)) {
1268         return A_EINVAL;
1269     }
1270     reply = (WMI_TX_RETRY_ERR_EVENT *)datap;
1271     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1272
1273     A_WMI_TX_RETRY_ERR_EVENT(wmip->wmi_devt);
1274
1275     return A_OK;
1276 }
1277
1278 static A_STATUS
1279 wmi_snrThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1280 {
1281     WMI_SNR_THRESHOLD_EVENT *reply;
1282
1283     if (len < sizeof(*reply)) {
1284         return A_EINVAL;
1285     }
1286     reply = (WMI_SNR_THRESHOLD_EVENT *)datap;
1287     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1288
1289     A_WMI_SNR_THRESHOLD_EVENT_RX(wmip->wmi_devt, reply->range, reply->snr);
1290
1291     return A_OK;
1292 }
1293
1294 static A_STATUS
1295 wmi_lqThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1296 {
1297     WMI_LQ_THRESHOLD_EVENT *reply;
1298
1299     if (len < sizeof(*reply)) {
1300         return A_EINVAL;
1301     }
1302     reply = (WMI_LQ_THRESHOLD_EVENT *)datap;
1303     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1304
1305     A_WMI_LQ_THRESHOLD_EVENT_RX(wmip->wmi_devt, reply->range, reply->lq);
1306
1307     return A_OK;
1308 }
1309
1310 static A_STATUS
1311 wmi_aplistEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1312 {
1313     A_UINT16 ap_info_entry_size;
1314     WMI_APLIST_EVENT *ev = (WMI_APLIST_EVENT *)datap;
1315     WMI_AP_INFO_V1 *ap_info_v1;
1316     A_UINT8 i;
1317
1318     if (len < sizeof(WMI_APLIST_EVENT)) {
1319         return A_EINVAL;
1320     }
1321
1322     if (ev->apListVer == APLIST_VER1) {
1323         ap_info_entry_size = sizeof(WMI_AP_INFO_V1);
1324         ap_info_v1 = (WMI_AP_INFO_V1 *)ev->apList;
1325     } else {
1326         return A_EINVAL;
1327     }
1328
1329     AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Number of APs in APLIST Event is %d\n", ev->numAP));
1330     if (len < (int)(sizeof(WMI_APLIST_EVENT) +
1331               (ev->numAP - 1) * ap_info_entry_size))
1332     {
1333         return A_EINVAL;
1334     }
1335
1336     /*
1337      * AP List Ver1 Contents
1338      */
1339     for (i = 0; i < ev->numAP; i++) {
1340         AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("AP#%d BSSID %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x "\
1341                     "Channel %d\n", i,
1342                    ap_info_v1->bssid[0], ap_info_v1->bssid[1],
1343                    ap_info_v1->bssid[2], ap_info_v1->bssid[3],
1344                    ap_info_v1->bssid[4], ap_info_v1->bssid[5],
1345                    ap_info_v1->channel));
1346         ap_info_v1++;
1347     }
1348     return A_OK;
1349 }
1350
1351 static A_STATUS
1352 wmi_dbglog_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1353 {
1354     A_UINT32 dropped;
1355
1356     dropped = *((A_UINT32 *)datap);
1357     datap += sizeof(dropped);
1358     len -= sizeof(dropped);
1359     A_WMI_DBGLOG_EVENT(wmip->wmi_devt, dropped, datap, len);
1360     return A_OK;
1361 }
1362
1363 #ifdef CONFIG_HOST_GPIO_SUPPORT
1364 static A_STATUS
1365 wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1366 {
1367     WMIX_GPIO_INTR_EVENT *gpio_intr = (WMIX_GPIO_INTR_EVENT *)datap;
1368
1369     A_DPRINTF(DBG_WMI,
1370         (DBGFMT "Enter - intrmask=0x%x input=0x%x.\n", DBGARG,
1371         gpio_intr->intr_mask, gpio_intr->input_values));
1372
1373     A_WMI_GPIO_INTR_RX(gpio_intr->intr_mask, gpio_intr->input_values);
1374
1375     return A_OK;
1376 }
1377
1378 static A_STATUS
1379 wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1380 {
1381     WMIX_GPIO_DATA_EVENT *gpio_data = (WMIX_GPIO_DATA_EVENT *)datap;
1382
1383     A_DPRINTF(DBG_WMI,
1384         (DBGFMT "Enter - reg=%d value=0x%x\n", DBGARG,
1385         gpio_data->reg_id, gpio_data->value));
1386
1387     A_WMI_GPIO_DATA_RX(gpio_data->reg_id, gpio_data->value);
1388
1389     return A_OK;
1390 }
1391
1392 static A_STATUS
1393 wmi_gpio_ack_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
1394 {
1395     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1396
1397     A_WMI_GPIO_ACK_RX();
1398
1399     return A_OK;
1400 }
1401 #endif /* CONFIG_HOST_GPIO_SUPPORT */
1402
1403 /*
1404  * Called to send a wmi command. Command specific data is already built
1405  * on osbuf and current osbuf->data points to it.
1406  */
1407 A_STATUS
1408 wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId,
1409                WMI_SYNC_FLAG syncflag)
1410 {
1411 #define IS_LONG_CMD(cmdId) ((cmdId == WMI_OPT_TX_FRAME_CMDID) || (cmdId == WMI_ADD_WOW_PATTERN_CMDID))
1412     WMI_CMD_HDR         *cHdr;
1413     WMI_PRI_STREAM_ID   streamID = WMI_CONTROL_PRI;
1414
1415     A_ASSERT(osbuf != NULL);
1416
1417     if (syncflag >= END_WMIFLAG) {
1418         return A_EINVAL;
1419     }
1420
1421     if ((syncflag == SYNC_BEFORE_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) {
1422         /*
1423          * We want to make sure all data currently queued is transmitted before
1424          * the cmd execution.  Establish a new sync point.
1425          */
1426         wmi_sync_point(wmip);
1427     }
1428
1429     if (A_NETBUF_PUSH(osbuf, sizeof(WMI_CMD_HDR)) != A_OK) {
1430         return A_NO_MEMORY;
1431     }
1432
1433     cHdr = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf);
1434     cHdr->commandId = cmdId;
1435
1436     /*
1437      * Send cmd, some via control pipe, others via data pipe
1438      */
1439     if (IS_LONG_CMD(cmdId)) {
1440         wmi_data_hdr_add(wmip, osbuf, CNTL_MSGTYPE);
1441         // TODO ... these can now go through the control endpoint via HTC 2.0
1442         streamID = WMI_BEST_EFFORT_PRI;
1443     }
1444     A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, streamID);
1445
1446     if ((syncflag == SYNC_AFTER_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) {
1447         /*
1448          * We want to make sure all new data queued waits for the command to
1449          * execute. Establish a new sync point.
1450          */
1451         wmi_sync_point(wmip);
1452     }
1453     return (A_OK);
1454 #undef IS_LONG_CMD
1455 }
1456
1457 A_STATUS
1458 wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId,
1459                   WMI_SYNC_FLAG syncflag)
1460 {
1461     WMIX_CMD_HDR     *cHdr;
1462
1463     if (A_NETBUF_PUSH(osbuf, sizeof(WMIX_CMD_HDR)) != A_OK) {
1464         return A_NO_MEMORY;
1465     }
1466
1467     cHdr = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf);
1468     cHdr->commandId = cmdId;
1469
1470     return wmi_cmd_send(wmip, osbuf, WMI_EXTENSION_CMDID, syncflag);
1471 }
1472
1473 A_STATUS
1474 wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType,
1475                 DOT11_AUTH_MODE dot11AuthMode, AUTH_MODE authMode,
1476                 CRYPTO_TYPE pairwiseCrypto, A_UINT8 pairwiseCryptoLen,
1477                 CRYPTO_TYPE groupCrypto,A_UINT8 groupCryptoLen,
1478                 int ssidLength, A_UCHAR *ssid,
1479                 A_UINT8 *bssid, A_UINT16 channel, A_UINT32 ctrl_flags)
1480 {
1481     void *osbuf;
1482     WMI_CONNECT_CMD *cc;
1483
1484     if ((pairwiseCrypto == NONE_CRYPT) && (groupCrypto != NONE_CRYPT)) {
1485         return A_EINVAL;
1486     }
1487     if ((pairwiseCrypto != NONE_CRYPT) && (groupCrypto == NONE_CRYPT)) {
1488         return A_EINVAL;
1489     }
1490
1491     osbuf = A_NETBUF_ALLOC(sizeof(WMI_CONNECT_CMD));
1492     if (osbuf == NULL) {
1493         return A_NO_MEMORY;
1494     }
1495
1496     A_NETBUF_PUT(osbuf, sizeof(WMI_CONNECT_CMD));
1497
1498     cc = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf));
1499     A_MEMZERO(cc, sizeof(*cc));
1500
1501     A_MEMCPY(cc->ssid, ssid, ssidLength);
1502     cc->ssidLength          = ssidLength;
1503     cc->networkType         = netType;
1504     cc->dot11AuthMode       = dot11AuthMode;
1505     cc->authMode            = authMode;
1506     cc->pairwiseCryptoType  = pairwiseCrypto;
1507     cc->pairwiseCryptoLen   = pairwiseCryptoLen;
1508     cc->groupCryptoType     = groupCrypto;
1509     cc->groupCryptoLen      = groupCryptoLen;
1510     cc->channel             = channel;
1511     cc->ctrl_flags          = ctrl_flags;
1512
1513     if (bssid != NULL) {
1514         A_MEMCPY(cc->bssid, bssid, ATH_MAC_LEN);
1515     }
1516     if (wmi_set_keepalive_cmd(wmip, wmip->wmi_keepaliveInterval) != A_OK) {
1517         return(A_ERROR);
1518     }
1519
1520     return (wmi_cmd_send(wmip, osbuf, WMI_CONNECT_CMDID, NO_SYNC_WMIFLAG));
1521 }
1522
1523 A_STATUS
1524 wmi_reconnect_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT16 channel)
1525 {
1526     void *osbuf;
1527     WMI_RECONNECT_CMD *cc;
1528
1529     osbuf = A_NETBUF_ALLOC(sizeof(WMI_RECONNECT_CMD));
1530     if (osbuf == NULL) {
1531         return A_NO_MEMORY;
1532     }
1533
1534     A_NETBUF_PUT(osbuf, sizeof(WMI_RECONNECT_CMD));
1535
1536     cc = (WMI_RECONNECT_CMD *)(A_NETBUF_DATA(osbuf));
1537     A_MEMZERO(cc, sizeof(*cc));
1538
1539     cc->channel = channel;
1540
1541     if (bssid != NULL) {
1542         A_MEMCPY(cc->bssid, bssid, ATH_MAC_LEN);
1543     }
1544
1545     return (wmi_cmd_send(wmip, osbuf, WMI_RECONNECT_CMDID, NO_SYNC_WMIFLAG));
1546 }
1547
1548 A_STATUS
1549 wmi_disconnect_cmd(struct wmi_t *wmip)
1550 {
1551     void *osbuf;
1552     A_STATUS status;
1553
1554     osbuf = A_NETBUF_ALLOC(0);      /* no payload */
1555     if (osbuf == NULL) {
1556         return A_NO_MEMORY;
1557     }
1558
1559     /* Bug fix for 24817(elevator bug) - the disconnect command does not
1560        need to do a SYNC before.*/
1561     status = (wmi_cmd_send(wmip, osbuf, WMI_DISCONNECT_CMDID,
1562                          NO_SYNC_WMIFLAG));
1563
1564     return status;
1565 }
1566
1567 A_STATUS
1568 wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType,
1569                   A_BOOL forceFgScan, A_BOOL isLegacy,
1570                   A_UINT32 homeDwellTime, A_UINT32 forceScanInterval)
1571 {
1572     void *osbuf;
1573     WMI_START_SCAN_CMD *sc;
1574
1575     if ((scanType != WMI_LONG_SCAN) && (scanType != WMI_SHORT_SCAN)) {
1576         return A_EINVAL;
1577     }
1578
1579     osbuf = A_NETBUF_ALLOC(sizeof(*sc));
1580     if (osbuf == NULL) {
1581         return A_NO_MEMORY;
1582     }
1583
1584     A_NETBUF_PUT(osbuf, sizeof(*sc));
1585
1586     sc = (WMI_START_SCAN_CMD *)(A_NETBUF_DATA(osbuf));
1587     sc->scanType = scanType;
1588     sc->forceFgScan = forceFgScan;
1589     sc->isLegacy = isLegacy;
1590     sc->homeDwellTime = homeDwellTime;
1591     sc->forceScanInterval = forceScanInterval;
1592
1593     return (wmi_cmd_send(wmip, osbuf, WMI_START_SCAN_CMDID, NO_SYNC_WMIFLAG));
1594 }
1595
1596 A_STATUS
1597 wmi_scanparams_cmd(struct wmi_t *wmip, A_UINT16 fg_start_sec,
1598                    A_UINT16 fg_end_sec, A_UINT16 bg_sec,
1599                    A_UINT16 minact_chdw_msec, A_UINT16 maxact_chdw_msec,
1600                    A_UINT16 pas_chdw_msec,
1601                    A_UINT8 shScanRatio, A_UINT8 scanCtrlFlags,
1602                    A_UINT32 max_dfsch_act_time)
1603 {
1604     void *osbuf;
1605     WMI_SCAN_PARAMS_CMD *sc;
1606
1607     osbuf = A_NETBUF_ALLOC(sizeof(*sc));
1608     if (osbuf == NULL) {
1609         return A_NO_MEMORY;
1610     }
1611
1612     A_NETBUF_PUT(osbuf, sizeof(*sc));
1613
1614     sc = (WMI_SCAN_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
1615     A_MEMZERO(sc, sizeof(*sc));
1616     sc->fg_start_period  = fg_start_sec;
1617     sc->fg_end_period    = fg_end_sec;
1618     sc->bg_period        = bg_sec;
1619     sc->minact_chdwell_time = minact_chdw_msec;
1620     sc->maxact_chdwell_time = maxact_chdw_msec;
1621     sc->pas_chdwell_time = pas_chdw_msec;
1622     sc->shortScanRatio   = shScanRatio;
1623     sc->scanCtrlFlags    = scanCtrlFlags;
1624     sc->max_dfsch_act_time = max_dfsch_act_time;
1625
1626     return (wmi_cmd_send(wmip, osbuf, WMI_SET_SCAN_PARAMS_CMDID,
1627                          NO_SYNC_WMIFLAG));
1628 }
1629
1630 A_STATUS
1631 wmi_bssfilter_cmd(struct wmi_t *wmip, A_UINT8 filter, A_UINT32 ieMask)
1632 {
1633     void *osbuf;
1634     WMI_BSS_FILTER_CMD *cmd;
1635
1636     if (filter >= LAST_BSS_FILTER) {
1637         return A_EINVAL;
1638     }
1639
1640     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
1641     if (osbuf == NULL) {
1642         return A_NO_MEMORY;
1643     }
1644
1645     A_NETBUF_PUT(osbuf, sizeof(*cmd));
1646
1647     cmd = (WMI_BSS_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
1648     A_MEMZERO(cmd, sizeof(*cmd));
1649     cmd->bssFilter = filter;
1650     cmd->ieMask = ieMask;
1651
1652     return (wmi_cmd_send(wmip, osbuf, WMI_SET_BSS_FILTER_CMDID,
1653                          NO_SYNC_WMIFLAG));
1654 }
1655
1656 A_STATUS
1657 wmi_probedSsid_cmd(struct wmi_t *wmip, A_UINT8 index, A_UINT8 flag,
1658                    A_UINT8 ssidLength, A_UCHAR *ssid)
1659 {
1660     void *osbuf;
1661     WMI_PROBED_SSID_CMD *cmd;
1662
1663     if (index > MAX_PROBED_SSID_INDEX) {
1664         return A_EINVAL;
1665     }
1666     if (ssidLength > sizeof(cmd->ssid)) {
1667         return A_EINVAL;
1668     }
1669     if ((flag & (DISABLE_SSID_FLAG | ANY_SSID_FLAG)) && (ssidLength > 0)) {
1670         return A_EINVAL;
1671     }
1672     if ((flag & SPECIFIC_SSID_FLAG) && !ssidLength) {
1673         return A_EINVAL;
1674     }
1675
1676     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
1677     if (osbuf == NULL) {
1678         return A_NO_MEMORY;
1679     }
1680
1681     A_NETBUF_PUT(osbuf, sizeof(*cmd));
1682
1683     cmd = (WMI_PROBED_SSID_CMD *)(A_NETBUF_DATA(osbuf));
1684     A_MEMZERO(cmd, sizeof(*cmd));
1685     cmd->entryIndex = index;
1686     cmd->flag       = flag;
1687     cmd->ssidLength = ssidLength;
1688     A_MEMCPY(cmd->ssid, ssid, ssidLength);
1689
1690     return (wmi_cmd_send(wmip, osbuf, WMI_SET_PROBED_SSID_CMDID,
1691                          NO_SYNC_WMIFLAG));
1692 }
1693
1694 A_STATUS
1695 wmi_listeninterval_cmd(struct wmi_t *wmip, A_UINT16 listenInterval, A_UINT16 listenBeacons)
1696 {
1697     void *osbuf;
1698     WMI_LISTEN_INT_CMD *cmd;
1699
1700     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
1701     if (osbuf == NULL) {
1702         return A_NO_MEMORY;
1703     }
1704
1705     A_NETBUF_PUT(osbuf, sizeof(*cmd));
1706
1707     cmd = (WMI_LISTEN_INT_CMD *)(A_NETBUF_DATA(osbuf));
1708     A_MEMZERO(cmd, sizeof(*cmd));
1709     cmd->listenInterval = listenInterval;
1710     cmd->numBeacons = listenBeacons;
1711
1712     return (wmi_cmd_send(wmip, osbuf, WMI_SET_LISTEN_INT_CMDID,
1713                          NO_SYNC_WMIFLAG));
1714 }
1715
1716 A_STATUS
1717 wmi_bmisstime_cmd(struct wmi_t *wmip, A_UINT16 bmissTime, A_UINT16 bmissBeacons)
1718 {
1719     void *osbuf;
1720     WMI_BMISS_TIME_CMD *cmd;
1721
1722     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
1723     if (osbuf == NULL) {
1724         return A_NO_MEMORY;
1725     }
1726
1727     A_NETBUF_PUT(osbuf, sizeof(*cmd));
1728
1729     cmd = (WMI_BMISS_TIME_CMD *)(A_NETBUF_DATA(osbuf));
1730     A_MEMZERO(cmd, sizeof(*cmd));
1731     cmd->bmissTime = bmissTime;
1732     cmd->numBeacons =  bmissBeacons;
1733
1734     return (wmi_cmd_send(wmip, osbuf, WMI_SET_BMISS_TIME_CMDID,
1735                          NO_SYNC_WMIFLAG));
1736 }
1737
1738 A_STATUS
1739 wmi_associnfo_cmd(struct wmi_t *wmip, A_UINT8 ieType,
1740                      A_UINT8 ieLen, A_UINT8 *ieInfo)
1741 {
1742     void *osbuf;
1743     WMI_SET_ASSOC_INFO_CMD *cmd;
1744     A_UINT16 cmdLen;
1745
1746     cmdLen = sizeof(*cmd) + ieLen - 1;
1747     osbuf = A_NETBUF_ALLOC(cmdLen);
1748     if (osbuf == NULL) {
1749         return A_NO_MEMORY;
1750     }
1751
1752     A_NETBUF_PUT(osbuf, cmdLen);
1753
1754     cmd = (WMI_SET_ASSOC_INFO_CMD *)(A_NETBUF_DATA(osbuf));
1755     A_MEMZERO(cmd, cmdLen);
1756     cmd->ieType = ieType;
1757     cmd->bufferSize = ieLen;
1758     A_MEMCPY(cmd->assocInfo, ieInfo, ieLen);
1759
1760     return (wmi_cmd_send(wmip, osbuf, WMI_SET_ASSOC_INFO_CMDID,
1761                          NO_SYNC_WMIFLAG));
1762 }
1763
1764 A_STATUS
1765 wmi_powermode_cmd(struct wmi_t *wmip, A_UINT8 powerMode)
1766 {
1767     void *osbuf;
1768     WMI_POWER_MODE_CMD *cmd;
1769
1770     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
1771     if (osbuf == NULL) {
1772         return A_NO_MEMORY;
1773     }
1774
1775     A_NETBUF_PUT(osbuf, sizeof(*cmd));
1776
1777     cmd = (WMI_POWER_MODE_CMD *)(A_NETBUF_DATA(osbuf));
1778     A_MEMZERO(cmd, sizeof(*cmd));
1779     cmd->powerMode = powerMode;
1780     wmip->wmi_powerMode = powerMode;
1781
1782     return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_MODE_CMDID,
1783                          NO_SYNC_WMIFLAG));
1784 }
1785
1786 A_STATUS
1787 wmi_ibsspmcaps_cmd(struct wmi_t *wmip, A_UINT8 pmEnable, A_UINT8 ttl,
1788                    A_UINT16 atim_windows, A_UINT16 timeout_value)
1789 {
1790     void *osbuf;
1791     WMI_IBSS_PM_CAPS_CMD *cmd;
1792
1793     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
1794     if (osbuf == NULL) {
1795         return A_NO_MEMORY;
1796     }
1797
1798     A_NETBUF_PUT(osbuf, sizeof(*cmd));
1799
1800     cmd = (WMI_IBSS_PM_CAPS_CMD *)(A_NETBUF_DATA(osbuf));
1801     A_MEMZERO(cmd, sizeof(*cmd));
1802     cmd->power_saving = pmEnable;
1803     cmd->ttl = ttl;
1804     cmd->atim_windows = atim_windows;
1805     cmd->timeout_value = timeout_value;
1806
1807     return (wmi_cmd_send(wmip, osbuf, WMI_SET_IBSS_PM_CAPS_CMDID,
1808                          NO_SYNC_WMIFLAG));
1809 }
1810
1811 A_STATUS
1812 wmi_pmparams_cmd(struct wmi_t *wmip, A_UINT16 idlePeriod,
1813                  A_UINT16 psPollNum, A_UINT16 dtimPolicy)
1814 {
1815     void *osbuf;
1816     WMI_POWER_PARAMS_CMD *pm;
1817
1818     osbuf = A_NETBUF_ALLOC(sizeof(*pm));
1819     if (osbuf == NULL) {
1820         return A_NO_MEMORY;
1821     }
1822
1823     A_NETBUF_PUT(osbuf, sizeof(*pm));
1824
1825     pm = (WMI_POWER_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
1826     A_MEMZERO(pm, sizeof(*pm));
1827     pm->idle_period   = idlePeriod;
1828     pm->pspoll_number = psPollNum;
1829     pm->dtim_policy   = dtimPolicy;
1830
1831     return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_PARAMS_CMDID,
1832                          NO_SYNC_WMIFLAG));
1833 }
1834
1835 A_STATUS
1836 wmi_disctimeout_cmd(struct wmi_t *wmip, A_UINT8 timeout)
1837 {
1838     void *osbuf;
1839     WMI_DISC_TIMEOUT_CMD *cmd;
1840
1841     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
1842     if (osbuf == NULL) {
1843         return A_NO_MEMORY;
1844     }
1845
1846     A_NETBUF_PUT(osbuf, sizeof(*cmd));
1847
1848     cmd = (WMI_DISC_TIMEOUT_CMD *)(A_NETBUF_DATA(osbuf));
1849     A_MEMZERO(cmd, sizeof(*cmd));
1850     cmd->disconnectTimeout = timeout;
1851
1852     return (wmi_cmd_send(wmip, osbuf, WMI_SET_DISC_TIMEOUT_CMDID,
1853                          NO_SYNC_WMIFLAG));
1854 }
1855
1856 A_STATUS
1857 wmi_addKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex, CRYPTO_TYPE keyType,
1858                A_UINT8 keyUsage, A_UINT8 keyLength, A_UINT8 *keyRSC,
1859                A_UINT8 *keyMaterial, A_UINT8 key_op_ctrl,
1860                WMI_SYNC_FLAG sync_flag)
1861 {
1862     void *osbuf;
1863     WMI_ADD_CIPHER_KEY_CMD *cmd;
1864
1865     if ((keyIndex > WMI_MAX_KEY_INDEX) || (keyLength > WMI_MAX_KEY_LEN) ||
1866         (keyMaterial == NULL))
1867     {
1868         return A_EINVAL;
1869     }
1870
1871     if ((WEP_CRYPT != keyType) && (NULL == keyRSC)) {
1872         return A_EINVAL;
1873     }
1874
1875     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
1876     if (osbuf == NULL) {
1877         return A_NO_MEMORY;
1878     }
1879
1880     A_NETBUF_PUT(osbuf, sizeof(*cmd));
1881
1882     cmd = (WMI_ADD_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf));
1883     A_MEMZERO(cmd, sizeof(*cmd));
1884     cmd->keyIndex = keyIndex;
1885     cmd->keyType  = keyType;
1886     cmd->keyUsage = keyUsage;
1887     cmd->keyLength = keyLength;
1888     A_MEMCPY(cmd->key, keyMaterial, keyLength);
1889     if (NULL != keyRSC) {
1890         A_MEMCPY(cmd->keyRSC, keyRSC, sizeof(cmd->keyRSC));
1891     }
1892     cmd->key_op_ctrl = key_op_ctrl;
1893
1894     return (wmi_cmd_send(wmip, osbuf, WMI_ADD_CIPHER_KEY_CMDID, sync_flag));
1895 }
1896
1897 A_STATUS
1898 wmi_add_krk_cmd(struct wmi_t *wmip, A_UINT8 *krk)
1899 {
1900     void *osbuf;
1901     WMI_ADD_KRK_CMD *cmd;
1902
1903     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
1904
1905     if (osbuf == NULL) {
1906         return A_NO_MEMORY;
1907     }
1908
1909     A_NETBUF_PUT(osbuf, sizeof(*cmd));
1910
1911     cmd = (WMI_ADD_KRK_CMD *)(A_NETBUF_DATA(osbuf));
1912     A_MEMZERO(cmd, sizeof(*cmd));
1913     A_MEMCPY(cmd->krk, krk, WMI_KRK_LEN);
1914
1915     return (wmi_cmd_send(wmip, osbuf, WMI_ADD_KRK_CMDID, NO_SYNC_WMIFLAG));
1916 }
1917
1918 A_STATUS
1919 wmi_delete_krk_cmd(struct wmi_t *wmip)
1920 {
1921     void *osbuf;
1922
1923     osbuf = A_NETBUF_ALLOC(0);
1924
1925     if (osbuf == NULL) {
1926         return A_NO_MEMORY;
1927     }
1928
1929     return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_KRK_CMDID, NO_SYNC_WMIFLAG));
1930 }
1931
1932 A_STATUS
1933 wmi_deleteKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex)
1934 {
1935     void *osbuf;
1936     WMI_DELETE_CIPHER_KEY_CMD *cmd;
1937
1938     if (keyIndex > WMI_MAX_KEY_INDEX) {
1939         return A_EINVAL;
1940     }
1941
1942     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
1943     if (osbuf == NULL) {
1944         return A_NO_MEMORY;
1945     }
1946
1947     A_NETBUF_PUT(osbuf, sizeof(*cmd));
1948
1949     cmd = (WMI_DELETE_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf));
1950     A_MEMZERO(cmd, sizeof(*cmd));
1951     cmd->keyIndex = keyIndex;
1952
1953     return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_CIPHER_KEY_CMDID,
1954                          NO_SYNC_WMIFLAG));
1955 }
1956
1957 A_STATUS
1958 wmi_setPmkid_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT8 *pmkId,
1959                  A_BOOL set)
1960 {
1961     void *osbuf;
1962     WMI_SET_PMKID_CMD *cmd;
1963
1964     if (bssid == NULL) {
1965         return A_EINVAL;
1966     }
1967
1968     if ((set == TRUE) && (pmkId == NULL)) {
1969         return A_EINVAL;
1970     }
1971
1972     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
1973     if (osbuf == NULL) {
1974         return A_NO_MEMORY;
1975     }
1976
1977     A_NETBUF_PUT(osbuf, sizeof(*cmd));
1978
1979     cmd = (WMI_SET_PMKID_CMD *)(A_NETBUF_DATA(osbuf));
1980     A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid));
1981     if (set == TRUE) {
1982         A_MEMCPY(cmd->pmkid, pmkId, sizeof(cmd->pmkid));
1983         cmd->enable = PMKID_ENABLE;
1984     } else {
1985         A_MEMZERO(cmd->pmkid, sizeof(cmd->pmkid));
1986         cmd->enable = PMKID_DISABLE;
1987     }
1988
1989     return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_CMDID, NO_SYNC_WMIFLAG));
1990 }
1991
1992 A_STATUS
1993 wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, A_BOOL en)
1994 {
1995     void *osbuf;
1996     WMI_SET_TKIP_COUNTERMEASURES_CMD *cmd;
1997
1998     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
1999     if (osbuf == NULL) {
2000         return A_NO_MEMORY;
2001     }
2002
2003     A_NETBUF_PUT(osbuf, sizeof(*cmd));
2004
2005     cmd = (WMI_SET_TKIP_COUNTERMEASURES_CMD *)(A_NETBUF_DATA(osbuf));
2006     cmd->cm_en = (en == TRUE)? WMI_TKIP_CM_ENABLE : WMI_TKIP_CM_DISABLE;
2007
2008     return (wmi_cmd_send(wmip, osbuf, WMI_SET_TKIP_COUNTERMEASURES_CMDID,
2009             NO_SYNC_WMIFLAG));
2010 }
2011
2012 A_STATUS
2013 wmi_set_akmp_params_cmd(struct wmi_t *wmip,
2014                         WMI_SET_AKMP_PARAMS_CMD *akmpParams)
2015 {
2016     void *osbuf;
2017     WMI_SET_AKMP_PARAMS_CMD *cmd;
2018
2019     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2020     if (osbuf == NULL) {
2021         return A_NO_MEMORY;
2022     }
2023
2024     A_NETBUF_PUT(osbuf, sizeof(*cmd));
2025     cmd = (WMI_SET_AKMP_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
2026     cmd->akmpInfo = akmpParams->akmpInfo;
2027
2028     return (wmi_cmd_send(wmip, osbuf, WMI_SET_AKMP_PARAMS_CMDID,
2029             NO_SYNC_WMIFLAG));
2030 }
2031
2032 A_STATUS
2033 wmi_set_pmkid_list_cmd(struct wmi_t *wmip,
2034                        WMI_SET_PMKID_LIST_CMD *pmkInfo)
2035 {
2036     void *osbuf;
2037     WMI_SET_PMKID_LIST_CMD *cmd;
2038     A_UINT16 cmdLen;
2039     A_UINT8 i;
2040
2041     cmdLen = sizeof(pmkInfo->numPMKID) +
2042              pmkInfo->numPMKID * sizeof(WMI_PMKID);
2043
2044     osbuf = A_NETBUF_ALLOC(cmdLen);
2045
2046     if (osbuf == NULL) {
2047         return A_NO_MEMORY;
2048     }
2049
2050     A_NETBUF_PUT(osbuf, cmdLen);
2051     cmd = (WMI_SET_PMKID_LIST_CMD *)(A_NETBUF_DATA(osbuf));
2052     cmd->numPMKID = pmkInfo->numPMKID;
2053
2054     for (i = 0; i < cmd->numPMKID; i++) {
2055         A_MEMCPY(&cmd->pmkidList[i], &pmkInfo->pmkidList[i],
2056                  WMI_PMKID_LEN);
2057     }
2058
2059     return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_LIST_CMDID,
2060             NO_SYNC_WMIFLAG));
2061 }
2062
2063 A_STATUS
2064 wmi_get_pmkid_list_cmd(struct wmi_t *wmip)
2065 {
2066     void *osbuf;
2067
2068     osbuf = A_NETBUF_ALLOC(0);      /* no payload */
2069     if (osbuf == NULL) {
2070         return A_NO_MEMORY;
2071     }
2072
2073     return (wmi_cmd_send(wmip, osbuf, WMI_GET_PMKID_LIST_CMDID,
2074                          NO_SYNC_WMIFLAG));
2075 }
2076
2077 A_STATUS
2078 wmi_dataSync_send(struct wmi_t *wmip, void *osbuf, WMI_PRI_STREAM_ID streamID)
2079 {
2080     WMI_DATA_HDR     *dtHdr;
2081
2082     A_ASSERT(streamID != WMI_CONTROL_PRI);
2083     A_ASSERT(osbuf != NULL);
2084
2085     if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != A_OK) {
2086         return A_NO_MEMORY;
2087     }
2088
2089     dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf);
2090     dtHdr->info =
2091       (SYNC_MSGTYPE & WMI_DATA_HDR_MSG_TYPE_MASK) << WMI_DATA_HDR_MSG_TYPE_SHIFT;
2092
2093     A_DPRINTF(DBG_WMI, (DBGFMT "Enter - streamID %d\n", DBGARG, streamID));
2094
2095     return (A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, streamID));
2096 }
2097
2098 typedef struct _WMI_DATA_SYNC_BUFS {
2099     A_UINT8            trafficClass;
2100     void               *osbuf;
2101 }WMI_DATA_SYNC_BUFS;
2102
2103 static A_STATUS
2104 wmi_sync_point(struct wmi_t *wmip)
2105 {
2106         void *cmd_osbuf;
2107     WMI_DATA_SYNC_BUFS dataSyncBufs[WMM_NUM_AC];
2108         A_UINT8 i,numPriStreams=0;
2109         A_STATUS status;
2110
2111         A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2112
2113     memset(dataSyncBufs,0,sizeof(dataSyncBufs));
2114
2115     /* lock out while we walk through the priority list and assemble our local array */
2116     LOCK_WMI(wmip);
2117
2118     for (i=0; i < WMM_NUM_AC ; i++) {
2119                 if (wmip->wmi_fatPipeExists & (1 << i)) {
2120             numPriStreams++;
2121             dataSyncBufs[numPriStreams-1].trafficClass = i;
2122         }
2123     }
2124
2125     UNLOCK_WMI(wmip);
2126
2127     /* dataSyncBufs is now filled with entries (starting at index 0) containing valid streamIDs */
2128
2129     do {
2130             /*
2131              * We allocate all network buffers needed so we will be able to
2132              * send all required frames.
2133              */
2134             cmd_osbuf = A_NETBUF_ALLOC(0);      /* no payload */
2135             if (cmd_osbuf == NULL) {
2136                     status = A_NO_MEMORY;
2137             break;
2138             }
2139
2140             for (i=0; i < numPriStreams ; i++) {
2141                 dataSyncBufs[i].osbuf = A_NETBUF_ALLOC(0);
2142             if (dataSyncBufs[i].osbuf == NULL) {
2143                 status = A_NO_MEMORY;
2144                 break;
2145             }
2146             } //end for
2147
2148             /*
2149              * Send sync cmd followed by sync data messages on all endpoints being
2150              * used
2151              */
2152             status = wmi_cmd_send(wmip, cmd_osbuf, WMI_SYNCHRONIZE_CMDID,
2153                                                   NO_SYNC_WMIFLAG);
2154
2155         if (A_FAILED(status)) {
2156             break;
2157         }
2158             /* cmd buffer sent, we no longer own it */
2159         cmd_osbuf = NULL;
2160
2161                 for(i=0; i < numPriStreams; i++) {
2162             A_ASSERT(dataSyncBufs[i].osbuf != NULL);
2163
2164             status = wmi_dataSync_send(wmip, dataSyncBufs[i].osbuf,
2165                         WMI_ACCESSCATEGORY_WMISTREAM(wmip,dataSyncBufs[i].trafficClass));
2166
2167             if (A_FAILED(status)) {
2168                 break;
2169             }
2170             /* we don't own this buffer anymore, NULL it out of the array so it
2171              * won't get cleaned up */
2172             dataSyncBufs[i].osbuf = NULL;
2173                 } //end for
2174
2175     } while(FALSE);
2176
2177     /* free up any resources left over (possibly due to an error) */
2178
2179     if (cmd_osbuf != NULL) {
2180         A_NETBUF_FREE(cmd_osbuf);
2181     }
2182
2183     for (i = 0; i < numPriStreams; i++) {
2184         if (dataSyncBufs[i].osbuf != NULL) {
2185             A_NETBUF_FREE(dataSyncBufs[i].osbuf);
2186         }
2187     }
2188
2189         return (status);
2190 }
2191
2192 A_STATUS
2193 wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *params)
2194 {
2195     void *osbuf;
2196     WMI_CREATE_PSTREAM_CMD *cmd;
2197         A_UINT16 activeTsids=0;
2198     A_UINT8 fatPipeExistsForAC=0;
2199
2200     /* Validate all the parameters. */
2201     if( !((params->userPriority < 8) &&
2202          (params->userPriority <= 0x7) &&
2203          (convert_userPriority_to_trafficClass(params->userPriority) == params->trafficClass)  &&
2204          (params->trafficDirection == UPLINK_TRAFFIC ||
2205             params->trafficDirection == DNLINK_TRAFFIC ||
2206             params->trafficDirection == BIDIR_TRAFFIC) &&
2207          (params->trafficType == TRAFFIC_TYPE_APERIODIC ||
2208             params->trafficType == TRAFFIC_TYPE_PERIODIC ) &&
2209          (params->voicePSCapability == DISABLE_FOR_THIS_AC  ||
2210             params->voicePSCapability == ENABLE_FOR_THIS_AC ||
2211             params->voicePSCapability == ENABLE_FOR_ALL_AC) &&
2212          (params->tsid == WMI_IMPLICIT_PSTREAM || params->tsid <= WMI_MAX_THINSTREAM)) )
2213     {
2214         return  A_EINVAL;
2215     }
2216
2217     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2218     if (osbuf == NULL) {
2219         return A_NO_MEMORY;
2220     }
2221
2222     A_NETBUF_PUT(osbuf, sizeof(*cmd));
2223
2224     A_DPRINTF(DBG_WMI,
2225         (DBGFMT "Sending create_pstream_cmd: ac=%d    tsid:%d\n", DBGARG,
2226         params->trafficClass, params->tsid));
2227
2228     cmd = (WMI_CREATE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf));
2229     A_MEMZERO(cmd, sizeof(*cmd));
2230     A_MEMCPY(cmd, params, sizeof(*cmd));
2231
2232         /* this is an implicitly created Fat pipe */
2233     if (params->tsid == WMI_IMPLICIT_PSTREAM) {
2234         LOCK_WMI(wmip);
2235         fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass));
2236         wmip->wmi_fatPipeExists |= (1<<params->trafficClass);
2237         UNLOCK_WMI(wmip);
2238     } else {
2239             /* this is an explicitly created thin stream within a fat pipe */
2240         LOCK_WMI(wmip);
2241         fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass));
2242         activeTsids = wmip->wmi_streamExistsForAC[params->trafficClass];
2243         wmip->wmi_streamExistsForAC[params->trafficClass] |= (1<<params->tsid);
2244             /* if a thinstream becomes active, the fat pipe automatically
2245             * becomes active
2246             */
2247         wmip->wmi_fatPipeExists |= (1<<params->trafficClass);
2248         UNLOCK_WMI(wmip);
2249     }
2250
2251         /* Indicate activty change to driver layer only if this is the
2252          * first TSID to get created in this AC explicitly or an implicit
2253          * fat pipe is getting created.
2254          */
2255     if (!fatPipeExistsForAC) {
2256         A_WMI_STREAM_TX_ACTIVE(wmip->wmi_devt, params->trafficClass);
2257     }
2258
2259     /* mike: should be SYNC_BEFORE_WMIFLAG */
2260     return (wmi_cmd_send(wmip, osbuf, WMI_CREATE_PSTREAM_CMDID,
2261                          NO_SYNC_WMIFLAG));
2262 }
2263
2264 A_STATUS
2265 wmi_delete_pstream_cmd(struct wmi_t *wmip, A_UINT8 trafficClass, A_UINT8 tsid)
2266 {
2267     void *osbuf;
2268     WMI_DELETE_PSTREAM_CMD *cmd;
2269     A_STATUS status;
2270         A_UINT16 activeTsids=0;
2271
2272     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2273     if (osbuf == NULL) {
2274         return A_NO_MEMORY;
2275     }
2276
2277     A_NETBUF_PUT(osbuf, sizeof(*cmd));
2278
2279     cmd = (WMI_DELETE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf));
2280     A_MEMZERO(cmd, sizeof(*cmd));
2281
2282     cmd->trafficClass = trafficClass;
2283     cmd->tsid = tsid;
2284
2285     LOCK_WMI(wmip);
2286     activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
2287     UNLOCK_WMI(wmip);
2288
2289         /* Check if the tsid was created & exists */
2290     if (!(activeTsids & (1<<tsid))) {
2291
2292         A_DPRINTF(DBG_WMI,
2293         (DBGFMT "TSID %d does'nt exist for trafficClass: %d\n", DBGARG, tsid, trafficClass));
2294             /* TODO: return a more appropriate err code */
2295         return A_ERROR;
2296     }
2297
2298     A_DPRINTF(DBG_WMI,
2299         (DBGFMT "Sending delete_pstream_cmd: trafficClass: %d tsid=%d\n", DBGARG, trafficClass, tsid));
2300
2301     status = (wmi_cmd_send(wmip, osbuf, WMI_DELETE_PSTREAM_CMDID,
2302                          SYNC_BEFORE_WMIFLAG));
2303
2304     LOCK_WMI(wmip);
2305     wmip->wmi_streamExistsForAC[trafficClass] &= ~(1<<tsid);
2306     activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
2307     UNLOCK_WMI(wmip);
2308
2309
2310         /* Indicate stream inactivity to driver layer only if all tsids
2311          * within this AC are deleted.
2312          */
2313     if(!activeTsids) {
2314         A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, trafficClass);
2315         wmip->wmi_fatPipeExists &= ~(1<<trafficClass);
2316     }
2317
2318     return status;
2319 }
2320
2321 /*
2322  * used to set the bit rate.  rate is in Kbps.  If rate == -1
2323  * then auto selection is used.
2324  */
2325 A_STATUS
2326 wmi_set_bitrate_cmd(struct wmi_t *wmip, A_INT32 rate)
2327 {
2328     void *osbuf;
2329     WMI_BIT_RATE_CMD *cmd;
2330     A_INT8 index;
2331
2332     if (rate != -1) {
2333         index = wmi_validate_bitrate(wmip, rate);
2334         if(index == A_EINVAL){
2335             return A_EINVAL;
2336         }
2337     } else {
2338         index = -1;
2339     }
2340
2341     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2342     if (osbuf == NULL) {
2343         return A_NO_MEMORY;
2344     }
2345
2346     A_NETBUF_PUT(osbuf, sizeof(*cmd));
2347
2348     cmd = (WMI_BIT_RATE_CMD *)(A_NETBUF_DATA(osbuf));
2349     A_MEMZERO(cmd, sizeof(*cmd));
2350
2351     cmd->rateIndex = index;
2352
2353     return (wmi_cmd_send(wmip, osbuf, WMI_SET_BITRATE_CMDID, NO_SYNC_WMIFLAG));
2354 }
2355
2356 A_STATUS
2357 wmi_get_bitrate_cmd(struct wmi_t *wmip)
2358 {
2359     void *osbuf;
2360
2361     osbuf = A_NETBUF_ALLOC(0);      /* no payload */
2362     if (osbuf == NULL) {
2363         return A_NO_MEMORY;
2364     }
2365
2366     return (wmi_cmd_send(wmip, osbuf, WMI_GET_BITRATE_CMDID, NO_SYNC_WMIFLAG));
2367 }
2368
2369 /*
2370  * Returns TRUE iff the given rate index is legal in the current PHY mode.
2371  */
2372 A_BOOL
2373 wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_UINT32 rateIndex)
2374 {
2375     WMI_PHY_MODE phyMode = wmip->wmi_phyMode;
2376     A_BOOL isValid = TRUE;
2377     switch(phyMode) {
2378         case WMI_11A_MODE:
2379             if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_A_SUPPORT_RATE_STOP)) {
2380                 isValid = FALSE;
2381             }
2382             break;
2383
2384         case WMI_11B_MODE:
2385             if ((rateIndex < MODE_B_SUPPORT_RATE_START) || (rateIndex > MODE_B_SUPPORT_RATE_STOP)) {
2386                 isValid = FALSE;
2387             }
2388             break;
2389
2390         case WMI_11GONLY_MODE:
2391             if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE_GONLY_SUPPORT_RATE_STOP)) {
2392                 isValid = FALSE;
2393             }
2394             break;
2395
2396         case WMI_11G_MODE:
2397         case WMI_11AG_MODE:
2398             if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_G_SUPPORT_RATE_STOP)) {
2399                 isValid = FALSE;
2400             }
2401             break;
2402
2403         default:
2404             A_ASSERT(FALSE);
2405             break;
2406     }
2407
2408     return isValid;
2409 }
2410
2411 A_INT8
2412 wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate)
2413 {
2414     A_INT8 i;
2415     if (rate != -1)
2416     {
2417         for (i=0;;i++)
2418         {
2419             if (wmi_rateTable[(A_UINT32) i] == 0) {
2420                 return A_EINVAL;
2421             }
2422             if (wmi_rateTable[(A_UINT32) i] == rate) {
2423                 break;
2424             }
2425         }
2426     }
2427     else{
2428      i = -1;
2429     }
2430
2431     if(wmi_is_bitrate_index_valid(wmip, i) != TRUE) {
2432         return A_EINVAL;
2433     }
2434
2435     return i;
2436 }
2437
2438 A_STATUS
2439 wmi_set_fixrates_cmd(struct wmi_t *wmip, A_INT16 fixRatesMask)
2440 {
2441     void *osbuf;
2442     WMI_FIX_RATES_CMD *cmd;
2443     A_UINT32 rateIndex;
2444
2445     /* Make sure all rates in the mask are valid in the current PHY mode */
2446     for(rateIndex = 0; rateIndex < MAX_NUMBER_OF_SUPPORT_RATES; rateIndex++) {
2447        if((1 << rateIndex) & (A_UINT32)fixRatesMask) {
2448             if(wmi_is_bitrate_index_valid(wmip, rateIndex) != TRUE) {
2449                 A_DPRINTF(DBG_WMI, (DBGFMT "Set Fix Rates command failed: Given rate is illegal in current PHY mode\n", DBGARG));
2450                 return A_EINVAL;
2451             }
2452        }
2453     }
2454
2455
2456     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2457     if (osbuf == NULL) {
2458         return A_NO_MEMORY;
2459     }
2460
2461     A_NETBUF_PUT(osbuf, sizeof(*cmd));
2462
2463     cmd = (WMI_FIX_RATES_CMD *)(A_NETBUF_DATA(osbuf));
2464     A_MEMZERO(cmd, sizeof(*cmd));
2465
2466     cmd->fixRateMask = fixRatesMask;
2467
2468     return (wmi_cmd_send(wmip, osbuf, WMI_SET_FIXRATES_CMDID, NO_SYNC_WMIFLAG));
2469 }
2470
2471 A_STATUS
2472 wmi_get_ratemask_cmd(struct wmi_t *wmip)
2473 {
2474     void *osbuf;
2475
2476     osbuf = A_NETBUF_ALLOC(0);      /* no payload */
2477     if (osbuf == NULL) {
2478         return A_NO_MEMORY;
2479     }
2480
2481     return (wmi_cmd_send(wmip, osbuf, WMI_GET_FIXRATES_CMDID, NO_SYNC_WMIFLAG));
2482 }
2483
2484 A_STATUS
2485 wmi_get_channelList_cmd(struct wmi_t *wmip)
2486 {
2487     void *osbuf;
2488
2489     osbuf = A_NETBUF_ALLOC(0);      /* no payload */
2490     if (osbuf == NULL) {
2491         return A_NO_MEMORY;
2492     }
2493
2494     return (wmi_cmd_send(wmip, osbuf, WMI_GET_CHANNEL_LIST_CMDID,
2495                          NO_SYNC_WMIFLAG));
2496 }
2497
2498 /*
2499  * used to generate a wmi sey channel Parameters cmd.
2500  * mode should always be specified and corresponds to the phy mode of the
2501  * wlan.
2502  * numChan should alway sbe specified. If zero indicates that all available
2503  * channels should be used.
2504  * channelList is an array of channel frequencies (in Mhz) which the radio
2505  * should limit its operation to.  It should be NULL if numChan == 0.  Size of
2506  * array should correspond to numChan entries.
2507  */
2508 A_STATUS
2509 wmi_set_channelParams_cmd(struct wmi_t *wmip, A_UINT8 scanParam,
2510                           WMI_PHY_MODE mode, A_INT8 numChan,
2511                           A_UINT16 *channelList)
2512 {
2513     void *osbuf;
2514     WMI_CHANNEL_PARAMS_CMD *cmd;
2515     A_INT8 size;
2516
2517     size = sizeof (*cmd);
2518
2519     if (numChan) {
2520         if (numChan > WMI_MAX_CHANNELS) {
2521             return A_EINVAL;
2522         }
2523         size += sizeof(A_UINT16) * (numChan - 1);
2524     }
2525
2526     osbuf = A_NETBUF_ALLOC(size);
2527     if (osbuf == NULL) {
2528         return A_NO_MEMORY;
2529     }
2530
2531     A_NETBUF_PUT(osbuf, size);
2532
2533     cmd = (WMI_CHANNEL_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
2534     A_MEMZERO(cmd, size);
2535
2536     wmip->wmi_phyMode = mode;
2537     cmd->scanParam   = scanParam;
2538     cmd->phyMode     = mode;
2539     cmd->numChannels = numChan;
2540     A_MEMCPY(cmd->channelList, channelList, numChan * sizeof(A_UINT16));
2541
2542     return (wmi_cmd_send(wmip, osbuf, WMI_SET_CHANNEL_PARAMS_CMDID,
2543                          NO_SYNC_WMIFLAG));
2544 }
2545
2546 A_STATUS
2547 wmi_set_rssi_threshold_params(struct wmi_t *wmip,
2548                               WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
2549 {
2550     void    *osbuf;
2551     A_INT8  size;
2552     WMI_RSSI_THRESHOLD_PARAMS_CMD *cmd;
2553     /* These values are in ascending order */
2554     if( rssiCmd->thresholdAbove6_Val <= rssiCmd->thresholdAbove5_Val ||
2555         rssiCmd->thresholdAbove5_Val <= rssiCmd->thresholdAbove4_Val ||
2556         rssiCmd->thresholdAbove4_Val <= rssiCmd->thresholdAbove3_Val ||
2557         rssiCmd->thresholdAbove3_Val <= rssiCmd->thresholdAbove2_Val ||
2558         rssiCmd->thresholdAbove2_Val <= rssiCmd->thresholdAbove1_Val ||
2559         rssiCmd->thresholdBelow6_Val <= rssiCmd->thresholdBelow5_Val ||
2560         rssiCmd->thresholdBelow5_Val <= rssiCmd->thresholdBelow4_Val ||
2561         rssiCmd->thresholdBelow4_Val <= rssiCmd->thresholdBelow3_Val ||
2562         rssiCmd->thresholdBelow3_Val <= rssiCmd->thresholdBelow2_Val ||
2563         rssiCmd->thresholdBelow2_Val <= rssiCmd->thresholdBelow1_Val) {
2564
2565         return A_EINVAL;
2566     }
2567
2568     size = sizeof (*cmd);
2569
2570     osbuf = A_NETBUF_ALLOC(size);
2571     if (osbuf == NULL) {
2572         return A_NO_MEMORY;
2573     }
2574
2575     A_NETBUF_PUT(osbuf, size);
2576
2577     cmd = (WMI_RSSI_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
2578     A_MEMZERO(cmd, size);
2579     A_MEMCPY(cmd, rssiCmd, sizeof(WMI_RSSI_THRESHOLD_PARAMS_CMD));
2580
2581     return (wmi_cmd_send(wmip, osbuf, WMI_RSSI_THRESHOLD_PARAMS_CMDID,
2582                             NO_SYNC_WMIFLAG));
2583 }
2584
2585 A_STATUS
2586 wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip,
2587                               WMI_SET_HOST_SLEEP_MODE_CMD *hostModeCmd)
2588 {
2589     void    *osbuf;
2590     A_INT8  size;
2591     WMI_SET_HOST_SLEEP_MODE_CMD *cmd;
2592
2593     if( hostModeCmd->awake == hostModeCmd->asleep) {
2594         return A_EINVAL;
2595     }
2596
2597     size = sizeof (*cmd);
2598
2599     osbuf = A_NETBUF_ALLOC(size);
2600     if (osbuf == NULL) {
2601         return A_NO_MEMORY;
2602     }
2603
2604     A_NETBUF_PUT(osbuf, size);
2605
2606     cmd = (WMI_SET_HOST_SLEEP_MODE_CMD *)(A_NETBUF_DATA(osbuf));
2607     A_MEMZERO(cmd, size);
2608     A_MEMCPY(cmd, hostModeCmd, sizeof(WMI_SET_HOST_SLEEP_MODE_CMD));
2609
2610     return (wmi_cmd_send(wmip, osbuf, WMI_SET_HOST_SLEEP_MODE_CMDID,
2611                             NO_SYNC_WMIFLAG));
2612 }
2613
2614 A_STATUS
2615 wmi_set_wow_mode_cmd(struct wmi_t *wmip,
2616                               WMI_SET_WOW_MODE_CMD *wowModeCmd)
2617 {
2618     void    *osbuf;
2619     A_INT8  size;
2620     WMI_SET_WOW_MODE_CMD *cmd;
2621
2622     size = sizeof (*cmd);
2623
2624     osbuf = A_NETBUF_ALLOC(size);
2625     if (osbuf == NULL) {
2626         return A_NO_MEMORY;
2627     }
2628
2629     A_NETBUF_PUT(osbuf, size);
2630
2631     cmd = (WMI_SET_WOW_MODE_CMD *)(A_NETBUF_DATA(osbuf));
2632     A_MEMZERO(cmd, size);
2633     A_MEMCPY(cmd, wowModeCmd, sizeof(WMI_SET_WOW_MODE_CMD));
2634
2635     return (wmi_cmd_send(wmip, osbuf, WMI_SET_WOW_MODE_CMDID,
2636                             NO_SYNC_WMIFLAG));
2637
2638 }
2639
2640 A_STATUS
2641 wmi_get_wow_list_cmd(struct wmi_t *wmip,
2642                               WMI_GET_WOW_LIST_CMD *wowListCmd)
2643 {
2644     void    *osbuf;
2645     A_INT8  size;
2646     WMI_GET_WOW_LIST_CMD *cmd;
2647
2648     size = sizeof (*cmd);
2649
2650     osbuf = A_NETBUF_ALLOC(size);
2651     if (osbuf == NULL) {
2652         return A_NO_MEMORY;
2653     }
2654
2655     A_NETBUF_PUT(osbuf, size);
2656
2657     cmd = (WMI_GET_WOW_LIST_CMD *)(A_NETBUF_DATA(osbuf));
2658     A_MEMZERO(cmd, size);
2659     A_MEMCPY(cmd, wowListCmd, sizeof(WMI_GET_WOW_LIST_CMD));
2660
2661     return (wmi_cmd_send(wmip, osbuf, WMI_GET_WOW_LIST_CMDID,
2662                             NO_SYNC_WMIFLAG));
2663
2664 }
2665
2666 static A_STATUS
2667 wmi_get_wow_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
2668 {
2669     WMI_GET_WOW_LIST_REPLY *reply;
2670
2671     if (len < sizeof(WMI_GET_WOW_LIST_REPLY)) {
2672         return A_EINVAL;
2673     }
2674     reply = (WMI_GET_WOW_LIST_REPLY *)datap;
2675
2676     A_WMI_WOW_LIST_EVENT(wmip->wmi_devt, reply->num_filters,
2677                           reply);
2678
2679     return A_OK;
2680 }
2681
2682 A_STATUS wmi_add_wow_pattern_cmd(struct wmi_t *wmip,
2683                                  WMI_ADD_WOW_PATTERN_CMD *addWowCmd,
2684                                  A_UINT8* pattern, A_UINT8* mask,
2685                                  A_UINT8 pattern_size)
2686 {
2687     void    *osbuf;
2688     A_INT8  size;
2689     WMI_ADD_WOW_PATTERN_CMD *cmd;
2690     A_UINT8 *filter_mask = NULL;
2691
2692     size = sizeof (*cmd);
2693
2694     size += ((2 * addWowCmd->filter_size)* sizeof(A_UINT8));
2695     osbuf = A_NETBUF_ALLOC(size);
2696     if (osbuf == NULL) {
2697         return A_NO_MEMORY;
2698     }
2699
2700     A_NETBUF_PUT(osbuf, size);
2701
2702     cmd = (WMI_ADD_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf));
2703     cmd->filter_list_id = addWowCmd->filter_list_id;
2704     cmd->filter_offset = addWowCmd->filter_offset;
2705     cmd->filter_size = addWowCmd->filter_size;
2706
2707     A_MEMCPY(cmd->filter, pattern, addWowCmd->filter_size);
2708
2709     filter_mask = (A_UINT8*)(cmd->filter + cmd->filter_size);
2710     A_MEMCPY(filter_mask, mask, addWowCmd->filter_size);
2711
2712
2713     return (wmi_cmd_send(wmip, osbuf, WMI_ADD_WOW_PATTERN_CMDID,
2714                             NO_SYNC_WMIFLAG));
2715 }
2716
2717 A_STATUS
2718 wmi_del_wow_pattern_cmd(struct wmi_t *wmip,
2719                               WMI_DEL_WOW_PATTERN_CMD *delWowCmd)
2720 {
2721     void    *osbuf;
2722     A_INT8  size;
2723     WMI_DEL_WOW_PATTERN_CMD *cmd;
2724
2725     size = sizeof (*cmd);
2726
2727     osbuf = A_NETBUF_ALLOC(size);
2728     if (osbuf == NULL) {
2729         return A_NO_MEMORY;
2730     }
2731
2732     A_NETBUF_PUT(osbuf, size);
2733
2734     cmd = (WMI_DEL_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf));
2735     A_MEMZERO(cmd, size);
2736     A_MEMCPY(cmd, delWowCmd, sizeof(WMI_DEL_WOW_PATTERN_CMD));
2737
2738     return (wmi_cmd_send(wmip, osbuf, WMI_DEL_WOW_PATTERN_CMDID,
2739                             NO_SYNC_WMIFLAG));
2740
2741 }
2742
2743 A_STATUS
2744 wmi_set_snr_threshold_params(struct wmi_t *wmip,
2745                              WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
2746 {
2747     void    *osbuf;
2748     A_INT8  size;
2749     WMI_SNR_THRESHOLD_PARAMS_CMD *cmd;
2750     /* These values are in ascending order */
2751     if( snrCmd->thresholdAbove4_Val <= snrCmd->thresholdAbove3_Val ||
2752         snrCmd->thresholdAbove3_Val <= snrCmd->thresholdAbove2_Val ||
2753         snrCmd->thresholdAbove2_Val <= snrCmd->thresholdAbove1_Val ||
2754         snrCmd->thresholdBelow4_Val <= snrCmd->thresholdBelow3_Val ||
2755         snrCmd->thresholdBelow3_Val <= snrCmd->thresholdBelow2_Val ||
2756         snrCmd->thresholdBelow2_Val <= snrCmd->thresholdBelow1_Val) {
2757
2758         return A_EINVAL;
2759     }
2760
2761     size = sizeof (*cmd);
2762
2763     osbuf = A_NETBUF_ALLOC(size);
2764     if (osbuf == NULL) {
2765         return A_NO_MEMORY;
2766     }
2767
2768     A_NETBUF_PUT(osbuf, size);
2769
2770     cmd = (WMI_SNR_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
2771     A_MEMZERO(cmd, size);
2772     A_MEMCPY(cmd, snrCmd, sizeof(WMI_SNR_THRESHOLD_PARAMS_CMD));
2773
2774     return (wmi_cmd_send(wmip, osbuf, WMI_SNR_THRESHOLD_PARAMS_CMDID,
2775                             NO_SYNC_WMIFLAG));
2776 }
2777
2778 A_STATUS
2779 wmi_clr_rssi_snr(struct wmi_t *wmip)
2780 {
2781     void    *osbuf;
2782
2783     osbuf = A_NETBUF_ALLOC(sizeof(int));
2784     if (osbuf == NULL) {
2785         return A_NO_MEMORY;
2786     }
2787
2788     return (wmi_cmd_send(wmip, osbuf, WMI_CLR_RSSI_SNR_CMDID,
2789                             NO_SYNC_WMIFLAG));
2790 }
2791
2792 A_STATUS
2793 wmi_set_lq_threshold_params(struct wmi_t *wmip,
2794                              WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd)
2795 {
2796     void    *osbuf;
2797     A_INT8  size;
2798     WMI_LQ_THRESHOLD_PARAMS_CMD *cmd;
2799     /* These values are in ascending order */
2800     if( lqCmd->thresholdAbove4_Val <= lqCmd->thresholdAbove3_Val ||
2801         lqCmd->thresholdAbove3_Val <= lqCmd->thresholdAbove2_Val ||
2802         lqCmd->thresholdAbove2_Val <= lqCmd->thresholdAbove1_Val ||
2803         lqCmd->thresholdBelow4_Val <= lqCmd->thresholdBelow3_Val ||
2804         lqCmd->thresholdBelow3_Val <= lqCmd->thresholdBelow2_Val ||
2805         lqCmd->thresholdBelow2_Val <= lqCmd->thresholdBelow1_Val ) {
2806
2807         return A_EINVAL;
2808     }
2809
2810     size = sizeof (*cmd);
2811
2812     osbuf = A_NETBUF_ALLOC(size);
2813     if (osbuf == NULL) {
2814         return A_NO_MEMORY;
2815     }
2816
2817     A_NETBUF_PUT(osbuf, size);
2818
2819     cmd = (WMI_LQ_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
2820     A_MEMZERO(cmd, size);
2821     A_MEMCPY(cmd, lqCmd, sizeof(WMI_LQ_THRESHOLD_PARAMS_CMD));
2822
2823     return (wmi_cmd_send(wmip, osbuf, WMI_LQ_THRESHOLD_PARAMS_CMDID,
2824                             NO_SYNC_WMIFLAG));
2825 }
2826
2827 A_STATUS
2828 wmi_set_error_report_bitmask(struct wmi_t *wmip, A_UINT32 mask)
2829 {
2830     void    *osbuf;
2831     A_INT8  size;
2832     WMI_TARGET_ERROR_REPORT_BITMASK *cmd;
2833
2834     size = sizeof (*cmd);
2835
2836     osbuf = A_NETBUF_ALLOC(size);
2837     if (osbuf == NULL) {
2838         return A_NO_MEMORY;
2839     }
2840
2841     A_NETBUF_PUT(osbuf, size);
2842
2843     cmd = (WMI_TARGET_ERROR_REPORT_BITMASK *)(A_NETBUF_DATA(osbuf));
2844     A_MEMZERO(cmd, size);
2845
2846     cmd->bitmask = mask;
2847
2848     return (wmi_cmd_send(wmip, osbuf, WMI_TARGET_ERROR_REPORT_BITMASK_CMDID,
2849                             NO_SYNC_WMIFLAG));
2850 }
2851
2852 A_STATUS
2853 wmi_get_challenge_resp_cmd(struct wmi_t *wmip, A_UINT32 cookie, A_UINT32 source)
2854 {
2855     void *osbuf;
2856     WMIX_HB_CHALLENGE_RESP_CMD *cmd;
2857
2858     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2859     if (osbuf == NULL) {
2860         return A_NO_MEMORY;
2861     }
2862
2863     A_NETBUF_PUT(osbuf, sizeof(*cmd));
2864
2865     cmd = (WMIX_HB_CHALLENGE_RESP_CMD *)(A_NETBUF_DATA(osbuf));
2866     cmd->cookie = cookie;
2867     cmd->source = source;
2868
2869     return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_HB_CHALLENGE_RESP_CMDID,
2870                               NO_SYNC_WMIFLAG));
2871 }
2872
2873 A_STATUS
2874 wmi_config_debug_module_cmd(struct wmi_t *wmip, A_UINT16 mmask,
2875                             A_UINT16 tsr, A_BOOL rep, A_UINT16 size,
2876                             A_UINT32 valid)
2877 {
2878     void *osbuf;
2879     WMIX_DBGLOG_CFG_MODULE_CMD *cmd;
2880
2881     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2882     if (osbuf == NULL) {
2883         return A_NO_MEMORY;
2884     }
2885
2886     A_NETBUF_PUT(osbuf, sizeof(*cmd));
2887
2888     cmd = (WMIX_DBGLOG_CFG_MODULE_CMD *)(A_NETBUF_DATA(osbuf));
2889     cmd->config.cfgmmask = mmask;
2890     cmd->config.cfgtsr = tsr;
2891     cmd->config.cfgrep = rep;
2892     cmd->config.cfgsize = size;
2893     cmd->config.cfgvalid = valid;
2894
2895     return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DBGLOG_CFG_MODULE_CMDID,
2896                               NO_SYNC_WMIFLAG));
2897 }
2898
2899 A_STATUS
2900 wmi_get_stats_cmd(struct wmi_t *wmip)
2901 {
2902     void *osbuf;
2903
2904     osbuf = A_NETBUF_ALLOC(0);      /* no payload */
2905     if (osbuf == NULL) {
2906         return A_NO_MEMORY;
2907     }
2908
2909     return (wmi_cmd_send(wmip, osbuf, WMI_GET_STATISTICS_CMDID,
2910                          NO_SYNC_WMIFLAG));
2911 }
2912
2913 A_STATUS
2914 wmi_addBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex, A_UINT8 *bssid)
2915 {
2916     void *osbuf;
2917     WMI_ADD_BAD_AP_CMD *cmd;
2918
2919     if ((bssid == NULL) || (apIndex > WMI_MAX_BAD_AP_INDEX)) {
2920         return A_EINVAL;
2921     }
2922
2923     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2924     if (osbuf == NULL) {
2925         return A_NO_MEMORY;
2926     }
2927
2928     A_NETBUF_PUT(osbuf, sizeof(*cmd));
2929
2930     cmd = (WMI_ADD_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf));
2931     cmd->badApIndex = apIndex;
2932     A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid));
2933
2934     return (wmi_cmd_send(wmip, osbuf, WMI_ADD_BAD_AP_CMDID, NO_SYNC_WMIFLAG));
2935 }
2936
2937 A_STATUS
2938 wmi_deleteBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex)
2939 {
2940     void *osbuf;
2941     WMI_DELETE_BAD_AP_CMD *cmd;
2942
2943     if (apIndex > WMI_MAX_BAD_AP_INDEX) {
2944         return A_EINVAL;
2945     }
2946
2947     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2948     if (osbuf == NULL) {
2949         return A_NO_MEMORY;
2950     }
2951
2952     A_NETBUF_PUT(osbuf, sizeof(*cmd));
2953
2954     cmd = (WMI_DELETE_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf));
2955     cmd->badApIndex = apIndex;
2956
2957     return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_BAD_AP_CMDID,
2958                          NO_SYNC_WMIFLAG));
2959 }
2960
2961 A_STATUS
2962 wmi_set_txPwr_cmd(struct wmi_t *wmip, A_UINT8 dbM)
2963 {
2964     void *osbuf;
2965     WMI_SET_TX_PWR_CMD *cmd;
2966
2967     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2968     if (osbuf == NULL) {
2969         return A_NO_MEMORY;
2970     }
2971
2972     A_NETBUF_PUT(osbuf, sizeof(*cmd));
2973
2974     cmd = (WMI_SET_TX_PWR_CMD *)(A_NETBUF_DATA(osbuf));
2975     cmd->dbM = dbM;
2976
2977     return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_PWR_CMDID, NO_SYNC_WMIFLAG));
2978 }
2979
2980 A_STATUS
2981 wmi_get_txPwr_cmd(struct wmi_t *wmip)
2982 {
2983     void *osbuf;
2984
2985     osbuf = A_NETBUF_ALLOC(0);      /* no payload */
2986     if (osbuf == NULL) {
2987         return A_NO_MEMORY;
2988     }
2989
2990     return (wmi_cmd_send(wmip, osbuf, WMI_GET_TX_PWR_CMDID, NO_SYNC_WMIFLAG));
2991 }
2992
2993 A_STATUS
2994 wmi_switch_radio(struct wmi_t *wmip, A_UINT8 on)
2995 {
2996         WMI_SCAN_PARAMS_CMD scParams = {0, 0, 0, 0, 0,
2997                                         WMI_SHORTSCANRATIO_DEFAULT,
2998                                         DEFAULT_SCAN_CTRL_FLAGS,
2999                                         0};
3000
3001         if (on) {
3002                 /* Enable foreground scanning */
3003                 if (wmi_scanparams_cmd(wmip, scParams.fg_start_period,
3004                                        scParams.fg_end_period,
3005                                        scParams.bg_period,
3006                                        scParams.minact_chdwell_time,
3007                                        scParams.maxact_chdwell_time,
3008                                        scParams.pas_chdwell_time,
3009                                        scParams.shortScanRatio,
3010                                        scParams.scanCtrlFlags,
3011                                        scParams.max_dfsch_act_time) != A_OK) {
3012                         return -EIO;
3013                 }
3014         } else {
3015                 wmi_disconnect_cmd(wmip);
3016                 if (wmi_scanparams_cmd(wmip, 0xFFFF, 0, 0, 0,
3017                                        0, 0, 0, 0xFF, 0) != A_OK) {
3018                         return -EIO;
3019                 }
3020         }
3021
3022         return A_OK;
3023 }
3024
3025
3026 A_UINT16
3027 wmi_get_mapped_qos_queue(struct wmi_t *wmip, A_UINT8 trafficClass)
3028 {
3029         A_UINT16 activeTsids=0;
3030
3031     LOCK_WMI(wmip);
3032     activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
3033     UNLOCK_WMI(wmip);
3034
3035     return activeTsids;
3036 }
3037
3038 A_STATUS
3039 wmi_get_roam_tbl_cmd(struct wmi_t *wmip)
3040 {
3041     void *osbuf;
3042
3043     osbuf = A_NETBUF_ALLOC(0);      /* no payload */
3044     if (osbuf == NULL) {
3045         return A_NO_MEMORY;
3046     }
3047
3048     return (wmi_cmd_send(wmip, osbuf, WMI_GET_ROAM_TBL_CMDID,
3049                          NO_SYNC_WMIFLAG));
3050 }
3051
3052 A_STATUS
3053 wmi_get_roam_data_cmd(struct wmi_t *wmip, A_UINT8 roamDataType)
3054 {
3055     void *osbuf;
3056     A_UINT32 size = sizeof(A_UINT8);
3057     WMI_TARGET_ROAM_DATA *cmd;
3058
3059     osbuf = A_NETBUF_ALLOC(size);      /* no payload */
3060     if (osbuf == NULL) {
3061         return A_NO_MEMORY;
3062     }
3063
3064     A_NETBUF_PUT(osbuf, size);
3065
3066     cmd = (WMI_TARGET_ROAM_DATA *)(A_NETBUF_DATA(osbuf));
3067     cmd->roamDataType = roamDataType;
3068
3069     return (wmi_cmd_send(wmip, osbuf, WMI_GET_ROAM_DATA_CMDID,
3070                          NO_SYNC_WMIFLAG));
3071 }
3072
3073 A_STATUS
3074 wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p,
3075                       A_UINT8 size)
3076 {
3077     void *osbuf;
3078     WMI_SET_ROAM_CTRL_CMD *cmd;
3079
3080     osbuf = A_NETBUF_ALLOC(size);
3081     if (osbuf == NULL) {
3082         return A_NO_MEMORY;
3083     }
3084
3085     A_NETBUF_PUT(osbuf, size);
3086
3087     cmd = (WMI_SET_ROAM_CTRL_CMD *)(A_NETBUF_DATA(osbuf));
3088     A_MEMZERO(cmd, size);
3089
3090     A_MEMCPY(cmd, p, size);
3091
3092     return (wmi_cmd_send(wmip, osbuf, WMI_SET_ROAM_CTRL_CMDID,
3093                          NO_SYNC_WMIFLAG));
3094 }
3095
3096 A_STATUS
3097 wmi_set_powersave_timers_cmd(struct wmi_t *wmip,
3098                             WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd,
3099                             A_UINT8 size)
3100 {
3101     void *osbuf;
3102     WMI_POWERSAVE_TIMERS_POLICY_CMD *cmd;
3103
3104     /* These timers can't be zero */
3105     if(!pCmd->psPollTimeout || !pCmd->triggerTimeout ||
3106        !(pCmd->apsdTimPolicy == IGNORE_TIM_ALL_QUEUES_APSD ||
3107          pCmd->apsdTimPolicy == PROCESS_TIM_ALL_QUEUES_APSD) ||
3108        !(pCmd->simulatedAPSDTimPolicy == IGNORE_TIM_SIMULATED_APSD ||
3109          pCmd->simulatedAPSDTimPolicy == PROCESS_TIM_SIMULATED_APSD))
3110         return A_EINVAL;
3111
3112     osbuf = A_NETBUF_ALLOC(size);
3113     if (osbuf == NULL) {
3114         return A_NO_MEMORY;
3115     }
3116
3117     A_NETBUF_PUT(osbuf, size);
3118
3119     cmd = (WMI_POWERSAVE_TIMERS_POLICY_CMD *)(A_NETBUF_DATA(osbuf));
3120     A_MEMZERO(cmd, size);
3121
3122     A_MEMCPY(cmd, pCmd, size);
3123
3124     return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID,
3125                          NO_SYNC_WMIFLAG));
3126 }
3127
3128 #ifdef CONFIG_HOST_GPIO_SUPPORT
3129 /* Send a command to Target to change GPIO output pins. */
3130 A_STATUS
3131 wmi_gpio_output_set(struct wmi_t *wmip,
3132                     A_UINT32 set_mask,
3133                     A_UINT32 clear_mask,
3134                     A_UINT32 enable_mask,
3135                     A_UINT32 disable_mask)
3136 {
3137     void *osbuf;
3138     WMIX_GPIO_OUTPUT_SET_CMD *output_set;
3139     int size;
3140
3141     size = sizeof(*output_set);
3142
3143     A_DPRINTF(DBG_WMI,
3144         (DBGFMT "Enter - set=0x%x clear=0x%x enb=0x%x dis=0x%x\n", DBGARG,
3145         set_mask, clear_mask, enable_mask, disable_mask));
3146
3147     osbuf = A_NETBUF_ALLOC(size);
3148     if (osbuf == NULL) {
3149         return A_NO_MEMORY;
3150     }
3151     A_NETBUF_PUT(osbuf, size);
3152     output_set = (WMIX_GPIO_OUTPUT_SET_CMD *)(A_NETBUF_DATA(osbuf));
3153
3154     output_set->set_mask                   = set_mask;
3155     output_set->clear_mask                 = clear_mask;
3156     output_set->enable_mask                = enable_mask;
3157     output_set->disable_mask               = disable_mask;
3158
3159     return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_OUTPUT_SET_CMDID,
3160                              NO_SYNC_WMIFLAG));
3161 }
3162
3163 /* Send a command to the Target requesting state of the GPIO input pins */
3164 A_STATUS
3165 wmi_gpio_input_get(struct wmi_t *wmip)
3166 {
3167     void *osbuf;
3168
3169     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
3170
3171     osbuf = A_NETBUF_ALLOC(0);
3172     if (osbuf == NULL) {
3173         return A_NO_MEMORY;
3174     }
3175
3176     return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_INPUT_GET_CMDID,
3177                              NO_SYNC_WMIFLAG));
3178 }
3179
3180 /* Send a command to the Target that changes the value of a GPIO register. */
3181 A_STATUS
3182 wmi_gpio_register_set(struct wmi_t *wmip,
3183                       A_UINT32 gpioreg_id,
3184                       A_UINT32 value)
3185 {
3186     void *osbuf;
3187     WMIX_GPIO_REGISTER_SET_CMD *register_set;
3188     int size;
3189
3190     size = sizeof(*register_set);
3191
3192     A_DPRINTF(DBG_WMI,
3193         (DBGFMT "Enter - reg=%d value=0x%x\n", DBGARG, gpioreg_id, value));
3194
3195     osbuf = A_NETBUF_ALLOC(size);
3196     if (osbuf == NULL) {
3197         return A_NO_MEMORY;
3198     }
3199     A_NETBUF_PUT(osbuf, size);
3200     register_set = (WMIX_GPIO_REGISTER_SET_CMD *)(A_NETBUF_DATA(osbuf));
3201
3202     register_set->gpioreg_id               = gpioreg_id;
3203     register_set->value                    = value;
3204
3205     return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_REGISTER_SET_CMDID,
3206                              NO_SYNC_WMIFLAG));
3207 }
3208
3209 /* Send a command to the Target to fetch the value of a GPIO register. */
3210 A_STATUS
3211 wmi_gpio_register_get(struct wmi_t *wmip,
3212                       A_UINT32 gpioreg_id)
3213 {
3214     void *osbuf;
3215     WMIX_GPIO_REGISTER_GET_CMD *register_get;
3216     int size;
3217
3218     size = sizeof(*register_get);
3219
3220     A_DPRINTF(DBG_WMI, (DBGFMT "Enter - reg=%d\n", DBGARG, gpioreg_id));
3221
3222     osbuf = A_NETBUF_ALLOC(size);
3223     if (osbuf == NULL) {
3224         return A_NO_MEMORY;
3225     }
3226     A_NETBUF_PUT(osbuf, size);
3227     register_get = (WMIX_GPIO_REGISTER_GET_CMD *)(A_NETBUF_DATA(osbuf));
3228
3229     register_get->gpioreg_id               = gpioreg_id;
3230
3231     return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_REGISTER_GET_CMDID,
3232                              NO_SYNC_WMIFLAG));
3233 }
3234
3235 /* Send a command to the Target acknowledging some GPIO interrupts. */
3236 A_STATUS
3237 wmi_gpio_intr_ack(struct wmi_t *wmip,
3238                   A_UINT32 ack_mask)
3239 {
3240     void *osbuf;
3241     WMIX_GPIO_INTR_ACK_CMD *intr_ack;
3242     int size;
3243
3244     size = sizeof(*intr_ack);
3245
3246     A_DPRINTF(DBG_WMI, (DBGFMT "Enter ack_mask=0x%x\n", DBGARG, ack_mask));
3247
3248     osbuf = A_NETBUF_ALLOC(size);
3249     if (osbuf == NULL) {
3250         return A_NO_MEMORY;
3251     }
3252     A_NETBUF_PUT(osbuf, size);
3253     intr_ack = (WMIX_GPIO_INTR_ACK_CMD *)(A_NETBUF_DATA(osbuf));
3254
3255     intr_ack->ack_mask               = ack_mask;
3256
3257     return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_INTR_ACK_CMDID,
3258                              NO_SYNC_WMIFLAG));
3259 }
3260 #endif /* CONFIG_HOST_GPIO_SUPPORT */
3261
3262 A_STATUS
3263 wmi_set_access_params_cmd(struct wmi_t *wmip, A_UINT16 txop, A_UINT8 eCWmin,
3264                           A_UINT8 eCWmax, A_UINT8 aifsn)
3265 {
3266     void *osbuf;
3267     WMI_SET_ACCESS_PARAMS_CMD *cmd;
3268
3269     if ((eCWmin > WMI_MAX_CW_ACPARAM) || (eCWmax > WMI_MAX_CW_ACPARAM) ||
3270         (aifsn > WMI_MAX_AIFSN_ACPARAM))
3271     {
3272         return A_EINVAL;
3273     }
3274
3275     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3276     if (osbuf == NULL) {
3277         return A_NO_MEMORY;
3278     }
3279
3280     A_NETBUF_PUT(osbuf, sizeof(*cmd));
3281
3282     cmd = (WMI_SET_ACCESS_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
3283     cmd->txop   = txop;
3284     cmd->eCWmin = eCWmin;
3285     cmd->eCWmax = eCWmax;
3286     cmd->aifsn  = aifsn;
3287
3288     return (wmi_cmd_send(wmip, osbuf, WMI_SET_ACCESS_PARAMS_CMDID,
3289                          NO_SYNC_WMIFLAG));
3290 }
3291
3292 A_STATUS
3293 wmi_set_retry_limits_cmd(struct wmi_t *wmip, A_UINT8 frameType,
3294                          A_UINT8 trafficClass, A_UINT8 maxRetries,
3295                          A_UINT8 enableNotify)
3296 {
3297     void *osbuf;
3298     WMI_SET_RETRY_LIMITS_CMD *cmd;
3299
3300     if ((frameType != MGMT_FRAMETYPE) && (frameType != CONTROL_FRAMETYPE) &&
3301         (frameType != DATA_FRAMETYPE))
3302     {
3303         return A_EINVAL;
3304     }
3305
3306     if (maxRetries > WMI_MAX_RETRIES) {
3307         return A_EINVAL;
3308     }
3309
3310     if (frameType != DATA_FRAMETYPE) {
3311         trafficClass = 0;
3312     }
3313
3314     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3315     if (osbuf == NULL) {
3316         return A_NO_MEMORY;
3317     }
3318
3319     A_NETBUF_PUT(osbuf, sizeof(*cmd));
3320
3321     cmd = (WMI_SET_RETRY_LIMITS_CMD *)(A_NETBUF_DATA(osbuf));
3322     cmd->frameType    = frameType;
3323     cmd->trafficClass = trafficClass;
3324     cmd->maxRetries   = maxRetries;
3325     cmd->enableNotify = enableNotify;
3326
3327     return (wmi_cmd_send(wmip, osbuf, WMI_SET_RETRY_LIMITS_CMDID,
3328                          NO_SYNC_WMIFLAG));
3329 }
3330
3331 void
3332 wmi_get_current_bssid(struct wmi_t *wmip, A_UINT8 *bssid)
3333 {
3334     if (bssid != NULL) {
3335         A_MEMCPY(bssid, wmip->wmi_bssid, ATH_MAC_LEN);
3336     }
3337 }
3338
3339 A_STATUS
3340 wmi_set_opt_mode_cmd(struct wmi_t *wmip, A_UINT8 optMode)
3341 {
3342     void *osbuf;
3343     WMI_SET_OPT_MODE_CMD *cmd;
3344
3345     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3346     if (osbuf == NULL) {
3347         return A_NO_MEMORY;
3348     }
3349
3350     A_NETBUF_PUT(osbuf, sizeof(*cmd));
3351
3352     cmd = (WMI_SET_OPT_MODE_CMD *)(A_NETBUF_DATA(osbuf));
3353     A_MEMZERO(cmd, sizeof(*cmd));
3354     cmd->optMode = optMode;
3355
3356     return (wmi_cmd_send(wmip, osbuf, WMI_SET_OPT_MODE_CMDID,
3357                          SYNC_BOTH_WMIFLAG));
3358 }
3359
3360 A_STATUS
3361 wmi_opt_tx_frame_cmd(struct wmi_t *wmip,
3362                       A_UINT8 frmType,
3363                       A_UINT8 *dstMacAddr,
3364                       A_UINT8 *bssid,
3365                       A_UINT16 optIEDataLen,
3366                       A_UINT8 *optIEData)
3367 {
3368     void *osbuf;
3369     WMI_OPT_TX_FRAME_CMD *cmd;
3370     osbuf = A_NETBUF_ALLOC(optIEDataLen + sizeof(*cmd));
3371     if (osbuf == NULL) {
3372         return A_NO_MEMORY;
3373     }
3374
3375     A_NETBUF_PUT(osbuf, (optIEDataLen + sizeof(*cmd)));
3376
3377     cmd = (WMI_OPT_TX_FRAME_CMD *)(A_NETBUF_DATA(osbuf));
3378     A_MEMZERO(cmd, (optIEDataLen + sizeof(*cmd)-1));
3379
3380     cmd->frmType    = frmType;
3381     cmd->optIEDataLen   = optIEDataLen;
3382     //cmd->optIEData     = (A_UINT8 *)((int)cmd + sizeof(*cmd));
3383     A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid));
3384     A_MEMCPY(cmd->dstAddr, dstMacAddr, sizeof(cmd->dstAddr));
3385     A_MEMCPY(&cmd->optIEData[0], optIEData, optIEDataLen);
3386
3387     return (wmi_cmd_send(wmip, osbuf, WMI_OPT_TX_FRAME_CMDID,
3388                          NO_SYNC_WMIFLAG));
3389 }
3390
3391 A_STATUS
3392 wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, A_UINT16 intvl)
3393 {
3394     void *osbuf;
3395     WMI_BEACON_INT_CMD *cmd;
3396
3397     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3398     if (osbuf == NULL) {
3399         return A_NO_MEMORY;
3400     }
3401
3402     A_NETBUF_PUT(osbuf, sizeof(*cmd));
3403
3404     cmd = (WMI_BEACON_INT_CMD *)(A_NETBUF_DATA(osbuf));
3405     A_MEMZERO(cmd, sizeof(*cmd));
3406     cmd->beaconInterval = intvl;
3407
3408     return (wmi_cmd_send(wmip, osbuf, WMI_SET_BEACON_INT_CMDID,
3409             NO_SYNC_WMIFLAG));
3410 }
3411
3412
3413 A_STATUS
3414 wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, A_UINT16 voicePktSize)
3415 {
3416     void *osbuf;
3417     WMI_SET_VOICE_PKT_SIZE_CMD *cmd;
3418
3419     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3420     if (osbuf == NULL) {
3421         return A_NO_MEMORY;
3422     }
3423
3424     A_NETBUF_PUT(osbuf, sizeof(*cmd));
3425
3426     cmd = (WMI_SET_VOICE_PKT_SIZE_CMD *)(A_NETBUF_DATA(osbuf));
3427     A_MEMZERO(cmd, sizeof(*cmd));
3428     cmd->voicePktSize = voicePktSize;
3429
3430     return (wmi_cmd_send(wmip, osbuf, WMI_SET_VOICE_PKT_SIZE_CMDID,
3431             NO_SYNC_WMIFLAG));
3432 }
3433
3434
3435 A_STATUS
3436 wmi_set_max_sp_len_cmd(struct wmi_t *wmip, A_UINT8 maxSPLen)
3437 {
3438     void *osbuf;
3439     WMI_SET_MAX_SP_LEN_CMD *cmd;
3440
3441     /* maxSPLen is a two-bit value. If user trys to set anything
3442      * other than this, then its invalid
3443      */
3444     if(maxSPLen & ~0x03)
3445         return  A_EINVAL;
3446
3447     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3448     if (osbuf == NULL) {
3449         return A_NO_MEMORY;
3450     }
3451
3452     A_NETBUF_PUT(osbuf, sizeof(*cmd));
3453
3454     cmd = (WMI_SET_MAX_SP_LEN_CMD *)(A_NETBUF_DATA(osbuf));
3455     A_MEMZERO(cmd, sizeof(*cmd));
3456     cmd->maxSPLen = maxSPLen;
3457
3458     return (wmi_cmd_send(wmip, osbuf, WMI_SET_MAX_SP_LEN_CMDID,
3459             NO_SYNC_WMIFLAG));
3460 }
3461
3462 A_UINT8
3463 convert_userPriority_to_trafficClass(A_UINT8 userPriority)
3464 {
3465         return  (up_to_ac[userPriority & 0x7]);
3466 }
3467
3468 A_UINT8
3469 wmi_get_power_mode_cmd(struct wmi_t *wmip)
3470 {
3471     return wmip->wmi_powerMode;
3472 }
3473
3474 A_STATUS
3475 wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, A_BOOL tspecCompliance)
3476 {
3477     return A_OK;
3478 }
3479
3480 #ifdef CONFIG_HOST_TCMD_SUPPORT
3481 static A_STATUS
3482 wmi_tcmd_test_report_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
3483 {
3484
3485    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
3486
3487    A_WMI_TCMD_RX_REPORT_EVENT(wmip->wmi_devt, datap, len);
3488
3489    return A_OK;
3490 }
3491
3492 #endif /* CONFIG_HOST_TCMD_SUPPORT*/
3493
3494 A_STATUS
3495 wmi_set_authmode_cmd(struct wmi_t *wmip, A_UINT8 mode)
3496 {
3497     void *osbuf;
3498     WMI_SET_AUTH_MODE_CMD *cmd;
3499
3500     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3501     if (osbuf == NULL) {
3502         return A_NO_MEMORY;
3503     }
3504
3505     A_NETBUF_PUT(osbuf, sizeof(*cmd));
3506
3507     cmd = (WMI_SET_AUTH_MODE_CMD *)(A_NETBUF_DATA(osbuf));
3508     A_MEMZERO(cmd, sizeof(*cmd));
3509     cmd->mode = mode;
3510
3511     return (wmi_cmd_send(wmip, osbuf, WMI_SET_AUTH_MODE_CMDID,
3512             NO_SYNC_WMIFLAG));
3513 }
3514
3515 A_STATUS
3516 wmi_set_reassocmode_cmd(struct wmi_t *wmip, A_UINT8 mode)
3517 {
3518     void *osbuf;
3519     WMI_SET_REASSOC_MODE_CMD *cmd;
3520
3521     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3522     if (osbuf == NULL) {
3523         return A_NO_MEMORY;
3524     }
3525
3526     A_NETBUF_PUT(osbuf, sizeof(*cmd));
3527
3528     cmd = (WMI_SET_REASSOC_MODE_CMD *)(A_NETBUF_DATA(osbuf));
3529     A_MEMZERO(cmd, sizeof(*cmd));
3530     cmd->mode = mode;
3531
3532     return (wmi_cmd_send(wmip, osbuf, WMI_SET_REASSOC_MODE_CMDID,
3533             NO_SYNC_WMIFLAG));
3534 }
3535
3536 A_STATUS
3537 wmi_set_lpreamble_cmd(struct wmi_t *wmip, A_UINT8 status)
3538 {
3539     void *osbuf;
3540     WMI_SET_LPREAMBLE_CMD *cmd;
3541
3542     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3543     if (osbuf == NULL) {
3544         return A_NO_MEMORY;
3545     }
3546
3547     A_NETBUF_PUT(osbuf, sizeof(*cmd));
3548
3549     cmd = (WMI_SET_LPREAMBLE_CMD *)(A_NETBUF_DATA(osbuf));
3550     A_MEMZERO(cmd, sizeof(*cmd));
3551     cmd->status = status;
3552
3553     return (wmi_cmd_send(wmip, osbuf, WMI_SET_LPREAMBLE_CMDID,
3554             NO_SYNC_WMIFLAG));
3555 }
3556
3557 A_STATUS
3558 wmi_set_rts_cmd(struct wmi_t *wmip, A_UINT16 threshold)
3559 {
3560     void *osbuf;
3561     WMI_SET_RTS_CMD *cmd;
3562
3563     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3564     if (osbuf == NULL) {
3565         return A_NO_MEMORY;
3566     }
3567
3568     A_NETBUF_PUT(osbuf, sizeof(*cmd));
3569
3570     cmd = (WMI_SET_RTS_CMD*)(A_NETBUF_DATA(osbuf));
3571     A_MEMZERO(cmd, sizeof(*cmd));
3572     cmd->threshold = threshold;
3573
3574     return (wmi_cmd_send(wmip, osbuf, WMI_SET_RTS_CMDID,
3575             NO_SYNC_WMIFLAG));
3576 }
3577
3578 A_STATUS
3579 wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status)
3580 {
3581     void *osbuf;
3582     WMI_SET_WMM_CMD *cmd;
3583
3584     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3585     if (osbuf == NULL) {
3586         return A_NO_MEMORY;
3587     }
3588
3589     A_NETBUF_PUT(osbuf, sizeof(*cmd));
3590
3591     cmd = (WMI_SET_WMM_CMD*)(A_NETBUF_DATA(osbuf));
3592     A_MEMZERO(cmd, sizeof(*cmd));
3593     cmd->status = status;
3594
3595     return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_CMDID,
3596             NO_SYNC_WMIFLAG));
3597
3598 }
3599
3600 A_STATUS
3601 wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG cfg)
3602 {
3603     void *osbuf;
3604     WMI_SET_WMM_TXOP_CMD *cmd;
3605
3606     if( !((cfg == WMI_TXOP_DISABLED) || (cfg == WMI_TXOP_ENABLED)) )
3607         return A_EINVAL;
3608
3609     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3610     if (osbuf == NULL) {
3611         return A_NO_MEMORY;
3612     }
3613
3614     A_NETBUF_PUT(osbuf, sizeof(*cmd));
3615
3616     cmd = (WMI_SET_WMM_TXOP_CMD *)(A_NETBUF_DATA(osbuf));
3617     A_MEMZERO(cmd, sizeof(*cmd));
3618     cmd->txopEnable = cfg;
3619
3620     return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_TXOP_CMDID,
3621             NO_SYNC_WMIFLAG));
3622
3623 }
3624
3625 #ifdef CONFIG_HOST_TCMD_SUPPORT
3626 /* WMI  layer doesn't need to know the data type of the test cmd.
3627    This would be beneficial for customers like Qualcomm, who might
3628    have different test command requirements from differnt manufacturers
3629  */
3630 A_STATUS
3631 wmi_test_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT32  len)
3632 {
3633     void *osbuf;
3634     char *data;
3635
3636     A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
3637
3638     osbuf= A_NETBUF_ALLOC(len);
3639     if(osbuf == NULL)
3640     {
3641         return A_NO_MEMORY;
3642     }
3643     A_NETBUF_PUT(osbuf, len);
3644     data = A_NETBUF_DATA(osbuf);
3645     A_MEMCPY(data, buf, len);
3646
3647     return(wmi_cmd_send(wmip, osbuf, WMI_TEST_CMDID,
3648          NO_SYNC_WMIFLAG));
3649 }
3650
3651 #endif
3652
3653 A_STATUS
3654 wmi_set_bt_status_cmd(struct wmi_t *wmip, A_UINT8 streamType, A_UINT8 status)
3655 {
3656     void *osbuf;
3657     WMI_SET_BT_STATUS_CMD *cmd;
3658
3659     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3660     if (osbuf == NULL) {
3661         return A_NO_MEMORY;
3662     }
3663
3664     A_NETBUF_PUT(osbuf, sizeof(*cmd));
3665
3666     cmd = (WMI_SET_BT_STATUS_CMD *)(A_NETBUF_DATA(osbuf));
3667     A_MEMZERO(cmd, sizeof(*cmd));
3668     cmd->streamType = streamType;
3669     cmd->status = status;
3670
3671     return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_STATUS_CMDID,
3672             NO_SYNC_WMIFLAG));
3673 }
3674
3675 A_STATUS
3676 wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd)
3677 {
3678     void *osbuf;
3679     WMI_SET_BT_PARAMS_CMD* alloc_cmd;
3680
3681     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3682     if (osbuf == NULL) {
3683         return A_NO_MEMORY;
3684     }
3685
3686     A_NETBUF_PUT(osbuf, sizeof(*cmd));
3687
3688     alloc_cmd = (WMI_SET_BT_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
3689     A_MEMZERO(alloc_cmd, sizeof(*cmd));
3690     A_MEMCPY(alloc_cmd, cmd, sizeof(*cmd));
3691
3692     return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_PARAMS_CMDID,
3693             NO_SYNC_WMIFLAG));
3694 }
3695
3696 A_STATUS
3697 wmi_get_keepalive_configured(struct wmi_t *wmip)
3698 {
3699     void *osbuf;
3700     WMI_GET_KEEPALIVE_CMD *cmd;
3701     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3702     if (osbuf == NULL) {
3703         return A_NO_MEMORY;
3704     }
3705     A_NETBUF_PUT(osbuf, sizeof(*cmd));
3706     cmd = (WMI_GET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf));
3707     A_MEMZERO(cmd, sizeof(*cmd));
3708     return (wmi_cmd_send(wmip, osbuf, WMI_GET_KEEPALIVE_CMDID,
3709                          NO_SYNC_WMIFLAG));
3710 }
3711
3712 A_UINT8
3713 wmi_get_keepalive_cmd(struct wmi_t *wmip)
3714 {
3715     return wmip->wmi_keepaliveInterval;
3716 }
3717
3718 A_STATUS
3719 wmi_set_keepalive_cmd(struct wmi_t *wmip, A_UINT8 keepaliveInterval)
3720 {
3721     void *osbuf;
3722     WMI_SET_KEEPALIVE_CMD *cmd;
3723
3724     osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3725     if (osbuf == NULL) {
3726         return A_NO_MEMORY;
3727     }
3728
3729     A_NETBUF_PUT(osbuf, sizeof(*cmd));
3730
3731     cmd = (WMI_SET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf));
3732     A_MEMZERO(cmd, sizeof(*cmd));
3733     cmd->keepaliveInterval = keepaliveInterval;
3734     wmip->wmi_keepaliveInterval = keepaliveInterval;
3735
3736     return (wmi_cmd_send(wmip, osbuf, WMI_SET_KEEPALIVE_CMDID,
3737                          NO_SYNC_WMIFLAG));
3738 }
3739
3740 A_STATUS
3741 wmi_set_appie_cmd(struct wmi_t *wmip, A_UINT8 mgmtFrmType, A_UINT8 ieLen,
3742                   A_UINT8 *ieInfo)
3743 {
3744     void *osbuf;
3745     WMI_SET_APPIE_CMD *cmd;
3746     A_UINT16 cmdLen;
3747
3748     if (ieLen > WMI_MAX_IE_LEN) {
3749         return A_ERROR;
3750     }
3751     cmdLen = sizeof(*cmd) + ieLen - 1;
3752     osbuf = A_NETBUF_ALLOC(cmdLen);
3753     if (osbuf == NULL) {
3754         return A_NO_MEMORY;
3755     }
3756
3757     A_NETBUF_PUT(osbuf, cmdLen);
3758
3759     cmd = (WMI_SET_APPIE_CMD *)(A_NETBUF_DATA(osbuf));
3760     A_MEMZERO(cmd, cmdLen);
3761
3762     cmd->mgmtFrmType = mgmtFrmType;
3763     cmd->ieLen = ieLen;
3764     A_MEMCPY(cmd->ieInfo, ieInfo, ieLen);
3765
3766     return (wmi_cmd_send(wmip, osbuf, WMI_SET_APPIE_CMDID, NO_SYNC_WMIFLAG));
3767 }
3768
3769 A_STATUS
3770 wmi_set_halparam_cmd(struct wmi_t *wmip, A_UINT8 *cmd, A_UINT16 dataLen)
3771 {
3772     void *osbuf;
3773     A_UINT8 *data;
3774
3775     osbuf = A_NETBUF_ALLOC(dataLen);
3776     if (osbuf == NULL) {
3777         return A_NO_MEMORY;
3778     }
3779
3780     A_NETBUF_PUT(osbuf, dataLen);
3781
3782     data = A_NETBUF_DATA(osbuf);
3783
3784     A_MEMCPY(data, cmd, dataLen);
3785
3786     return (wmi_cmd_send(wmip, osbuf, WMI_SET_WHALPARAM_CMDID, NO_SYNC_WMIFLAG));
3787 }
3788
3789 A_INT32
3790 wmi_get_rate(A_INT8 rateindex)
3791 {
3792     if (rateindex == RATE_AUTO) {
3793         return 0;
3794     } else {
3795         return(wmi_rateTable[(A_UINT32) rateindex]);
3796     }
3797 }
3798
3799 void
3800 wmi_node_return (struct wmi_t *wmip, bss_t *bss)
3801 {
3802         if (NULL != bss)
3803         {
3804                 wlan_node_return (&wmip->wmi_scan_table, bss);
3805         }
3806 }
3807
3808 bss_t *
3809 wmi_find_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid,
3810                                    A_UINT32 ssidLength, A_BOOL bIsWPA2)
3811 {
3812         bss_t *node = NULL;
3813     node = wlan_find_Ssidnode (&wmip->wmi_scan_table, pSsid,
3814                                                            ssidLength, bIsWPA2);
3815         return node;
3816 }
3817
3818 void
3819 wmi_free_allnodes(struct wmi_t *wmip)
3820 {
3821         wlan_free_allnodes(&wmip->wmi_scan_table);
3822 }
3823
3824 bss_t *
3825 wmi_find_node(struct wmi_t *wmip, const A_UINT8 *macaddr)
3826 {
3827         bss_t *ni=NULL;
3828         ni=wlan_find_node(&wmip->wmi_scan_table,macaddr);
3829         return ni;
3830 }
3831
3832 A_STATUS
3833 wmi_dset_open_reply(struct wmi_t *wmip,
3834                     A_UINT32 status,
3835                     A_UINT32 access_cookie,
3836                     A_UINT32 dset_size,
3837                     A_UINT32 dset_version,
3838                     A_UINT32 targ_handle,
3839                     A_UINT32 targ_reply_fn,
3840                     A_UINT32 targ_reply_arg)
3841 {
3842     void *osbuf;
3843     WMIX_DSETOPEN_REPLY_CMD *open_reply;
3844
3845     A_DPRINTF(DBG_WMI, (DBGFMT "Enter - wmip=0x%x\n", DBGARG, (int)wmip));
3846
3847     osbuf = A_NETBUF_ALLOC(sizeof(*open_reply));
3848     if (osbuf == NULL) {
3849         return A_NO_MEMORY;
3850     }
3851
3852     A_NETBUF_PUT(osbuf, sizeof(*open_reply));
3853     open_reply = (WMIX_DSETOPEN_REPLY_CMD *)(A_NETBUF_DATA(osbuf));
3854
3855     open_reply->status                   = status;
3856     open_reply->targ_dset_handle         = targ_handle;
3857     open_reply->targ_reply_fn            = targ_reply_fn;
3858     open_reply->targ_reply_arg           = targ_reply_arg;
3859     open_reply->access_cookie            = access_cookie;
3860     open_reply->size                     = dset_size;
3861     open_reply->version                  = dset_version;
3862
3863     return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETOPEN_REPLY_CMDID,
3864                              NO_SYNC_WMIFLAG));
3865 }
3866
3867 static A_STATUS
3868 wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len)
3869 {
3870     WMI_PMKID_LIST_REPLY *reply;
3871     A_UINT32 expected_len;
3872
3873     if (len < sizeof(WMI_PMKID_LIST_REPLY)) {
3874         return A_EINVAL;
3875     }
3876     reply = (WMI_PMKID_LIST_REPLY *)datap;
3877     expected_len = sizeof(reply->numPMKID) + reply->numPMKID * WMI_PMKID_LEN;
3878
3879     if (len < expected_len) {
3880         return A_EINVAL;
3881     }
3882
3883     A_WMI_PMKID_LIST_EVENT(wmip->wmi_devt, reply->numPMKID,
3884                            reply->pmkidList);
3885
3886     return A_OK;
3887 }
3888
3889 #ifdef CONFIG_HOST_DSET_SUPPORT
3890 A_STATUS
3891 wmi_dset_data_reply(struct wmi_t *wmip,
3892                     A_UINT32 status,
3893                     A_UINT8 *user_buf,
3894                     A_UINT32 length,
3895                     A_UINT32&n