tty/serial: atmel_serial: whitespace and braces modifications
[zen-stable.git] / drivers / staging / ath6kl / wmi / wmi.c
blobc7b5e5cf9df7af8d3cb02466f0ccad978fe328f5
1 //------------------------------------------------------------------------------
2 // Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
3 //
4 //
5 // Permission to use, copy, modify, and/or distribute this software for any
6 // purpose with or without fee is hereby granted, provided that the above
7 // copyright notice and this permission notice appear in all copies.
8 //
9 // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 //------------------------------------------------------------------------------
19 //==============================================================================
20 // This module implements the hardware independent layer of the
21 // Wireless Module Interface (WMI) protocol.
23 // Author(s): ="Atheros"
24 //==============================================================================
26 #include <a_config.h>
27 #include <athdefs.h>
28 #include <a_osapi.h>
29 #include "htc.h"
30 #include "htc_api.h"
31 #include "wmi.h"
32 #include <wlan_api.h>
33 #include <wmi_api.h>
34 #include <ieee80211.h>
35 #include <ieee80211_node.h>
36 #include "dset_api.h"
37 #include "wmi_host.h"
38 #include "a_drv.h"
39 #include "a_drv_api.h"
40 #define ATH_MODULE_NAME wmi
41 #include "a_debug.h"
42 #include "dbglog_api.h"
43 #include "roaming.h"
44 #include "cfg80211.h"
46 #define ATH_DEBUG_WMI ATH_DEBUG_MAKE_MODULE_MASK(0)
48 #ifdef ATH_DEBUG_MODULE
50 static struct ath_debug_mask_description wmi_debug_desc[] = {
51 { ATH_DEBUG_WMI , "General WMI Tracing"},
54 ATH_DEBUG_INSTANTIATE_MODULE_VAR(wmi,
55 "wmi",
56 "Wireless Module Interface",
57 ATH_DEBUG_MASK_DEFAULTS,
58 ATH_DEBUG_DESCRIPTION_COUNT(wmi_debug_desc),
59 wmi_debug_desc);
61 #endif
63 #ifndef REXOS
64 #define DBGARG _A_FUNCNAME_
65 #define DBGFMT "%s() : "
66 #define DBG_WMI ATH_DEBUG_WMI
67 #define DBG_ERROR ATH_DEBUG_ERR
68 #define DBG_WMI2 ATH_DEBUG_WMI
69 #define A_DPRINTF AR_DEBUG_PRINTF
70 #endif
72 static int wmi_ready_event_rx(struct wmi_t *wmip, u8 *datap, int len);
74 static int wmi_connect_event_rx(struct wmi_t *wmip, u8 *datap,
75 int len);
76 static int wmi_disconnect_event_rx(struct wmi_t *wmip, u8 *datap,
77 int len);
79 static int wmi_tkip_micerr_event_rx(struct wmi_t *wmip, u8 *datap,
80 int len);
81 static int wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap,
82 int len);
83 static int wmi_opt_frame_event_rx(struct wmi_t *wmip, u8 *datap,
84 int len);
85 static int wmi_pstream_timeout_event_rx(struct wmi_t *wmip, u8 *datap,
86 int len);
87 static int wmi_sync_point(struct wmi_t *wmip);
89 static int wmi_bitrate_reply_rx(struct wmi_t *wmip, u8 *datap,
90 int len);
91 static int wmi_ratemask_reply_rx(struct wmi_t *wmip, u8 *datap,
92 int len);
93 static int wmi_channelList_reply_rx(struct wmi_t *wmip, u8 *datap,
94 int len);
95 static int wmi_regDomain_event_rx(struct wmi_t *wmip, u8 *datap,
96 int len);
97 static int wmi_txPwr_reply_rx(struct wmi_t *wmip, u8 *datap, int len);
98 static int wmi_neighborReport_event_rx(struct wmi_t *wmip, u8 *datap,
99 int len);
101 static int wmi_dset_open_req_rx(struct wmi_t *wmip, u8 *datap,
102 int len);
103 #ifdef CONFIG_HOST_DSET_SUPPORT
104 static int wmi_dset_close_rx(struct wmi_t *wmip, u8 *datap, int len);
105 static int wmi_dset_data_req_rx(struct wmi_t *wmip, u8 *datap,
106 int len);
107 #endif /* CONFIG_HOST_DSET_SUPPORT */
110 static int wmi_scanComplete_rx(struct wmi_t *wmip, u8 *datap,
111 int len);
112 static int wmi_errorEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
113 static int wmi_statsEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
114 static int wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
115 static int wmi_hbChallengeResp_rx(struct wmi_t *wmip, u8 *datap, int len);
116 static int wmi_reportErrorEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
117 static int wmi_cac_event_rx(struct wmi_t *wmip, u8 *datap, int len);
118 static int wmi_channel_change_event_rx(struct wmi_t *wmip, u8 *datap, int len);
119 static int wmi_roam_tbl_event_rx(struct wmi_t *wmip, u8 *datap,
120 int len);
121 static int wmi_roam_data_event_rx(struct wmi_t *wmip, u8 *datap,
122 int len);
123 static int wmi_get_wow_list_event_rx(struct wmi_t *wmip, u8 *datap,
124 int len);
125 static int
126 wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, u8 *datap, u32 len);
128 static int
129 wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, u32 len);
132 #ifdef CONFIG_HOST_TCMD_SUPPORT
133 static int
134 wmi_tcmd_test_report_rx(struct wmi_t *wmip, u8 *datap, int len);
135 #endif
137 static int
138 wmi_txRetryErrEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
140 static int
141 wmi_snrThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
143 static int
144 wmi_lqThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
146 static bool
147 wmi_is_bitrate_index_valid(struct wmi_t *wmip, s32 rateIndex);
149 static int
150 wmi_aplistEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
152 static int
153 wmi_dbglog_event_rx(struct wmi_t *wmip, u8 *datap, int len);
155 static int wmi_keepalive_reply_rx(struct wmi_t *wmip, u8 *datap, int len);
157 int wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId,
158 WMI_SYNC_FLAG syncflag);
160 u8 ar6000_get_upper_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, u32 size);
161 u8 ar6000_get_lower_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, u32 size);
163 void wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd);
164 void wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd);
165 static int wmi_send_rssi_threshold_params(struct wmi_t *wmip,
166 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd);
167 static int wmi_send_snr_threshold_params(struct wmi_t *wmip,
168 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd);
169 #if defined(CONFIG_TARGET_PROFILE_SUPPORT)
170 static int
171 wmi_prof_count_rx(struct wmi_t *wmip, u8 *datap, int len);
172 #endif /* CONFIG_TARGET_PROFILE_SUPPORT */
174 static int wmi_pspoll_event_rx(struct wmi_t *wmip, u8 *datap,
175 int len);
176 static int wmi_dtimexpiry_event_rx(struct wmi_t *wmip, u8 *datap,
177 int len);
179 static int wmi_peer_node_event_rx (struct wmi_t *wmip, u8 *datap,
180 int len);
181 static int wmi_addba_req_event_rx(struct wmi_t *, u8 *, int);
182 static int wmi_addba_resp_event_rx(struct wmi_t *, u8 *, int);
183 static int wmi_delba_req_event_rx(struct wmi_t *, u8 *, int);
184 static int wmi_btcoex_config_event_rx(struct wmi_t *wmip, u8 *datap, int len);
185 static int wmi_btcoex_stats_event_rx(struct wmi_t *wmip, u8 *datap, int len);
186 static int wmi_hci_event_rx(struct wmi_t *, u8 *, int);
188 #ifdef WAPI_ENABLE
189 static int wmi_wapi_rekey_event_rx(struct wmi_t *wmip, u8 *datap,
190 int len);
191 #endif
193 #if defined(UNDER_CE)
194 #if defined(NDIS51_MINIPORT)
195 unsigned int processDot11Hdr = 0;
196 #else
197 unsigned int processDot11Hdr = 1;
198 #endif
199 #else
200 extern unsigned int processDot11Hdr;
201 #endif
203 int wps_enable;
204 static const s32 wmi_rateTable[][2] = {
205 //{W/O SGI, with SGI}
206 {1000, 1000},
207 {2000, 2000},
208 {5500, 5500},
209 {11000, 11000},
210 {6000, 6000},
211 {9000, 9000},
212 {12000, 12000},
213 {18000, 18000},
214 {24000, 24000},
215 {36000, 36000},
216 {48000, 48000},
217 {54000, 54000},
218 {6500, 7200},
219 {13000, 14400},
220 {19500, 21700},
221 {26000, 28900},
222 {39000, 43300},
223 {52000, 57800},
224 {58500, 65000},
225 {65000, 72200},
226 {13500, 15000},
227 {27000, 30000},
228 {40500, 45000},
229 {54000, 60000},
230 {81000, 90000},
231 {108000, 120000},
232 {121500, 135000},
233 {135000, 150000},
234 {0, 0}};
236 #define MODE_A_SUPPORT_RATE_START ((s32) 4)
237 #define MODE_A_SUPPORT_RATE_STOP ((s32) 11)
239 #define MODE_GONLY_SUPPORT_RATE_START MODE_A_SUPPORT_RATE_START
240 #define MODE_GONLY_SUPPORT_RATE_STOP MODE_A_SUPPORT_RATE_STOP
242 #define MODE_B_SUPPORT_RATE_START ((s32) 0)
243 #define MODE_B_SUPPORT_RATE_STOP ((s32) 3)
245 #define MODE_G_SUPPORT_RATE_START ((s32) 0)
246 #define MODE_G_SUPPORT_RATE_STOP ((s32) 11)
248 #define MODE_GHT20_SUPPORT_RATE_START ((s32) 0)
249 #define MODE_GHT20_SUPPORT_RATE_STOP ((s32) 19)
251 #define MAX_NUMBER_OF_SUPPORT_RATES (MODE_GHT20_SUPPORT_RATE_STOP + 1)
253 /* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */
254 const u8 up_to_ac[]= {
255 WMM_AC_BE,
256 WMM_AC_BK,
257 WMM_AC_BK,
258 WMM_AC_BE,
259 WMM_AC_VI,
260 WMM_AC_VI,
261 WMM_AC_VO,
262 WMM_AC_VO,
265 /* This stuff is used when we want a simple layer-3 visibility */
266 typedef PREPACK struct _iphdr {
267 u8 ip_ver_hdrlen; /* version and hdr length */
268 u8 ip_tos; /* type of service */
269 u16 ip_len; /* total length */
270 u16 ip_id; /* identification */
271 s16 ip_off; /* fragment offset field */
272 #define IP_DF 0x4000 /* dont fragment flag */
273 #define IP_MF 0x2000 /* more fragments flag */
274 #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
275 u8 ip_ttl; /* time to live */
276 u8 ip_p; /* protocol */
277 u16 ip_sum; /* checksum */
278 u8 ip_src[4]; /* source and dest address */
279 u8 ip_dst[4];
280 } POSTPACK iphdr;
282 static s16 rssi_event_value = 0;
283 static s16 snr_event_value = 0;
285 bool is_probe_ssid = false;
287 void *
288 wmi_init(void *devt)
290 struct wmi_t *wmip;
292 A_REGISTER_MODULE_DEBUG_INFO(wmi);
294 wmip = A_MALLOC (sizeof(struct wmi_t));
295 if (wmip == NULL) {
296 return (NULL);
298 A_MEMZERO(wmip, sizeof(struct wmi_t ));
299 #ifdef THREAD_X
300 INIT_WMI_LOCK(wmip);
301 #else
302 A_MUTEX_INIT(&wmip->wmi_lock);
303 #endif
304 wmip->wmi_devt = devt;
305 wlan_node_table_init(wmip, &wmip->wmi_scan_table);
306 wmi_qos_state_init(wmip);
308 wmip->wmi_powerMode = REC_POWER;
309 wmip->wmi_phyMode = WMI_11G_MODE;
311 wmip->wmi_pair_crypto_type = NONE_CRYPT;
312 wmip->wmi_grp_crypto_type = NONE_CRYPT;
314 wmip->wmi_ht_allowed[A_BAND_24GHZ] = 1;
315 wmip->wmi_ht_allowed[A_BAND_5GHZ] = 1;
317 return (wmip);
320 void
321 wmi_qos_state_init(struct wmi_t *wmip)
323 u8 i;
325 if (wmip == NULL) {
326 return;
328 LOCK_WMI(wmip);
330 /* Initialize QoS States */
331 wmip->wmi_numQoSStream = 0;
333 wmip->wmi_fatPipeExists = 0;
335 for (i=0; i < WMM_NUM_AC; i++) {
336 wmip->wmi_streamExistsForAC[i]=0;
339 UNLOCK_WMI(wmip);
341 A_WMI_SET_NUMDATAENDPTS(wmip->wmi_devt, 1);
344 void
345 wmi_set_control_ep(struct wmi_t * wmip, HTC_ENDPOINT_ID eid)
347 A_ASSERT( eid != ENDPOINT_UNUSED);
348 wmip->wmi_endpoint_id = eid;
351 HTC_ENDPOINT_ID
352 wmi_get_control_ep(struct wmi_t * wmip)
354 return(wmip->wmi_endpoint_id);
357 void
358 wmi_shutdown(struct wmi_t *wmip)
360 if (wmip != NULL) {
361 wlan_node_table_cleanup(&wmip->wmi_scan_table);
362 if (A_IS_MUTEX_VALID(&wmip->wmi_lock)) {
363 #ifdef THREAD_X
364 DELETE_WMI_LOCK(&wmip);
365 #else
366 A_MUTEX_DELETE(&wmip->wmi_lock);
367 #endif
369 kfree(wmip);
374 * performs DIX to 802.3 encapsulation for transmit packets.
375 * uses passed in buffer. Returns buffer or NULL if failed.
376 * Assumes the entire DIX header is contigous and that there is
377 * enough room in the buffer for a 802.3 mac header and LLC+SNAP headers.
380 wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf)
382 u8 *datap;
383 u16 typeorlen;
384 ATH_MAC_HDR macHdr;
385 ATH_LLC_SNAP_HDR *llcHdr;
387 A_ASSERT(osbuf != NULL);
389 if (A_NETBUF_HEADROOM(osbuf) <
390 (sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR)))
392 return A_NO_MEMORY;
395 datap = A_NETBUF_DATA(osbuf);
397 typeorlen = *(u16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN);
399 if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) {
401 * packet is already in 802.3 format - return success
403 A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG));
404 return (0);
408 * Save mac fields and length to be inserted later
410 memcpy(macHdr.dstMac, datap, ATH_MAC_LEN);
411 memcpy(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN);
412 macHdr.typeOrLen = A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) +
413 sizeof(ATH_LLC_SNAP_HDR));
416 * Make room for LLC+SNAP headers
418 if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != 0) {
419 return A_NO_MEMORY;
421 datap = A_NETBUF_DATA(osbuf);
423 memcpy(datap, &macHdr, sizeof (ATH_MAC_HDR));
425 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR));
426 llcHdr->dsap = 0xAA;
427 llcHdr->ssap = 0xAA;
428 llcHdr->cntl = 0x03;
429 llcHdr->orgCode[0] = 0x0;
430 llcHdr->orgCode[1] = 0x0;
431 llcHdr->orgCode[2] = 0x0;
432 llcHdr->etherType = typeorlen;
434 return (0);
437 int wmi_meta_add(struct wmi_t *wmip, void *osbuf, u8 *pVersion,void *pTxMetaS)
439 switch(*pVersion){
440 case 0:
441 return (0);
442 case WMI_META_VERSION_1:
444 WMI_TX_META_V1 *pV1= NULL;
445 A_ASSERT(osbuf != NULL);
446 if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != 0) {
447 return A_NO_MEMORY;
450 pV1 = (WMI_TX_META_V1 *)A_NETBUF_DATA(osbuf);
451 /* the pktID is used in conjunction with txComplete messages
452 * allowing the target to notify which tx requests have been
453 * completed and how. */
454 pV1->pktID = 0;
455 /* the ratePolicyID allows the host to specify which rate policy
456 * to use for transmitting this packet. 0 means use default behavior. */
457 pV1->ratePolicyID = 0;
458 A_ASSERT(pVersion != NULL);
459 /* the version must be used to populate the meta field of the WMI_DATA_HDR */
460 *pVersion = WMI_META_VERSION_1;
461 return (0);
463 case WMI_META_VERSION_2:
465 WMI_TX_META_V2 *pV2 ;
466 A_ASSERT(osbuf != NULL);
467 if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != 0) {
468 return A_NO_MEMORY;
470 pV2 = (WMI_TX_META_V2 *)A_NETBUF_DATA(osbuf);
471 memcpy(pV2,(WMI_TX_META_V2 *)pTxMetaS,sizeof(WMI_TX_META_V2));
472 return (0);
474 default:
475 return (0);
479 /* Adds a WMI data header */
481 wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, u8 msgType, bool bMoreData,
482 WMI_DATA_HDR_DATA_TYPE data_type,u8 metaVersion, void *pTxMetaS)
484 WMI_DATA_HDR *dtHdr;
485 // u8 metaVersion = 0;
486 int status;
488 A_ASSERT(osbuf != NULL);
490 /* adds the meta data field after the wmi data hdr. If metaVersion
491 * is returns 0 then no meta field was added. */
492 if ((status = wmi_meta_add(wmip, osbuf, &metaVersion,pTxMetaS)) != 0) {
493 return status;
496 if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != 0) {
497 return A_NO_MEMORY;
500 dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf);
501 A_MEMZERO(dtHdr, sizeof(WMI_DATA_HDR));
503 WMI_DATA_HDR_SET_MSG_TYPE(dtHdr, msgType);
504 WMI_DATA_HDR_SET_DATA_TYPE(dtHdr, data_type);
506 if (bMoreData) {
507 WMI_DATA_HDR_SET_MORE_BIT(dtHdr);
510 WMI_DATA_HDR_SET_META(dtHdr, metaVersion);
512 dtHdr->info3 = 0;
514 return (0);
518 u8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, u32 layer2Priority, bool wmmEnabled)
520 u8 *datap;
521 u8 trafficClass = WMM_AC_BE;
522 u16 ipType = IP_ETHERTYPE;
523 WMI_DATA_HDR *dtHdr;
524 u8 streamExists = 0;
525 u8 userPriority;
526 u32 hdrsize, metasize;
527 ATH_LLC_SNAP_HDR *llcHdr;
529 WMI_CREATE_PSTREAM_CMD cmd;
531 A_ASSERT(osbuf != NULL);
534 // Initialize header size
536 hdrsize = 0;
538 datap = A_NETBUF_DATA(osbuf);
539 dtHdr = (WMI_DATA_HDR *)datap;
540 metasize = (WMI_DATA_HDR_GET_META(dtHdr))? WMI_MAX_TX_META_SZ : 0;
542 if (!wmmEnabled)
544 /* If WMM is disabled all traffic goes as BE traffic */
545 userPriority = 0;
547 else
549 if (processDot11Hdr)
551 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32));
552 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) + metasize +
553 hdrsize);
557 else
559 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) + metasize +
560 sizeof(ATH_MAC_HDR));
563 if (llcHdr->etherType == A_CPU2BE16(ipType))
565 /* Extract the endpoint info from the TOS field in the IP header */
567 userPriority = wmi_determine_userPriority (((u8 *)llcHdr) + sizeof(ATH_LLC_SNAP_HDR),layer2Priority);
569 else
571 userPriority = layer2Priority & 0x7;
576 /* workaround for WMM S5 */
577 if ((WMM_AC_VI == wmip->wmi_traffic_class) && ((5 == userPriority) || (4 == userPriority)))
579 userPriority = 1;
582 trafficClass = convert_userPriority_to_trafficClass(userPriority);
584 WMI_DATA_HDR_SET_UP(dtHdr, userPriority);
585 /* lower 3-bits are 802.1d priority */
586 //dtHdr->info |= (userPriority & WMI_DATA_HDR_UP_MASK) << WMI_DATA_HDR_UP_SHIFT;
588 LOCK_WMI(wmip);
589 streamExists = wmip->wmi_fatPipeExists;
590 UNLOCK_WMI(wmip);
592 if (!(streamExists & (1 << trafficClass)))
595 A_MEMZERO(&cmd, sizeof(cmd));
596 cmd.trafficClass = trafficClass;
597 cmd.userPriority = userPriority;
598 cmd.inactivityInt = WMI_IMPLICIT_PSTREAM_INACTIVITY_INT;
599 /* Implicit streams are created with TSID 0xFF */
601 cmd.tsid = WMI_IMPLICIT_PSTREAM;
602 wmi_create_pstream_cmd(wmip, &cmd);
605 return trafficClass;
609 wmi_dot11_hdr_add (struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode)
611 u8 *datap;
612 u16 typeorlen;
613 ATH_MAC_HDR macHdr;
614 ATH_LLC_SNAP_HDR *llcHdr;
615 struct ieee80211_frame *wh;
616 u32 hdrsize;
618 A_ASSERT(osbuf != NULL);
620 if (A_NETBUF_HEADROOM(osbuf) <
621 (sizeof(struct ieee80211_qosframe) + sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR)))
623 return A_NO_MEMORY;
626 datap = A_NETBUF_DATA(osbuf);
628 typeorlen = *(u16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN);
630 if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) {
632 * packet is already in 802.3 format - return success
634 A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG));
635 goto AddDot11Hdr;
639 * Save mac fields and length to be inserted later
641 memcpy(macHdr.dstMac, datap, ATH_MAC_LEN);
642 memcpy(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN);
643 macHdr.typeOrLen = A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) +
644 sizeof(ATH_LLC_SNAP_HDR));
646 // Remove the Ethernet hdr
647 A_NETBUF_PULL(osbuf, sizeof(ATH_MAC_HDR));
649 * Make room for LLC+SNAP headers
651 if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != 0) {
652 return A_NO_MEMORY;
654 datap = A_NETBUF_DATA(osbuf);
656 llcHdr = (ATH_LLC_SNAP_HDR *)(datap);
657 llcHdr->dsap = 0xAA;
658 llcHdr->ssap = 0xAA;
659 llcHdr->cntl = 0x03;
660 llcHdr->orgCode[0] = 0x0;
661 llcHdr->orgCode[1] = 0x0;
662 llcHdr->orgCode[2] = 0x0;
663 llcHdr->etherType = typeorlen;
665 AddDot11Hdr:
666 /* Make room for 802.11 hdr */
667 if (wmip->wmi_is_wmm_enabled)
669 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32));
670 if (A_NETBUF_PUSH(osbuf, hdrsize) != 0)
672 return A_NO_MEMORY;
674 wh = (struct ieee80211_frame *) A_NETBUF_DATA(osbuf);
675 wh->i_fc[0] = IEEE80211_FC0_SUBTYPE_QOS;
677 else
679 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_frame),sizeof(u32));
680 if (A_NETBUF_PUSH(osbuf, hdrsize) != 0)
682 return A_NO_MEMORY;
684 wh = (struct ieee80211_frame *) A_NETBUF_DATA(osbuf);
685 wh->i_fc[0] = IEEE80211_FC0_SUBTYPE_DATA;
687 /* Setup the SA & DA */
688 IEEE80211_ADDR_COPY(wh->i_addr2, macHdr.srcMac);
690 if (mode == INFRA_NETWORK) {
691 IEEE80211_ADDR_COPY(wh->i_addr3, macHdr.dstMac);
693 else if (mode == ADHOC_NETWORK) {
694 IEEE80211_ADDR_COPY(wh->i_addr1, macHdr.dstMac);
697 return (0);
701 wmi_dot11_hdr_remove(struct wmi_t *wmip, void *osbuf)
703 u8 *datap;
704 struct ieee80211_frame *pwh,wh;
705 u8 type,subtype;
706 ATH_LLC_SNAP_HDR *llcHdr;
707 ATH_MAC_HDR macHdr;
708 u32 hdrsize;
710 A_ASSERT(osbuf != NULL);
711 datap = A_NETBUF_DATA(osbuf);
713 pwh = (struct ieee80211_frame *)datap;
714 type = pwh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
715 subtype = pwh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
717 memcpy((u8 *)&wh, datap, sizeof(struct ieee80211_frame));
719 /* strip off the 802.11 hdr*/
720 if (subtype == IEEE80211_FC0_SUBTYPE_QOS) {
721 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32));
722 A_NETBUF_PULL(osbuf, hdrsize);
723 } else if (subtype == IEEE80211_FC0_SUBTYPE_DATA) {
724 A_NETBUF_PULL(osbuf, sizeof(struct ieee80211_frame));
727 datap = A_NETBUF_DATA(osbuf);
728 llcHdr = (ATH_LLC_SNAP_HDR *)(datap);
730 macHdr.typeOrLen = llcHdr->etherType;
731 A_MEMZERO(macHdr.dstMac, sizeof(macHdr.dstMac));
732 A_MEMZERO(macHdr.srcMac, sizeof(macHdr.srcMac));
734 switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) {
735 case IEEE80211_FC1_DIR_NODS:
736 IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr1);
737 IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr2);
738 break;
739 case IEEE80211_FC1_DIR_TODS:
740 IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr3);
741 IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr2);
742 break;
743 case IEEE80211_FC1_DIR_FROMDS:
744 IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr1);
745 IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr3);
746 break;
747 case IEEE80211_FC1_DIR_DSTODS:
748 break;
751 // Remove the LLC Hdr.
752 A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR));
754 // Insert the ATH MAC hdr.
756 A_NETBUF_PUSH(osbuf, sizeof(ATH_MAC_HDR));
757 datap = A_NETBUF_DATA(osbuf);
759 memcpy (datap, &macHdr, sizeof(ATH_MAC_HDR));
761 return 0;
765 * performs 802.3 to DIX encapsulation for received packets.
766 * Assumes the entire 802.3 header is contigous.
769 wmi_dot3_2_dix(void *osbuf)
771 u8 *datap;
772 ATH_MAC_HDR macHdr;
773 ATH_LLC_SNAP_HDR *llcHdr;
775 A_ASSERT(osbuf != NULL);
776 datap = A_NETBUF_DATA(osbuf);
778 memcpy(&macHdr, datap, sizeof(ATH_MAC_HDR));
779 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR));
780 macHdr.typeOrLen = llcHdr->etherType;
782 if (A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != 0) {
783 return A_NO_MEMORY;
786 datap = A_NETBUF_DATA(osbuf);
788 memcpy(datap, &macHdr, sizeof (ATH_MAC_HDR));
790 return (0);
794 * Removes a WMI data header
797 wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf)
799 A_ASSERT(osbuf != NULL);
801 return (A_NETBUF_PULL(osbuf, sizeof(WMI_DATA_HDR)));
804 void
805 wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg)
807 wlan_iterate_nodes(&wmip->wmi_scan_table, f, arg);
811 * WMI Extended Event received from Target.
814 wmi_control_rx_xtnd(struct wmi_t *wmip, void *osbuf)
816 WMIX_CMD_HDR *cmd;
817 u16 id;
818 u8 *datap;
819 u32 len;
820 int status = 0;
822 if (A_NETBUF_LEN(osbuf) < sizeof(WMIX_CMD_HDR)) {
823 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG));
824 wmip->wmi_stats.cmd_len_err++;
825 return A_ERROR;
828 cmd = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf);
829 id = cmd->commandId;
831 if (A_NETBUF_PULL(osbuf, sizeof(WMIX_CMD_HDR)) != 0) {
832 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG));
833 wmip->wmi_stats.cmd_len_err++;
834 return A_ERROR;
837 datap = A_NETBUF_DATA(osbuf);
838 len = A_NETBUF_LEN(osbuf);
840 switch (id) {
841 case (WMIX_DSETOPENREQ_EVENTID):
842 status = wmi_dset_open_req_rx(wmip, datap, len);
843 break;
844 #ifdef CONFIG_HOST_DSET_SUPPORT
845 case (WMIX_DSETCLOSE_EVENTID):
846 status = wmi_dset_close_rx(wmip, datap, len);
847 break;
848 case (WMIX_DSETDATAREQ_EVENTID):
849 status = wmi_dset_data_req_rx(wmip, datap, len);
850 break;
851 #endif /* CONFIG_HOST_DSET_SUPPORT */
852 case (WMIX_HB_CHALLENGE_RESP_EVENTID):
853 wmi_hbChallengeResp_rx(wmip, datap, len);
854 break;
855 case (WMIX_DBGLOG_EVENTID):
856 wmi_dbglog_event_rx(wmip, datap, len);
857 break;
858 #if defined(CONFIG_TARGET_PROFILE_SUPPORT)
859 case (WMIX_PROF_COUNT_EVENTID):
860 wmi_prof_count_rx(wmip, datap, len);
861 break;
862 #endif /* CONFIG_TARGET_PROFILE_SUPPORT */
863 default:
864 A_DPRINTF(DBG_WMI|DBG_ERROR,
865 (DBGFMT "Unknown id 0x%x\n", DBGARG, id));
866 wmip->wmi_stats.cmd_id_err++;
867 status = A_ERROR;
868 break;
871 return status;
875 * Control Path
877 u32 cmdRecvNum;
880 wmi_control_rx(struct wmi_t *wmip, void *osbuf)
882 WMI_CMD_HDR *cmd;
883 u16 id;
884 u8 *datap;
885 u32 len, i, loggingReq;
886 int status = 0;
888 A_ASSERT(osbuf != NULL);
889 if (A_NETBUF_LEN(osbuf) < sizeof(WMI_CMD_HDR)) {
890 A_NETBUF_FREE(osbuf);
891 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG));
892 wmip->wmi_stats.cmd_len_err++;
893 return A_ERROR;
896 cmd = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf);
897 id = cmd->commandId;
899 if (A_NETBUF_PULL(osbuf, sizeof(WMI_CMD_HDR)) != 0) {
900 A_NETBUF_FREE(osbuf);
901 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG));
902 wmip->wmi_stats.cmd_len_err++;
903 return A_ERROR;
906 datap = A_NETBUF_DATA(osbuf);
907 len = A_NETBUF_LEN(osbuf);
909 loggingReq = 0;
911 ar6000_get_driver_cfg(wmip->wmi_devt,
912 AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS,
913 &loggingReq);
915 if(loggingReq) {
916 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI %d \n",id));
917 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI recv, MsgNo %d : ", cmdRecvNum));
918 for(i = 0; i < len; i++)
919 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("%x ", datap[i]));
920 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("\n"));
923 LOCK_WMI(wmip);
924 cmdRecvNum++;
925 UNLOCK_WMI(wmip);
927 switch (id) {
928 case (WMI_GET_BITRATE_CMDID):
929 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_BITRATE_CMDID\n", DBGARG));
930 status = wmi_bitrate_reply_rx(wmip, datap, len);
931 break;
932 case (WMI_GET_CHANNEL_LIST_CMDID):
933 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_CHANNEL_LIST_CMDID\n", DBGARG));
934 status = wmi_channelList_reply_rx(wmip, datap, len);
935 break;
936 case (WMI_GET_TX_PWR_CMDID):
937 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_TX_PWR_CMDID\n", DBGARG));
938 status = wmi_txPwr_reply_rx(wmip, datap, len);
939 break;
940 case (WMI_READY_EVENTID):
941 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_READY_EVENTID\n", DBGARG));
942 status = wmi_ready_event_rx(wmip, datap, len);
943 A_WMI_DBGLOG_INIT_DONE(wmip->wmi_devt);
944 break;
945 case (WMI_CONNECT_EVENTID):
946 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CONNECT_EVENTID\n", DBGARG));
947 status = wmi_connect_event_rx(wmip, datap, len);
948 break;
949 case (WMI_DISCONNECT_EVENTID):
950 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_DISCONNECT_EVENTID\n", DBGARG));
951 status = wmi_disconnect_event_rx(wmip, datap, len);
952 break;
953 case (WMI_PEER_NODE_EVENTID):
954 A_DPRINTF (DBG_WMI, (DBGFMT "WMI_PEER_NODE_EVENTID\n", DBGARG));
955 status = wmi_peer_node_event_rx(wmip, datap, len);
956 break;
957 case (WMI_TKIP_MICERR_EVENTID):
958 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TKIP_MICERR_EVENTID\n", DBGARG));
959 status = wmi_tkip_micerr_event_rx(wmip, datap, len);
960 break;
961 case (WMI_BSSINFO_EVENTID):
962 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BSSINFO_EVENTID\n", DBGARG));
965 * convert WMI_BSS_INFO_HDR2 to WMI_BSS_INFO_HDR
966 * Take a local copy of the WMI_BSS_INFO_HDR2 from the wmi buffer
967 * and reconstruct the WMI_BSS_INFO_HDR in its place
969 WMI_BSS_INFO_HDR2 bih2;
970 WMI_BSS_INFO_HDR *bih;
971 memcpy(&bih2, datap, sizeof(WMI_BSS_INFO_HDR2));
973 A_NETBUF_PUSH(osbuf, 4);
974 datap = A_NETBUF_DATA(osbuf);
975 len = A_NETBUF_LEN(osbuf);
976 bih = (WMI_BSS_INFO_HDR *)datap;
978 bih->channel = bih2.channel;
979 bih->frameType = bih2.frameType;
980 bih->snr = bih2.snr;
981 bih->rssi = bih2.snr - 95;
982 bih->ieMask = bih2.ieMask;
983 memcpy(bih->bssid, bih2.bssid, ATH_MAC_LEN);
985 status = wmi_bssInfo_event_rx(wmip, datap, len);
987 break;
988 case (WMI_REGDOMAIN_EVENTID):
989 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REGDOMAIN_EVENTID\n", DBGARG));
990 status = wmi_regDomain_event_rx(wmip, datap, len);
991 break;
992 case (WMI_PSTREAM_TIMEOUT_EVENTID):
993 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_PSTREAM_TIMEOUT_EVENTID\n", DBGARG));
994 status = wmi_pstream_timeout_event_rx(wmip, datap, len);
995 break;
996 case (WMI_NEIGHBOR_REPORT_EVENTID):
997 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_NEIGHBOR_REPORT_EVENTID\n", DBGARG));
998 status = wmi_neighborReport_event_rx(wmip, datap, len);
999 break;
1000 case (WMI_SCAN_COMPLETE_EVENTID):
1001 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SCAN_COMPLETE_EVENTID\n", DBGARG));
1002 status = wmi_scanComplete_rx(wmip, datap, len);
1003 break;
1004 case (WMI_CMDERROR_EVENTID):
1005 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CMDERROR_EVENTID\n", DBGARG));
1006 status = wmi_errorEvent_rx(wmip, datap, len);
1007 break;
1008 case (WMI_REPORT_STATISTICS_EVENTID):
1009 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_STATISTICS_EVENTID\n", DBGARG));
1010 status = wmi_statsEvent_rx(wmip, datap, len);
1011 break;
1012 case (WMI_RSSI_THRESHOLD_EVENTID):
1013 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_RSSI_THRESHOLD_EVENTID\n", DBGARG));
1014 status = wmi_rssiThresholdEvent_rx(wmip, datap, len);
1015 break;
1016 case (WMI_ERROR_REPORT_EVENTID):
1017 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_ERROR_REPORT_EVENTID\n", DBGARG));
1018 status = wmi_reportErrorEvent_rx(wmip, datap, len);
1019 break;
1020 case (WMI_OPT_RX_FRAME_EVENTID):
1021 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_OPT_RX_FRAME_EVENTID\n", DBGARG));
1022 status = wmi_opt_frame_event_rx(wmip, datap, len);
1023 break;
1024 case (WMI_REPORT_ROAM_TBL_EVENTID):
1025 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_ROAM_TBL_EVENTID\n", DBGARG));
1026 status = wmi_roam_tbl_event_rx(wmip, datap, len);
1027 break;
1028 case (WMI_EXTENSION_EVENTID):
1029 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_EXTENSION_EVENTID\n", DBGARG));
1030 status = wmi_control_rx_xtnd(wmip, osbuf);
1031 break;
1032 case (WMI_CAC_EVENTID):
1033 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CAC_EVENTID\n", DBGARG));
1034 status = wmi_cac_event_rx(wmip, datap, len);
1035 break;
1036 case (WMI_CHANNEL_CHANGE_EVENTID):
1037 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CHANNEL_CHANGE_EVENTID\n", DBGARG));
1038 status = wmi_channel_change_event_rx(wmip, datap, len);
1039 break;
1040 case (WMI_REPORT_ROAM_DATA_EVENTID):
1041 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_ROAM_DATA_EVENTID\n", DBGARG));
1042 status = wmi_roam_data_event_rx(wmip, datap, len);
1043 break;
1044 #ifdef CONFIG_HOST_TCMD_SUPPORT
1045 case (WMI_TEST_EVENTID):
1046 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TEST_EVENTID\n", DBGARG));
1047 status = wmi_tcmd_test_report_rx(wmip, datap, len);
1048 break;
1049 #endif
1050 case (WMI_GET_FIXRATES_CMDID):
1051 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_FIXRATES_CMDID\n", DBGARG));
1052 status = wmi_ratemask_reply_rx(wmip, datap, len);
1053 break;
1054 case (WMI_TX_RETRY_ERR_EVENTID):
1055 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TX_RETRY_ERR_EVENTID\n", DBGARG));
1056 status = wmi_txRetryErrEvent_rx(wmip, datap, len);
1057 break;
1058 case (WMI_SNR_THRESHOLD_EVENTID):
1059 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SNR_THRESHOLD_EVENTID\n", DBGARG));
1060 status = wmi_snrThresholdEvent_rx(wmip, datap, len);
1061 break;
1062 case (WMI_LQ_THRESHOLD_EVENTID):
1063 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_LQ_THRESHOLD_EVENTID\n", DBGARG));
1064 status = wmi_lqThresholdEvent_rx(wmip, datap, len);
1065 break;
1066 case (WMI_APLIST_EVENTID):
1067 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Received APLIST Event\n"));
1068 status = wmi_aplistEvent_rx(wmip, datap, len);
1069 break;
1070 case (WMI_GET_KEEPALIVE_CMDID):
1071 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_KEEPALIVE_CMDID\n", DBGARG));
1072 status = wmi_keepalive_reply_rx(wmip, datap, len);
1073 break;
1074 case (WMI_GET_WOW_LIST_EVENTID):
1075 status = wmi_get_wow_list_event_rx(wmip, datap, len);
1076 break;
1077 case (WMI_GET_PMKID_LIST_EVENTID):
1078 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_PMKID_LIST Event\n", DBGARG));
1079 status = wmi_get_pmkid_list_event_rx(wmip, datap, len);
1080 break;
1081 case (WMI_PSPOLL_EVENTID):
1082 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_PSPOLL_EVENT\n", DBGARG));
1083 status = wmi_pspoll_event_rx(wmip, datap, len);
1084 break;
1085 case (WMI_DTIMEXPIRY_EVENTID):
1086 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_DTIMEXPIRY_EVENT\n", DBGARG));
1087 status = wmi_dtimexpiry_event_rx(wmip, datap, len);
1088 break;
1089 case (WMI_SET_PARAMS_REPLY_EVENTID):
1090 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SET_PARAMS_REPLY Event\n", DBGARG));
1091 status = wmi_set_params_event_rx(wmip, datap, len);
1092 break;
1093 case (WMI_ADDBA_REQ_EVENTID):
1094 status = wmi_addba_req_event_rx(wmip, datap, len);
1095 break;
1096 case (WMI_ADDBA_RESP_EVENTID):
1097 status = wmi_addba_resp_event_rx(wmip, datap, len);
1098 break;
1099 case (WMI_DELBA_REQ_EVENTID):
1100 status = wmi_delba_req_event_rx(wmip, datap, len);
1101 break;
1102 case (WMI_REPORT_BTCOEX_CONFIG_EVENTID):
1103 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BTCOEX_CONFIG_EVENTID", DBGARG));
1104 status = wmi_btcoex_config_event_rx(wmip, datap, len);
1105 break;
1106 case (WMI_REPORT_BTCOEX_STATS_EVENTID):
1107 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BTCOEX_STATS_EVENTID", DBGARG));
1108 status = wmi_btcoex_stats_event_rx(wmip, datap, len);
1109 break;
1110 case (WMI_TX_COMPLETE_EVENTID):
1112 int index;
1113 TX_COMPLETE_MSG_V1 *pV1;
1114 WMI_TX_COMPLETE_EVENT *pEv = (WMI_TX_COMPLETE_EVENT *)datap;
1115 A_PRINTF("comp: %d %d %d\n", pEv->numMessages, pEv->msgLen, pEv->msgType);
1117 for(index = 0 ; index < pEv->numMessages ; index++) {
1118 pV1 = (TX_COMPLETE_MSG_V1 *)(datap + sizeof(WMI_TX_COMPLETE_EVENT) + index*sizeof(TX_COMPLETE_MSG_V1));
1119 A_PRINTF("msg: %d %d %d %d\n", pV1->status, pV1->pktID, pV1->rateIdx, pV1->ackFailures);
1122 break;
1123 case (WMI_HCI_EVENT_EVENTID):
1124 status = wmi_hci_event_rx(wmip, datap, len);
1125 break;
1126 #ifdef WAPI_ENABLE
1127 case (WMI_WAPI_REKEY_EVENTID):
1128 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_WAPI_REKEY_EVENTID", DBGARG));
1129 status = wmi_wapi_rekey_event_rx(wmip, datap, len);
1130 break;
1131 #endif
1132 default:
1133 A_DPRINTF(DBG_WMI|DBG_ERROR,
1134 (DBGFMT "Unknown id 0x%x\n", DBGARG, id));
1135 wmip->wmi_stats.cmd_id_err++;
1136 status = A_ERROR;
1137 break;
1140 A_NETBUF_FREE(osbuf);
1142 return status;
1145 /* Send a "simple" wmi command -- one with no arguments */
1146 static int
1147 wmi_simple_cmd(struct wmi_t *wmip, WMI_COMMAND_ID cmdid)
1149 void *osbuf;
1151 osbuf = A_NETBUF_ALLOC(0);
1152 if (osbuf == NULL) {
1153 return A_NO_MEMORY;
1156 return (wmi_cmd_send(wmip, osbuf, cmdid, NO_SYNC_WMIFLAG));
1159 /* Send a "simple" extended wmi command -- one with no arguments.
1160 Enabling this command only if GPIO or profiling support is enabled.
1161 This is to suppress warnings on some platforms */
1162 #if defined(CONFIG_TARGET_PROFILE_SUPPORT)
1163 static int
1164 wmi_simple_cmd_xtnd(struct wmi_t *wmip, WMIX_COMMAND_ID cmdid)
1166 void *osbuf;
1168 osbuf = A_NETBUF_ALLOC(0);
1169 if (osbuf == NULL) {
1170 return A_NO_MEMORY;
1173 return (wmi_cmd_send_xtnd(wmip, osbuf, cmdid, NO_SYNC_WMIFLAG));
1175 #endif
1177 static int
1178 wmi_ready_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1180 WMI_READY_EVENT *ev = (WMI_READY_EVENT *)datap;
1182 if (len < sizeof(WMI_READY_EVENT)) {
1183 return A_EINVAL;
1185 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1186 wmip->wmi_ready = true;
1187 A_WMI_READY_EVENT(wmip->wmi_devt, ev->macaddr, ev->phyCapability,
1188 ev->sw_version, ev->abi_version);
1190 return 0;
1193 #define LE_READ_4(p) \
1194 ((u32) \
1195 ((((u8 *)(p))[0] ) | (((u8 *)(p))[1] << 8) | \
1196 (((u8 *)(p))[2] << 16) | (((u8 *)(p))[3] << 24)))
1198 static int __inline
1199 iswmmoui(const u8 *frm)
1201 return frm[1] > 3 && LE_READ_4(frm+2) == ((WMM_OUI_TYPE<<24)|WMM_OUI);
1204 static int __inline
1205 iswmmparam(const u8 *frm)
1207 return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE;
1211 static int
1212 wmi_connect_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1214 WMI_CONNECT_EVENT *ev;
1215 u8 *pie,*peie;
1217 if (len < sizeof(WMI_CONNECT_EVENT))
1219 return A_EINVAL;
1221 ev = (WMI_CONNECT_EVENT *)datap;
1223 A_DPRINTF(DBG_WMI,
1224 (DBGFMT "freq %d bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
1225 DBGARG, ev->channel,
1226 ev->bssid[0], ev->bssid[1], ev->bssid[2],
1227 ev->bssid[3], ev->bssid[4], ev->bssid[5]));
1229 memcpy(wmip->wmi_bssid, ev->bssid, ATH_MAC_LEN);
1231 /* initialize pointer to start of assoc rsp IEs */
1232 pie = ev->assocInfo + ev->beaconIeLen + ev->assocReqLen +
1233 sizeof(u16) + /* capinfo*/
1234 sizeof(u16) + /* status Code */
1235 sizeof(u16) ; /* associd */
1237 /* initialize pointer to end of assoc rsp IEs */
1238 peie = ev->assocInfo + ev->beaconIeLen + ev->assocReqLen + ev->assocRespLen;
1240 while (pie < peie)
1242 switch (*pie)
1244 case IEEE80211_ELEMID_VENDOR:
1245 if (iswmmoui(pie))
1247 if(iswmmparam (pie))
1249 wmip->wmi_is_wmm_enabled = true;
1252 break;
1255 if (wmip->wmi_is_wmm_enabled)
1257 break;
1259 pie += pie[1] + 2;
1262 A_WMI_CONNECT_EVENT(wmip->wmi_devt, ev->channel, ev->bssid,
1263 ev->listenInterval, ev->beaconInterval,
1264 (NETWORK_TYPE) ev->networkType, ev->beaconIeLen,
1265 ev->assocReqLen, ev->assocRespLen,
1266 ev->assocInfo);
1268 return 0;
1271 static int
1272 wmi_regDomain_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1274 WMI_REG_DOMAIN_EVENT *ev;
1276 if (len < sizeof(*ev)) {
1277 return A_EINVAL;
1279 ev = (WMI_REG_DOMAIN_EVENT *)datap;
1281 A_WMI_REGDOMAIN_EVENT(wmip->wmi_devt, ev->regDomain);
1283 return 0;
1286 static int
1287 wmi_neighborReport_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1289 WMI_NEIGHBOR_REPORT_EVENT *ev;
1290 int numAps;
1292 if (len < sizeof(*ev)) {
1293 return A_EINVAL;
1295 ev = (WMI_NEIGHBOR_REPORT_EVENT *)datap;
1296 numAps = ev->numberOfAps;
1298 if (len < (int)(sizeof(*ev) + ((numAps - 1) * sizeof(WMI_NEIGHBOR_INFO)))) {
1299 return A_EINVAL;
1302 A_WMI_NEIGHBORREPORT_EVENT(wmip->wmi_devt, numAps, ev->neighbor);
1304 return 0;
1307 static int
1308 wmi_disconnect_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1310 WMI_DISCONNECT_EVENT *ev;
1311 wmip->wmi_traffic_class = 100;
1313 if (len < sizeof(WMI_DISCONNECT_EVENT)) {
1314 return A_EINVAL;
1316 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1318 ev = (WMI_DISCONNECT_EVENT *)datap;
1320 A_MEMZERO(wmip->wmi_bssid, sizeof(wmip->wmi_bssid));
1322 wmip->wmi_is_wmm_enabled = false;
1323 wmip->wmi_pair_crypto_type = NONE_CRYPT;
1324 wmip->wmi_grp_crypto_type = NONE_CRYPT;
1326 A_WMI_DISCONNECT_EVENT(wmip->wmi_devt, ev->disconnectReason, ev->bssid,
1327 ev->assocRespLen, ev->assocInfo, ev->protocolReasonStatus);
1329 return 0;
1332 static int
1333 wmi_peer_node_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1335 WMI_PEER_NODE_EVENT *ev;
1337 if (len < sizeof(WMI_PEER_NODE_EVENT)) {
1338 return A_EINVAL;
1340 ev = (WMI_PEER_NODE_EVENT *)datap;
1341 if (ev->eventCode == PEER_NODE_JOIN_EVENT) {
1342 A_DPRINTF (DBG_WMI, (DBGFMT "Joined node with Macaddr: ", DBGARG));
1343 } else if(ev->eventCode == PEER_NODE_LEAVE_EVENT) {
1344 A_DPRINTF (DBG_WMI, (DBGFMT "left node with Macaddr: ", DBGARG));
1347 A_WMI_PEER_EVENT (wmip->wmi_devt, ev->eventCode, ev->peerMacAddr);
1349 return 0;
1352 static int
1353 wmi_tkip_micerr_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1355 WMI_TKIP_MICERR_EVENT *ev;
1357 if (len < sizeof(*ev)) {
1358 return A_EINVAL;
1360 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1362 ev = (WMI_TKIP_MICERR_EVENT *)datap;
1363 A_WMI_TKIP_MICERR_EVENT(wmip->wmi_devt, ev->keyid, ev->ismcast);
1365 return 0;
1368 static int
1369 wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1371 bss_t *bss = NULL;
1372 WMI_BSS_INFO_HDR *bih;
1373 u8 *buf;
1374 u32 nodeCachingAllowed = 1;
1375 u8 cached_ssid_len = 0;
1376 u8 cached_ssid_buf[IEEE80211_NWID_LEN] = {0};
1377 u8 beacon_ssid_len = 0;
1379 if (len <= sizeof(WMI_BSS_INFO_HDR)) {
1380 return A_EINVAL;
1383 bih = (WMI_BSS_INFO_HDR *)datap;
1384 bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid);
1386 if (bih->rssi > 0) {
1387 if (NULL == bss)
1388 return 0; //no node found in the table, just drop the node with incorrect RSSI
1389 else
1390 bih->rssi = bss->ni_rssi; //Adjust RSSI in datap in case it is used in A_WMI_BSSINFO_EVENT_RX
1393 A_WMI_BSSINFO_EVENT_RX(wmip->wmi_devt, datap, len);
1394 /* What is driver config for wlan node caching? */
1395 if(ar6000_get_driver_cfg(wmip->wmi_devt,
1396 AR6000_DRIVER_CFG_GET_WLANNODECACHING,
1397 &nodeCachingAllowed) != 0) {
1398 wmi_node_return(wmip, bss);
1399 return A_EINVAL;
1402 if(!nodeCachingAllowed) {
1403 wmi_node_return(wmip, bss);
1404 return 0;
1407 buf = datap + sizeof(WMI_BSS_INFO_HDR);
1408 len -= sizeof(WMI_BSS_INFO_HDR);
1410 A_DPRINTF(DBG_WMI2, (DBGFMT "bssInfo event - ch %u, rssi %02x, "
1411 "bssid \"%pM\"\n", DBGARG, bih->channel,
1412 (unsigned char) bih->rssi, bih->bssid));
1414 if(wps_enable && (bih->frameType == PROBERESP_FTYPE) ) {
1415 wmi_node_return(wmip, bss);
1416 return 0;
1419 if (bss != NULL) {
1421 * Free up the node. Not the most efficient process given
1422 * we are about to allocate a new node but it is simple and should be
1423 * adequate.
1426 /* In case of hidden AP, beacon will not have ssid,
1427 * but a directed probe response will have it,
1428 * so cache the probe-resp-ssid if already present. */
1429 if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType))
1431 u8 *ie_ssid;
1433 ie_ssid = bss->ni_cie.ie_ssid;
1434 if(ie_ssid && (ie_ssid[1] <= IEEE80211_NWID_LEN) && (ie_ssid[2] != 0))
1436 cached_ssid_len = ie_ssid[1];
1437 memcpy(cached_ssid_buf, ie_ssid + 2, cached_ssid_len);
1442 * Use the current average rssi of associated AP base on assumpiton
1443 * 1. Most os with GUI will update RSSI by wmi_get_stats_cmd() periodically
1444 * 2. wmi_get_stats_cmd(..) will be called when calling wmi_startscan_cmd(...)
1445 * The average value of RSSI give end-user better feeling for instance value of scan result
1446 * It also sync up RSSI info in GUI between scan result and RSSI signal icon
1448 if (IEEE80211_ADDR_EQ(wmip->wmi_bssid, bih->bssid)) {
1449 bih->rssi = bss->ni_rssi;
1450 bih->snr = bss->ni_snr;
1453 wlan_node_reclaim(&wmip->wmi_scan_table, bss);
1456 /* beacon/probe response frame format
1457 * [8] time stamp
1458 * [2] beacon interval
1459 * [2] capability information
1460 * [tlv] ssid */
1461 beacon_ssid_len = buf[SSID_IE_LEN_INDEX];
1463 /* If ssid is cached for this hidden AP, then change buffer len accordingly. */
1464 if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) &&
1465 (0 != cached_ssid_len) &&
1466 (0 == beacon_ssid_len || (cached_ssid_len > beacon_ssid_len && 0 == buf[SSID_IE_LEN_INDEX + 1])))
1468 len += (cached_ssid_len - beacon_ssid_len);
1471 bss = wlan_node_alloc(&wmip->wmi_scan_table, len);
1472 if (bss == NULL) {
1473 return A_NO_MEMORY;
1476 bss->ni_snr = bih->snr;
1477 bss->ni_rssi = bih->rssi;
1478 A_ASSERT(bss->ni_buf != NULL);
1480 /* In case of hidden AP, beacon will not have ssid,
1481 * but a directed probe response will have it,
1482 * so place the cached-ssid(probe-resp) in the bssinfo. */
1483 if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) &&
1484 (0 != cached_ssid_len) &&
1485 (0 == beacon_ssid_len || (beacon_ssid_len && 0 == buf[SSID_IE_LEN_INDEX + 1])))
1487 u8 *ni_buf = bss->ni_buf;
1488 int buf_len = len;
1490 /* copy the first 14 bytes such as
1491 * time-stamp(8), beacon-interval(2), cap-info(2), ssid-id(1), ssid-len(1). */
1492 memcpy(ni_buf, buf, SSID_IE_LEN_INDEX + 1);
1494 ni_buf[SSID_IE_LEN_INDEX] = cached_ssid_len;
1495 ni_buf += (SSID_IE_LEN_INDEX + 1);
1497 buf += (SSID_IE_LEN_INDEX + 1);
1498 buf_len -= (SSID_IE_LEN_INDEX + 1);
1500 /* copy the cached ssid */
1501 memcpy(ni_buf, cached_ssid_buf, cached_ssid_len);
1502 ni_buf += cached_ssid_len;
1504 buf += beacon_ssid_len;
1505 buf_len -= beacon_ssid_len;
1507 if (cached_ssid_len > beacon_ssid_len)
1508 buf_len -= (cached_ssid_len - beacon_ssid_len);
1510 /* now copy the rest of bytes */
1511 memcpy(ni_buf, buf, buf_len);
1513 else
1514 memcpy(bss->ni_buf, buf, len);
1516 bss->ni_framelen = len;
1517 if (wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie) != 0) {
1518 wlan_node_free(bss);
1519 return A_EINVAL;
1523 * Update the frequency in ie_chan, overwriting of channel number
1524 * which is done in wlan_parse_beacon
1526 bss->ni_cie.ie_chan = bih->channel;
1527 wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid);
1529 return 0;
1532 static int
1533 wmi_opt_frame_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1535 bss_t *bss;
1536 WMI_OPT_RX_INFO_HDR *bih;
1537 u8 *buf;
1539 if (len <= sizeof(WMI_OPT_RX_INFO_HDR)) {
1540 return A_EINVAL;
1543 bih = (WMI_OPT_RX_INFO_HDR *)datap;
1544 buf = datap + sizeof(WMI_OPT_RX_INFO_HDR);
1545 len -= sizeof(WMI_OPT_RX_INFO_HDR);
1547 A_DPRINTF(DBG_WMI2, (DBGFMT "opt frame event %2.2x:%2.2x\n", DBGARG,
1548 bih->bssid[4], bih->bssid[5]));
1550 bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid);
1551 if (bss != NULL) {
1553 * Free up the node. Not the most efficient process given
1554 * we are about to allocate a new node but it is simple and should be
1555 * adequate.
1557 wlan_node_reclaim(&wmip->wmi_scan_table, bss);
1560 bss = wlan_node_alloc(&wmip->wmi_scan_table, len);
1561 if (bss == NULL) {
1562 return A_NO_MEMORY;
1565 bss->ni_snr = bih->snr;
1566 bss->ni_cie.ie_chan = bih->channel;
1567 A_ASSERT(bss->ni_buf != NULL);
1568 memcpy(bss->ni_buf, buf, len);
1569 wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid);
1571 return 0;
1574 /* This event indicates inactivity timeout of a fatpipe(pstream)
1575 * at the target
1577 static int
1578 wmi_pstream_timeout_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1580 WMI_PSTREAM_TIMEOUT_EVENT *ev;
1582 if (len < sizeof(WMI_PSTREAM_TIMEOUT_EVENT)) {
1583 return A_EINVAL;
1586 A_DPRINTF(DBG_WMI, (DBGFMT "wmi_pstream_timeout_event_rx\n", DBGARG));
1588 ev = (WMI_PSTREAM_TIMEOUT_EVENT *)datap;
1590 /* When the pstream (fat pipe == AC) timesout, it means there were no
1591 * thinStreams within this pstream & it got implicitly created due to
1592 * data flow on this AC. We start the inactivity timer only for
1593 * implicitly created pstream. Just reset the host state.
1595 /* Set the activeTsids for this AC to 0 */
1596 LOCK_WMI(wmip);
1597 wmip->wmi_streamExistsForAC[ev->trafficClass]=0;
1598 wmip->wmi_fatPipeExists &= ~(1 << ev->trafficClass);
1599 UNLOCK_WMI(wmip);
1601 /*Indicate inactivity to driver layer for this fatpipe (pstream)*/
1602 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, ev->trafficClass);
1604 return 0;
1607 static int
1608 wmi_bitrate_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1610 WMI_BIT_RATE_REPLY *reply;
1611 s32 rate;
1612 u32 sgi,index;
1613 /* 54149:
1614 * WMI_BIT_RATE_CMD structure is changed to WMI_BIT_RATE_REPLY.
1615 * since there is difference in the length and to avoid returning
1616 * error value.
1618 if (len < sizeof(WMI_BIT_RATE_REPLY)) {
1619 return A_EINVAL;
1621 reply = (WMI_BIT_RATE_REPLY *)datap;
1622 A_DPRINTF(DBG_WMI,
1623 (DBGFMT "Enter - rateindex %d\n", DBGARG, reply->rateIndex));
1625 if (reply->rateIndex == (s8) RATE_AUTO) {
1626 rate = RATE_AUTO;
1627 } else {
1628 // the SGI state is stored as the MSb of the rateIndex
1629 index = reply->rateIndex & 0x7f;
1630 sgi = (reply->rateIndex & 0x80)? 1:0;
1631 rate = wmi_rateTable[index][sgi];
1634 A_WMI_BITRATE_RX(wmip->wmi_devt, rate);
1635 return 0;
1638 static int
1639 wmi_ratemask_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1641 WMI_FIX_RATES_REPLY *reply;
1643 if (len < sizeof(WMI_FIX_RATES_REPLY)) {
1644 return A_EINVAL;
1646 reply = (WMI_FIX_RATES_REPLY *)datap;
1647 A_DPRINTF(DBG_WMI,
1648 (DBGFMT "Enter - fixed rate mask %x\n", DBGARG, reply->fixRateMask));
1650 A_WMI_RATEMASK_RX(wmip->wmi_devt, reply->fixRateMask);
1652 return 0;
1655 static int
1656 wmi_channelList_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1658 WMI_CHANNEL_LIST_REPLY *reply;
1660 if (len < sizeof(WMI_CHANNEL_LIST_REPLY)) {
1661 return A_EINVAL;
1663 reply = (WMI_CHANNEL_LIST_REPLY *)datap;
1664 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1666 A_WMI_CHANNELLIST_RX(wmip->wmi_devt, reply->numChannels,
1667 reply->channelList);
1669 return 0;
1672 static int
1673 wmi_txPwr_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1675 WMI_TX_PWR_REPLY *reply;
1677 if (len < sizeof(*reply)) {
1678 return A_EINVAL;
1680 reply = (WMI_TX_PWR_REPLY *)datap;
1681 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1683 A_WMI_TXPWR_RX(wmip->wmi_devt, reply->dbM);
1685 return 0;
1687 static int
1688 wmi_keepalive_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1690 WMI_GET_KEEPALIVE_CMD *reply;
1692 if (len < sizeof(*reply)) {
1693 return A_EINVAL;
1695 reply = (WMI_GET_KEEPALIVE_CMD *)datap;
1696 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1698 A_WMI_KEEPALIVE_RX(wmip->wmi_devt, reply->configured);
1700 return 0;
1704 static int
1705 wmi_dset_open_req_rx(struct wmi_t *wmip, u8 *datap, int len)
1707 WMIX_DSETOPENREQ_EVENT *dsetopenreq;
1709 if (len < sizeof(WMIX_DSETOPENREQ_EVENT)) {
1710 return A_EINVAL;
1712 dsetopenreq = (WMIX_DSETOPENREQ_EVENT *)datap;
1713 A_DPRINTF(DBG_WMI,
1714 (DBGFMT "Enter - dset_id=0x%x\n", DBGARG, dsetopenreq->dset_id));
1715 A_WMI_DSET_OPEN_REQ(wmip->wmi_devt,
1716 dsetopenreq->dset_id,
1717 dsetopenreq->targ_dset_handle,
1718 dsetopenreq->targ_reply_fn,
1719 dsetopenreq->targ_reply_arg);
1721 return 0;
1724 #ifdef CONFIG_HOST_DSET_SUPPORT
1725 static int
1726 wmi_dset_close_rx(struct wmi_t *wmip, u8 *datap, int len)
1728 WMIX_DSETCLOSE_EVENT *dsetclose;
1730 if (len < sizeof(WMIX_DSETCLOSE_EVENT)) {
1731 return A_EINVAL;
1733 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1735 dsetclose = (WMIX_DSETCLOSE_EVENT *)datap;
1736 A_WMI_DSET_CLOSE(wmip->wmi_devt, dsetclose->access_cookie);
1738 return 0;
1741 static int
1742 wmi_dset_data_req_rx(struct wmi_t *wmip, u8 *datap, int len)
1744 WMIX_DSETDATAREQ_EVENT *dsetdatareq;
1746 if (len < sizeof(WMIX_DSETDATAREQ_EVENT)) {
1747 return A_EINVAL;
1749 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1751 dsetdatareq = (WMIX_DSETDATAREQ_EVENT *)datap;
1752 A_WMI_DSET_DATA_REQ(wmip->wmi_devt,
1753 dsetdatareq->access_cookie,
1754 dsetdatareq->offset,
1755 dsetdatareq->length,
1756 dsetdatareq->targ_buf,
1757 dsetdatareq->targ_reply_fn,
1758 dsetdatareq->targ_reply_arg);
1760 return 0;
1762 #endif /* CONFIG_HOST_DSET_SUPPORT */
1764 static int
1765 wmi_scanComplete_rx(struct wmi_t *wmip, u8 *datap, int len)
1767 WMI_SCAN_COMPLETE_EVENT *ev;
1769 ev = (WMI_SCAN_COMPLETE_EVENT *)datap;
1770 if ((int)ev->status == 0) {
1771 wlan_refresh_inactive_nodes(&wmip->wmi_scan_table);
1773 A_WMI_SCANCOMPLETE_EVENT(wmip->wmi_devt, (int) ev->status);
1774 is_probe_ssid = false;
1776 return 0;
1780 * Target is reporting a programming error. This is for
1781 * developer aid only. Target only checks a few common violations
1782 * and it is responsibility of host to do all error checking.
1783 * Behavior of target after wmi error event is undefined.
1784 * A reset is recommended.
1786 static int
1787 wmi_errorEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
1789 WMI_CMD_ERROR_EVENT *ev;
1791 ev = (WMI_CMD_ERROR_EVENT *)datap;
1792 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Programming Error: cmd=%d ", ev->commandId));
1793 switch (ev->errorCode) {
1794 case (INVALID_PARAM):
1795 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal Parameter\n"));
1796 break;
1797 case (ILLEGAL_STATE):
1798 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal State\n"));
1799 break;
1800 case (INTERNAL_ERROR):
1801 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Internal Error\n"));
1802 break;
1805 return 0;
1809 static int
1810 wmi_statsEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
1812 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1814 A_WMI_TARGETSTATS_EVENT(wmip->wmi_devt, datap, len);
1816 return 0;
1819 static int
1820 wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
1822 WMI_RSSI_THRESHOLD_EVENT *reply;
1823 WMI_RSSI_THRESHOLD_VAL newThreshold;
1824 WMI_RSSI_THRESHOLD_PARAMS_CMD cmd;
1825 SQ_THRESHOLD_PARAMS *sq_thresh =
1826 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI];
1827 u8 upper_rssi_threshold, lower_rssi_threshold;
1828 s16 rssi;
1830 if (len < sizeof(*reply)) {
1831 return A_EINVAL;
1833 reply = (WMI_RSSI_THRESHOLD_EVENT *)datap;
1834 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1835 newThreshold = (WMI_RSSI_THRESHOLD_VAL) reply->range;
1836 rssi = reply->rssi;
1839 * Identify the threshold breached and communicate that to the app. After
1840 * that install a new set of thresholds based on the signal quality
1841 * reported by the target
1843 if (newThreshold) {
1844 /* Upper threshold breached */
1845 if (rssi < sq_thresh->upper_threshold[0]) {
1846 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious upper RSSI threshold event: "
1847 " %d\n", DBGARG, rssi));
1848 } else if ((rssi < sq_thresh->upper_threshold[1]) &&
1849 (rssi >= sq_thresh->upper_threshold[0]))
1851 newThreshold = WMI_RSSI_THRESHOLD1_ABOVE;
1852 } else if ((rssi < sq_thresh->upper_threshold[2]) &&
1853 (rssi >= sq_thresh->upper_threshold[1]))
1855 newThreshold = WMI_RSSI_THRESHOLD2_ABOVE;
1856 } else if ((rssi < sq_thresh->upper_threshold[3]) &&
1857 (rssi >= sq_thresh->upper_threshold[2]))
1859 newThreshold = WMI_RSSI_THRESHOLD3_ABOVE;
1860 } else if ((rssi < sq_thresh->upper_threshold[4]) &&
1861 (rssi >= sq_thresh->upper_threshold[3]))
1863 newThreshold = WMI_RSSI_THRESHOLD4_ABOVE;
1864 } else if ((rssi < sq_thresh->upper_threshold[5]) &&
1865 (rssi >= sq_thresh->upper_threshold[4]))
1867 newThreshold = WMI_RSSI_THRESHOLD5_ABOVE;
1868 } else if (rssi >= sq_thresh->upper_threshold[5]) {
1869 newThreshold = WMI_RSSI_THRESHOLD6_ABOVE;
1871 } else {
1872 /* Lower threshold breached */
1873 if (rssi > sq_thresh->lower_threshold[0]) {
1874 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious lower RSSI threshold event: "
1875 "%d %d\n", DBGARG, rssi, sq_thresh->lower_threshold[0]));
1876 } else if ((rssi > sq_thresh->lower_threshold[1]) &&
1877 (rssi <= sq_thresh->lower_threshold[0]))
1879 newThreshold = WMI_RSSI_THRESHOLD6_BELOW;
1880 } else if ((rssi > sq_thresh->lower_threshold[2]) &&
1881 (rssi <= sq_thresh->lower_threshold[1]))
1883 newThreshold = WMI_RSSI_THRESHOLD5_BELOW;
1884 } else if ((rssi > sq_thresh->lower_threshold[3]) &&
1885 (rssi <= sq_thresh->lower_threshold[2]))
1887 newThreshold = WMI_RSSI_THRESHOLD4_BELOW;
1888 } else if ((rssi > sq_thresh->lower_threshold[4]) &&
1889 (rssi <= sq_thresh->lower_threshold[3]))
1891 newThreshold = WMI_RSSI_THRESHOLD3_BELOW;
1892 } else if ((rssi > sq_thresh->lower_threshold[5]) &&
1893 (rssi <= sq_thresh->lower_threshold[4]))
1895 newThreshold = WMI_RSSI_THRESHOLD2_BELOW;
1896 } else if (rssi <= sq_thresh->lower_threshold[5]) {
1897 newThreshold = WMI_RSSI_THRESHOLD1_BELOW;
1900 /* Calculate and install the next set of thresholds */
1901 lower_rssi_threshold = ar6000_get_lower_threshold(rssi, sq_thresh,
1902 sq_thresh->lower_threshold_valid_count);
1903 upper_rssi_threshold = ar6000_get_upper_threshold(rssi, sq_thresh,
1904 sq_thresh->upper_threshold_valid_count);
1905 /* Issue a wmi command to install the thresholds */
1906 cmd.thresholdAbove1_Val = upper_rssi_threshold;
1907 cmd.thresholdBelow1_Val = lower_rssi_threshold;
1908 cmd.weight = sq_thresh->weight;
1909 cmd.pollTime = sq_thresh->polling_interval;
1911 rssi_event_value = rssi;
1913 if (wmi_send_rssi_threshold_params(wmip, &cmd) != 0) {
1914 A_DPRINTF(DBG_WMI, (DBGFMT "Unable to configure the RSSI thresholds\n",
1915 DBGARG));
1918 A_WMI_RSSI_THRESHOLD_EVENT(wmip->wmi_devt, newThreshold, reply->rssi);
1920 return 0;
1924 static int
1925 wmi_reportErrorEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
1927 WMI_TARGET_ERROR_REPORT_EVENT *reply;
1929 if (len < sizeof(*reply)) {
1930 return A_EINVAL;
1932 reply = (WMI_TARGET_ERROR_REPORT_EVENT *)datap;
1933 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1935 A_WMI_REPORT_ERROR_EVENT(wmip->wmi_devt, (WMI_TARGET_ERROR_VAL) reply->errorVal);
1937 return 0;
1940 static int
1941 wmi_cac_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1943 WMI_CAC_EVENT *reply;
1944 WMM_TSPEC_IE *tspec_ie;
1945 u16 activeTsids;
1947 if (len < sizeof(*reply)) {
1948 return A_EINVAL;
1950 reply = (WMI_CAC_EVENT *)datap;
1952 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1954 if ((reply->cac_indication == CAC_INDICATION_ADMISSION_RESP) &&
1955 (reply->statusCode != TSPEC_STATUS_CODE_ADMISSION_ACCEPTED)) {
1956 tspec_ie = (WMM_TSPEC_IE *) &(reply->tspecSuggestion);
1958 wmi_delete_pstream_cmd(wmip, reply->ac,
1959 (tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK);
1961 else if (reply->cac_indication == CAC_INDICATION_NO_RESP) {
1962 u8 i;
1964 /* following assumes that there is only one outstanding ADDTS request
1965 when this event is received */
1966 LOCK_WMI(wmip);
1967 activeTsids = wmip->wmi_streamExistsForAC[reply->ac];
1968 UNLOCK_WMI(wmip);
1970 for (i = 0; i < sizeof(activeTsids) * 8; i++) {
1971 if ((activeTsids >> i) & 1) {
1972 break;
1975 if (i < (sizeof(activeTsids) * 8)) {
1976 wmi_delete_pstream_cmd(wmip, reply->ac, i);
1980 * Ev#72990: Clear active tsids and Add missing handling
1981 * for delete qos stream from AP
1983 else if (reply->cac_indication == CAC_INDICATION_DELETE) {
1984 u8 tsid = 0;
1986 tspec_ie = (WMM_TSPEC_IE *) &(reply->tspecSuggestion);
1987 tsid= ((tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK);
1988 LOCK_WMI(wmip);
1989 wmip->wmi_streamExistsForAC[reply->ac] &= ~(1<<tsid);
1990 activeTsids = wmip->wmi_streamExistsForAC[reply->ac];
1991 UNLOCK_WMI(wmip);
1994 /* Indicate stream inactivity to driver layer only if all tsids
1995 * within this AC are deleted.
1997 if (!activeTsids) {
1998 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, reply->ac);
1999 wmip->wmi_fatPipeExists &= ~(1 << reply->ac);
2003 A_WMI_CAC_EVENT(wmip->wmi_devt, reply->ac,
2004 reply->cac_indication, reply->statusCode,
2005 reply->tspecSuggestion);
2007 return 0;
2010 static int
2011 wmi_channel_change_event_rx(struct wmi_t *wmip, u8 *datap, int len)
2013 WMI_CHANNEL_CHANGE_EVENT *reply;
2015 if (len < sizeof(*reply)) {
2016 return A_EINVAL;
2018 reply = (WMI_CHANNEL_CHANGE_EVENT *)datap;
2019 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2021 A_WMI_CHANNEL_CHANGE_EVENT(wmip->wmi_devt, reply->oldChannel,
2022 reply->newChannel);
2024 return 0;
2027 static int
2028 wmi_hbChallengeResp_rx(struct wmi_t *wmip, u8 *datap, int len)
2030 WMIX_HB_CHALLENGE_RESP_EVENT *reply;
2032 if (len < sizeof(*reply)) {
2033 return A_EINVAL;
2035 reply = (WMIX_HB_CHALLENGE_RESP_EVENT *)datap;
2036 A_DPRINTF(DBG_WMI, (DBGFMT "wmi: challenge response event\n", DBGARG));
2038 A_WMI_HBCHALLENGERESP_EVENT(wmip->wmi_devt, reply->cookie, reply->source);
2040 return 0;
2043 static int
2044 wmi_roam_tbl_event_rx(struct wmi_t *wmip, u8 *datap, int len)
2046 WMI_TARGET_ROAM_TBL *reply;
2048 if (len < sizeof(*reply)) {
2049 return A_EINVAL;
2051 reply = (WMI_TARGET_ROAM_TBL *)datap;
2052 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2054 A_WMI_ROAM_TABLE_EVENT(wmip->wmi_devt, reply);
2056 return 0;
2059 static int
2060 wmi_roam_data_event_rx(struct wmi_t *wmip, u8 *datap, int len)
2062 WMI_TARGET_ROAM_DATA *reply;
2064 if (len < sizeof(*reply)) {
2065 return A_EINVAL;
2067 reply = (WMI_TARGET_ROAM_DATA *)datap;
2068 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2070 A_WMI_ROAM_DATA_EVENT(wmip->wmi_devt, reply);
2072 return 0;
2075 static int
2076 wmi_txRetryErrEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
2078 if (len < sizeof(WMI_TX_RETRY_ERR_EVENT)) {
2079 return A_EINVAL;
2081 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2083 A_WMI_TX_RETRY_ERR_EVENT(wmip->wmi_devt);
2085 return 0;
2088 static int
2089 wmi_snrThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
2091 WMI_SNR_THRESHOLD_EVENT *reply;
2092 SQ_THRESHOLD_PARAMS *sq_thresh =
2093 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_SNR];
2094 WMI_SNR_THRESHOLD_VAL newThreshold;
2095 WMI_SNR_THRESHOLD_PARAMS_CMD cmd;
2096 u8 upper_snr_threshold, lower_snr_threshold;
2097 s16 snr;
2099 if (len < sizeof(*reply)) {
2100 return A_EINVAL;
2102 reply = (WMI_SNR_THRESHOLD_EVENT *)datap;
2103 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2105 newThreshold = (WMI_SNR_THRESHOLD_VAL) reply->range;
2106 snr = reply->snr;
2108 * Identify the threshold breached and communicate that to the app. After
2109 * that install a new set of thresholds based on the signal quality
2110 * reported by the target
2112 if (newThreshold) {
2113 /* Upper threshold breached */
2114 if (snr < sq_thresh->upper_threshold[0]) {
2115 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious upper SNR threshold event: "
2116 "%d\n", DBGARG, snr));
2117 } else if ((snr < sq_thresh->upper_threshold[1]) &&
2118 (snr >= sq_thresh->upper_threshold[0]))
2120 newThreshold = WMI_SNR_THRESHOLD1_ABOVE;
2121 } else if ((snr < sq_thresh->upper_threshold[2]) &&
2122 (snr >= sq_thresh->upper_threshold[1]))
2124 newThreshold = WMI_SNR_THRESHOLD2_ABOVE;
2125 } else if ((snr < sq_thresh->upper_threshold[3]) &&
2126 (snr >= sq_thresh->upper_threshold[2]))
2128 newThreshold = WMI_SNR_THRESHOLD3_ABOVE;
2129 } else if (snr >= sq_thresh->upper_threshold[3]) {
2130 newThreshold = WMI_SNR_THRESHOLD4_ABOVE;
2132 } else {
2133 /* Lower threshold breached */
2134 if (snr > sq_thresh->lower_threshold[0]) {
2135 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious lower SNR threshold event: "
2136 "%d %d\n", DBGARG, snr, sq_thresh->lower_threshold[0]));
2137 } else if ((snr > sq_thresh->lower_threshold[1]) &&
2138 (snr <= sq_thresh->lower_threshold[0]))
2140 newThreshold = WMI_SNR_THRESHOLD4_BELOW;
2141 } else if ((snr > sq_thresh->lower_threshold[2]) &&
2142 (snr <= sq_thresh->lower_threshold[1]))
2144 newThreshold = WMI_SNR_THRESHOLD3_BELOW;
2145 } else if ((snr > sq_thresh->lower_threshold[3]) &&
2146 (snr <= sq_thresh->lower_threshold[2]))
2148 newThreshold = WMI_SNR_THRESHOLD2_BELOW;
2149 } else if (snr <= sq_thresh->lower_threshold[3]) {
2150 newThreshold = WMI_SNR_THRESHOLD1_BELOW;
2154 /* Calculate and install the next set of thresholds */
2155 lower_snr_threshold = ar6000_get_lower_threshold(snr, sq_thresh,
2156 sq_thresh->lower_threshold_valid_count);
2157 upper_snr_threshold = ar6000_get_upper_threshold(snr, sq_thresh,
2158 sq_thresh->upper_threshold_valid_count);
2160 /* Issue a wmi command to install the thresholds */
2161 cmd.thresholdAbove1_Val = upper_snr_threshold;
2162 cmd.thresholdBelow1_Val = lower_snr_threshold;
2163 cmd.weight = sq_thresh->weight;
2164 cmd.pollTime = sq_thresh->polling_interval;
2166 A_DPRINTF(DBG_WMI, (DBGFMT "snr: %d, threshold: %d, lower: %d, upper: %d\n"
2167 ,DBGARG, snr, newThreshold, lower_snr_threshold,
2168 upper_snr_threshold));
2170 snr_event_value = snr;
2172 if (wmi_send_snr_threshold_params(wmip, &cmd) != 0) {
2173 A_DPRINTF(DBG_WMI, (DBGFMT "Unable to configure the SNR thresholds\n",
2174 DBGARG));
2176 A_WMI_SNR_THRESHOLD_EVENT_RX(wmip->wmi_devt, newThreshold, reply->snr);
2178 return 0;
2181 static int
2182 wmi_lqThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
2184 WMI_LQ_THRESHOLD_EVENT *reply;
2186 if (len < sizeof(*reply)) {
2187 return A_EINVAL;
2189 reply = (WMI_LQ_THRESHOLD_EVENT *)datap;
2190 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2192 A_WMI_LQ_THRESHOLD_EVENT_RX(wmip->wmi_devt,
2193 (WMI_LQ_THRESHOLD_VAL) reply->range,
2194 reply->lq);
2196 return 0;
2199 static int
2200 wmi_aplistEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
2202 u16 ap_info_entry_size;
2203 WMI_APLIST_EVENT *ev = (WMI_APLIST_EVENT *)datap;
2204 WMI_AP_INFO_V1 *ap_info_v1;
2205 u8 i;
2207 if (len < sizeof(WMI_APLIST_EVENT)) {
2208 return A_EINVAL;
2211 if (ev->apListVer == APLIST_VER1) {
2212 ap_info_entry_size = sizeof(WMI_AP_INFO_V1);
2213 ap_info_v1 = (WMI_AP_INFO_V1 *)ev->apList;
2214 } else {
2215 return A_EINVAL;
2218 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Number of APs in APLIST Event is %d\n", ev->numAP));
2219 if (len < (int)(sizeof(WMI_APLIST_EVENT) +
2220 (ev->numAP - 1) * ap_info_entry_size))
2222 return A_EINVAL;
2226 * AP List Ver1 Contents
2228 for (i = 0; i < ev->numAP; i++) {
2229 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("AP#%d BSSID %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x "\
2230 "Channel %d\n", i,
2231 ap_info_v1->bssid[0], ap_info_v1->bssid[1],
2232 ap_info_v1->bssid[2], ap_info_v1->bssid[3],
2233 ap_info_v1->bssid[4], ap_info_v1->bssid[5],
2234 ap_info_v1->channel));
2235 ap_info_v1++;
2237 return 0;
2240 static int
2241 wmi_dbglog_event_rx(struct wmi_t *wmip, u8 *datap, int len)
2243 u32 dropped;
2245 dropped = *((u32 *)datap);
2246 datap += sizeof(dropped);
2247 len -= sizeof(dropped);
2248 A_WMI_DBGLOG_EVENT(wmip->wmi_devt, dropped, (s8 *)datap, len);
2249 return 0;
2253 * Called to send a wmi command. Command specific data is already built
2254 * on osbuf and current osbuf->data points to it.
2257 wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId,
2258 WMI_SYNC_FLAG syncflag)
2260 int status;
2261 #define IS_OPT_TX_CMD(cmdId) ((cmdId == WMI_OPT_TX_FRAME_CMDID))
2262 WMI_CMD_HDR *cHdr;
2263 HTC_ENDPOINT_ID eid = wmip->wmi_endpoint_id;
2265 A_ASSERT(osbuf != NULL);
2267 if (syncflag >= END_WMIFLAG) {
2268 A_NETBUF_FREE(osbuf);
2269 return A_EINVAL;
2272 if ((syncflag == SYNC_BEFORE_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) {
2274 * We want to make sure all data currently queued is transmitted before
2275 * the cmd execution. Establish a new sync point.
2277 wmi_sync_point(wmip);
2280 if (A_NETBUF_PUSH(osbuf, sizeof(WMI_CMD_HDR)) != 0) {
2281 A_NETBUF_FREE(osbuf);
2282 return A_NO_MEMORY;
2285 cHdr = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf);
2286 cHdr->commandId = (u16) cmdId;
2287 cHdr->info1 = 0; // added for virtual interface
2290 * Only for OPT_TX_CMD, use BE endpoint.
2292 if (IS_OPT_TX_CMD(cmdId)) {
2293 if ((status=wmi_data_hdr_add(wmip, osbuf, OPT_MSGTYPE, false, false,0,NULL)) != 0) {
2294 A_NETBUF_FREE(osbuf);
2295 return status;
2297 eid = A_WMI_Ac2EndpointID(wmip->wmi_devt, WMM_AC_BE);
2299 A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid);
2301 if ((syncflag == SYNC_AFTER_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) {
2303 * We want to make sure all new data queued waits for the command to
2304 * execute. Establish a new sync point.
2306 wmi_sync_point(wmip);
2308 return (0);
2309 #undef IS_OPT_TX_CMD
2313 wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId,
2314 WMI_SYNC_FLAG syncflag)
2316 WMIX_CMD_HDR *cHdr;
2318 if (A_NETBUF_PUSH(osbuf, sizeof(WMIX_CMD_HDR)) != 0) {
2319 A_NETBUF_FREE(osbuf);
2320 return A_NO_MEMORY;
2323 cHdr = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf);
2324 cHdr->commandId = (u32) cmdId;
2326 return wmi_cmd_send(wmip, osbuf, WMI_EXTENSION_CMDID, syncflag);
2330 wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType,
2331 DOT11_AUTH_MODE dot11AuthMode, AUTH_MODE authMode,
2332 CRYPTO_TYPE pairwiseCrypto, u8 pairwiseCryptoLen,
2333 CRYPTO_TYPE groupCrypto, u8 groupCryptoLen,
2334 int ssidLength, u8 *ssid,
2335 u8 *bssid, u16 channel, u32 ctrl_flags)
2337 void *osbuf;
2338 WMI_CONNECT_CMD *cc;
2339 wmip->wmi_traffic_class = 100;
2341 if ((pairwiseCrypto == NONE_CRYPT) && (groupCrypto != NONE_CRYPT)) {
2342 return A_EINVAL;
2344 if ((pairwiseCrypto != NONE_CRYPT) && (groupCrypto == NONE_CRYPT)) {
2345 return A_EINVAL;
2348 osbuf = A_NETBUF_ALLOC(sizeof(WMI_CONNECT_CMD));
2349 if (osbuf == NULL) {
2350 return A_NO_MEMORY;
2353 A_NETBUF_PUT(osbuf, sizeof(WMI_CONNECT_CMD));
2355 cc = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf));
2356 A_MEMZERO(cc, sizeof(*cc));
2358 if (ssidLength)
2360 memcpy(cc->ssid, ssid, ssidLength);
2363 cc->ssidLength = ssidLength;
2364 cc->networkType = netType;
2365 cc->dot11AuthMode = dot11AuthMode;
2366 cc->authMode = authMode;
2367 cc->pairwiseCryptoType = pairwiseCrypto;
2368 cc->pairwiseCryptoLen = pairwiseCryptoLen;
2369 cc->groupCryptoType = groupCrypto;
2370 cc->groupCryptoLen = groupCryptoLen;
2371 cc->channel = channel;
2372 cc->ctrl_flags = ctrl_flags;
2374 if (bssid != NULL) {
2375 memcpy(cc->bssid, bssid, ATH_MAC_LEN);
2378 wmip->wmi_pair_crypto_type = pairwiseCrypto;
2379 wmip->wmi_grp_crypto_type = groupCrypto;
2381 return (wmi_cmd_send(wmip, osbuf, WMI_CONNECT_CMDID, NO_SYNC_WMIFLAG));
2385 wmi_reconnect_cmd(struct wmi_t *wmip, u8 *bssid, u16 channel)
2387 void *osbuf;
2388 WMI_RECONNECT_CMD *cc;
2389 wmip->wmi_traffic_class = 100;
2391 osbuf = A_NETBUF_ALLOC(sizeof(WMI_RECONNECT_CMD));
2392 if (osbuf == NULL) {
2393 return A_NO_MEMORY;
2396 A_NETBUF_PUT(osbuf, sizeof(WMI_RECONNECT_CMD));
2398 cc = (WMI_RECONNECT_CMD *)(A_NETBUF_DATA(osbuf));
2399 A_MEMZERO(cc, sizeof(*cc));
2401 cc->channel = channel;
2403 if (bssid != NULL) {
2404 memcpy(cc->bssid, bssid, ATH_MAC_LEN);
2407 return (wmi_cmd_send(wmip, osbuf, WMI_RECONNECT_CMDID, NO_SYNC_WMIFLAG));
2411 wmi_disconnect_cmd(struct wmi_t *wmip)
2413 int status;
2414 wmip->wmi_traffic_class = 100;
2416 /* Bug fix for 24817(elevator bug) - the disconnect command does not
2417 need to do a SYNC before.*/
2418 status = wmi_simple_cmd(wmip, WMI_DISCONNECT_CMDID);
2420 return status;
2424 wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType,
2425 u32 forceFgScan, u32 isLegacy,
2426 u32 homeDwellTime, u32 forceScanInterval,
2427 s8 numChan, u16 *channelList)
2429 void *osbuf;
2430 WMI_START_SCAN_CMD *sc;
2431 s8 size;
2433 size = sizeof (*sc);
2435 if ((scanType != WMI_LONG_SCAN) && (scanType != WMI_SHORT_SCAN)) {
2436 return A_EINVAL;
2439 if (numChan) {
2440 if (numChan > WMI_MAX_CHANNELS) {
2441 return A_EINVAL;
2443 size += sizeof(u16) * (numChan - 1);
2446 osbuf = A_NETBUF_ALLOC(size);
2447 if (osbuf == NULL) {
2448 return A_NO_MEMORY;
2451 A_NETBUF_PUT(osbuf, size);
2453 sc = (WMI_START_SCAN_CMD *)(A_NETBUF_DATA(osbuf));
2454 sc->scanType = scanType;
2455 sc->forceFgScan = forceFgScan;
2456 sc->isLegacy = isLegacy;
2457 sc->homeDwellTime = homeDwellTime;
2458 sc->forceScanInterval = forceScanInterval;
2459 sc->numChannels = numChan;
2460 if (numChan) {
2461 memcpy(sc->channelList, channelList, numChan * sizeof(u16));
2464 return (wmi_cmd_send(wmip, osbuf, WMI_START_SCAN_CMDID, NO_SYNC_WMIFLAG));
2468 wmi_scanparams_cmd(struct wmi_t *wmip, u16 fg_start_sec,
2469 u16 fg_end_sec, u16 bg_sec,
2470 u16 minact_chdw_msec, u16 maxact_chdw_msec,
2471 u16 pas_chdw_msec,
2472 u8 shScanRatio, u8 scanCtrlFlags,
2473 u32 max_dfsch_act_time, u16 maxact_scan_per_ssid)
2475 void *osbuf;
2476 WMI_SCAN_PARAMS_CMD *sc;
2478 osbuf = A_NETBUF_ALLOC(sizeof(*sc));
2479 if (osbuf == NULL) {
2480 return A_NO_MEMORY;
2483 A_NETBUF_PUT(osbuf, sizeof(*sc));
2485 sc = (WMI_SCAN_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
2486 A_MEMZERO(sc, sizeof(*sc));
2487 sc->fg_start_period = fg_start_sec;
2488 sc->fg_end_period = fg_end_sec;
2489 sc->bg_period = bg_sec;
2490 sc->minact_chdwell_time = minact_chdw_msec;
2491 sc->maxact_chdwell_time = maxact_chdw_msec;
2492 sc->pas_chdwell_time = pas_chdw_msec;
2493 sc->shortScanRatio = shScanRatio;
2494 sc->scanCtrlFlags = scanCtrlFlags;
2495 sc->max_dfsch_act_time = max_dfsch_act_time;
2496 sc->maxact_scan_per_ssid = maxact_scan_per_ssid;
2498 return (wmi_cmd_send(wmip, osbuf, WMI_SET_SCAN_PARAMS_CMDID,
2499 NO_SYNC_WMIFLAG));
2503 wmi_bssfilter_cmd(struct wmi_t *wmip, u8 filter, u32 ieMask)
2505 void *osbuf;
2506 WMI_BSS_FILTER_CMD *cmd;
2508 if (filter >= LAST_BSS_FILTER) {
2509 return A_EINVAL;
2512 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2513 if (osbuf == NULL) {
2514 return A_NO_MEMORY;
2517 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2519 cmd = (WMI_BSS_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
2520 A_MEMZERO(cmd, sizeof(*cmd));
2521 cmd->bssFilter = filter;
2522 cmd->ieMask = ieMask;
2524 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BSS_FILTER_CMDID,
2525 NO_SYNC_WMIFLAG));
2529 wmi_probedSsid_cmd(struct wmi_t *wmip, u8 index, u8 flag,
2530 u8 ssidLength, u8 *ssid)
2532 void *osbuf;
2533 WMI_PROBED_SSID_CMD *cmd;
2535 if (index > MAX_PROBED_SSID_INDEX) {
2536 return A_EINVAL;
2538 if (ssidLength > sizeof(cmd->ssid)) {
2539 return A_EINVAL;
2541 if ((flag & (DISABLE_SSID_FLAG | ANY_SSID_FLAG)) && (ssidLength > 0)) {
2542 return A_EINVAL;
2544 if ((flag & SPECIFIC_SSID_FLAG) && !ssidLength) {
2545 return A_EINVAL;
2548 if (flag & SPECIFIC_SSID_FLAG) {
2549 is_probe_ssid = true;
2552 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2553 if (osbuf == NULL) {
2554 return A_NO_MEMORY;
2557 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2559 cmd = (WMI_PROBED_SSID_CMD *)(A_NETBUF_DATA(osbuf));
2560 A_MEMZERO(cmd, sizeof(*cmd));
2561 cmd->entryIndex = index;
2562 cmd->flag = flag;
2563 cmd->ssidLength = ssidLength;
2564 memcpy(cmd->ssid, ssid, ssidLength);
2566 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PROBED_SSID_CMDID,
2567 NO_SYNC_WMIFLAG));
2571 wmi_listeninterval_cmd(struct wmi_t *wmip, u16 listenInterval, u16 listenBeacons)
2573 void *osbuf;
2574 WMI_LISTEN_INT_CMD *cmd;
2576 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2577 if (osbuf == NULL) {
2578 return A_NO_MEMORY;
2581 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2583 cmd = (WMI_LISTEN_INT_CMD *)(A_NETBUF_DATA(osbuf));
2584 A_MEMZERO(cmd, sizeof(*cmd));
2585 cmd->listenInterval = listenInterval;
2586 cmd->numBeacons = listenBeacons;
2588 return (wmi_cmd_send(wmip, osbuf, WMI_SET_LISTEN_INT_CMDID,
2589 NO_SYNC_WMIFLAG));
2593 wmi_bmisstime_cmd(struct wmi_t *wmip, u16 bmissTime, u16 bmissBeacons)
2595 void *osbuf;
2596 WMI_BMISS_TIME_CMD *cmd;
2598 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2599 if (osbuf == NULL) {
2600 return A_NO_MEMORY;
2603 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2605 cmd = (WMI_BMISS_TIME_CMD *)(A_NETBUF_DATA(osbuf));
2606 A_MEMZERO(cmd, sizeof(*cmd));
2607 cmd->bmissTime = bmissTime;
2608 cmd->numBeacons = bmissBeacons;
2610 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BMISS_TIME_CMDID,
2611 NO_SYNC_WMIFLAG));
2615 wmi_associnfo_cmd(struct wmi_t *wmip, u8 ieType,
2616 u8 ieLen, u8 *ieInfo)
2618 void *osbuf;
2619 WMI_SET_ASSOC_INFO_CMD *cmd;
2620 u16 cmdLen;
2622 cmdLen = sizeof(*cmd) + ieLen - 1;
2623 osbuf = A_NETBUF_ALLOC(cmdLen);
2624 if (osbuf == NULL) {
2625 return A_NO_MEMORY;
2628 A_NETBUF_PUT(osbuf, cmdLen);
2630 cmd = (WMI_SET_ASSOC_INFO_CMD *)(A_NETBUF_DATA(osbuf));
2631 A_MEMZERO(cmd, cmdLen);
2632 cmd->ieType = ieType;
2633 cmd->bufferSize = ieLen;
2634 memcpy(cmd->assocInfo, ieInfo, ieLen);
2636 return (wmi_cmd_send(wmip, osbuf, WMI_SET_ASSOC_INFO_CMDID,
2637 NO_SYNC_WMIFLAG));
2641 wmi_powermode_cmd(struct wmi_t *wmip, u8 powerMode)
2643 void *osbuf;
2644 WMI_POWER_MODE_CMD *cmd;
2646 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2647 if (osbuf == NULL) {
2648 return A_NO_MEMORY;
2651 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2653 cmd = (WMI_POWER_MODE_CMD *)(A_NETBUF_DATA(osbuf));
2654 A_MEMZERO(cmd, sizeof(*cmd));
2655 cmd->powerMode = powerMode;
2656 wmip->wmi_powerMode = powerMode;
2658 return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_MODE_CMDID,
2659 NO_SYNC_WMIFLAG));
2663 wmi_ibsspmcaps_cmd(struct wmi_t *wmip, u8 pmEnable, u8 ttl,
2664 u16 atim_windows, u16 timeout_value)
2666 void *osbuf;
2667 WMI_IBSS_PM_CAPS_CMD *cmd;
2669 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2670 if (osbuf == NULL) {
2671 return A_NO_MEMORY;
2674 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2676 cmd = (WMI_IBSS_PM_CAPS_CMD *)(A_NETBUF_DATA(osbuf));
2677 A_MEMZERO(cmd, sizeof(*cmd));
2678 cmd->power_saving = pmEnable;
2679 cmd->ttl = ttl;
2680 cmd->atim_windows = atim_windows;
2681 cmd->timeout_value = timeout_value;
2683 return (wmi_cmd_send(wmip, osbuf, WMI_SET_IBSS_PM_CAPS_CMDID,
2684 NO_SYNC_WMIFLAG));
2688 wmi_apps_cmd(struct wmi_t *wmip, u8 psType, u32 idle_time,
2689 u32 ps_period, u8 sleep_period)
2691 void *osbuf;
2692 WMI_AP_PS_CMD *cmd;
2694 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2695 if (osbuf == NULL) {
2696 return A_NO_MEMORY;
2699 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2701 cmd = (WMI_AP_PS_CMD *)(A_NETBUF_DATA(osbuf));
2702 A_MEMZERO(cmd, sizeof(*cmd));
2703 cmd->psType = psType;
2704 cmd->idle_time = idle_time;
2705 cmd->ps_period = ps_period;
2706 cmd->sleep_period = sleep_period;
2708 return (wmi_cmd_send(wmip, osbuf, WMI_SET_AP_PS_CMDID,
2709 NO_SYNC_WMIFLAG));
2713 wmi_pmparams_cmd(struct wmi_t *wmip, u16 idlePeriod,
2714 u16 psPollNum, u16 dtimPolicy,
2715 u16 tx_wakeup_policy, u16 num_tx_to_wakeup,
2716 u16 ps_fail_event_policy)
2718 void *osbuf;
2719 WMI_POWER_PARAMS_CMD *pm;
2721 osbuf = A_NETBUF_ALLOC(sizeof(*pm));
2722 if (osbuf == NULL) {
2723 return A_NO_MEMORY;
2726 A_NETBUF_PUT(osbuf, sizeof(*pm));
2728 pm = (WMI_POWER_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
2729 A_MEMZERO(pm, sizeof(*pm));
2730 pm->idle_period = idlePeriod;
2731 pm->pspoll_number = psPollNum;
2732 pm->dtim_policy = dtimPolicy;
2733 pm->tx_wakeup_policy = tx_wakeup_policy;
2734 pm->num_tx_to_wakeup = num_tx_to_wakeup;
2735 pm->ps_fail_event_policy = ps_fail_event_policy;
2737 return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_PARAMS_CMDID,
2738 NO_SYNC_WMIFLAG));
2742 wmi_disctimeout_cmd(struct wmi_t *wmip, u8 timeout)
2744 void *osbuf;
2745 WMI_DISC_TIMEOUT_CMD *cmd;
2747 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2748 if (osbuf == NULL) {
2749 return A_NO_MEMORY;
2752 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2754 cmd = (WMI_DISC_TIMEOUT_CMD *)(A_NETBUF_DATA(osbuf));
2755 A_MEMZERO(cmd, sizeof(*cmd));
2756 cmd->disconnectTimeout = timeout;
2758 return (wmi_cmd_send(wmip, osbuf, WMI_SET_DISC_TIMEOUT_CMDID,
2759 NO_SYNC_WMIFLAG));
2763 wmi_addKey_cmd(struct wmi_t *wmip, u8 keyIndex, CRYPTO_TYPE keyType,
2764 u8 keyUsage, u8 keyLength, u8 *keyRSC,
2765 u8 *keyMaterial, u8 key_op_ctrl, u8 *macAddr,
2766 WMI_SYNC_FLAG sync_flag)
2768 void *osbuf;
2769 WMI_ADD_CIPHER_KEY_CMD *cmd;
2771 if ((keyIndex > WMI_MAX_KEY_INDEX) || (keyLength > WMI_MAX_KEY_LEN) ||
2772 (keyMaterial == NULL))
2774 return A_EINVAL;
2777 if ((WEP_CRYPT != keyType) && (NULL == keyRSC)) {
2778 return A_EINVAL;
2781 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2782 if (osbuf == NULL) {
2783 return A_NO_MEMORY;
2786 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2788 cmd = (WMI_ADD_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf));
2789 A_MEMZERO(cmd, sizeof(*cmd));
2790 cmd->keyIndex = keyIndex;
2791 cmd->keyType = keyType;
2792 cmd->keyUsage = keyUsage;
2793 cmd->keyLength = keyLength;
2794 memcpy(cmd->key, keyMaterial, keyLength);
2795 #ifdef WAPI_ENABLE
2796 if (NULL != keyRSC && key_op_ctrl != KEY_OP_INIT_WAPIPN) {
2797 #else
2798 if (NULL != keyRSC) {
2799 #endif // WAPI_ENABLE
2800 memcpy(cmd->keyRSC, keyRSC, sizeof(cmd->keyRSC));
2802 cmd->key_op_ctrl = key_op_ctrl;
2804 if(macAddr) {
2805 memcpy(cmd->key_macaddr,macAddr,IEEE80211_ADDR_LEN);
2808 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_CIPHER_KEY_CMDID, sync_flag));
2812 wmi_add_krk_cmd(struct wmi_t *wmip, u8 *krk)
2814 void *osbuf;
2815 WMI_ADD_KRK_CMD *cmd;
2817 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2818 if (osbuf == NULL) {
2819 return A_NO_MEMORY;
2822 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2824 cmd = (WMI_ADD_KRK_CMD *)(A_NETBUF_DATA(osbuf));
2825 A_MEMZERO(cmd, sizeof(*cmd));
2826 memcpy(cmd->krk, krk, WMI_KRK_LEN);
2828 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_KRK_CMDID, NO_SYNC_WMIFLAG));
2832 wmi_delete_krk_cmd(struct wmi_t *wmip)
2834 return wmi_simple_cmd(wmip, WMI_DELETE_KRK_CMDID);
2838 wmi_deleteKey_cmd(struct wmi_t *wmip, u8 keyIndex)
2840 void *osbuf;
2841 WMI_DELETE_CIPHER_KEY_CMD *cmd;
2843 if (keyIndex > WMI_MAX_KEY_INDEX) {
2844 return A_EINVAL;
2847 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2848 if (osbuf == NULL) {
2849 return A_NO_MEMORY;
2852 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2854 cmd = (WMI_DELETE_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf));
2855 A_MEMZERO(cmd, sizeof(*cmd));
2856 cmd->keyIndex = keyIndex;
2858 return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_CIPHER_KEY_CMDID,
2859 NO_SYNC_WMIFLAG));
2863 wmi_setPmkid_cmd(struct wmi_t *wmip, u8 *bssid, u8 *pmkId,
2864 bool set)
2866 void *osbuf;
2867 WMI_SET_PMKID_CMD *cmd;
2869 if (bssid == NULL) {
2870 return A_EINVAL;
2873 if ((set == true) && (pmkId == NULL)) {
2874 return A_EINVAL;
2877 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2878 if (osbuf == NULL) {
2879 return A_NO_MEMORY;
2882 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2884 cmd = (WMI_SET_PMKID_CMD *)(A_NETBUF_DATA(osbuf));
2885 memcpy(cmd->bssid, bssid, sizeof(cmd->bssid));
2886 if (set == true) {
2887 memcpy(cmd->pmkid, pmkId, sizeof(cmd->pmkid));
2888 cmd->enable = PMKID_ENABLE;
2889 } else {
2890 A_MEMZERO(cmd->pmkid, sizeof(cmd->pmkid));
2891 cmd->enable = PMKID_DISABLE;
2894 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_CMDID, NO_SYNC_WMIFLAG));
2898 wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, bool en)
2900 void *osbuf;
2901 WMI_SET_TKIP_COUNTERMEASURES_CMD *cmd;
2903 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2904 if (osbuf == NULL) {
2905 return A_NO_MEMORY;
2908 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2910 cmd = (WMI_SET_TKIP_COUNTERMEASURES_CMD *)(A_NETBUF_DATA(osbuf));
2911 cmd->cm_en = (en == true)? WMI_TKIP_CM_ENABLE : WMI_TKIP_CM_DISABLE;
2913 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TKIP_COUNTERMEASURES_CMDID,
2914 NO_SYNC_WMIFLAG));
2918 wmi_set_akmp_params_cmd(struct wmi_t *wmip,
2919 WMI_SET_AKMP_PARAMS_CMD *akmpParams)
2921 void *osbuf;
2922 WMI_SET_AKMP_PARAMS_CMD *cmd;
2924 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2925 if (osbuf == NULL) {
2926 return A_NO_MEMORY;
2929 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2930 cmd = (WMI_SET_AKMP_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
2931 cmd->akmpInfo = akmpParams->akmpInfo;
2933 return (wmi_cmd_send(wmip, osbuf, WMI_SET_AKMP_PARAMS_CMDID,
2934 NO_SYNC_WMIFLAG));
2938 wmi_set_pmkid_list_cmd(struct wmi_t *wmip,
2939 WMI_SET_PMKID_LIST_CMD *pmkInfo)
2941 void *osbuf;
2942 WMI_SET_PMKID_LIST_CMD *cmd;
2943 u16 cmdLen;
2944 u8 i;
2946 cmdLen = sizeof(pmkInfo->numPMKID) +
2947 pmkInfo->numPMKID * sizeof(WMI_PMKID);
2949 osbuf = A_NETBUF_ALLOC(cmdLen);
2950 if (osbuf == NULL) {
2951 return A_NO_MEMORY;
2954 A_NETBUF_PUT(osbuf, cmdLen);
2955 cmd = (WMI_SET_PMKID_LIST_CMD *)(A_NETBUF_DATA(osbuf));
2956 cmd->numPMKID = pmkInfo->numPMKID;
2958 for (i = 0; i < cmd->numPMKID; i++) {
2959 memcpy(&cmd->pmkidList[i], &pmkInfo->pmkidList[i],
2960 WMI_PMKID_LEN);
2963 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_LIST_CMDID,
2964 NO_SYNC_WMIFLAG));
2968 wmi_get_pmkid_list_cmd(struct wmi_t *wmip)
2970 return wmi_simple_cmd(wmip, WMI_GET_PMKID_LIST_CMDID);
2974 wmi_dataSync_send(struct wmi_t *wmip, void *osbuf, HTC_ENDPOINT_ID eid)
2976 WMI_DATA_HDR *dtHdr;
2978 A_ASSERT( eid != wmip->wmi_endpoint_id);
2979 A_ASSERT(osbuf != NULL);
2981 if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != 0) {
2982 return A_NO_MEMORY;
2985 dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf);
2986 dtHdr->info =
2987 (SYNC_MSGTYPE & WMI_DATA_HDR_MSG_TYPE_MASK) << WMI_DATA_HDR_MSG_TYPE_SHIFT;
2989 dtHdr->info3 = 0;
2990 A_DPRINTF(DBG_WMI, (DBGFMT "Enter - eid %d\n", DBGARG, eid));
2992 return (A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid));
2995 typedef struct _WMI_DATA_SYNC_BUFS {
2996 u8 trafficClass;
2997 void *osbuf;
2998 }WMI_DATA_SYNC_BUFS;
3000 static int
3001 wmi_sync_point(struct wmi_t *wmip)
3003 void *cmd_osbuf;
3004 WMI_SYNC_CMD *cmd;
3005 WMI_DATA_SYNC_BUFS dataSyncBufs[WMM_NUM_AC];
3006 u8 i,numPriStreams=0;
3007 int status = 0;
3009 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
3011 memset(dataSyncBufs,0,sizeof(dataSyncBufs));
3013 /* lock out while we walk through the priority list and assemble our local array */
3014 LOCK_WMI(wmip);
3016 for (i=0; i < WMM_NUM_AC ; i++) {
3017 if (wmip->wmi_fatPipeExists & (1 << i)) {
3018 numPriStreams++;
3019 dataSyncBufs[numPriStreams-1].trafficClass = i;
3023 UNLOCK_WMI(wmip);
3025 /* dataSyncBufs is now filled with entries (starting at index 0) containing valid streamIDs */
3027 do {
3029 * We allocate all network buffers needed so we will be able to
3030 * send all required frames.
3032 cmd_osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3033 if (cmd_osbuf == NULL) {
3034 status = A_NO_MEMORY;
3035 break;
3038 A_NETBUF_PUT(cmd_osbuf, sizeof(*cmd));
3040 cmd = (WMI_SYNC_CMD *)(A_NETBUF_DATA(cmd_osbuf));
3041 A_MEMZERO(cmd, sizeof(*cmd));
3043 /* In the SYNC cmd sent on the control Ep, send a bitmap of the data
3044 * eps on which the Data Sync will be sent
3046 cmd->dataSyncMap = wmip->wmi_fatPipeExists;
3048 for (i=0; i < numPriStreams ; i++) {
3049 dataSyncBufs[i].osbuf = A_NETBUF_ALLOC(0);
3050 if (dataSyncBufs[i].osbuf == NULL) {
3051 status = A_NO_MEMORY;
3052 break;
3054 } //end for
3056 /* if Buffer allocation for any of the dataSync fails, then do not
3057 * send the Synchronize cmd on the control ep
3059 if (status) {
3060 break;
3064 * Send sync cmd followed by sync data messages on all endpoints being
3065 * used
3067 status = wmi_cmd_send(wmip, cmd_osbuf, WMI_SYNCHRONIZE_CMDID,
3068 NO_SYNC_WMIFLAG);
3070 if (status) {
3071 break;
3073 /* cmd buffer sent, we no longer own it */
3074 cmd_osbuf = NULL;
3076 for(i=0; i < numPriStreams; i++) {
3077 A_ASSERT(dataSyncBufs[i].osbuf != NULL);
3078 status = wmi_dataSync_send(wmip,
3079 dataSyncBufs[i].osbuf,
3080 A_WMI_Ac2EndpointID(wmip->wmi_devt,
3081 dataSyncBufs[i].
3082 trafficClass)
3085 if (status) {
3086 break;
3088 /* we don't own this buffer anymore, NULL it out of the array so it
3089 * won't get cleaned up */
3090 dataSyncBufs[i].osbuf = NULL;
3091 } //end for
3093 } while(false);
3095 /* free up any resources left over (possibly due to an error) */
3097 if (cmd_osbuf != NULL) {
3098 A_NETBUF_FREE(cmd_osbuf);
3101 for (i = 0; i < numPriStreams; i++) {
3102 if (dataSyncBufs[i].osbuf != NULL) {
3103 A_NETBUF_FREE(dataSyncBufs[i].osbuf);
3107 return (status);
3111 wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *params)
3113 void *osbuf;
3114 WMI_CREATE_PSTREAM_CMD *cmd;
3115 u8 fatPipeExistsForAC=0;
3116 s32 minimalPHY = 0;
3117 s32 nominalPHY = 0;
3119 /* Validate all the parameters. */
3120 if( !((params->userPriority < 8) &&
3121 (params->userPriority <= 0x7) &&
3122 (convert_userPriority_to_trafficClass(params->userPriority) == params->trafficClass) &&
3123 (params->trafficDirection == UPLINK_TRAFFIC ||
3124 params->trafficDirection == DNLINK_TRAFFIC ||
3125 params->trafficDirection == BIDIR_TRAFFIC) &&
3126 (params->trafficType == TRAFFIC_TYPE_APERIODIC ||
3127 params->trafficType == TRAFFIC_TYPE_PERIODIC ) &&
3128 (params->voicePSCapability == DISABLE_FOR_THIS_AC ||
3129 params->voicePSCapability == ENABLE_FOR_THIS_AC ||
3130 params->voicePSCapability == ENABLE_FOR_ALL_AC) &&
3131 (params->tsid == WMI_IMPLICIT_PSTREAM || params->tsid <= WMI_MAX_THINSTREAM)) )
3133 return A_EINVAL;
3137 // check nominal PHY rate is >= minimalPHY, so that DUT
3138 // can allow TSRS IE
3141 // get the physical rate
3142 minimalPHY = ((params->minPhyRate / 1000)/1000); // unit of bps
3144 // check minimal phy < nominal phy rate
3146 if (params->nominalPHY >= minimalPHY)
3148 nominalPHY = (params->nominalPHY * 1000)/500; // unit of 500 kbps
3149 A_DPRINTF(DBG_WMI,
3150 (DBGFMT "TSRS IE Enabled::MinPhy %x->NominalPhy ===> %x\n", DBGARG,
3151 minimalPHY, nominalPHY));
3153 params->nominalPHY = nominalPHY;
3155 else
3157 params->nominalPHY = 0;
3160 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3161 if (osbuf == NULL) {
3162 return A_NO_MEMORY;
3165 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3167 A_DPRINTF(DBG_WMI,
3168 (DBGFMT "Sending create_pstream_cmd: ac=%d tsid:%d\n", DBGARG,
3169 params->trafficClass, params->tsid));
3171 cmd = (WMI_CREATE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf));
3172 A_MEMZERO(cmd, sizeof(*cmd));
3173 memcpy(cmd, params, sizeof(*cmd));
3175 /* this is an implicitly created Fat pipe */
3176 if ((u32)params->tsid == (u32)WMI_IMPLICIT_PSTREAM) {
3177 LOCK_WMI(wmip);
3178 fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass));
3179 wmip->wmi_fatPipeExists |= (1<<params->trafficClass);
3180 UNLOCK_WMI(wmip);
3181 } else {
3182 /* this is an explicitly created thin stream within a fat pipe */
3183 LOCK_WMI(wmip);
3184 fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass));
3185 wmip->wmi_streamExistsForAC[params->trafficClass] |= (1<<params->tsid);
3186 /* if a thinstream becomes active, the fat pipe automatically
3187 * becomes active
3189 wmip->wmi_fatPipeExists |= (1<<params->trafficClass);
3190 UNLOCK_WMI(wmip);
3193 /* Indicate activty change to driver layer only if this is the
3194 * first TSID to get created in this AC explicitly or an implicit
3195 * fat pipe is getting created.
3197 if (!fatPipeExistsForAC) {
3198 A_WMI_STREAM_TX_ACTIVE(wmip->wmi_devt, params->trafficClass);
3201 /* mike: should be SYNC_BEFORE_WMIFLAG */
3202 return (wmi_cmd_send(wmip, osbuf, WMI_CREATE_PSTREAM_CMDID,
3203 NO_SYNC_WMIFLAG));
3207 wmi_delete_pstream_cmd(struct wmi_t *wmip, u8 trafficClass, u8 tsid)
3209 void *osbuf;
3210 WMI_DELETE_PSTREAM_CMD *cmd;
3211 int status;
3212 u16 activeTsids=0;
3214 /* validate the parameters */
3215 if (trafficClass > 3) {
3216 A_DPRINTF(DBG_WMI, (DBGFMT "Invalid trafficClass: %d\n", DBGARG, trafficClass));
3217 return A_EINVAL;
3220 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3221 if (osbuf == NULL) {
3222 return A_NO_MEMORY;
3225 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3227 cmd = (WMI_DELETE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf));
3228 A_MEMZERO(cmd, sizeof(*cmd));
3230 cmd->trafficClass = trafficClass;
3231 cmd->tsid = tsid;
3233 LOCK_WMI(wmip);
3234 activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
3235 UNLOCK_WMI(wmip);
3237 /* Check if the tsid was created & exists */
3238 if (!(activeTsids & (1<<tsid))) {
3240 A_NETBUF_FREE(osbuf);
3241 A_DPRINTF(DBG_WMI,
3242 (DBGFMT "TSID %d does'nt exist for trafficClass: %d\n", DBGARG, tsid, trafficClass));
3243 /* TODO: return a more appropriate err code */
3244 return A_ERROR;
3247 A_DPRINTF(DBG_WMI,
3248 (DBGFMT "Sending delete_pstream_cmd: trafficClass: %d tsid=%d\n", DBGARG, trafficClass, tsid));
3250 status = (wmi_cmd_send(wmip, osbuf, WMI_DELETE_PSTREAM_CMDID,
3251 SYNC_BEFORE_WMIFLAG));
3253 LOCK_WMI(wmip);
3254 wmip->wmi_streamExistsForAC[trafficClass] &= ~(1<<tsid);
3255 activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
3256 UNLOCK_WMI(wmip);
3259 /* Indicate stream inactivity to driver layer only if all tsids
3260 * within this AC are deleted.
3262 if(!activeTsids) {
3263 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, trafficClass);
3264 wmip->wmi_fatPipeExists &= ~(1<<trafficClass);
3267 return status;
3271 wmi_set_framerate_cmd(struct wmi_t *wmip, u8 bEnable, u8 type, u8 subType, u16 rateMask)
3273 void *osbuf;
3274 WMI_FRAME_RATES_CMD *cmd;
3275 u8 frameType;
3277 A_DPRINTF(DBG_WMI,
3278 (DBGFMT " type %02X, subType %02X, rateMask %04x\n", DBGARG, type, subType, rateMask));
3280 if((type != IEEE80211_FRAME_TYPE_MGT && type != IEEE80211_FRAME_TYPE_CTL) ||
3281 (subType > 15)){
3283 return A_EINVAL;
3286 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3287 if (osbuf == NULL) {
3288 return A_NO_MEMORY;
3291 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3293 cmd = (WMI_FRAME_RATES_CMD *)(A_NETBUF_DATA(osbuf));
3294 A_MEMZERO(cmd, sizeof(*cmd));
3296 frameType = (u8)((subType << 4) | type);
3298 cmd->bEnableMask = bEnable;
3299 cmd->frameType = frameType;
3300 cmd->frameRateMask = rateMask;
3302 return (wmi_cmd_send(wmip, osbuf, WMI_SET_FRAMERATES_CMDID, NO_SYNC_WMIFLAG));
3306 * used to set the bit rate. rate is in Kbps. If rate == -1
3307 * then auto selection is used.
3310 wmi_set_bitrate_cmd(struct wmi_t *wmip, s32 dataRate, s32 mgmtRate, s32 ctlRate)
3312 void *osbuf;
3313 WMI_BIT_RATE_CMD *cmd;
3314 s8 drix, mrix, crix, ret_val;
3316 if (dataRate != -1) {
3317 ret_val = wmi_validate_bitrate(wmip, dataRate, &drix);
3318 if(ret_val == A_EINVAL){
3319 return A_EINVAL;
3321 } else {
3322 drix = -1;
3325 if (mgmtRate != -1) {
3326 ret_val = wmi_validate_bitrate(wmip, mgmtRate, &mrix);
3327 if(ret_val == A_EINVAL){
3328 return A_EINVAL;
3330 } else {
3331 mrix = -1;
3333 if (ctlRate != -1) {
3334 ret_val = wmi_validate_bitrate(wmip, ctlRate, &crix);
3335 if(ret_val == A_EINVAL){
3336 return A_EINVAL;
3338 } else {
3339 crix = -1;
3341 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3342 if (osbuf == NULL) {
3343 return A_NO_MEMORY;
3346 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3348 cmd = (WMI_BIT_RATE_CMD *)(A_NETBUF_DATA(osbuf));
3349 A_MEMZERO(cmd, sizeof(*cmd));
3351 cmd->rateIndex = drix;
3352 cmd->mgmtRateIndex = mrix;
3353 cmd->ctlRateIndex = crix;
3356 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BITRATE_CMDID, NO_SYNC_WMIFLAG));
3360 wmi_get_bitrate_cmd(struct wmi_t *wmip)
3362 return wmi_simple_cmd(wmip, WMI_GET_BITRATE_CMDID);
3366 * Returns true iff the given rate index is legal in the current PHY mode.
3368 bool
3369 wmi_is_bitrate_index_valid(struct wmi_t *wmip, s32 rateIndex)
3371 WMI_PHY_MODE phyMode = (WMI_PHY_MODE) wmip->wmi_phyMode;
3372 bool isValid = true;
3373 switch(phyMode) {
3374 case WMI_11A_MODE:
3375 if (wmip->wmi_ht_allowed[A_BAND_5GHZ]){
3376 if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
3377 isValid = false;
3379 } else {
3380 if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_A_SUPPORT_RATE_STOP)) {
3381 isValid = false;
3384 break;
3386 case WMI_11B_MODE:
3387 if ((rateIndex < MODE_B_SUPPORT_RATE_START) || (rateIndex > MODE_B_SUPPORT_RATE_STOP)) {
3388 isValid = false;
3390 break;
3392 case WMI_11GONLY_MODE:
3393 if (wmip->wmi_ht_allowed[A_BAND_24GHZ]){
3394 if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
3395 isValid = false;
3397 } else {
3398 if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE_GONLY_SUPPORT_RATE_STOP)) {
3399 isValid = false;
3402 break;
3404 case WMI_11G_MODE:
3405 case WMI_11AG_MODE:
3406 if (wmip->wmi_ht_allowed[A_BAND_24GHZ]){
3407 if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
3408 isValid = false;
3410 } else {
3411 if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_G_SUPPORT_RATE_STOP)) {
3412 isValid = false;
3415 break;
3416 default:
3417 A_ASSERT(false);
3418 break;
3421 return isValid;
3424 s8 wmi_validate_bitrate(struct wmi_t *wmip, s32 rate, s8 *rate_idx)
3426 s8 i;
3428 for (i=0;;i++)
3430 if (wmi_rateTable[(u32) i][0] == 0) {
3431 return A_EINVAL;
3433 if (wmi_rateTable[(u32) i][0] == rate) {
3434 break;
3438 if(wmi_is_bitrate_index_valid(wmip, (s32) i) != true) {
3439 return A_EINVAL;
3442 *rate_idx = i;
3443 return 0;
3447 wmi_set_fixrates_cmd(struct wmi_t *wmip, u32 fixRatesMask)
3449 void *osbuf;
3450 WMI_FIX_RATES_CMD *cmd;
3451 #if 0
3452 s32 rateIndex;
3453 /* This check does not work for AR6003 as the HT modes are enabled only when
3454 * the STA is connected to a HT_BSS and is not based only on channel. It is
3455 * safe to skip this check however because rate control will only use rates
3456 * that are permitted by the valid rate mask and the fix rate mask. Meaning
3457 * the fix rate mask is not sufficient by itself to cause an invalid rate
3458 * to be used. */
3459 /* Make sure all rates in the mask are valid in the current PHY mode */
3460 for(rateIndex = 0; rateIndex < MAX_NUMBER_OF_SUPPORT_RATES; rateIndex++) {
3461 if((1 << rateIndex) & (u32)fixRatesMask) {
3462 if(wmi_is_bitrate_index_valid(wmip, rateIndex) != true) {
3463 A_DPRINTF(DBG_WMI, (DBGFMT "Set Fix Rates command failed: Given rate is illegal in current PHY mode\n", DBGARG));
3464 return A_EINVAL;
3468 #endif
3471 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3472 if (osbuf == NULL) {
3473 return A_NO_MEMORY;
3476 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3478 cmd = (WMI_FIX_RATES_CMD *)(A_NETBUF_DATA(osbuf));
3479 A_MEMZERO(cmd, sizeof(*cmd));
3481 cmd->fixRateMask = fixRatesMask;
3483 return (wmi_cmd_send(wmip, osbuf, WMI_SET_FIXRATES_CMDID, NO_SYNC_WMIFLAG));
3487 wmi_get_ratemask_cmd(struct wmi_t *wmip)
3489 return wmi_simple_cmd(wmip, WMI_GET_FIXRATES_CMDID);
3493 wmi_get_channelList_cmd(struct wmi_t *wmip)
3495 return wmi_simple_cmd(wmip, WMI_GET_CHANNEL_LIST_CMDID);
3499 * used to generate a wmi sey channel Parameters cmd.
3500 * mode should always be specified and corresponds to the phy mode of the
3501 * wlan.
3502 * numChan should alway sbe specified. If zero indicates that all available
3503 * channels should be used.
3504 * channelList is an array of channel frequencies (in Mhz) which the radio
3505 * should limit its operation to. It should be NULL if numChan == 0. Size of
3506 * array should correspond to numChan entries.
3509 wmi_set_channelParams_cmd(struct wmi_t *wmip, u8 scanParam,
3510 WMI_PHY_MODE mode, s8 numChan,
3511 u16 *channelList)
3513 void *osbuf;
3514 WMI_CHANNEL_PARAMS_CMD *cmd;
3515 s8 size;
3517 size = sizeof (*cmd);
3519 if (numChan) {
3520 if (numChan > WMI_MAX_CHANNELS) {
3521 return A_EINVAL;
3523 size += sizeof(u16) * (numChan - 1);
3526 osbuf = A_NETBUF_ALLOC(size);
3527 if (osbuf == NULL) {
3528 return A_NO_MEMORY;
3531 A_NETBUF_PUT(osbuf, size);
3533 cmd = (WMI_CHANNEL_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
3534 A_MEMZERO(cmd, size);
3536 wmip->wmi_phyMode = mode;
3537 cmd->scanParam = scanParam;
3538 cmd->phyMode = mode;
3539 cmd->numChannels = numChan;
3540 memcpy(cmd->channelList, channelList, numChan * sizeof(u16));
3542 return (wmi_cmd_send(wmip, osbuf, WMI_SET_CHANNEL_PARAMS_CMDID,
3543 NO_SYNC_WMIFLAG));
3546 void
3547 wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
3549 SQ_THRESHOLD_PARAMS *sq_thresh =
3550 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI];
3552 * Parse the command and store the threshold values here. The checks
3553 * for valid values can be put here
3555 sq_thresh->weight = rssiCmd->weight;
3556 sq_thresh->polling_interval = rssiCmd->pollTime;
3558 sq_thresh->upper_threshold[0] = rssiCmd->thresholdAbove1_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3559 sq_thresh->upper_threshold[1] = rssiCmd->thresholdAbove2_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3560 sq_thresh->upper_threshold[2] = rssiCmd->thresholdAbove3_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3561 sq_thresh->upper_threshold[3] = rssiCmd->thresholdAbove4_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3562 sq_thresh->upper_threshold[4] = rssiCmd->thresholdAbove5_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3563 sq_thresh->upper_threshold[5] = rssiCmd->thresholdAbove6_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3564 sq_thresh->upper_threshold_valid_count = 6;
3566 /* List sorted in descending order */
3567 sq_thresh->lower_threshold[0] = rssiCmd->thresholdBelow6_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3568 sq_thresh->lower_threshold[1] = rssiCmd->thresholdBelow5_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3569 sq_thresh->lower_threshold[2] = rssiCmd->thresholdBelow4_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3570 sq_thresh->lower_threshold[3] = rssiCmd->thresholdBelow3_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3571 sq_thresh->lower_threshold[4] = rssiCmd->thresholdBelow2_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3572 sq_thresh->lower_threshold[5] = rssiCmd->thresholdBelow1_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3573 sq_thresh->lower_threshold_valid_count = 6;
3575 if (!rssi_event_value) {
3577 * Configuring the thresholds to their extremes allows the host to get an
3578 * event from the target which is used for the configuring the correct
3579 * thresholds
3581 rssiCmd->thresholdAbove1_Val = sq_thresh->upper_threshold[0];
3582 rssiCmd->thresholdBelow1_Val = sq_thresh->lower_threshold[0];
3583 } else {
3585 * In case the user issues multiple times of rssi_threshold_setting,
3586 * we should not use the extreames anymore, the target does not expect that.
3588 rssiCmd->thresholdAbove1_Val = ar6000_get_upper_threshold(rssi_event_value, sq_thresh,
3589 sq_thresh->upper_threshold_valid_count);
3590 rssiCmd->thresholdBelow1_Val = ar6000_get_lower_threshold(rssi_event_value, sq_thresh,
3591 sq_thresh->lower_threshold_valid_count);
3596 wmi_set_rssi_threshold_params(struct wmi_t *wmip,
3597 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
3600 /* Check these values are in ascending order */
3601 if( rssiCmd->thresholdAbove6_Val <= rssiCmd->thresholdAbove5_Val ||
3602 rssiCmd->thresholdAbove5_Val <= rssiCmd->thresholdAbove4_Val ||
3603 rssiCmd->thresholdAbove4_Val <= rssiCmd->thresholdAbove3_Val ||
3604 rssiCmd->thresholdAbove3_Val <= rssiCmd->thresholdAbove2_Val ||
3605 rssiCmd->thresholdAbove2_Val <= rssiCmd->thresholdAbove1_Val ||
3606 rssiCmd->thresholdBelow6_Val <= rssiCmd->thresholdBelow5_Val ||
3607 rssiCmd->thresholdBelow5_Val <= rssiCmd->thresholdBelow4_Val ||
3608 rssiCmd->thresholdBelow4_Val <= rssiCmd->thresholdBelow3_Val ||
3609 rssiCmd->thresholdBelow3_Val <= rssiCmd->thresholdBelow2_Val ||
3610 rssiCmd->thresholdBelow2_Val <= rssiCmd->thresholdBelow1_Val)
3612 return A_EINVAL;
3615 wmi_cache_configure_rssithreshold(wmip, rssiCmd);
3617 return (wmi_send_rssi_threshold_params(wmip, rssiCmd));
3621 wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *ipCmd)
3623 void *osbuf;
3624 WMI_SET_IP_CMD *cmd;
3626 /* Multicast address are not valid */
3627 if((*((u8 *)&ipCmd->ips[0]) >= 0xE0) ||
3628 (*((u8 *)&ipCmd->ips[1]) >= 0xE0)) {
3629 return A_EINVAL;
3632 osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_IP_CMD));
3633 if (osbuf == NULL) {
3634 return A_NO_MEMORY;
3637 A_NETBUF_PUT(osbuf, sizeof(WMI_SET_IP_CMD));
3638 cmd = (WMI_SET_IP_CMD *)(A_NETBUF_DATA(osbuf));
3639 memcpy(cmd, ipCmd, sizeof(WMI_SET_IP_CMD));
3641 return (wmi_cmd_send(wmip, osbuf, WMI_SET_IP_CMDID,
3642 NO_SYNC_WMIFLAG));
3646 wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip,
3647 WMI_SET_HOST_SLEEP_MODE_CMD *hostModeCmd)
3649 void *osbuf;
3650 s8 size;
3651 WMI_SET_HOST_SLEEP_MODE_CMD *cmd;
3652 u16 activeTsids=0;
3653 u8 streamExists=0;
3654 u8 i;
3656 if( hostModeCmd->awake == hostModeCmd->asleep) {
3657 return A_EINVAL;
3660 size = sizeof (*cmd);
3662 osbuf = A_NETBUF_ALLOC(size);
3663 if (osbuf == NULL) {
3664 return A_NO_MEMORY;
3667 A_NETBUF_PUT(osbuf, size);
3669 cmd = (WMI_SET_HOST_SLEEP_MODE_CMD *)(A_NETBUF_DATA(osbuf));
3670 A_MEMZERO(cmd, size);
3671 memcpy(cmd, hostModeCmd, sizeof(WMI_SET_HOST_SLEEP_MODE_CMD));
3673 if(hostModeCmd->asleep) {
3675 * Relinquish credits from all implicitly created pstreams since when we
3676 * go to sleep. If user created explicit thinstreams exists with in a
3677 * fatpipe leave them intact for the user to delete
3679 LOCK_WMI(wmip);
3680 streamExists = wmip->wmi_fatPipeExists;
3681 UNLOCK_WMI(wmip);
3683 for(i=0;i< WMM_NUM_AC;i++) {
3684 if (streamExists & (1<<i)) {
3685 LOCK_WMI(wmip);
3686 activeTsids = wmip->wmi_streamExistsForAC[i];
3687 UNLOCK_WMI(wmip);
3688 /* If there are no user created thin streams delete the fatpipe */
3689 if(!activeTsids) {
3690 streamExists &= ~(1<<i);
3691 /*Indicate inactivity to drv layer for this fatpipe(pstream)*/
3692 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt,i);
3697 /* Update the fatpipes that exists*/
3698 LOCK_WMI(wmip);
3699 wmip->wmi_fatPipeExists = streamExists;
3700 UNLOCK_WMI(wmip);
3703 return (wmi_cmd_send(wmip, osbuf, WMI_SET_HOST_SLEEP_MODE_CMDID,
3704 NO_SYNC_WMIFLAG));
3708 wmi_set_wow_mode_cmd(struct wmi_t *wmip,
3709 WMI_SET_WOW_MODE_CMD *wowModeCmd)
3711 void *osbuf;
3712 s8 size;
3713 WMI_SET_WOW_MODE_CMD *cmd;
3715 size = sizeof (*cmd);
3717 osbuf = A_NETBUF_ALLOC(size);
3718 if (osbuf == NULL) {
3719 return A_NO_MEMORY;
3722 A_NETBUF_PUT(osbuf, size);
3724 cmd = (WMI_SET_WOW_MODE_CMD *)(A_NETBUF_DATA(osbuf));
3725 A_MEMZERO(cmd, size);
3726 memcpy(cmd, wowModeCmd, sizeof(WMI_SET_WOW_MODE_CMD));
3728 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WOW_MODE_CMDID,
3729 NO_SYNC_WMIFLAG));
3734 wmi_get_wow_list_cmd(struct wmi_t *wmip,
3735 WMI_GET_WOW_LIST_CMD *wowListCmd)
3737 void *osbuf;
3738 s8 size;
3739 WMI_GET_WOW_LIST_CMD *cmd;
3741 size = sizeof (*cmd);
3743 osbuf = A_NETBUF_ALLOC(size);
3744 if (osbuf == NULL) {
3745 return A_NO_MEMORY;
3748 A_NETBUF_PUT(osbuf, size);
3750 cmd = (WMI_GET_WOW_LIST_CMD *)(A_NETBUF_DATA(osbuf));
3751 A_MEMZERO(cmd, size);
3752 memcpy(cmd, wowListCmd, sizeof(WMI_GET_WOW_LIST_CMD));
3754 return (wmi_cmd_send(wmip, osbuf, WMI_GET_WOW_LIST_CMDID,
3755 NO_SYNC_WMIFLAG));
3759 static int
3760 wmi_get_wow_list_event_rx(struct wmi_t *wmip, u8 *datap, int len)
3762 WMI_GET_WOW_LIST_REPLY *reply;
3764 if (len < sizeof(WMI_GET_WOW_LIST_REPLY)) {
3765 return A_EINVAL;
3767 reply = (WMI_GET_WOW_LIST_REPLY *)datap;
3769 A_WMI_WOW_LIST_EVENT(wmip->wmi_devt, reply->num_filters,
3770 reply);
3772 return 0;
3775 int wmi_add_wow_pattern_cmd(struct wmi_t *wmip,
3776 WMI_ADD_WOW_PATTERN_CMD *addWowCmd,
3777 u8 *pattern, u8 *mask,
3778 u8 pattern_size)
3780 void *osbuf;
3781 s8 size;
3782 WMI_ADD_WOW_PATTERN_CMD *cmd;
3783 u8 *filter_mask = NULL;
3785 size = sizeof (*cmd);
3787 size += ((2 * addWowCmd->filter_size)* sizeof(u8));
3788 osbuf = A_NETBUF_ALLOC(size);
3789 if (osbuf == NULL) {
3790 return A_NO_MEMORY;
3793 A_NETBUF_PUT(osbuf, size);
3795 cmd = (WMI_ADD_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf));
3796 cmd->filter_list_id = addWowCmd->filter_list_id;
3797 cmd->filter_offset = addWowCmd->filter_offset;
3798 cmd->filter_size = addWowCmd->filter_size;
3800 memcpy(cmd->filter, pattern, addWowCmd->filter_size);
3802 filter_mask = (u8 *)(cmd->filter + cmd->filter_size);
3803 memcpy(filter_mask, mask, addWowCmd->filter_size);
3806 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_WOW_PATTERN_CMDID,
3807 NO_SYNC_WMIFLAG));
3811 wmi_del_wow_pattern_cmd(struct wmi_t *wmip,
3812 WMI_DEL_WOW_PATTERN_CMD *delWowCmd)
3814 void *osbuf;
3815 s8 size;
3816 WMI_DEL_WOW_PATTERN_CMD *cmd;
3818 size = sizeof (*cmd);
3820 osbuf = A_NETBUF_ALLOC(size);
3821 if (osbuf == NULL) {
3822 return A_NO_MEMORY;
3825 A_NETBUF_PUT(osbuf, size);
3827 cmd = (WMI_DEL_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf));
3828 A_MEMZERO(cmd, size);
3829 memcpy(cmd, delWowCmd, sizeof(WMI_DEL_WOW_PATTERN_CMD));
3831 return (wmi_cmd_send(wmip, osbuf, WMI_DEL_WOW_PATTERN_CMDID,
3832 NO_SYNC_WMIFLAG));
3836 void
3837 wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
3839 SQ_THRESHOLD_PARAMS *sq_thresh =
3840 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_SNR];
3842 * Parse the command and store the threshold values here. The checks
3843 * for valid values can be put here
3845 sq_thresh->weight = snrCmd->weight;
3846 sq_thresh->polling_interval = snrCmd->pollTime;
3848 sq_thresh->upper_threshold[0] = snrCmd->thresholdAbove1_Val;
3849 sq_thresh->upper_threshold[1] = snrCmd->thresholdAbove2_Val;
3850 sq_thresh->upper_threshold[2] = snrCmd->thresholdAbove3_Val;
3851 sq_thresh->upper_threshold[3] = snrCmd->thresholdAbove4_Val;
3852 sq_thresh->upper_threshold_valid_count = 4;
3854 /* List sorted in descending order */
3855 sq_thresh->lower_threshold[0] = snrCmd->thresholdBelow4_Val;
3856 sq_thresh->lower_threshold[1] = snrCmd->thresholdBelow3_Val;
3857 sq_thresh->lower_threshold[2] = snrCmd->thresholdBelow2_Val;
3858 sq_thresh->lower_threshold[3] = snrCmd->thresholdBelow1_Val;
3859 sq_thresh->lower_threshold_valid_count = 4;
3861 if (!snr_event_value) {
3863 * Configuring the thresholds to their extremes allows the host to get an
3864 * event from the target which is used for the configuring the correct
3865 * thresholds
3867 snrCmd->thresholdAbove1_Val = (u8)sq_thresh->upper_threshold[0];
3868 snrCmd->thresholdBelow1_Val = (u8)sq_thresh->lower_threshold[0];
3869 } else {
3871 * In case the user issues multiple times of snr_threshold_setting,
3872 * we should not use the extreames anymore, the target does not expect that.
3874 snrCmd->thresholdAbove1_Val = ar6000_get_upper_threshold(snr_event_value, sq_thresh,
3875 sq_thresh->upper_threshold_valid_count);
3876 snrCmd->thresholdBelow1_Val = ar6000_get_lower_threshold(snr_event_value, sq_thresh,
3877 sq_thresh->lower_threshold_valid_count);
3882 wmi_set_snr_threshold_params(struct wmi_t *wmip,
3883 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
3885 if( snrCmd->thresholdAbove4_Val <= snrCmd->thresholdAbove3_Val ||
3886 snrCmd->thresholdAbove3_Val <= snrCmd->thresholdAbove2_Val ||
3887 snrCmd->thresholdAbove2_Val <= snrCmd->thresholdAbove1_Val ||
3888 snrCmd->thresholdBelow4_Val <= snrCmd->thresholdBelow3_Val ||
3889 snrCmd->thresholdBelow3_Val <= snrCmd->thresholdBelow2_Val ||
3890 snrCmd->thresholdBelow2_Val <= snrCmd->thresholdBelow1_Val)
3892 return A_EINVAL;
3894 wmi_cache_configure_snrthreshold(wmip, snrCmd);
3895 return (wmi_send_snr_threshold_params(wmip, snrCmd));
3899 wmi_clr_rssi_snr(struct wmi_t *wmip)
3901 void *osbuf;
3903 osbuf = A_NETBUF_ALLOC(sizeof(int));
3904 if (osbuf == NULL) {
3905 return A_NO_MEMORY;
3908 return (wmi_cmd_send(wmip, osbuf, WMI_CLR_RSSI_SNR_CMDID,
3909 NO_SYNC_WMIFLAG));
3913 wmi_set_lq_threshold_params(struct wmi_t *wmip,
3914 WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd)
3916 void *osbuf;
3917 s8 size;
3918 WMI_LQ_THRESHOLD_PARAMS_CMD *cmd;
3919 /* These values are in ascending order */
3920 if( lqCmd->thresholdAbove4_Val <= lqCmd->thresholdAbove3_Val ||
3921 lqCmd->thresholdAbove3_Val <= lqCmd->thresholdAbove2_Val ||
3922 lqCmd->thresholdAbove2_Val <= lqCmd->thresholdAbove1_Val ||
3923 lqCmd->thresholdBelow4_Val <= lqCmd->thresholdBelow3_Val ||
3924 lqCmd->thresholdBelow3_Val <= lqCmd->thresholdBelow2_Val ||
3925 lqCmd->thresholdBelow2_Val <= lqCmd->thresholdBelow1_Val ) {
3927 return A_EINVAL;
3930 size = sizeof (*cmd);
3932 osbuf = A_NETBUF_ALLOC(size);
3933 if (osbuf == NULL) {
3934 return A_NO_MEMORY;
3937 A_NETBUF_PUT(osbuf, size);
3939 cmd = (WMI_LQ_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
3940 A_MEMZERO(cmd, size);
3941 memcpy(cmd, lqCmd, sizeof(WMI_LQ_THRESHOLD_PARAMS_CMD));
3943 return (wmi_cmd_send(wmip, osbuf, WMI_LQ_THRESHOLD_PARAMS_CMDID,
3944 NO_SYNC_WMIFLAG));
3948 wmi_set_error_report_bitmask(struct wmi_t *wmip, u32 mask)
3950 void *osbuf;
3951 s8 size;
3952 WMI_TARGET_ERROR_REPORT_BITMASK *cmd;
3954 size = sizeof (*cmd);
3956 osbuf = A_NETBUF_ALLOC(size);
3957 if (osbuf == NULL) {
3958 return A_NO_MEMORY;
3961 A_NETBUF_PUT(osbuf, size);
3963 cmd = (WMI_TARGET_ERROR_REPORT_BITMASK *)(A_NETBUF_DATA(osbuf));
3964 A_MEMZERO(cmd, size);
3966 cmd->bitmask = mask;
3968 return (wmi_cmd_send(wmip, osbuf, WMI_TARGET_ERROR_REPORT_BITMASK_CMDID,
3969 NO_SYNC_WMIFLAG));
3973 wmi_get_challenge_resp_cmd(struct wmi_t *wmip, u32 cookie, u32 source)
3975 void *osbuf;
3976 WMIX_HB_CHALLENGE_RESP_CMD *cmd;
3978 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3979 if (osbuf == NULL) {
3980 return A_NO_MEMORY;
3983 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3985 cmd = (WMIX_HB_CHALLENGE_RESP_CMD *)(A_NETBUF_DATA(osbuf));
3986 cmd->cookie = cookie;
3987 cmd->source = source;
3989 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_HB_CHALLENGE_RESP_CMDID,
3990 NO_SYNC_WMIFLAG));
3994 wmi_config_debug_module_cmd(struct wmi_t *wmip, u16 mmask,
3995 u16 tsr, bool rep, u16 size,
3996 u32 valid)
3998 void *osbuf;
3999 WMIX_DBGLOG_CFG_MODULE_CMD *cmd;
4001 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4002 if (osbuf == NULL) {
4003 return A_NO_MEMORY;
4006 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4008 cmd = (WMIX_DBGLOG_CFG_MODULE_CMD *)(A_NETBUF_DATA(osbuf));
4009 cmd->config.cfgmmask = mmask;
4010 cmd->config.cfgtsr = tsr;
4011 cmd->config.cfgrep = rep;
4012 cmd->config.cfgsize = size;
4013 cmd->config.cfgvalid = valid;
4015 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DBGLOG_CFG_MODULE_CMDID,
4016 NO_SYNC_WMIFLAG));
4020 wmi_get_stats_cmd(struct wmi_t *wmip)
4022 return wmi_simple_cmd(wmip, WMI_GET_STATISTICS_CMDID);
4026 wmi_addBadAp_cmd(struct wmi_t *wmip, u8 apIndex, u8 *bssid)
4028 void *osbuf;
4029 WMI_ADD_BAD_AP_CMD *cmd;
4031 if ((bssid == NULL) || (apIndex > WMI_MAX_BAD_AP_INDEX)) {
4032 return A_EINVAL;
4035 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4036 if (osbuf == NULL) {
4037 return A_NO_MEMORY;
4040 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4042 cmd = (WMI_ADD_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf));
4043 cmd->badApIndex = apIndex;
4044 memcpy(cmd->bssid, bssid, sizeof(cmd->bssid));
4046 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_BAD_AP_CMDID, SYNC_BEFORE_WMIFLAG));
4050 wmi_deleteBadAp_cmd(struct wmi_t *wmip, u8 apIndex)
4052 void *osbuf;
4053 WMI_DELETE_BAD_AP_CMD *cmd;
4055 if (apIndex > WMI_MAX_BAD_AP_INDEX) {
4056 return A_EINVAL;
4059 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4060 if (osbuf == NULL) {
4061 return A_NO_MEMORY;
4064 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4066 cmd = (WMI_DELETE_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf));
4067 cmd->badApIndex = apIndex;
4069 return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_BAD_AP_CMDID,
4070 NO_SYNC_WMIFLAG));
4074 wmi_abort_scan_cmd(struct wmi_t *wmip)
4076 return wmi_simple_cmd(wmip, WMI_ABORT_SCAN_CMDID);
4080 wmi_set_txPwr_cmd(struct wmi_t *wmip, u8 dbM)
4082 void *osbuf;
4083 WMI_SET_TX_PWR_CMD *cmd;
4085 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4086 if (osbuf == NULL) {
4087 return A_NO_MEMORY;
4090 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4092 cmd = (WMI_SET_TX_PWR_CMD *)(A_NETBUF_DATA(osbuf));
4093 cmd->dbM = dbM;
4095 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_PWR_CMDID, NO_SYNC_WMIFLAG));
4099 wmi_get_txPwr_cmd(struct wmi_t *wmip)
4101 return wmi_simple_cmd(wmip, WMI_GET_TX_PWR_CMDID);
4104 u16 wmi_get_mapped_qos_queue(struct wmi_t *wmip, u8 trafficClass)
4106 u16 activeTsids=0;
4108 LOCK_WMI(wmip);
4109 activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
4110 UNLOCK_WMI(wmip);
4112 return activeTsids;
4116 wmi_get_roam_tbl_cmd(struct wmi_t *wmip)
4118 return wmi_simple_cmd(wmip, WMI_GET_ROAM_TBL_CMDID);
4122 wmi_get_roam_data_cmd(struct wmi_t *wmip, u8 roamDataType)
4124 void *osbuf;
4125 u32 size = sizeof(u8);
4126 WMI_TARGET_ROAM_DATA *cmd;
4128 osbuf = A_NETBUF_ALLOC(size); /* no payload */
4129 if (osbuf == NULL) {
4130 return A_NO_MEMORY;
4133 A_NETBUF_PUT(osbuf, size);
4135 cmd = (WMI_TARGET_ROAM_DATA *)(A_NETBUF_DATA(osbuf));
4136 cmd->roamDataType = roamDataType;
4138 return (wmi_cmd_send(wmip, osbuf, WMI_GET_ROAM_DATA_CMDID,
4139 NO_SYNC_WMIFLAG));
4143 wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p,
4144 u8 size)
4146 void *osbuf;
4147 WMI_SET_ROAM_CTRL_CMD *cmd;
4149 osbuf = A_NETBUF_ALLOC(size);
4150 if (osbuf == NULL) {
4151 return A_NO_MEMORY;
4154 A_NETBUF_PUT(osbuf, size);
4156 cmd = (WMI_SET_ROAM_CTRL_CMD *)(A_NETBUF_DATA(osbuf));
4157 A_MEMZERO(cmd, size);
4159 memcpy(cmd, p, size);
4161 return (wmi_cmd_send(wmip, osbuf, WMI_SET_ROAM_CTRL_CMDID,
4162 NO_SYNC_WMIFLAG));
4166 wmi_set_powersave_timers_cmd(struct wmi_t *wmip,
4167 WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd,
4168 u8 size)
4170 void *osbuf;
4171 WMI_POWERSAVE_TIMERS_POLICY_CMD *cmd;
4173 /* These timers can't be zero */
4174 if(!pCmd->psPollTimeout || !pCmd->triggerTimeout ||
4175 !(pCmd->apsdTimPolicy == IGNORE_TIM_ALL_QUEUES_APSD ||
4176 pCmd->apsdTimPolicy == PROCESS_TIM_ALL_QUEUES_APSD) ||
4177 !(pCmd->simulatedAPSDTimPolicy == IGNORE_TIM_SIMULATED_APSD ||
4178 pCmd->simulatedAPSDTimPolicy == PROCESS_TIM_SIMULATED_APSD))
4179 return A_EINVAL;
4181 osbuf = A_NETBUF_ALLOC(size);
4182 if (osbuf == NULL) {
4183 return A_NO_MEMORY;
4186 A_NETBUF_PUT(osbuf, size);
4188 cmd = (WMI_POWERSAVE_TIMERS_POLICY_CMD *)(A_NETBUF_DATA(osbuf));
4189 A_MEMZERO(cmd, size);
4191 memcpy(cmd, pCmd, size);
4193 return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID,
4194 NO_SYNC_WMIFLAG));
4198 wmi_set_access_params_cmd(struct wmi_t *wmip, u8 ac, u16 txop, u8 eCWmin,
4199 u8 eCWmax, u8 aifsn)
4201 void *osbuf;
4202 WMI_SET_ACCESS_PARAMS_CMD *cmd;
4204 if ((eCWmin > WMI_MAX_CW_ACPARAM) || (eCWmax > WMI_MAX_CW_ACPARAM) ||
4205 (aifsn > WMI_MAX_AIFSN_ACPARAM) || (ac >= WMM_NUM_AC))
4207 return A_EINVAL;
4210 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4211 if (osbuf == NULL) {
4212 return A_NO_MEMORY;
4215 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4217 cmd = (WMI_SET_ACCESS_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
4218 cmd->txop = txop;
4219 cmd->eCWmin = eCWmin;
4220 cmd->eCWmax = eCWmax;
4221 cmd->aifsn = aifsn;
4222 cmd->ac = ac;
4224 return (wmi_cmd_send(wmip, osbuf, WMI_SET_ACCESS_PARAMS_CMDID,
4225 NO_SYNC_WMIFLAG));
4229 wmi_set_retry_limits_cmd(struct wmi_t *wmip, u8 frameType,
4230 u8 trafficClass, u8 maxRetries,
4231 u8 enableNotify)
4233 void *osbuf;
4234 WMI_SET_RETRY_LIMITS_CMD *cmd;
4236 if ((frameType != MGMT_FRAMETYPE) && (frameType != CONTROL_FRAMETYPE) &&
4237 (frameType != DATA_FRAMETYPE))
4239 return A_EINVAL;
4242 if (maxRetries > WMI_MAX_RETRIES) {
4243 return A_EINVAL;
4246 if (frameType != DATA_FRAMETYPE) {
4247 trafficClass = 0;
4250 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4251 if (osbuf == NULL) {
4252 return A_NO_MEMORY;
4255 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4257 cmd = (WMI_SET_RETRY_LIMITS_CMD *)(A_NETBUF_DATA(osbuf));
4258 cmd->frameType = frameType;
4259 cmd->trafficClass = trafficClass;
4260 cmd->maxRetries = maxRetries;
4261 cmd->enableNotify = enableNotify;
4263 return (wmi_cmd_send(wmip, osbuf, WMI_SET_RETRY_LIMITS_CMDID,
4264 NO_SYNC_WMIFLAG));
4267 void
4268 wmi_get_current_bssid(struct wmi_t *wmip, u8 *bssid)
4270 if (bssid != NULL) {
4271 memcpy(bssid, wmip->wmi_bssid, ATH_MAC_LEN);
4276 wmi_set_opt_mode_cmd(struct wmi_t *wmip, u8 optMode)
4278 void *osbuf;
4279 WMI_SET_OPT_MODE_CMD *cmd;
4281 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4282 if (osbuf == NULL) {
4283 return A_NO_MEMORY;
4286 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4288 cmd = (WMI_SET_OPT_MODE_CMD *)(A_NETBUF_DATA(osbuf));
4289 A_MEMZERO(cmd, sizeof(*cmd));
4290 cmd->optMode = optMode;
4292 return (wmi_cmd_send(wmip, osbuf, WMI_SET_OPT_MODE_CMDID,
4293 SYNC_BOTH_WMIFLAG));
4297 wmi_opt_tx_frame_cmd(struct wmi_t *wmip,
4298 u8 frmType,
4299 u8 *dstMacAddr,
4300 u8 *bssid,
4301 u16 optIEDataLen,
4302 u8 *optIEData)
4304 void *osbuf;
4305 WMI_OPT_TX_FRAME_CMD *cmd;
4306 osbuf = A_NETBUF_ALLOC(optIEDataLen + sizeof(*cmd));
4307 if (osbuf == NULL) {
4308 return A_NO_MEMORY;
4311 A_NETBUF_PUT(osbuf, (optIEDataLen + sizeof(*cmd)));
4313 cmd = (WMI_OPT_TX_FRAME_CMD *)(A_NETBUF_DATA(osbuf));
4314 A_MEMZERO(cmd, (optIEDataLen + sizeof(*cmd)-1));
4316 cmd->frmType = frmType;
4317 cmd->optIEDataLen = optIEDataLen;
4318 //cmd->optIEData = (u8 *)((int)cmd + sizeof(*cmd));
4319 memcpy(cmd->bssid, bssid, sizeof(cmd->bssid));
4320 memcpy(cmd->dstAddr, dstMacAddr, sizeof(cmd->dstAddr));
4321 memcpy(&cmd->optIEData[0], optIEData, optIEDataLen);
4323 return (wmi_cmd_send(wmip, osbuf, WMI_OPT_TX_FRAME_CMDID,
4324 NO_SYNC_WMIFLAG));
4328 wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, u16 intvl)
4330 void *osbuf;
4331 WMI_BEACON_INT_CMD *cmd;
4333 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4334 if (osbuf == NULL) {
4335 return A_NO_MEMORY;
4338 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4340 cmd = (WMI_BEACON_INT_CMD *)(A_NETBUF_DATA(osbuf));
4341 A_MEMZERO(cmd, sizeof(*cmd));
4342 cmd->beaconInterval = intvl;
4344 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BEACON_INT_CMDID,
4345 NO_SYNC_WMIFLAG));
4350 wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, u16 voicePktSize)
4352 void *osbuf;
4353 WMI_SET_VOICE_PKT_SIZE_CMD *cmd;
4355 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4356 if (osbuf == NULL) {
4357 return A_NO_MEMORY;
4360 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4362 cmd = (WMI_SET_VOICE_PKT_SIZE_CMD *)(A_NETBUF_DATA(osbuf));
4363 A_MEMZERO(cmd, sizeof(*cmd));
4364 cmd->voicePktSize = voicePktSize;
4366 return (wmi_cmd_send(wmip, osbuf, WMI_SET_VOICE_PKT_SIZE_CMDID,
4367 NO_SYNC_WMIFLAG));
4372 wmi_set_max_sp_len_cmd(struct wmi_t *wmip, u8 maxSPLen)
4374 void *osbuf;
4375 WMI_SET_MAX_SP_LEN_CMD *cmd;
4377 /* maxSPLen is a two-bit value. If user trys to set anything
4378 * other than this, then its invalid
4380 if(maxSPLen & ~0x03)
4381 return A_EINVAL;
4383 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4384 if (osbuf == NULL) {
4385 return A_NO_MEMORY;
4388 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4390 cmd = (WMI_SET_MAX_SP_LEN_CMD *)(A_NETBUF_DATA(osbuf));
4391 A_MEMZERO(cmd, sizeof(*cmd));
4392 cmd->maxSPLen = maxSPLen;
4394 return (wmi_cmd_send(wmip, osbuf, WMI_SET_MAX_SP_LEN_CMDID,
4395 NO_SYNC_WMIFLAG));
4398 u8 wmi_determine_userPriority(
4399 u8 *pkt,
4400 u32 layer2Pri)
4402 u8 ipPri;
4403 iphdr *ipHdr = (iphdr *)pkt;
4405 /* Determine IPTOS priority */
4407 * IP Tos format :
4408 * (Refer Pg 57 WMM-test-plan-v1.2)
4409 * IP-TOS - 8bits
4410 * : DSCP(6-bits) ECN(2-bits)
4411 * : DSCP - P2 P1 P0 X X X
4412 * where (P2 P1 P0) form 802.1D
4414 ipPri = ipHdr->ip_tos >> 5;
4415 ipPri &= 0x7;
4417 if ((layer2Pri & 0x7) > ipPri)
4418 return ((u8)layer2Pri & 0x7);
4419 else
4420 return ipPri;
4423 u8 convert_userPriority_to_trafficClass(u8 userPriority)
4425 return (up_to_ac[userPriority & 0x7]);
4428 u8 wmi_get_power_mode_cmd(struct wmi_t *wmip)
4430 return wmip->wmi_powerMode;
4434 wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, int tspecCompliance)
4436 int ret = 0;
4438 #define TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF (~0)
4439 #define TSPEC_SERVICE_START_TIME_ATHEROS_DEF 0
4440 #define TSPEC_MAX_BURST_SIZE_ATHEROS_DEF 0
4441 #define TSPEC_DELAY_BOUND_ATHEROS_DEF 0
4442 #define TSPEC_MEDIUM_TIME_ATHEROS_DEF 0
4443 #define TSPEC_SBA_ATHEROS_DEF 0x2000 /* factor is 1 */
4445 /* Verify TSPEC params for ATHEROS compliance */
4446 if(tspecCompliance == ATHEROS_COMPLIANCE) {
4447 if ((pCmd->suspensionInt != TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF) ||
4448 (pCmd->serviceStartTime != TSPEC_SERVICE_START_TIME_ATHEROS_DEF) ||
4449 (pCmd->minDataRate != pCmd->meanDataRate) ||
4450 (pCmd->minDataRate != pCmd->peakDataRate) ||
4451 (pCmd->maxBurstSize != TSPEC_MAX_BURST_SIZE_ATHEROS_DEF) ||
4452 (pCmd->delayBound != TSPEC_DELAY_BOUND_ATHEROS_DEF) ||
4453 (pCmd->sba != TSPEC_SBA_ATHEROS_DEF) ||
4454 (pCmd->mediumTime != TSPEC_MEDIUM_TIME_ATHEROS_DEF)) {
4456 A_DPRINTF(DBG_WMI, (DBGFMT "Invalid TSPEC params\n", DBGARG));
4457 //A_PRINTF("%s: Invalid TSPEC params\n", __func__);
4458 ret = A_EINVAL;
4462 return ret;
4465 #ifdef CONFIG_HOST_TCMD_SUPPORT
4466 static int
4467 wmi_tcmd_test_report_rx(struct wmi_t *wmip, u8 *datap, int len)
4469 ar6000_testmode_rx_report_event(wmip->wmi_devt, datap, len);
4471 return 0;
4474 #endif /* CONFIG_HOST_TCMD_SUPPORT*/
4477 wmi_set_authmode_cmd(struct wmi_t *wmip, u8 mode)
4479 void *osbuf;
4480 WMI_SET_AUTH_MODE_CMD *cmd;
4482 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4483 if (osbuf == NULL) {
4484 return A_NO_MEMORY;
4487 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4489 cmd = (WMI_SET_AUTH_MODE_CMD *)(A_NETBUF_DATA(osbuf));
4490 A_MEMZERO(cmd, sizeof(*cmd));
4491 cmd->mode = mode;
4493 return (wmi_cmd_send(wmip, osbuf, WMI_SET_AUTH_MODE_CMDID,
4494 NO_SYNC_WMIFLAG));
4498 wmi_set_reassocmode_cmd(struct wmi_t *wmip, u8 mode)
4500 void *osbuf;
4501 WMI_SET_REASSOC_MODE_CMD *cmd;
4503 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4504 if (osbuf == NULL) {
4505 return A_NO_MEMORY;
4508 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4510 cmd = (WMI_SET_REASSOC_MODE_CMD *)(A_NETBUF_DATA(osbuf));
4511 A_MEMZERO(cmd, sizeof(*cmd));
4512 cmd->mode = mode;
4514 return (wmi_cmd_send(wmip, osbuf, WMI_SET_REASSOC_MODE_CMDID,
4515 NO_SYNC_WMIFLAG));
4519 wmi_set_lpreamble_cmd(struct wmi_t *wmip, u8 status, u8 preamblePolicy)
4521 void *osbuf;
4522 WMI_SET_LPREAMBLE_CMD *cmd;
4524 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4525 if (osbuf == NULL) {
4526 return A_NO_MEMORY;
4529 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4531 cmd = (WMI_SET_LPREAMBLE_CMD *)(A_NETBUF_DATA(osbuf));
4532 A_MEMZERO(cmd, sizeof(*cmd));
4533 cmd->status = status;
4534 cmd->preamblePolicy = preamblePolicy;
4536 return (wmi_cmd_send(wmip, osbuf, WMI_SET_LPREAMBLE_CMDID,
4537 NO_SYNC_WMIFLAG));
4541 wmi_set_rts_cmd(struct wmi_t *wmip, u16 threshold)
4543 void *osbuf;
4544 WMI_SET_RTS_CMD *cmd;
4546 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4547 if (osbuf == NULL) {
4548 return A_NO_MEMORY;
4551 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4553 cmd = (WMI_SET_RTS_CMD*)(A_NETBUF_DATA(osbuf));
4554 A_MEMZERO(cmd, sizeof(*cmd));
4555 cmd->threshold = threshold;
4557 return (wmi_cmd_send(wmip, osbuf, WMI_SET_RTS_CMDID,
4558 NO_SYNC_WMIFLAG));
4562 wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status)
4564 void *osbuf;
4565 WMI_SET_WMM_CMD *cmd;
4567 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4568 if (osbuf == NULL) {
4569 return A_NO_MEMORY;
4572 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4574 cmd = (WMI_SET_WMM_CMD*)(A_NETBUF_DATA(osbuf));
4575 A_MEMZERO(cmd, sizeof(*cmd));
4576 cmd->status = status;
4578 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_CMDID,
4579 NO_SYNC_WMIFLAG));
4584 wmi_set_qos_supp_cmd(struct wmi_t *wmip, u8 status)
4586 void *osbuf;
4587 WMI_SET_QOS_SUPP_CMD *cmd;
4589 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4590 if (osbuf == NULL) {
4591 return A_NO_MEMORY;
4594 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4596 cmd = (WMI_SET_QOS_SUPP_CMD*)(A_NETBUF_DATA(osbuf));
4597 A_MEMZERO(cmd, sizeof(*cmd));
4598 cmd->status = status;
4599 return (wmi_cmd_send(wmip, osbuf, WMI_SET_QOS_SUPP_CMDID,
4600 NO_SYNC_WMIFLAG));
4605 wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG cfg)
4607 void *osbuf;
4608 WMI_SET_WMM_TXOP_CMD *cmd;
4610 if( !((cfg == WMI_TXOP_DISABLED) || (cfg == WMI_TXOP_ENABLED)) )
4611 return A_EINVAL;
4613 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4614 if (osbuf == NULL) {
4615 return A_NO_MEMORY;
4618 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4620 cmd = (WMI_SET_WMM_TXOP_CMD *)(A_NETBUF_DATA(osbuf));
4621 A_MEMZERO(cmd, sizeof(*cmd));
4622 cmd->txopEnable = cfg;
4624 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_TXOP_CMDID,
4625 NO_SYNC_WMIFLAG));
4630 wmi_set_country(struct wmi_t *wmip, u8 *countryCode)
4632 void *osbuf;
4633 WMI_AP_SET_COUNTRY_CMD *cmd;
4635 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4636 if (osbuf == NULL) {
4637 return A_NO_MEMORY;
4640 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4642 cmd = (WMI_AP_SET_COUNTRY_CMD *)(A_NETBUF_DATA(osbuf));
4643 A_MEMZERO(cmd, sizeof(*cmd));
4644 memcpy(cmd->countryCode,countryCode,3);
4646 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_COUNTRY_CMDID,
4647 NO_SYNC_WMIFLAG));
4650 #ifdef CONFIG_HOST_TCMD_SUPPORT
4651 /* WMI layer doesn't need to know the data type of the test cmd.
4652 This would be beneficial for customers like Qualcomm, who might
4653 have different test command requirements from different manufacturers
4656 wmi_test_cmd(struct wmi_t *wmip, u8 *buf, u32 len)
4658 void *osbuf;
4659 char *data;
4661 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
4663 osbuf= A_NETBUF_ALLOC(len);
4664 if(osbuf == NULL)
4666 return A_NO_MEMORY;
4668 A_NETBUF_PUT(osbuf, len);
4669 data = A_NETBUF_DATA(osbuf);
4670 memcpy(data, buf, len);
4672 return(wmi_cmd_send(wmip, osbuf, WMI_TEST_CMDID,
4673 NO_SYNC_WMIFLAG));
4676 #endif
4679 wmi_set_bt_status_cmd(struct wmi_t *wmip, u8 streamType, u8 status)
4681 void *osbuf;
4682 WMI_SET_BT_STATUS_CMD *cmd;
4684 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Enter - streamType=%d, status=%d\n", streamType, status));
4686 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4687 if (osbuf == NULL) {
4688 return A_NO_MEMORY;
4691 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4693 cmd = (WMI_SET_BT_STATUS_CMD *)(A_NETBUF_DATA(osbuf));
4694 A_MEMZERO(cmd, sizeof(*cmd));
4695 cmd->streamType = streamType;
4696 cmd->status = status;
4698 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_STATUS_CMDID,
4699 NO_SYNC_WMIFLAG));
4703 wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd)
4705 void *osbuf;
4706 WMI_SET_BT_PARAMS_CMD* alloc_cmd;
4708 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("cmd params is %d\n", cmd->paramType));
4710 if (cmd->paramType == BT_PARAM_SCO) {
4711 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("sco params %d %d %d %d %d %d %d %d %d %d %d %d\n", cmd->info.scoParams.numScoCyclesForceTrigger,
4712 cmd->info.scoParams.dataResponseTimeout,
4713 cmd->info.scoParams.stompScoRules,
4714 cmd->info.scoParams.scoOptFlags,
4715 cmd->info.scoParams.stompDutyCyleVal,
4716 cmd->info.scoParams.stompDutyCyleMaxVal,
4717 cmd->info.scoParams.psPollLatencyFraction,
4718 cmd->info.scoParams.noSCOSlots,
4719 cmd->info.scoParams.noIdleSlots,
4720 cmd->info.scoParams.scoOptOffRssi,
4721 cmd->info.scoParams.scoOptOnRssi,
4722 cmd->info.scoParams.scoOptRtsCount));
4724 else if (cmd->paramType == BT_PARAM_A2DP) {
4725 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("A2DP params %d %d %d %d %d %d %d %d\n", cmd->info.a2dpParams.a2dpWlanUsageLimit,
4726 cmd->info.a2dpParams.a2dpBurstCntMin,
4727 cmd->info.a2dpParams.a2dpDataRespTimeout,
4728 cmd->info.a2dpParams.a2dpOptFlags,
4729 cmd->info.a2dpParams.isCoLocatedBtRoleMaster,
4730 cmd->info.a2dpParams.a2dpOptOffRssi,
4731 cmd->info.a2dpParams.a2dpOptOnRssi,
4732 cmd->info.a2dpParams.a2dpOptRtsCount));
4734 else if (cmd->paramType == BT_PARAM_ANTENNA_CONFIG) {
4735 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Ant config %d\n", cmd->info.antType));
4737 else if (cmd->paramType == BT_PARAM_COLOCATED_BT_DEVICE) {
4738 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("co-located BT %d\n", cmd->info.coLocatedBtDev));
4740 else if (cmd->paramType == BT_PARAM_ACLCOEX) {
4741 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("ACL params %d %d %d\n", cmd->info.aclCoexParams.aclWlanMediumUsageTime,
4742 cmd->info.aclCoexParams.aclBtMediumUsageTime,
4743 cmd->info.aclCoexParams.aclDataRespTimeout));
4745 else if (cmd->paramType == BT_PARAM_11A_SEPARATE_ANT) {
4746 A_DPRINTF(DBG_WMI, (DBGFMT "11A ant\n", DBGARG));
4749 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4750 if (osbuf == NULL) {
4751 return A_NO_MEMORY;
4754 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4756 alloc_cmd = (WMI_SET_BT_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
4757 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4758 memcpy(alloc_cmd, cmd, sizeof(*cmd));
4760 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_PARAMS_CMDID,
4761 NO_SYNC_WMIFLAG));
4765 wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd)
4767 void *osbuf;
4768 WMI_SET_BTCOEX_FE_ANT_CMD *alloc_cmd;
4770 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4771 if (osbuf == NULL) {
4772 return A_NO_MEMORY;
4774 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4775 alloc_cmd = (WMI_SET_BTCOEX_FE_ANT_CMD *)(A_NETBUF_DATA(osbuf));
4776 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4777 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_FE_ANT_CMD));
4778 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_FE_ANT_CMDID,
4779 NO_SYNC_WMIFLAG));
4785 wmi_set_btcoex_colocated_bt_dev_cmd(struct wmi_t *wmip,
4786 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD * cmd)
4788 void *osbuf;
4789 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD *alloc_cmd;
4791 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4792 if (osbuf == NULL) {
4793 return A_NO_MEMORY;
4795 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4796 alloc_cmd = (WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD *)(A_NETBUF_DATA(osbuf));
4797 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4798 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD));
4799 A_PRINTF("colocated bt = %d\n", alloc_cmd->btcoexCoLocatedBTdev);
4800 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID,
4801 NO_SYNC_WMIFLAG));
4806 wmi_set_btcoex_btinquiry_page_config_cmd(struct wmi_t *wmip,
4807 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD* cmd)
4809 void *osbuf;
4810 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *alloc_cmd;
4812 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4813 if (osbuf == NULL) {
4814 return A_NO_MEMORY;
4816 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4817 alloc_cmd = (WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
4818 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4819 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD));
4820 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID,
4821 NO_SYNC_WMIFLAG));
4826 wmi_set_btcoex_sco_config_cmd(struct wmi_t *wmip,
4827 WMI_SET_BTCOEX_SCO_CONFIG_CMD * cmd)
4829 void *osbuf;
4830 WMI_SET_BTCOEX_SCO_CONFIG_CMD *alloc_cmd;
4832 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4833 if (osbuf == NULL) {
4834 return A_NO_MEMORY;
4836 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4837 alloc_cmd = (WMI_SET_BTCOEX_SCO_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
4838 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4839 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_SCO_CONFIG_CMD));
4840 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_SCO_CONFIG_CMDID ,
4841 NO_SYNC_WMIFLAG));
4846 wmi_set_btcoex_a2dp_config_cmd(struct wmi_t *wmip,
4847 WMI_SET_BTCOEX_A2DP_CONFIG_CMD * cmd)
4849 void *osbuf;
4850 WMI_SET_BTCOEX_A2DP_CONFIG_CMD *alloc_cmd;
4852 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4853 if (osbuf == NULL) {
4854 return A_NO_MEMORY;
4856 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4857 alloc_cmd = (WMI_SET_BTCOEX_A2DP_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
4858 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4859 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_A2DP_CONFIG_CMD));
4860 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_A2DP_CONFIG_CMDID ,
4861 NO_SYNC_WMIFLAG));
4866 wmi_set_btcoex_aclcoex_config_cmd(struct wmi_t *wmip,
4867 WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD * cmd)
4869 void *osbuf;
4870 WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD *alloc_cmd;
4872 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4873 if (osbuf == NULL) {
4874 return A_NO_MEMORY;
4876 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4877 alloc_cmd = (WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
4878 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4879 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD));
4880 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID ,
4881 NO_SYNC_WMIFLAG));
4886 wmi_set_btcoex_debug_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_DEBUG_CMD * cmd)
4888 void *osbuf;
4889 WMI_SET_BTCOEX_DEBUG_CMD *alloc_cmd;
4891 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4892 if (osbuf == NULL) {
4893 return A_NO_MEMORY;
4895 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4896 alloc_cmd = (WMI_SET_BTCOEX_DEBUG_CMD *)(A_NETBUF_DATA(osbuf));
4897 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4898 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_DEBUG_CMD));
4899 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_DEBUG_CMDID ,
4900 NO_SYNC_WMIFLAG));
4905 wmi_set_btcoex_bt_operating_status_cmd(struct wmi_t * wmip,
4906 WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD * cmd)
4908 void *osbuf;
4909 WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *alloc_cmd;
4911 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4912 if (osbuf == NULL) {
4913 return A_NO_MEMORY;
4915 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4916 alloc_cmd = (WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *)(A_NETBUF_DATA(osbuf));
4917 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4918 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD));
4919 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID ,
4920 NO_SYNC_WMIFLAG));
4925 wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * cmd)
4927 void *osbuf;
4928 WMI_GET_BTCOEX_CONFIG_CMD *alloc_cmd;
4930 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4931 if (osbuf == NULL) {
4932 return A_NO_MEMORY;
4934 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4935 alloc_cmd = (WMI_GET_BTCOEX_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
4936 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4937 memcpy(alloc_cmd,cmd,sizeof(WMI_GET_BTCOEX_CONFIG_CMD));
4938 return (wmi_cmd_send(wmip, osbuf, WMI_GET_BTCOEX_CONFIG_CMDID ,
4939 NO_SYNC_WMIFLAG));
4944 wmi_get_btcoex_stats_cmd(struct wmi_t *wmip)
4947 return wmi_simple_cmd(wmip, WMI_GET_BTCOEX_STATS_CMDID);
4952 wmi_get_keepalive_configured(struct wmi_t *wmip)
4954 void *osbuf;
4955 WMI_GET_KEEPALIVE_CMD *cmd;
4956 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4957 if (osbuf == NULL) {
4958 return A_NO_MEMORY;
4960 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4961 cmd = (WMI_GET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf));
4962 A_MEMZERO(cmd, sizeof(*cmd));
4963 return (wmi_cmd_send(wmip, osbuf, WMI_GET_KEEPALIVE_CMDID,
4964 NO_SYNC_WMIFLAG));
4967 u8 wmi_get_keepalive_cmd(struct wmi_t *wmip)
4969 return wmip->wmi_keepaliveInterval;
4973 wmi_set_keepalive_cmd(struct wmi_t *wmip, u8 keepaliveInterval)
4975 void *osbuf;
4976 WMI_SET_KEEPALIVE_CMD *cmd;
4978 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4979 if (osbuf == NULL) {
4980 return A_NO_MEMORY;
4983 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4985 cmd = (WMI_SET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf));
4986 A_MEMZERO(cmd, sizeof(*cmd));
4987 cmd->keepaliveInterval = keepaliveInterval;
4988 wmip->wmi_keepaliveInterval = keepaliveInterval;
4990 return (wmi_cmd_send(wmip, osbuf, WMI_SET_KEEPALIVE_CMDID,
4991 NO_SYNC_WMIFLAG));
4995 wmi_set_params_cmd(struct wmi_t *wmip, u32 opcode, u32 length, char *buffer)
4997 void *osbuf;
4998 WMI_SET_PARAMS_CMD *cmd;
5000 osbuf = A_NETBUF_ALLOC(sizeof(*cmd) + length);
5001 if (osbuf == NULL) {
5002 return A_NO_MEMORY;
5005 A_NETBUF_PUT(osbuf, sizeof(*cmd) + length);
5007 cmd = (WMI_SET_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
5008 A_MEMZERO(cmd, sizeof(*cmd));
5009 cmd->opcode = opcode;
5010 cmd->length = length;
5011 memcpy(cmd->buffer, buffer, length);
5013 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PARAMS_CMDID,
5014 NO_SYNC_WMIFLAG));
5019 wmi_set_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4)
5021 void *osbuf;
5022 WMI_SET_MCAST_FILTER_CMD *cmd;
5024 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5025 if (osbuf == NULL) {
5026 return A_NO_MEMORY;
5029 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5031 cmd = (WMI_SET_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
5032 cmd->multicast_mac[0] = 0x01;
5033 cmd->multicast_mac[1] = 0x00;
5034 cmd->multicast_mac[2] = 0x5e;
5035 cmd->multicast_mac[3] = dot2&0x7F;
5036 cmd->multicast_mac[4] = dot3;
5037 cmd->multicast_mac[5] = dot4;
5039 return (wmi_cmd_send(wmip, osbuf, WMI_SET_MCAST_FILTER_CMDID,
5040 NO_SYNC_WMIFLAG));
5045 wmi_del_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4)
5047 void *osbuf;
5048 WMI_SET_MCAST_FILTER_CMD *cmd;
5050 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5051 if (osbuf == NULL) {
5052 return A_NO_MEMORY;
5055 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5057 cmd = (WMI_SET_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
5058 cmd->multicast_mac[0] = 0x01;
5059 cmd->multicast_mac[1] = 0x00;
5060 cmd->multicast_mac[2] = 0x5e;
5061 cmd->multicast_mac[3] = dot2&0x7F;
5062 cmd->multicast_mac[4] = dot3;
5063 cmd->multicast_mac[5] = dot4;
5065 return (wmi_cmd_send(wmip, osbuf, WMI_DEL_MCAST_FILTER_CMDID,
5066 NO_SYNC_WMIFLAG));
5070 wmi_mcast_filter_cmd(struct wmi_t *wmip, u8 enable)
5072 void *osbuf;
5073 WMI_MCAST_FILTER_CMD *cmd;
5075 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5076 if (osbuf == NULL) {
5077 return A_NO_MEMORY;
5080 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5082 cmd = (WMI_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
5083 cmd->enable = enable;
5085 return (wmi_cmd_send(wmip, osbuf, WMI_MCAST_FILTER_CMDID,
5086 NO_SYNC_WMIFLAG));
5090 wmi_set_appie_cmd(struct wmi_t *wmip, u8 mgmtFrmType, u8 ieLen,
5091 u8 *ieInfo)
5093 void *osbuf;
5094 WMI_SET_APPIE_CMD *cmd;
5095 u16 cmdLen;
5097 cmdLen = sizeof(*cmd) + ieLen - 1;
5098 osbuf = A_NETBUF_ALLOC(cmdLen);
5099 if (osbuf == NULL) {
5100 return A_NO_MEMORY;
5103 A_NETBUF_PUT(osbuf, cmdLen);
5105 cmd = (WMI_SET_APPIE_CMD *)(A_NETBUF_DATA(osbuf));
5106 A_MEMZERO(cmd, cmdLen);
5108 cmd->mgmtFrmType = mgmtFrmType;
5109 cmd->ieLen = ieLen;
5110 memcpy(cmd->ieInfo, ieInfo, ieLen);
5112 return (wmi_cmd_send(wmip, osbuf, WMI_SET_APPIE_CMDID, NO_SYNC_WMIFLAG));
5116 wmi_set_halparam_cmd(struct wmi_t *wmip, u8 *cmd, u16 dataLen)
5118 void *osbuf;
5119 u8 *data;
5121 osbuf = A_NETBUF_ALLOC(dataLen);
5122 if (osbuf == NULL) {
5123 return A_NO_MEMORY;
5126 A_NETBUF_PUT(osbuf, dataLen);
5128 data = A_NETBUF_DATA(osbuf);
5130 memcpy(data, cmd, dataLen);
5132 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WHALPARAM_CMDID, NO_SYNC_WMIFLAG));
5135 s32 wmi_get_rate(s8 rateindex)
5137 if (rateindex == RATE_AUTO) {
5138 return 0;
5139 } else {
5140 return(wmi_rateTable[(u32) rateindex][0]);
5144 void
5145 wmi_node_return (struct wmi_t *wmip, bss_t *bss)
5147 if (NULL != bss)
5149 wlan_node_return (&wmip->wmi_scan_table, bss);
5153 void
5154 wmi_set_nodeage(struct wmi_t *wmip, u32 nodeAge)
5156 wlan_set_nodeage(&wmip->wmi_scan_table,nodeAge);
5159 bss_t *
5160 wmi_find_Ssidnode (struct wmi_t *wmip, u8 *pSsid,
5161 u32 ssidLength, bool bIsWPA2, bool bMatchSSID)
5163 bss_t *node = NULL;
5164 node = wlan_find_Ssidnode (&wmip->wmi_scan_table, pSsid,
5165 ssidLength, bIsWPA2, bMatchSSID);
5166 return node;
5170 #ifdef THREAD_X
5171 void
5172 wmi_refresh_scan_table (struct wmi_t *wmip)
5174 wlan_refresh_inactive_nodes (&wmip->wmi_scan_table);
5176 #endif
5178 void
5179 wmi_free_allnodes(struct wmi_t *wmip)
5181 wlan_free_allnodes(&wmip->wmi_scan_table);
5184 bss_t *
5185 wmi_find_node(struct wmi_t *wmip, const u8 *macaddr)
5187 bss_t *ni=NULL;
5188 ni=wlan_find_node(&wmip->wmi_scan_table,macaddr);
5189 return ni;
5192 void
5193 wmi_free_node(struct wmi_t *wmip, const u8 *macaddr)
5195 bss_t *ni=NULL;
5197 ni=wlan_find_node(&wmip->wmi_scan_table,macaddr);
5198 if (ni != NULL) {
5199 wlan_node_reclaim(&wmip->wmi_scan_table, ni);
5202 return;
5206 wmi_dset_open_reply(struct wmi_t *wmip,
5207 u32 status,
5208 u32 access_cookie,
5209 u32 dset_size,
5210 u32 dset_version,
5211 u32 targ_handle,
5212 u32 targ_reply_fn,
5213 u32 targ_reply_arg)
5215 void *osbuf;
5216 WMIX_DSETOPEN_REPLY_CMD *open_reply;
5218 A_DPRINTF(DBG_WMI, (DBGFMT "Enter - wmip=0x%lx\n", DBGARG, (unsigned long)wmip));
5220 osbuf = A_NETBUF_ALLOC(sizeof(*open_reply));
5221 if (osbuf == NULL) {
5222 return A_NO_MEMORY;
5225 A_NETBUF_PUT(osbuf, sizeof(*open_reply));
5226 open_reply = (WMIX_DSETOPEN_REPLY_CMD *)(A_NETBUF_DATA(osbuf));
5228 open_reply->status = status;
5229 open_reply->targ_dset_handle = targ_handle;
5230 open_reply->targ_reply_fn = targ_reply_fn;
5231 open_reply->targ_reply_arg = targ_reply_arg;
5232 open_reply->access_cookie = access_cookie;
5233 open_reply->size = dset_size;
5234 open_reply->version = dset_version;
5236 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETOPEN_REPLY_CMDID,
5237 NO_SYNC_WMIFLAG));
5240 static int
5241 wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, u8 *datap, u32 len)
5243 WMI_PMKID_LIST_REPLY *reply;
5244 u32 expected_len;
5246 if (len < sizeof(WMI_PMKID_LIST_REPLY)) {
5247 return A_EINVAL;
5249 reply = (WMI_PMKID_LIST_REPLY *)datap;
5250 expected_len = sizeof(reply->numPMKID) + reply->numPMKID * WMI_PMKID_LEN;
5252 if (len < expected_len) {
5253 return A_EINVAL;
5256 A_WMI_PMKID_LIST_EVENT(wmip->wmi_devt, reply->numPMKID,
5257 reply->pmkidList, reply->bssidList[0]);
5259 return 0;
5263 static int
5264 wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, u32 len)
5266 WMI_SET_PARAMS_REPLY *reply;
5268 if (len < sizeof(WMI_SET_PARAMS_REPLY)) {
5269 return A_EINVAL;
5271 reply = (WMI_SET_PARAMS_REPLY *)datap;
5273 if (0 == reply->status)
5277 else
5282 return 0;
5286 #ifdef CONFIG_HOST_DSET_SUPPORT
5288 wmi_dset_data_reply(struct wmi_t *wmip,
5289 u32 status,
5290 u8 *user_buf,
5291 u32 length,
5292 u32 targ_buf,
5293 u32 targ_reply_fn,
5294 u32 targ_reply_arg)
5296 void *osbuf;
5297 WMIX_DSETDATA_REPLY_CMD *data_reply;
5298 u32 size;
5300 size = sizeof(*data_reply) + length;
5302 if (size <= length) {
5303 return A_ERROR;
5306 A_DPRINTF(DBG_WMI,
5307 (DBGFMT "Enter - length=%d status=%d\n", DBGARG, length, status));
5309 osbuf = A_NETBUF_ALLOC(size);
5310 if (osbuf == NULL) {
5311 return A_NO_MEMORY;
5313 A_NETBUF_PUT(osbuf, size);
5314 data_reply = (WMIX_DSETDATA_REPLY_CMD *)(A_NETBUF_DATA(osbuf));
5316 data_reply->status = status;
5317 data_reply->targ_buf = targ_buf;
5318 data_reply->targ_reply_fn = targ_reply_fn;
5319 data_reply->targ_reply_arg = targ_reply_arg;
5320 data_reply->length = length;
5322 if (status == 0) {
5323 if (a_copy_from_user(data_reply->buf, user_buf, length)) {
5324 A_NETBUF_FREE(osbuf);
5325 return A_ERROR;
5329 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETDATA_REPLY_CMDID,
5330 NO_SYNC_WMIFLAG));
5332 #endif /* CONFIG_HOST_DSET_SUPPORT */
5335 wmi_set_wsc_status_cmd(struct wmi_t *wmip, u32 status)
5337 void *osbuf;
5338 char *cmd;
5340 wps_enable = status;
5342 osbuf = a_netbuf_alloc(sizeof(1));
5343 if (osbuf == NULL) {
5344 return A_NO_MEMORY;
5347 a_netbuf_put(osbuf, sizeof(1));
5349 cmd = (char *)(a_netbuf_to_data(osbuf));
5351 A_MEMZERO(cmd, sizeof(*cmd));
5352 cmd[0] = (status?1:0);
5353 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WSC_STATUS_CMDID,
5354 NO_SYNC_WMIFLAG));
5357 #if defined(CONFIG_TARGET_PROFILE_SUPPORT)
5359 wmi_prof_cfg_cmd(struct wmi_t *wmip,
5360 u32 period,
5361 u32 nbins)
5363 void *osbuf;
5364 WMIX_PROF_CFG_CMD *cmd;
5366 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5367 if (osbuf == NULL) {
5368 return A_NO_MEMORY;
5371 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5373 cmd = (WMIX_PROF_CFG_CMD *)(A_NETBUF_DATA(osbuf));
5374 A_MEMZERO(cmd, sizeof(*cmd));
5375 cmd->period = period;
5376 cmd->nbins = nbins;
5378 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_PROF_CFG_CMDID, NO_SYNC_WMIFLAG));
5382 wmi_prof_addr_set_cmd(struct wmi_t *wmip, u32 addr)
5384 void *osbuf;
5385 WMIX_PROF_ADDR_SET_CMD *cmd;
5387 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5388 if (osbuf == NULL) {
5389 return A_NO_MEMORY;
5392 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5394 cmd = (WMIX_PROF_ADDR_SET_CMD *)(A_NETBUF_DATA(osbuf));
5395 A_MEMZERO(cmd, sizeof(*cmd));
5396 cmd->addr = addr;
5398 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_PROF_ADDR_SET_CMDID, NO_SYNC_WMIFLAG));
5402 wmi_prof_start_cmd(struct wmi_t *wmip)
5404 return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_START_CMDID);
5408 wmi_prof_stop_cmd(struct wmi_t *wmip)
5410 return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_STOP_CMDID);
5414 wmi_prof_count_get_cmd(struct wmi_t *wmip)
5416 return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_COUNT_GET_CMDID);
5419 /* Called to handle WMIX_PROF_CONT_EVENTID */
5420 static int
5421 wmi_prof_count_rx(struct wmi_t *wmip, u8 *datap, int len)
5423 WMIX_PROF_COUNT_EVENT *prof_data = (WMIX_PROF_COUNT_EVENT *)datap;
5425 A_DPRINTF(DBG_WMI,
5426 (DBGFMT "Enter - addr=0x%x count=%d\n", DBGARG,
5427 prof_data->addr, prof_data->count));
5429 A_WMI_PROF_COUNT_RX(prof_data->addr, prof_data->count);
5431 return 0;
5433 #endif /* CONFIG_TARGET_PROFILE_SUPPORT */
5435 #ifdef OS_ROAM_MANAGEMENT
5437 #define ETHERNET_MAC_ADDRESS_LENGTH 6
5439 void
5440 wmi_scan_indication (struct wmi_t *wmip)
5442 struct ieee80211_node_table *nt;
5443 u32 gen;
5444 u32 size;
5445 u32 bsssize;
5446 bss_t *bss;
5447 u32 numbss;
5448 PNDIS_802_11_BSSID_SCAN_INFO psi;
5449 PBYTE pie;
5450 NDIS_802_11_FIXED_IEs *pFixed;
5451 NDIS_802_11_VARIABLE_IEs *pVar;
5452 u32 RateSize;
5454 struct ar6kScanIndication
5456 NDIS_802_11_STATUS_INDICATION ind;
5457 NDIS_802_11_BSSID_SCAN_INFO_LIST slist;
5458 } *pAr6kScanIndEvent;
5460 nt = &wmip->wmi_scan_table;
5462 ++nt->nt_si_gen;
5465 gen = nt->nt_si_gen;
5467 size = offsetof(struct ar6kScanIndication, slist) +
5468 offsetof(NDIS_802_11_BSSID_SCAN_INFO_LIST, BssidScanInfo);
5470 numbss = 0;
5472 IEEE80211_NODE_LOCK(nt);
5474 //calc size
5475 for (bss = nt->nt_node_first; bss; bss = bss->ni_list_next) {
5476 if (bss->ni_si_gen != gen) {
5477 bsssize = offsetof(NDIS_802_11_BSSID_SCAN_INFO, Bssid) + offsetof(NDIS_WLAN_BSSID_EX, IEs);
5478 bsssize = bsssize + sizeof(NDIS_802_11_FIXED_IEs);
5480 #ifdef SUPPORT_WPA2
5481 if (bss->ni_cie.ie_rsn) {
5482 bsssize = bsssize + bss->ni_cie.ie_rsn[1] + 2;
5484 #endif
5485 if (bss->ni_cie.ie_wpa) {
5486 bsssize = bsssize + bss->ni_cie.ie_wpa[1] + 2;
5489 // bsssize must be a multiple of 4 to maintain alignment.
5490 bsssize = (bsssize + 3) & ~3;
5492 size += bsssize;
5494 numbss++;
5498 if (0 == numbss)
5500 // RETAILMSG(1, (L"AR6K: scan indication: 0 bss\n"));
5501 ar6000_scan_indication (wmip->wmi_devt, NULL, 0);
5502 IEEE80211_NODE_UNLOCK (nt);
5503 return;
5506 pAr6kScanIndEvent = A_MALLOC(size);
5508 if (NULL == pAr6kScanIndEvent)
5510 IEEE80211_NODE_UNLOCK(nt);
5511 return;
5514 A_MEMZERO(pAr6kScanIndEvent, size);
5516 //copy data
5517 pAr6kScanIndEvent->ind.StatusType = Ndis802_11StatusType_BssidScanInfoList;
5518 pAr6kScanIndEvent->slist.Version = 1;
5519 pAr6kScanIndEvent->slist.NumItems = numbss;
5521 psi = &pAr6kScanIndEvent->slist.BssidScanInfo[0];
5523 for (bss = nt->nt_node_first; bss; bss = bss->ni_list_next) {
5524 if (bss->ni_si_gen != gen) {
5526 bss->ni_si_gen = gen;
5528 //Set scan time
5529 psi->ScanTime = bss->ni_tstamp - WLAN_NODE_INACT_TIMEOUT_MSEC;
5531 // Copy data to bssid_ex
5532 bsssize = offsetof(NDIS_WLAN_BSSID_EX, IEs);
5533 bsssize = bsssize + sizeof(NDIS_802_11_FIXED_IEs);
5535 #ifdef SUPPORT_WPA2
5536 if (bss->ni_cie.ie_rsn) {
5537 bsssize = bsssize + bss->ni_cie.ie_rsn[1] + 2;
5539 #endif
5540 if (bss->ni_cie.ie_wpa) {
5541 bsssize = bsssize + bss->ni_cie.ie_wpa[1] + 2;
5544 // bsssize must be a multiple of 4 to maintain alignment.
5545 bsssize = (bsssize + 3) & ~3;
5547 psi->Bssid.Length = bsssize;
5549 memcpy (psi->Bssid.MacAddress, bss->ni_macaddr, ETHERNET_MAC_ADDRESS_LENGTH);
5552 //if (((bss->ni_macaddr[3] == 0xCE) && (bss->ni_macaddr[4] == 0xF0) && (bss->ni_macaddr[5] == 0xE7)) ||
5553 // ((bss->ni_macaddr[3] == 0x03) && (bss->ni_macaddr[4] == 0xE2) && (bss->ni_macaddr[5] == 0x70)))
5554 // RETAILMSG (1, (L"%x\n",bss->ni_macaddr[5]));
5556 psi->Bssid.Ssid.SsidLength = 0;
5557 pie = bss->ni_cie.ie_ssid;
5559 if (pie) {
5560 // Format of SSID IE is:
5561 // Type (1 octet)
5562 // Length (1 octet)
5563 // SSID (Length octets)
5565 // Validation of the IE should have occurred within WMI.
5567 if (pie[1] <= 32) {
5568 psi->Bssid.Ssid.SsidLength = pie[1];
5569 memcpy(psi->Bssid.Ssid.Ssid, &pie[2], psi->Bssid.Ssid.SsidLength);
5572 psi->Bssid.Privacy = (bss->ni_cie.ie_capInfo & 0x10) ? 1 : 0;
5574 //Post the RSSI value relative to the Standard Noise floor value.
5575 psi->Bssid.Rssi = bss->ni_rssi;
5577 if (bss->ni_cie.ie_chan >= 2412 && bss->ni_cie.ie_chan <= 2484) {
5579 if (bss->ni_cie.ie_rates && bss->ni_cie.ie_xrates) {
5580 psi->Bssid.NetworkTypeInUse = Ndis802_11OFDM24;
5582 else {
5583 psi->Bssid.NetworkTypeInUse = Ndis802_11DS;
5586 else {
5587 psi->Bssid.NetworkTypeInUse = Ndis802_11OFDM5;
5590 psi->Bssid.Configuration.Length = sizeof(psi->Bssid.Configuration);
5591 psi->Bssid.Configuration.BeaconPeriod = bss->ni_cie.ie_beaconInt; // Units are Kmicroseconds (1024 us)
5592 psi->Bssid.Configuration.ATIMWindow = 0;
5593 psi->Bssid.Configuration.DSConfig = bss->ni_cie.ie_chan * 1000;
5594 psi->Bssid.InfrastructureMode = ((bss->ni_cie.ie_capInfo & 0x03) == 0x01 ) ? Ndis802_11Infrastructure : Ndis802_11IBSS;
5596 RateSize = 0;
5597 pie = bss->ni_cie.ie_rates;
5598 if (pie) {
5599 RateSize = (pie[1] < NDIS_802_11_LENGTH_RATES_EX) ? pie[1] : NDIS_802_11_LENGTH_RATES_EX;
5600 memcpy(psi->Bssid.SupportedRates, &pie[2], RateSize);
5602 pie = bss->ni_cie.ie_xrates;
5603 if (pie && RateSize < NDIS_802_11_LENGTH_RATES_EX) {
5604 memcpy(psi->Bssid.SupportedRates + RateSize, &pie[2],
5605 (pie[1] < (NDIS_802_11_LENGTH_RATES_EX - RateSize)) ? pie[1] : (NDIS_802_11_LENGTH_RATES_EX - RateSize));
5608 // Copy the fixed IEs
5609 psi->Bssid.IELength = sizeof(NDIS_802_11_FIXED_IEs);
5611 pFixed = (NDIS_802_11_FIXED_IEs *)psi->Bssid.IEs;
5612 memcpy(pFixed->Timestamp, bss->ni_cie.ie_tstamp, sizeof(pFixed->Timestamp));
5613 pFixed->BeaconInterval = bss->ni_cie.ie_beaconInt;
5614 pFixed->Capabilities = bss->ni_cie.ie_capInfo;
5616 // Copy selected variable IEs
5618 pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pFixed + sizeof(NDIS_802_11_FIXED_IEs));
5620 #ifdef SUPPORT_WPA2
5621 // Copy the WPAv2 IE
5622 if (bss->ni_cie.ie_rsn) {
5623 pie = bss->ni_cie.ie_rsn;
5624 psi->Bssid.IELength += pie[1] + 2;
5625 memcpy(pVar, pie, pie[1] + 2);
5626 pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pVar + pie[1] + 2);
5628 #endif
5629 // Copy the WPAv1 IE
5630 if (bss->ni_cie.ie_wpa) {
5631 pie = bss->ni_cie.ie_wpa;
5632 psi->Bssid.IELength += pie[1] + 2;
5633 memcpy(pVar, pie, pie[1] + 2);
5634 pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pVar + pie[1] + 2);
5637 // Advance buffer pointer
5638 psi = (PNDIS_802_11_BSSID_SCAN_INFO)((BYTE*)psi + bsssize + FIELD_OFFSET(NDIS_802_11_BSSID_SCAN_INFO, Bssid));
5642 IEEE80211_NODE_UNLOCK(nt);
5644 // wmi_free_allnodes(wmip);
5646 // RETAILMSG(1, (L"AR6K: scan indication: %u bss\n", numbss));
5648 ar6000_scan_indication (wmip->wmi_devt, pAr6kScanIndEvent, size);
5650 kfree(pAr6kScanIndEvent);
5652 #endif
5654 u8 ar6000_get_upper_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh,
5655 u32 size)
5657 u32 index;
5658 u8 threshold = (u8)sq_thresh->upper_threshold[size - 1];
5660 /* The list is already in sorted order. Get the next lower value */
5661 for (index = 0; index < size; index ++) {
5662 if (rssi < sq_thresh->upper_threshold[index]) {
5663 threshold = (u8)sq_thresh->upper_threshold[index];
5664 break;
5668 return threshold;
5671 u8 ar6000_get_lower_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh,
5672 u32 size)
5674 u32 index;
5675 u8 threshold = (u8)sq_thresh->lower_threshold[size - 1];
5677 /* The list is already in sorted order. Get the next lower value */
5678 for (index = 0; index < size; index ++) {
5679 if (rssi > sq_thresh->lower_threshold[index]) {
5680 threshold = (u8)sq_thresh->lower_threshold[index];
5681 break;
5685 return threshold;
5687 static int
5688 wmi_send_rssi_threshold_params(struct wmi_t *wmip,
5689 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
5691 void *osbuf;
5692 s8 size;
5693 WMI_RSSI_THRESHOLD_PARAMS_CMD *cmd;
5695 size = sizeof (*cmd);
5697 osbuf = A_NETBUF_ALLOC(size);
5698 if (osbuf == NULL) {
5699 return A_NO_MEMORY;
5702 A_NETBUF_PUT(osbuf, size);
5704 cmd = (WMI_RSSI_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
5705 A_MEMZERO(cmd, size);
5706 memcpy(cmd, rssiCmd, sizeof(WMI_RSSI_THRESHOLD_PARAMS_CMD));
5708 return (wmi_cmd_send(wmip, osbuf, WMI_RSSI_THRESHOLD_PARAMS_CMDID,
5709 NO_SYNC_WMIFLAG));
5711 static int
5712 wmi_send_snr_threshold_params(struct wmi_t *wmip,
5713 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
5715 void *osbuf;
5716 s8 size;
5717 WMI_SNR_THRESHOLD_PARAMS_CMD *cmd;
5719 size = sizeof (*cmd);
5721 osbuf = A_NETBUF_ALLOC(size);
5722 if (osbuf == NULL) {
5723 return A_NO_MEMORY;
5726 A_NETBUF_PUT(osbuf, size);
5727 cmd = (WMI_SNR_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
5728 A_MEMZERO(cmd, size);
5729 memcpy(cmd, snrCmd, sizeof(WMI_SNR_THRESHOLD_PARAMS_CMD));
5731 return (wmi_cmd_send(wmip, osbuf, WMI_SNR_THRESHOLD_PARAMS_CMDID,
5732 NO_SYNC_WMIFLAG));
5736 wmi_set_target_event_report_cmd(struct wmi_t *wmip, WMI_SET_TARGET_EVENT_REPORT_CMD* cmd)
5738 void *osbuf;
5739 WMI_SET_TARGET_EVENT_REPORT_CMD* alloc_cmd;
5741 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5742 if (osbuf == NULL) {
5743 return A_NO_MEMORY;
5746 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5748 alloc_cmd = (WMI_SET_TARGET_EVENT_REPORT_CMD *)(A_NETBUF_DATA(osbuf));
5749 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5750 memcpy(alloc_cmd, cmd, sizeof(*cmd));
5752 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TARGET_EVENT_REPORT_CMDID,
5753 NO_SYNC_WMIFLAG));
5756 bss_t *wmi_rm_current_bss (struct wmi_t *wmip, u8 *id)
5758 wmi_get_current_bssid (wmip, id);
5759 return wlan_node_remove (&wmip->wmi_scan_table, id);
5762 int wmi_add_current_bss (struct wmi_t *wmip, u8 *id, bss_t *bss)
5764 wlan_setup_node (&wmip->wmi_scan_table, bss, id);
5765 return 0;
5768 static int
5769 wmi_addba_req_event_rx(struct wmi_t *wmip, u8 *datap, int len)
5771 WMI_ADDBA_REQ_EVENT *cmd = (WMI_ADDBA_REQ_EVENT *)datap;
5773 A_WMI_AGGR_RECV_ADDBA_REQ_EVT(wmip->wmi_devt, cmd);
5775 return 0;
5779 static int
5780 wmi_addba_resp_event_rx(struct wmi_t *wmip, u8 *datap, int len)
5782 WMI_ADDBA_RESP_EVENT *cmd = (WMI_ADDBA_RESP_EVENT *)datap;
5784 A_WMI_AGGR_RECV_ADDBA_RESP_EVT(wmip->wmi_devt, cmd);
5786 return 0;
5789 static int
5790 wmi_delba_req_event_rx(struct wmi_t *wmip, u8 *datap, int len)
5792 WMI_DELBA_EVENT *cmd = (WMI_DELBA_EVENT *)datap;
5794 A_WMI_AGGR_RECV_DELBA_REQ_EVT(wmip->wmi_devt, cmd);
5796 return 0;
5800 wmi_btcoex_config_event_rx(struct wmi_t *wmip, u8 *datap, int len)
5802 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
5804 A_WMI_BTCOEX_CONFIG_EVENT(wmip->wmi_devt, datap, len);
5806 return 0;
5811 wmi_btcoex_stats_event_rx(struct wmi_t * wmip,u8 *datap,int len)
5813 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
5815 A_WMI_BTCOEX_STATS_EVENT(wmip->wmi_devt, datap, len);
5817 return 0;
5821 static int
5822 wmi_hci_event_rx(struct wmi_t *wmip, u8 *datap, int len)
5824 WMI_HCI_EVENT *cmd = (WMI_HCI_EVENT *)datap;
5825 A_WMI_HCI_EVENT_EVT(wmip->wmi_devt, cmd);
5827 return 0;
5830 ////////////////////////////////////////////////////////////////////////////////
5831 //// ////
5832 //// AP mode functions ////
5833 //// ////
5834 ////////////////////////////////////////////////////////////////////////////////
5836 * IOCTL: AR6000_XIOCTL_AP_COMMIT_CONFIG
5838 * When AR6K in AP mode, This command will be called after
5839 * changing ssid, channel etc. It will pass the profile to
5840 * target with a flag which will indicate which parameter changed,
5841 * also if this flag is 0, there was no change in parametes, so
5842 * commit cmd will not be sent to target. Without calling this IOCTL
5843 * the changes will not take effect.
5846 wmi_ap_profile_commit(struct wmi_t *wmip, WMI_CONNECT_CMD *p)
5848 void *osbuf;
5849 WMI_CONNECT_CMD *cm;
5851 osbuf = A_NETBUF_ALLOC(sizeof(*cm));
5852 if (osbuf == NULL) {
5853 return A_NO_MEMORY;
5856 A_NETBUF_PUT(osbuf, sizeof(*cm));
5857 cm = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf));
5858 A_MEMZERO(cm, sizeof(*cm));
5860 memcpy(cm,p,sizeof(*cm));
5862 return (wmi_cmd_send(wmip, osbuf, WMI_AP_CONFIG_COMMIT_CMDID, NO_SYNC_WMIFLAG));
5866 * IOCTL: AR6000_XIOCTL_AP_HIDDEN_SSID
5868 * This command will be used to enable/disable hidden ssid functioanlity of
5869 * beacon. If it is enabled, ssid will be NULL in beacon.
5872 wmi_ap_set_hidden_ssid(struct wmi_t *wmip, u8 hidden_ssid)
5874 void *osbuf;
5875 WMI_AP_HIDDEN_SSID_CMD *hs;
5877 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_HIDDEN_SSID_CMD));
5878 if (osbuf == NULL) {
5879 return A_NO_MEMORY;
5882 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_HIDDEN_SSID_CMD));
5883 hs = (WMI_AP_HIDDEN_SSID_CMD *)(A_NETBUF_DATA(osbuf));
5884 A_MEMZERO(hs, sizeof(*hs));
5886 hs->hidden_ssid = hidden_ssid;
5888 A_DPRINTF(DBG_WMI, (DBGFMT "AR6000_XIOCTL_AP_HIDDEN_SSID %d\n", DBGARG , hidden_ssid));
5889 return (wmi_cmd_send(wmip, osbuf, WMI_AP_HIDDEN_SSID_CMDID, NO_SYNC_WMIFLAG));
5893 * IOCTL: AR6000_XIOCTL_AP_SET_MAX_NUM_STA
5895 * This command is used to limit max num of STA that can connect
5896 * with this AP. This value should not exceed AP_MAX_NUM_STA (this
5897 * is max num of STA supported by AP). Value was already validated
5898 * in ioctl.c
5901 wmi_ap_set_num_sta(struct wmi_t *wmip, u8 num_sta)
5903 void *osbuf;
5904 WMI_AP_SET_NUM_STA_CMD *ns;
5906 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_NUM_STA_CMD));
5907 if (osbuf == NULL) {
5908 return A_NO_MEMORY;
5911 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_NUM_STA_CMD));
5912 ns = (WMI_AP_SET_NUM_STA_CMD *)(A_NETBUF_DATA(osbuf));
5913 A_MEMZERO(ns, sizeof(*ns));
5915 ns->num_sta = num_sta;
5917 A_DPRINTF(DBG_WMI, (DBGFMT "AR6000_XIOCTL_AP_SET_MAX_NUM_STA %d\n", DBGARG , num_sta));
5918 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_NUM_STA_CMDID, NO_SYNC_WMIFLAG));
5922 * IOCTL: AR6000_XIOCTL_AP_SET_ACL_MAC
5924 * This command is used to send list of mac of STAs which will
5925 * be allowed to connect with this AP. When this list is empty
5926 * firware will allow all STAs till the count reaches AP_MAX_NUM_STA.
5929 wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *acl)
5931 void *osbuf;
5932 WMI_AP_ACL_MAC_CMD *a;
5934 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_ACL_MAC_CMD));
5935 if (osbuf == NULL) {
5936 return A_NO_MEMORY;
5939 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_ACL_MAC_CMD));
5940 a = (WMI_AP_ACL_MAC_CMD *)(A_NETBUF_DATA(osbuf));
5941 A_MEMZERO(a, sizeof(*a));
5942 memcpy(a,acl,sizeof(*acl));
5944 return (wmi_cmd_send(wmip, osbuf, WMI_AP_ACL_MAC_LIST_CMDID, NO_SYNC_WMIFLAG));
5948 * IOCTL: AR6000_XIOCTL_AP_SET_MLME
5950 * This command is used to send list of mac of STAs which will
5951 * be allowed to connect with this AP. When this list is empty
5952 * firware will allow all STAs till the count reaches AP_MAX_NUM_STA.
5955 wmi_ap_set_mlme(struct wmi_t *wmip, u8 cmd, u8 *mac, u16 reason)
5957 void *osbuf;
5958 WMI_AP_SET_MLME_CMD *mlme;
5960 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_MLME_CMD));
5961 if (osbuf == NULL) {
5962 return A_NO_MEMORY;
5965 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_MLME_CMD));
5966 mlme = (WMI_AP_SET_MLME_CMD *)(A_NETBUF_DATA(osbuf));
5967 A_MEMZERO(mlme, sizeof(*mlme));
5969 mlme->cmd = cmd;
5970 memcpy(mlme->mac, mac, ATH_MAC_LEN);
5971 mlme->reason = reason;
5973 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_MLME_CMDID, NO_SYNC_WMIFLAG));
5976 static int
5977 wmi_pspoll_event_rx(struct wmi_t *wmip, u8 *datap, int len)
5979 WMI_PSPOLL_EVENT *ev;
5981 if (len < sizeof(WMI_PSPOLL_EVENT)) {
5982 return A_EINVAL;
5984 ev = (WMI_PSPOLL_EVENT *)datap;
5986 A_WMI_PSPOLL_EVENT(wmip->wmi_devt, ev->aid);
5987 return 0;
5990 static int
5991 wmi_dtimexpiry_event_rx(struct wmi_t *wmip, u8 *datap,int len)
5993 A_WMI_DTIMEXPIRY_EVENT(wmip->wmi_devt);
5994 return 0;
5997 #ifdef WAPI_ENABLE
5998 static int
5999 wmi_wapi_rekey_event_rx(struct wmi_t *wmip, u8 *datap,int len)
6001 u8 *ev;
6003 if (len < 7) {
6004 return A_EINVAL;
6006 ev = (u8 *)datap;
6008 A_WMI_WAPI_REKEY_EVENT(wmip->wmi_devt, *ev, &ev[1]);
6009 return 0;
6011 #endif
6014 wmi_set_pvb_cmd(struct wmi_t *wmip, u16 aid, bool flag)
6016 WMI_AP_SET_PVB_CMD *cmd;
6017 void *osbuf = NULL;
6019 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_PVB_CMD));
6020 if (osbuf == NULL) {
6021 return A_NO_MEMORY;
6024 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_PVB_CMD));
6025 cmd = (WMI_AP_SET_PVB_CMD *)(A_NETBUF_DATA(osbuf));
6026 A_MEMZERO(cmd, sizeof(*cmd));
6028 cmd->aid = aid;
6029 cmd->flag = flag;
6031 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_PVB_CMDID, NO_SYNC_WMIFLAG));
6035 wmi_ap_conn_inact_time(struct wmi_t *wmip, u32 period)
6037 WMI_AP_CONN_INACT_CMD *cmd;
6038 void *osbuf = NULL;
6040 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_CONN_INACT_CMD));
6041 if (osbuf == NULL) {
6042 return A_NO_MEMORY;
6045 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_CONN_INACT_CMD));
6046 cmd = (WMI_AP_CONN_INACT_CMD *)(A_NETBUF_DATA(osbuf));
6047 A_MEMZERO(cmd, sizeof(*cmd));
6049 cmd->period = period;
6051 return (wmi_cmd_send(wmip, osbuf, WMI_AP_CONN_INACT_CMDID, NO_SYNC_WMIFLAG));
6055 wmi_ap_bgscan_time(struct wmi_t *wmip, u32 period, u32 dwell)
6057 WMI_AP_PROT_SCAN_TIME_CMD *cmd;
6058 void *osbuf = NULL;
6060 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_PROT_SCAN_TIME_CMD));
6061 if (osbuf == NULL) {
6062 return A_NO_MEMORY;
6065 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_PROT_SCAN_TIME_CMD));
6066 cmd = (WMI_AP_PROT_SCAN_TIME_CMD *)(A_NETBUF_DATA(osbuf));
6067 A_MEMZERO(cmd, sizeof(*cmd));
6069 cmd->period_min = period;
6070 cmd->dwell_ms = dwell;
6072 return (wmi_cmd_send(wmip, osbuf, WMI_AP_PROT_SCAN_TIME_CMDID, NO_SYNC_WMIFLAG));
6076 wmi_ap_set_dtim(struct wmi_t *wmip, u8 dtim)
6078 WMI_AP_SET_DTIM_CMD *cmd;
6079 void *osbuf = NULL;
6081 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_DTIM_CMD));
6082 if (osbuf == NULL) {
6083 return A_NO_MEMORY;
6086 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_DTIM_CMD));
6087 cmd = (WMI_AP_SET_DTIM_CMD *)(A_NETBUF_DATA(osbuf));
6088 A_MEMZERO(cmd, sizeof(*cmd));
6090 cmd->dtim = dtim;
6092 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_DTIM_CMDID, NO_SYNC_WMIFLAG));
6096 * IOCTL: AR6000_XIOCTL_AP_SET_ACL_POLICY
6098 * This command is used to set ACL policay. While changing policy, if you
6099 * want to retain the existing MAC addresses in the ACL list, policy should be
6100 * OR with AP_ACL_RETAIN_LIST_MASK, else the existing list will be cleared.
6101 * If there is no chage in policy, the list will be intact.
6104 wmi_ap_set_acl_policy(struct wmi_t *wmip, u8 policy)
6106 void *osbuf;
6107 WMI_AP_ACL_POLICY_CMD *po;
6109 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_ACL_POLICY_CMD));
6110 if (osbuf == NULL) {
6111 return A_NO_MEMORY;
6114 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_ACL_POLICY_CMD));
6115 po = (WMI_AP_ACL_POLICY_CMD *)(A_NETBUF_DATA(osbuf));
6116 A_MEMZERO(po, sizeof(*po));
6118 po->policy = policy;
6120 return (wmi_cmd_send(wmip, osbuf, WMI_AP_ACL_POLICY_CMDID, NO_SYNC_WMIFLAG));
6124 wmi_ap_set_rateset(struct wmi_t *wmip, u8 rateset)
6126 void *osbuf;
6127 WMI_AP_SET_11BG_RATESET_CMD *rs;
6129 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_11BG_RATESET_CMD));
6130 if (osbuf == NULL) {
6131 return A_NO_MEMORY;
6134 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_11BG_RATESET_CMD));
6135 rs = (WMI_AP_SET_11BG_RATESET_CMD *)(A_NETBUF_DATA(osbuf));
6136 A_MEMZERO(rs, sizeof(*rs));
6138 rs->rateset = rateset;
6140 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_11BG_RATESET_CMDID, NO_SYNC_WMIFLAG));
6144 wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd)
6146 void *osbuf;
6147 WMI_SET_HT_CAP_CMD *htCap;
6148 u8 band;
6150 osbuf = A_NETBUF_ALLOC(sizeof(*htCap));
6151 if (osbuf == NULL) {
6152 return A_NO_MEMORY;
6155 A_NETBUF_PUT(osbuf, sizeof(*htCap));
6157 band = (cmd->band)? A_BAND_5GHZ : A_BAND_24GHZ;
6158 wmip->wmi_ht_allowed[band] = (cmd->enable)? 1:0;
6160 htCap = (WMI_SET_HT_CAP_CMD *)(A_NETBUF_DATA(osbuf));
6161 A_MEMZERO(htCap, sizeof(*htCap));
6162 memcpy(htCap, cmd, sizeof(*htCap));
6164 return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_CAP_CMDID,
6165 NO_SYNC_WMIFLAG));
6169 wmi_set_ht_op_cmd(struct wmi_t *wmip, u8 sta_chan_width)
6171 void *osbuf;
6172 WMI_SET_HT_OP_CMD *htInfo;
6174 osbuf = A_NETBUF_ALLOC(sizeof(*htInfo));
6175 if (osbuf == NULL) {
6176 return A_NO_MEMORY;
6179 A_NETBUF_PUT(osbuf, sizeof(*htInfo));
6181 htInfo = (WMI_SET_HT_OP_CMD *)(A_NETBUF_DATA(osbuf));
6182 A_MEMZERO(htInfo, sizeof(*htInfo));
6183 htInfo->sta_chan_width = sta_chan_width;
6185 return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_OP_CMDID,
6186 NO_SYNC_WMIFLAG));
6190 wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, u32 *pMaskArray)
6192 void *osbuf;
6193 WMI_SET_TX_SELECT_RATES_CMD *pData;
6195 osbuf = A_NETBUF_ALLOC(sizeof(*pData));
6196 if (osbuf == NULL) {
6197 return A_NO_MEMORY;
6200 A_NETBUF_PUT(osbuf, sizeof(*pData));
6202 pData = (WMI_SET_TX_SELECT_RATES_CMD *)(A_NETBUF_DATA(osbuf));
6203 memcpy(pData, pMaskArray, sizeof(*pData));
6205 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_SELECT_RATES_CMDID,
6206 NO_SYNC_WMIFLAG));
6211 wmi_send_hci_cmd(struct wmi_t *wmip, u8 *buf, u16 sz)
6213 void *osbuf;
6214 WMI_HCI_CMD *cmd;
6216 osbuf = A_NETBUF_ALLOC(sizeof(*cmd) + sz);
6217 if (osbuf == NULL) {
6218 return A_NO_MEMORY;
6221 A_NETBUF_PUT(osbuf, sizeof(*cmd) + sz);
6222 cmd = (WMI_HCI_CMD *)(A_NETBUF_DATA(osbuf));
6224 cmd->cmd_buf_sz = sz;
6225 memcpy(cmd->buf, buf, sz);
6226 return (wmi_cmd_send(wmip, osbuf, WMI_HCI_CMD_CMDID, NO_SYNC_WMIFLAG));
6230 wmi_allow_aggr_cmd(struct wmi_t *wmip, u16 tx_tidmask, u16 rx_tidmask)
6232 void *osbuf;
6233 WMI_ALLOW_AGGR_CMD *cmd;
6235 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6236 if (osbuf == NULL) {
6237 return A_NO_MEMORY;
6240 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6242 cmd = (WMI_ALLOW_AGGR_CMD *)(A_NETBUF_DATA(osbuf));
6243 cmd->tx_allow_aggr = tx_tidmask;
6244 cmd->rx_allow_aggr = rx_tidmask;
6246 return (wmi_cmd_send(wmip, osbuf, WMI_ALLOW_AGGR_CMDID, NO_SYNC_WMIFLAG));
6250 wmi_setup_aggr_cmd(struct wmi_t *wmip, u8 tid)
6252 void *osbuf;
6253 WMI_ADDBA_REQ_CMD *cmd;
6255 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6256 if (osbuf == NULL) {
6257 return A_NO_MEMORY;
6260 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6262 cmd = (WMI_ADDBA_REQ_CMD *)(A_NETBUF_DATA(osbuf));
6263 cmd->tid = tid;
6265 return (wmi_cmd_send(wmip, osbuf, WMI_ADDBA_REQ_CMDID, NO_SYNC_WMIFLAG));
6269 wmi_delete_aggr_cmd(struct wmi_t *wmip, u8 tid, bool uplink)
6271 void *osbuf;
6272 WMI_DELBA_REQ_CMD *cmd;
6274 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6275 if (osbuf == NULL) {
6276 return A_NO_MEMORY;
6279 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6281 cmd = (WMI_DELBA_REQ_CMD *)(A_NETBUF_DATA(osbuf));
6282 cmd->tid = tid;
6283 cmd->is_sender_initiator = uplink; /* uplink =1 - uplink direction, 0=downlink direction */
6285 /* Delete the local aggr state, on host */
6286 return (wmi_cmd_send(wmip, osbuf, WMI_DELBA_REQ_CMDID, NO_SYNC_WMIFLAG));
6290 wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, u8 rxMetaVersion,
6291 bool rxDot11Hdr, bool defragOnHost)
6293 void *osbuf;
6294 WMI_RX_FRAME_FORMAT_CMD *cmd;
6296 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6297 if (osbuf == NULL) {
6298 return A_NO_MEMORY;
6301 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6303 cmd = (WMI_RX_FRAME_FORMAT_CMD *)(A_NETBUF_DATA(osbuf));
6304 cmd->dot11Hdr = (rxDot11Hdr==true)? 1:0;
6305 cmd->defragOnHost = (defragOnHost==true)? 1:0;
6306 cmd->metaVersion = rxMetaVersion; /* */
6308 /* Delete the local aggr state, on host */
6309 return (wmi_cmd_send(wmip, osbuf, WMI_RX_FRAME_FORMAT_CMDID, NO_SYNC_WMIFLAG));
6314 wmi_set_thin_mode_cmd(struct wmi_t *wmip, bool bThinMode)
6316 void *osbuf;
6317 WMI_SET_THIN_MODE_CMD *cmd;
6319 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6320 if (osbuf == NULL) {
6321 return A_NO_MEMORY;
6324 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6326 cmd = (WMI_SET_THIN_MODE_CMD *)(A_NETBUF_DATA(osbuf));
6327 cmd->enable = (bThinMode==true)? 1:0;
6329 /* Delete the local aggr state, on host */
6330 return (wmi_cmd_send(wmip, osbuf, WMI_SET_THIN_MODE_CMDID, NO_SYNC_WMIFLAG));
6335 wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE precedence)
6337 void *osbuf;
6338 WMI_SET_BT_WLAN_CONN_PRECEDENCE *cmd;
6340 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6341 if (osbuf == NULL) {
6342 return A_NO_MEMORY;
6345 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6347 cmd = (WMI_SET_BT_WLAN_CONN_PRECEDENCE *)(A_NETBUF_DATA(osbuf));
6348 A_MEMZERO(cmd, sizeof(*cmd));
6349 cmd->precedence = precedence;
6351 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID,
6352 NO_SYNC_WMIFLAG));
6356 wmi_set_pmk_cmd(struct wmi_t *wmip, u8 *pmk)
6358 void *osbuf;
6359 WMI_SET_PMK_CMD *p;
6361 osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_PMK_CMD));
6362 if (osbuf == NULL) {
6363 return A_NO_MEMORY;
6366 A_NETBUF_PUT(osbuf, sizeof(WMI_SET_PMK_CMD));
6368 p = (WMI_SET_PMK_CMD *)(A_NETBUF_DATA(osbuf));
6369 A_MEMZERO(p, sizeof(*p));
6371 memcpy(p->pmk, pmk, WMI_PMK_LEN);
6373 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMK_CMDID, NO_SYNC_WMIFLAG));
6377 wmi_set_excess_tx_retry_thres_cmd(struct wmi_t *wmip, WMI_SET_EXCESS_TX_RETRY_THRES_CMD *cmd)
6379 void *osbuf;
6380 WMI_SET_EXCESS_TX_RETRY_THRES_CMD *p;
6382 osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_EXCESS_TX_RETRY_THRES_CMD));
6383 if (osbuf == NULL) {
6384 return A_NO_MEMORY;
6387 A_NETBUF_PUT(osbuf, sizeof(WMI_SET_EXCESS_TX_RETRY_THRES_CMD));
6389 p = (WMI_SET_EXCESS_TX_RETRY_THRES_CMD *)(A_NETBUF_DATA(osbuf));
6390 memset(p, 0, sizeof(*p));
6392 p->threshold = cmd->threshold;
6394 return (wmi_cmd_send(wmip, osbuf, WMI_SET_EXCESS_TX_RETRY_THRES_CMDID, NO_SYNC_WMIFLAG));
6398 wmi_SGI_cmd(struct wmi_t *wmip, u32 sgiMask, u8 sgiPERThreshold)
6400 void *osbuf;
6401 WMI_SET_TX_SGI_PARAM_CMD *cmd;
6403 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6404 if (osbuf == NULL) {
6405 return A_NO_MEMORY ;
6408 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6410 cmd = (WMI_SET_TX_SGI_PARAM_CMD *)(A_NETBUF_DATA(osbuf));
6411 A_MEMZERO(cmd, sizeof(*cmd));
6412 cmd->sgiMask = sgiMask;
6413 cmd->sgiPERThreshold = sgiPERThreshold;
6414 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_SGI_PARAM_CMDID,
6415 NO_SYNC_WMIFLAG));
6418 bss_t *
6419 wmi_find_matching_Ssidnode (struct wmi_t *wmip, u8 *pSsid,
6420 u32 ssidLength,
6421 u32 dot11AuthMode, u32 authMode,
6422 u32 pairwiseCryptoType, u32 grpwiseCryptoTyp)
6424 bss_t *node = NULL;
6425 node = wlan_find_matching_Ssidnode (&wmip->wmi_scan_table, pSsid,
6426 ssidLength, dot11AuthMode, authMode, pairwiseCryptoType, grpwiseCryptoTyp);
6428 return node;
6431 u16 wmi_ieee2freq (int chan)
6433 u16 freq = 0;
6434 freq = wlan_ieee2freq (chan);
6435 return freq;
6439 u32 wmi_freq2ieee (u16 freq)
6441 u16 chan = 0;
6442 chan = wlan_freq2ieee (freq);
6443 return chan;