Root/target/linux/s3c24xx/files-2.6.30/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
43static A_STATUS wmi_ready_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
44
45static A_STATUS wmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
46                                     int len);
47static A_STATUS wmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
48                                        int len);
49static A_STATUS wmi_tkip_micerr_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
50                                        int len);
51static A_STATUS wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
52                                     int len);
53static A_STATUS wmi_opt_frame_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
54                                       int len);
55static A_STATUS wmi_pstream_timeout_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
56                                     int len);
57static A_STATUS wmi_sync_point(struct wmi_t *wmip);
58
59static A_STATUS wmi_bitrate_reply_rx(struct wmi_t *wmip, A_UINT8 *datap,
60                                     int len);
61static A_STATUS wmi_ratemask_reply_rx(struct wmi_t *wmip, A_UINT8 *datap,
62                                     int len);
63static A_STATUS wmi_channelList_reply_rx(struct wmi_t *wmip, A_UINT8 *datap,
64                                         int len);
65static A_STATUS wmi_regDomain_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
66                                       int len);
67static A_STATUS wmi_txPwr_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
68static A_STATUS wmi_neighborReport_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
69                                             int len);
70
71static A_STATUS wmi_dset_open_req_rx(struct wmi_t *wmip, A_UINT8 *datap,
72                                     int len);
73#ifdef CONFIG_HOST_DSET_SUPPORT
74static A_STATUS wmi_dset_close_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
75static 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
80static A_STATUS wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap,
81                                     int len);
82static A_STATUS wmi_errorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
83static A_STATUS wmi_statsEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
84static A_STATUS wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
85static A_STATUS wmi_hbChallengeResp_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
86static A_STATUS wmi_reportErrorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
87static A_STATUS wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
88static A_STATUS wmi_roam_tbl_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
89                                      int len);
90static A_STATUS wmi_roam_data_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
91                                      int len);
92static A_STATUS wmi_get_wow_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
93                                      int len);
94static A_STATUS
95wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len);
96
97#ifdef CONFIG_HOST_GPIO_SUPPORT
98static A_STATUS wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
99static A_STATUS wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
100static 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
104static A_STATUS
105wmi_tcmd_test_report_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
106#endif
107
108static A_STATUS
109wmi_txRetryErrEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
110
111static A_STATUS
112wmi_snrThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
113
114static A_STATUS
115wmi_lqThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
116
117static A_BOOL
118wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_UINT32 rateIndex);
119
120static A_STATUS
121wmi_aplistEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
122
123static A_STATUS
124wmi_dbglog_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
125
126static A_STATUS wmi_keepalive_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
127
128int wps_enable;
129static 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 */
159const 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
170void *
171wmi_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
190void
191wmi_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
217void
218wmi_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 */
235A_STATUS
236wmi_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 */
298A_STATUS
299wmi_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
316A_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
366WMI_PRI_STREAM_ID
367wmi_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 */
376A_STATUS
377wmi_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 */
404A_STATUS
405wmi_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
412void
413wmi_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 */
421A_STATUS
422wmi_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 */
493A_UINT32 cmdRecvNum;
494
495A_STATUS
496wmi_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
693static A_STATUS
694wmi_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
708static A_STATUS
709wmi_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
734static A_STATUS
735wmi_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
749static A_STATUS
750wmi_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
770static A_STATUS
771wmi_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
790static A_STATUS
791wmi_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
806static A_STATUS
807wmi_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
881static A_STATUS
882wmi_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     */
926static A_STATUS
927wmi_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
956static A_STATUS
957wmi_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
980static A_STATUS
981wmi_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
997static A_STATUS
998wmi_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
1014static A_STATUS
1015wmi_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}
1029static A_STATUS
1030wmi_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
1046static A_STATUS
1047wmi_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
1067static A_STATUS
1068wmi_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
1083static A_STATUS
1084wmi_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
1106static A_STATUS
1107wmi_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 */
1124static A_STATUS
1125wmi_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
1147static A_STATUS
1148wmi_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
1163static A_STATUS
1164wmi_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
1180static A_STATUS
1181wmi_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
1196static A_STATUS
1197wmi_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
1214static A_STATUS
1215wmi_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
1230static A_STATUS
1231wmi_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
1246static A_STATUS
1247wmi_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
1262static A_STATUS
1263wmi_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
1278static A_STATUS
1279wmi_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
1294static A_STATUS
1295wmi_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
1310static A_STATUS
1311wmi_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
1351static A_STATUS
1352wmi_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
1364static A_STATUS
1365wmi_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
1378static A_STATUS
1379wmi_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
1392static A_STATUS
1393wmi_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 */
1407A_STATUS
1408wmi_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
1457A_STATUS
1458wmi_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
1473A_STATUS
1474wmi_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
1523A_STATUS
1524wmi_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
1548A_STATUS
1549wmi_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
1567A_STATUS
1568wmi_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
1596A_STATUS
1597wmi_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
1630A_STATUS
1631wmi_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
1656A_STATUS
1657wmi_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
1694A_STATUS
1695wmi_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
1716A_STATUS
1717wmi_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
1738A_STATUS
1739wmi_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
1764A_STATUS
1765wmi_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
1786A_STATUS
1787wmi_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
1811A_STATUS
1812wmi_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
1835A_STATUS
1836wmi_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
1856A_STATUS
1857wmi_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
1897A_STATUS
1898wmi_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
1918A_STATUS
1919wmi_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
1932A_STATUS
1933wmi_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
1957A_STATUS
1958wmi_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
1992A_STATUS
1993wmi_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
2012A_STATUS
2013wmi_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
2032A_STATUS
2033wmi_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
2063A_STATUS
2064wmi_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
2077A_STATUS
2078wmi_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
2098typedef struct _WMI_DATA_SYNC_BUFS {
2099    A_UINT8 trafficClass;
2100    void *osbuf;
2101}WMI_DATA_SYNC_BUFS;
2102
2103static A_STATUS
2104wmi_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
2192A_STATUS
2193wmi_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
2264A_STATUS
2265wmi_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 */
2325A_STATUS
2326wmi_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
2356A_STATUS
2357wmi_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 */
2372A_BOOL
2373wmi_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
2411A_INT8
2412wmi_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
2438A_STATUS
2439wmi_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
2471A_STATUS
2472wmi_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
2484A_STATUS
2485wmi_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 */
2508A_STATUS
2509wmi_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
2546A_STATUS
2547wmi_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
2585A_STATUS
2586wmi_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
2614A_STATUS
2615wmi_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
2640A_STATUS
2641wmi_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
2666static A_STATUS
2667wmi_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
2682A_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
2717A_STATUS
2718wmi_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
2743A_STATUS
2744wmi_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
2778A_STATUS
2779wmi_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
2792A_STATUS
2793wmi_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
2827A_STATUS
2828wmi_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
2852A_STATUS
2853wmi_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
2873A_STATUS
2874wmi_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
2899A_STATUS
2900wmi_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
2913A_STATUS
2914wmi_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
2937A_STATUS
2938wmi_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
2961A_STATUS
2962wmi_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
2980A_STATUS
2981wmi_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
2993A_STATUS
2994wmi_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
3026A_UINT16
3027wmi_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
3038A_STATUS
3039wmi_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
3052A_STATUS
3053wmi_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
3073A_STATUS
3074wmi_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
3096A_STATUS
3097wmi_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. */
3130A_STATUS
3131wmi_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 */
3164A_STATUS
3165wmi_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. */
3181A_STATUS
3182wmi_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. */
3210A_STATUS
3211wmi_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. */
3236A_STATUS
3237wmi_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
3262A_STATUS
3263wmi_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
3292A_STATUS
3293wmi_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
3331void
3332wmi_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
3339A_STATUS
3340wmi_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
3360A_STATUS
3361wmi_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
3391A_STATUS
3392wmi_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
3413A_STATUS
3414wmi_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
3435A_STATUS
3436wmi_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
3462A_UINT8
3463convert_userPriority_to_trafficClass(A_UINT8 userPriority)
3464{
3465        return (up_to_ac[userPriority & 0x7]);
3466}
3467
3468A_UINT8
3469wmi_get_power_mode_cmd(struct wmi_t *wmip)
3470{
3471    return wmip->wmi_powerMode;
3472}
3473
3474A_STATUS
3475wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, A_BOOL tspecCompliance)
3476{
3477    return A_OK;
3478}
3479
3480#ifdef CONFIG_HOST_TCMD_SUPPORT
3481static A_STATUS
3482wmi_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
3494A_STATUS
3495wmi_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
3515A_STATUS
3516wmi_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
3536A_STATUS
3537wmi_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
3557A_STATUS
3558wmi_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
3578A_STATUS
3579wmi_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
3600A_STATUS
3601wmi_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 */
3630A_STATUS
3631wmi_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
3653A_STATUS
3654wmi_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
3675A_STATUS
3676wmi_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
3696A_STATUS
3697wmi_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
3712A_UINT8
3713wmi_get_keepalive_cmd(struct wmi_t *wmip)
3714{
3715    return wmip->wmi_keepaliveInterval;
3716}
3717
3718A_STATUS
3719wmi_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
3740A_STATUS
3741wmi_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
3769A_STATUS
3770wmi_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
3789A_INT32
3790wmi_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
3799void
3800wmi_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
3808bss_t *
3809wmi_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
3818void
3819wmi_free_allnodes(struct wmi_t *wmip)
3820{
3821    wlan_free_allnodes(&wmip->wmi_scan_table);
3822}
3823
3824bss_t *
3825wmi_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
3832A_STATUS
3833wmi_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
3867static A_STATUS
3868wmi_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
3890A_STATUS
3891wmi_dset_data_reply(struct wmi_t *wmip,
3892                    A_UINT32 status,
3893                    A_UINT8 *user_buf,
3894                    A_UINT32 length,
3895                    A_UINT32 targ_buf,
3896                    A_UINT32 targ_reply_fn,
3897                    A_UINT32 targ_reply_arg)
3898{
3899    void *osbuf;
3900    WMIX_DSETDATA_REPLY_CMD *data_reply;
3901    int size;
3902
3903    size = sizeof(*data_reply) + length;
3904
3905    A_DPRINTF(DBG_WMI,
3906        (DBGFMT "Enter - length=%d status=%d\n", DBGARG, length, status));
3907
3908    osbuf = A_NETBUF_ALLOC(size);
3909    if (osbuf == NULL) {
3910        return A_NO_MEMORY;
3911    }
3912    A_NETBUF_PUT(osbuf, size);
3913    data_reply = (WMIX_DSETDATA_REPLY_CMD *)(A_NETBUF_DATA(osbuf));
3914
3915    data_reply->status = status;
3916    data_reply->targ_buf = targ_buf;
3917    data_reply->targ_reply_fn = targ_reply_fn;
3918    data_reply->targ_reply_arg = targ_reply_arg;
3919    data_reply->length = length;
3920
3921    if (status == A_OK) {
3922        if (a_copy_from_user(data_reply->buf, user_buf, length)) {
3923            return A_ERROR;
3924        }
3925    }
3926
3927    return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETDATA_REPLY_CMDID,
3928                             NO_SYNC_WMIFLAG));
3929}
3930#endif /* CONFIG_HOST_DSET_SUPPORT */
3931
3932A_STATUS
3933wmi_set_wsc_status_cmd(struct wmi_t *wmip, A_UINT32 status)
3934{
3935    void *osbuf;
3936    char *cmd;
3937
3938    wps_enable = status;
3939
3940    osbuf = a_netbuf_alloc(sizeof(1));
3941    if (osbuf == NULL) {
3942        return A_NO_MEMORY;
3943    }
3944
3945    a_netbuf_put(osbuf, sizeof(1));
3946
3947    cmd = (char *)(a_netbuf_to_data(osbuf));
3948
3949    A_MEMZERO(cmd, sizeof(*cmd));
3950    cmd[0] = (status?1:0);
3951    return (wmi_cmd_send(wmip, osbuf, WMI_SET_WSC_STATUS_CMDID,
3952                         NO_SYNC_WMIFLAG));
3953}
3954
3955

Archive Download this file



interactive