1 //------------------------------------------------------------------------------
2 // Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
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.
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 //==============================================================================
34 #include <ieee80211.h>
35 #include <ieee80211_node.h>
39 #include "a_drv_api.h"
40 #define ATH_MODULE_NAME wmi
42 #include "dbglog_api.h"
45 #define ATH_DEBUG_WMI ATH_DEBUG_MAKE_MODULE_MASK(0)
47 #ifdef ATH_DEBUG_MODULE
49 static struct ath_debug_mask_description wmi_debug_desc[] = {
50 { ATH_DEBUG_WMI , "General WMI Tracing"},
53 ATH_DEBUG_INSTANTIATE_MODULE_VAR(wmi,
55 "Wireless Module Interface",
56 ATH_DEBUG_MASK_DEFAULTS,
57 ATH_DEBUG_DESCRIPTION_COUNT(wmi_debug_desc),
63 #define DBGARG _A_FUNCNAME_
64 #define DBGFMT "%s() : "
65 #define DBG_WMI ATH_DEBUG_WMI
66 #define DBG_ERROR ATH_DEBUG_ERR
67 #define DBG_WMI2 ATH_DEBUG_WMI
68 #define A_DPRINTF AR_DEBUG_PRINTF
71 static int wmi_ready_event_rx(struct wmi_t *wmip, u8 *datap, int len);
73 static int wmi_connect_event_rx(struct wmi_t *wmip, u8 *datap,
75 static int wmi_disconnect_event_rx(struct wmi_t *wmip, u8 *datap,
78 static int wmi_tkip_micerr_event_rx(struct wmi_t *wmip, u8 *datap,
80 static int wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap,
82 static int wmi_opt_frame_event_rx(struct wmi_t *wmip, u8 *datap,
84 static int wmi_pstream_timeout_event_rx(struct wmi_t *wmip, u8 *datap,
86 static int wmi_sync_point(struct wmi_t *wmip);
88 static int wmi_bitrate_reply_rx(struct wmi_t *wmip, u8 *datap,
90 static int wmi_ratemask_reply_rx(struct wmi_t *wmip, u8 *datap,
92 static int wmi_channelList_reply_rx(struct wmi_t *wmip, u8 *datap,
94 static int wmi_regDomain_event_rx(struct wmi_t *wmip, u8 *datap,
96 static int wmi_txPwr_reply_rx(struct wmi_t *wmip, u8 *datap, int len);
97 static int wmi_neighborReport_event_rx(struct wmi_t *wmip, u8 *datap,
100 static int wmi_dset_open_req_rx(struct wmi_t *wmip, u8 *datap,
102 #ifdef CONFIG_HOST_DSET_SUPPORT
103 static int wmi_dset_close_rx(struct wmi_t *wmip, u8 *datap, int len);
104 static int wmi_dset_data_req_rx(struct wmi_t *wmip, u8 *datap,
106 #endif /* CONFIG_HOST_DSET_SUPPORT */
109 static int wmi_scanComplete_rx(struct wmi_t *wmip, u8 *datap,
111 static int wmi_errorEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
112 static int wmi_statsEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
113 static int wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
114 static int wmi_hbChallengeResp_rx(struct wmi_t *wmip, u8 *datap, int len);
115 static int wmi_reportErrorEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
116 static int wmi_cac_event_rx(struct wmi_t *wmip, u8 *datap, int len);
117 static int wmi_channel_change_event_rx(struct wmi_t *wmip, u8 *datap, int len);
118 static int wmi_roam_tbl_event_rx(struct wmi_t *wmip, u8 *datap,
120 static int wmi_roam_data_event_rx(struct wmi_t *wmip, u8 *datap,
122 static int wmi_get_wow_list_event_rx(struct wmi_t *wmip, u8 *datap,
125 wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, u8 *datap, u32 len);
128 wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, u32 len);
131 #ifdef CONFIG_HOST_TCMD_SUPPORT
133 wmi_tcmd_test_report_rx(struct wmi_t *wmip, u8 *datap, int len);
137 wmi_txRetryErrEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
140 wmi_snrThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
143 wmi_lqThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
146 wmi_is_bitrate_index_valid(struct wmi_t *wmip, s32 rateIndex);
149 wmi_aplistEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
152 wmi_dbglog_event_rx(struct wmi_t *wmip, u8 *datap, int len);
154 static int wmi_keepalive_reply_rx(struct wmi_t *wmip, u8 *datap, int len);
156 int wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId,
157 WMI_SYNC_FLAG syncflag);
159 u8 ar6000_get_upper_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, u32 size);
160 u8 ar6000_get_lower_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, u32 size);
162 void wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd);
163 void wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd);
164 static int wmi_send_rssi_threshold_params(struct wmi_t *wmip,
165 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd);
166 static int wmi_send_snr_threshold_params(struct wmi_t *wmip,
167 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd);
168 #if defined(CONFIG_TARGET_PROFILE_SUPPORT)
170 wmi_prof_count_rx(struct wmi_t *wmip, u8 *datap, int len);
171 #endif /* CONFIG_TARGET_PROFILE_SUPPORT */
173 static int wmi_pspoll_event_rx(struct wmi_t *wmip, u8 *datap,
175 static int wmi_dtimexpiry_event_rx(struct wmi_t *wmip, u8 *datap,
178 static int wmi_peer_node_event_rx (struct wmi_t *wmip, u8 *datap,
180 static int wmi_addba_req_event_rx(struct wmi_t *, u8 *, int);
181 static int wmi_addba_resp_event_rx(struct wmi_t *, u8 *, int);
182 static int wmi_delba_req_event_rx(struct wmi_t *, u8 *, int);
183 static int wmi_btcoex_config_event_rx(struct wmi_t *wmip, u8 *datap, int len);
184 static int wmi_btcoex_stats_event_rx(struct wmi_t *wmip, u8 *datap, int len);
185 static int wmi_hci_event_rx(struct wmi_t *, u8 *, int);
188 static int wmi_wapi_rekey_event_rx(struct wmi_t *wmip, u8 *datap,
192 #if defined(UNDER_CE)
193 #if defined(NDIS51_MINIPORT)
194 unsigned int processDot11Hdr = 0;
196 unsigned int processDot11Hdr = 1;
199 extern unsigned int processDot11Hdr;
203 static const s32 wmi_rateTable[][2] = {
204 //{W/O SGI, with SGI}
235 #define MODE_A_SUPPORT_RATE_START ((s32) 4)
236 #define MODE_A_SUPPORT_RATE_STOP ((s32) 11)
238 #define MODE_GONLY_SUPPORT_RATE_START MODE_A_SUPPORT_RATE_START
239 #define MODE_GONLY_SUPPORT_RATE_STOP MODE_A_SUPPORT_RATE_STOP
241 #define MODE_B_SUPPORT_RATE_START ((s32) 0)
242 #define MODE_B_SUPPORT_RATE_STOP ((s32) 3)
244 #define MODE_G_SUPPORT_RATE_START ((s32) 0)
245 #define MODE_G_SUPPORT_RATE_STOP ((s32) 11)
247 #define MODE_GHT20_SUPPORT_RATE_START ((s32) 0)
248 #define MODE_GHT20_SUPPORT_RATE_STOP ((s32) 19)
250 #define MAX_NUMBER_OF_SUPPORT_RATES (MODE_GHT20_SUPPORT_RATE_STOP + 1)
252 /* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */
253 const u8 up_to_ac[]= {
264 /* This stuff is used when we want a simple layer-3 visibility */
265 typedef PREPACK struct _iphdr {
266 u8 ip_ver_hdrlen; /* version and hdr length */
267 u8 ip_tos; /* type of service */
268 u16 ip_len; /* total length */
269 u16 ip_id; /* identification */
270 s16 ip_off; /* fragment offset field */
271 #define IP_DF 0x4000 /* dont fragment flag */
272 #define IP_MF 0x2000 /* more fragments flag */
273 #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
274 u8 ip_ttl; /* time to live */
275 u8 ip_p; /* protocol */
276 u16 ip_sum; /* checksum */
277 u8 ip_src[4]; /* source and dest address */
281 static s16 rssi_event_value = 0;
282 static s16 snr_event_value = 0;
284 bool is_probe_ssid = false;
291 A_REGISTER_MODULE_DEBUG_INFO(wmi);
293 wmip = A_MALLOC (sizeof(struct wmi_t));
297 A_MEMZERO(wmip, sizeof(struct wmi_t ));
301 A_MUTEX_INIT(&wmip->wmi_lock);
303 wmip->wmi_devt = devt;
304 wlan_node_table_init(wmip, &wmip->wmi_scan_table);
305 wmi_qos_state_init(wmip);
307 wmip->wmi_powerMode = REC_POWER;
308 wmip->wmi_phyMode = WMI_11G_MODE;
310 wmip->wmi_pair_crypto_type = NONE_CRYPT;
311 wmip->wmi_grp_crypto_type = NONE_CRYPT;
313 wmip->wmi_ht_allowed[A_BAND_24GHZ] = 1;
314 wmip->wmi_ht_allowed[A_BAND_5GHZ] = 1;
320 wmi_qos_state_init(struct wmi_t *wmip)
329 /* Initialize QoS States */
330 wmip->wmi_numQoSStream = 0;
332 wmip->wmi_fatPipeExists = 0;
334 for (i=0; i < WMM_NUM_AC; i++) {
335 wmip->wmi_streamExistsForAC[i]=0;
340 A_WMI_SET_NUMDATAENDPTS(wmip->wmi_devt, 1);
344 wmi_set_control_ep(struct wmi_t * wmip, HTC_ENDPOINT_ID eid)
346 A_ASSERT( eid != ENDPOINT_UNUSED);
347 wmip->wmi_endpoint_id = eid;
351 wmi_get_control_ep(struct wmi_t * wmip)
353 return(wmip->wmi_endpoint_id);
357 wmi_shutdown(struct wmi_t *wmip)
360 wlan_node_table_cleanup(&wmip->wmi_scan_table);
361 if (A_IS_MUTEX_VALID(&wmip->wmi_lock)) {
363 DELETE_WMI_LOCK(&wmip);
365 A_MUTEX_DELETE(&wmip->wmi_lock);
373 * performs DIX to 802.3 encapsulation for transmit packets.
374 * uses passed in buffer. Returns buffer or NULL if failed.
375 * Assumes the entire DIX header is contigous and that there is
376 * enough room in the buffer for a 802.3 mac header and LLC+SNAP headers.
379 wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf)
384 ATH_LLC_SNAP_HDR *llcHdr;
386 A_ASSERT(osbuf != NULL);
388 if (A_NETBUF_HEADROOM(osbuf) <
389 (sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR)))
394 datap = A_NETBUF_DATA(osbuf);
396 typeorlen = *(u16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN);
398 if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) {
400 * packet is already in 802.3 format - return success
402 A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG));
407 * Save mac fields and length to be inserted later
409 memcpy(macHdr.dstMac, datap, ATH_MAC_LEN);
410 memcpy(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN);
411 macHdr.typeOrLen = A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) +
412 sizeof(ATH_LLC_SNAP_HDR));
415 * Make room for LLC+SNAP headers
417 if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != 0) {
420 datap = A_NETBUF_DATA(osbuf);
422 memcpy(datap, &macHdr, sizeof (ATH_MAC_HDR));
424 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR));
428 llcHdr->orgCode[0] = 0x0;
429 llcHdr->orgCode[1] = 0x0;
430 llcHdr->orgCode[2] = 0x0;
431 llcHdr->etherType = typeorlen;
436 int wmi_meta_add(struct wmi_t *wmip, void *osbuf, u8 *pVersion,void *pTxMetaS)
441 case WMI_META_VERSION_1:
443 WMI_TX_META_V1 *pV1= NULL;
444 A_ASSERT(osbuf != NULL);
445 if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != 0) {
449 pV1 = (WMI_TX_META_V1 *)A_NETBUF_DATA(osbuf);
450 /* the pktID is used in conjunction with txComplete messages
451 * allowing the target to notify which tx requests have been
452 * completed and how. */
454 /* the ratePolicyID allows the host to specify which rate policy
455 * to use for transmitting this packet. 0 means use default behavior. */
456 pV1->ratePolicyID = 0;
457 A_ASSERT(pVersion != NULL);
458 /* the version must be used to populate the meta field of the WMI_DATA_HDR */
459 *pVersion = WMI_META_VERSION_1;
462 case WMI_META_VERSION_2:
464 WMI_TX_META_V2 *pV2 ;
465 A_ASSERT(osbuf != NULL);
466 if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != 0) {
469 pV2 = (WMI_TX_META_V2 *)A_NETBUF_DATA(osbuf);
470 memcpy(pV2,(WMI_TX_META_V2 *)pTxMetaS,sizeof(WMI_TX_META_V2));
478 /* Adds a WMI data header */
480 wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, u8 msgType, bool bMoreData,
481 WMI_DATA_HDR_DATA_TYPE data_type,u8 metaVersion, void *pTxMetaS)
484 // u8 metaVersion = 0;
487 A_ASSERT(osbuf != NULL);
489 /* adds the meta data field after the wmi data hdr. If metaVersion
490 * is returns 0 then no meta field was added. */
491 if ((status = wmi_meta_add(wmip, osbuf, &metaVersion,pTxMetaS)) != 0) {
495 if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != 0) {
499 dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf);
500 A_MEMZERO(dtHdr, sizeof(WMI_DATA_HDR));
502 WMI_DATA_HDR_SET_MSG_TYPE(dtHdr, msgType);
503 WMI_DATA_HDR_SET_DATA_TYPE(dtHdr, data_type);
506 WMI_DATA_HDR_SET_MORE_BIT(dtHdr);
509 WMI_DATA_HDR_SET_META(dtHdr, metaVersion);
517 u8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, u32 layer2Priority, bool wmmEnabled)
520 u8 trafficClass = WMM_AC_BE;
521 u16 ipType = IP_ETHERTYPE;
525 u32 hdrsize, metasize;
526 ATH_LLC_SNAP_HDR *llcHdr;
528 WMI_CREATE_PSTREAM_CMD cmd;
530 A_ASSERT(osbuf != NULL);
533 // Initialize header size
537 datap = A_NETBUF_DATA(osbuf);
538 dtHdr = (WMI_DATA_HDR *)datap;
539 metasize = (WMI_DATA_HDR_GET_META(dtHdr))? WMI_MAX_TX_META_SZ : 0;
543 /* If WMM is disabled all traffic goes as BE traffic */
550 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32));
551 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) + metasize +
558 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) + metasize +
559 sizeof(ATH_MAC_HDR));
562 if (llcHdr->etherType == A_CPU2BE16(ipType))
564 /* Extract the endpoint info from the TOS field in the IP header */
566 userPriority = wmi_determine_userPriority (((u8 *)llcHdr) + sizeof(ATH_LLC_SNAP_HDR),layer2Priority);
570 userPriority = layer2Priority & 0x7;
575 /* workaround for WMM S5 */
576 if ((WMM_AC_VI == wmip->wmi_traffic_class) && ((5 == userPriority) || (4 == userPriority)))
581 trafficClass = convert_userPriority_to_trafficClass(userPriority);
583 WMI_DATA_HDR_SET_UP(dtHdr, userPriority);
584 /* lower 3-bits are 802.1d priority */
585 //dtHdr->info |= (userPriority & WMI_DATA_HDR_UP_MASK) << WMI_DATA_HDR_UP_SHIFT;
588 streamExists = wmip->wmi_fatPipeExists;
591 if (!(streamExists & (1 << trafficClass)))
594 A_MEMZERO(&cmd, sizeof(cmd));
595 cmd.trafficClass = trafficClass;
596 cmd.userPriority = userPriority;
597 cmd.inactivityInt = WMI_IMPLICIT_PSTREAM_INACTIVITY_INT;
598 /* Implicit streams are created with TSID 0xFF */
600 cmd.tsid = WMI_IMPLICIT_PSTREAM;
601 wmi_create_pstream_cmd(wmip, &cmd);
608 wmi_dot11_hdr_add (struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode)
613 ATH_LLC_SNAP_HDR *llcHdr;
614 struct ieee80211_frame *wh;
617 A_ASSERT(osbuf != NULL);
619 if (A_NETBUF_HEADROOM(osbuf) <
620 (sizeof(struct ieee80211_qosframe) + sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR)))
625 datap = A_NETBUF_DATA(osbuf);
627 typeorlen = *(u16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN);
629 if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) {
631 * packet is already in 802.3 format - return success
633 A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG));
638 * Save mac fields and length to be inserted later
640 memcpy(macHdr.dstMac, datap, ATH_MAC_LEN);
641 memcpy(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN);
642 macHdr.typeOrLen = A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) +
643 sizeof(ATH_LLC_SNAP_HDR));
645 // Remove the Ethernet hdr
646 A_NETBUF_PULL(osbuf, sizeof(ATH_MAC_HDR));
648 * Make room for LLC+SNAP headers
650 if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != 0) {
653 datap = A_NETBUF_DATA(osbuf);
655 llcHdr = (ATH_LLC_SNAP_HDR *)(datap);
659 llcHdr->orgCode[0] = 0x0;
660 llcHdr->orgCode[1] = 0x0;
661 llcHdr->orgCode[2] = 0x0;
662 llcHdr->etherType = typeorlen;
665 /* Make room for 802.11 hdr */
666 if (wmip->wmi_is_wmm_enabled)
668 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32));
669 if (A_NETBUF_PUSH(osbuf, hdrsize) != 0)
673 wh = (struct ieee80211_frame *) A_NETBUF_DATA(osbuf);
674 wh->i_fc[0] = IEEE80211_FC0_SUBTYPE_QOS;
678 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_frame),sizeof(u32));
679 if (A_NETBUF_PUSH(osbuf, hdrsize) != 0)
683 wh = (struct ieee80211_frame *) A_NETBUF_DATA(osbuf);
684 wh->i_fc[0] = IEEE80211_FC0_SUBTYPE_DATA;
686 /* Setup the SA & DA */
687 IEEE80211_ADDR_COPY(wh->i_addr2, macHdr.srcMac);
689 if (mode == INFRA_NETWORK) {
690 IEEE80211_ADDR_COPY(wh->i_addr3, macHdr.dstMac);
692 else if (mode == ADHOC_NETWORK) {
693 IEEE80211_ADDR_COPY(wh->i_addr1, macHdr.dstMac);
700 wmi_dot11_hdr_remove(struct wmi_t *wmip, void *osbuf)
703 struct ieee80211_frame *pwh,wh;
705 ATH_LLC_SNAP_HDR *llcHdr;
709 A_ASSERT(osbuf != NULL);
710 datap = A_NETBUF_DATA(osbuf);
712 pwh = (struct ieee80211_frame *)datap;
713 type = pwh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
714 subtype = pwh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
716 memcpy((u8 *)&wh, datap, sizeof(struct ieee80211_frame));
718 /* strip off the 802.11 hdr*/
719 if (subtype == IEEE80211_FC0_SUBTYPE_QOS) {
720 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32));
721 A_NETBUF_PULL(osbuf, hdrsize);
722 } else if (subtype == IEEE80211_FC0_SUBTYPE_DATA) {
723 A_NETBUF_PULL(osbuf, sizeof(struct ieee80211_frame));
726 datap = A_NETBUF_DATA(osbuf);
727 llcHdr = (ATH_LLC_SNAP_HDR *)(datap);
729 macHdr.typeOrLen = llcHdr->etherType;
730 A_MEMZERO(macHdr.dstMac, sizeof(macHdr.dstMac));
731 A_MEMZERO(macHdr.srcMac, sizeof(macHdr.srcMac));
733 switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) {
734 case IEEE80211_FC1_DIR_NODS:
735 IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr1);
736 IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr2);
738 case IEEE80211_FC1_DIR_TODS:
739 IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr3);
740 IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr2);
742 case IEEE80211_FC1_DIR_FROMDS:
743 IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr1);
744 IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr3);
746 case IEEE80211_FC1_DIR_DSTODS:
750 // Remove the LLC Hdr.
751 A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR));
753 // Insert the ATH MAC hdr.
755 A_NETBUF_PUSH(osbuf, sizeof(ATH_MAC_HDR));
756 datap = A_NETBUF_DATA(osbuf);
758 memcpy (datap, &macHdr, sizeof(ATH_MAC_HDR));
764 * performs 802.3 to DIX encapsulation for received packets.
765 * Assumes the entire 802.3 header is contigous.
768 wmi_dot3_2_dix(void *osbuf)
772 ATH_LLC_SNAP_HDR *llcHdr;
774 A_ASSERT(osbuf != NULL);
775 datap = A_NETBUF_DATA(osbuf);
777 memcpy(&macHdr, datap, sizeof(ATH_MAC_HDR));
778 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR));
779 macHdr.typeOrLen = llcHdr->etherType;
781 if (A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != 0) {
785 datap = A_NETBUF_DATA(osbuf);
787 memcpy(datap, &macHdr, sizeof (ATH_MAC_HDR));
793 * Removes a WMI data header
796 wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf)
798 A_ASSERT(osbuf != NULL);
800 return (A_NETBUF_PULL(osbuf, sizeof(WMI_DATA_HDR)));
804 wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg)
806 wlan_iterate_nodes(&wmip->wmi_scan_table, f, arg);
810 * WMI Extended Event received from Target.
813 wmi_control_rx_xtnd(struct wmi_t *wmip, void *osbuf)
821 if (A_NETBUF_LEN(osbuf) < sizeof(WMIX_CMD_HDR)) {
822 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG));
823 wmip->wmi_stats.cmd_len_err++;
827 cmd = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf);
830 if (A_NETBUF_PULL(osbuf, sizeof(WMIX_CMD_HDR)) != 0) {
831 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG));
832 wmip->wmi_stats.cmd_len_err++;
836 datap = A_NETBUF_DATA(osbuf);
837 len = A_NETBUF_LEN(osbuf);
840 case (WMIX_DSETOPENREQ_EVENTID):
841 status = wmi_dset_open_req_rx(wmip, datap, len);
843 #ifdef CONFIG_HOST_DSET_SUPPORT
844 case (WMIX_DSETCLOSE_EVENTID):
845 status = wmi_dset_close_rx(wmip, datap, len);
847 case (WMIX_DSETDATAREQ_EVENTID):
848 status = wmi_dset_data_req_rx(wmip, datap, len);
850 #endif /* CONFIG_HOST_DSET_SUPPORT */
851 case (WMIX_HB_CHALLENGE_RESP_EVENTID):
852 wmi_hbChallengeResp_rx(wmip, datap, len);
854 case (WMIX_DBGLOG_EVENTID):
855 wmi_dbglog_event_rx(wmip, datap, len);
857 #if defined(CONFIG_TARGET_PROFILE_SUPPORT)
858 case (WMIX_PROF_COUNT_EVENTID):
859 wmi_prof_count_rx(wmip, datap, len);
861 #endif /* CONFIG_TARGET_PROFILE_SUPPORT */
863 A_DPRINTF(DBG_WMI|DBG_ERROR,
864 (DBGFMT "Unknown id 0x%x\n", DBGARG, id));
865 wmip->wmi_stats.cmd_id_err++;
879 wmi_control_rx(struct wmi_t *wmip, void *osbuf)
884 u32 len, i, loggingReq;
887 A_ASSERT(osbuf != NULL);
888 if (A_NETBUF_LEN(osbuf) < sizeof(WMI_CMD_HDR)) {
889 A_NETBUF_FREE(osbuf);
890 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG));
891 wmip->wmi_stats.cmd_len_err++;
895 cmd = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf);
898 if (A_NETBUF_PULL(osbuf, sizeof(WMI_CMD_HDR)) != 0) {
899 A_NETBUF_FREE(osbuf);
900 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG));
901 wmip->wmi_stats.cmd_len_err++;
905 datap = A_NETBUF_DATA(osbuf);
906 len = A_NETBUF_LEN(osbuf);
910 ar6000_get_driver_cfg(wmip->wmi_devt,
911 AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS,
915 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI %d \n",id));
916 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI recv, MsgNo %d : ", cmdRecvNum));
917 for(i = 0; i < len; i++)
918 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("%x ", datap[i]));
919 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("\n"));
927 case (WMI_GET_BITRATE_CMDID):
928 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_BITRATE_CMDID\n", DBGARG));
929 status = wmi_bitrate_reply_rx(wmip, datap, len);
931 case (WMI_GET_CHANNEL_LIST_CMDID):
932 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_CHANNEL_LIST_CMDID\n", DBGARG));
933 status = wmi_channelList_reply_rx(wmip, datap, len);
935 case (WMI_GET_TX_PWR_CMDID):
936 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_TX_PWR_CMDID\n", DBGARG));
937 status = wmi_txPwr_reply_rx(wmip, datap, len);
939 case (WMI_READY_EVENTID):
940 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_READY_EVENTID\n", DBGARG));
941 status = wmi_ready_event_rx(wmip, datap, len);
942 A_WMI_DBGLOG_INIT_DONE(wmip->wmi_devt);
944 case (WMI_CONNECT_EVENTID):
945 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CONNECT_EVENTID\n", DBGARG));
946 status = wmi_connect_event_rx(wmip, datap, len);
948 case (WMI_DISCONNECT_EVENTID):
949 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_DISCONNECT_EVENTID\n", DBGARG));
950 status = wmi_disconnect_event_rx(wmip, datap, len);
952 case (WMI_PEER_NODE_EVENTID):
953 A_DPRINTF (DBG_WMI, (DBGFMT "WMI_PEER_NODE_EVENTID\n", DBGARG));
954 status = wmi_peer_node_event_rx(wmip, datap, len);
956 case (WMI_TKIP_MICERR_EVENTID):
957 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TKIP_MICERR_EVENTID\n", DBGARG));
958 status = wmi_tkip_micerr_event_rx(wmip, datap, len);
960 case (WMI_BSSINFO_EVENTID):
961 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BSSINFO_EVENTID\n", DBGARG));
964 * convert WMI_BSS_INFO_HDR2 to WMI_BSS_INFO_HDR
965 * Take a local copy of the WMI_BSS_INFO_HDR2 from the wmi buffer
966 * and reconstruct the WMI_BSS_INFO_HDR in its place
968 WMI_BSS_INFO_HDR2 bih2;
969 WMI_BSS_INFO_HDR *bih;
970 memcpy(&bih2, datap, sizeof(WMI_BSS_INFO_HDR2));
972 A_NETBUF_PUSH(osbuf, 4);
973 datap = A_NETBUF_DATA(osbuf);
974 len = A_NETBUF_LEN(osbuf);
975 bih = (WMI_BSS_INFO_HDR *)datap;
977 bih->channel = bih2.channel;
978 bih->frameType = bih2.frameType;
980 bih->rssi = bih2.snr - 95;
981 bih->ieMask = bih2.ieMask;
982 memcpy(bih->bssid, bih2.bssid, ATH_MAC_LEN);
984 status = wmi_bssInfo_event_rx(wmip, datap, len);
987 case (WMI_REGDOMAIN_EVENTID):
988 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REGDOMAIN_EVENTID\n", DBGARG));
989 status = wmi_regDomain_event_rx(wmip, datap, len);
991 case (WMI_PSTREAM_TIMEOUT_EVENTID):
992 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_PSTREAM_TIMEOUT_EVENTID\n", DBGARG));
993 status = wmi_pstream_timeout_event_rx(wmip, datap, len);
995 case (WMI_NEIGHBOR_REPORT_EVENTID):
996 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_NEIGHBOR_REPORT_EVENTID\n", DBGARG));
997 status = wmi_neighborReport_event_rx(wmip, datap, len);
999 case (WMI_SCAN_COMPLETE_EVENTID):
1000 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SCAN_COMPLETE_EVENTID\n", DBGARG));
1001 status = wmi_scanComplete_rx(wmip, datap, len);
1003 case (WMI_CMDERROR_EVENTID):
1004 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CMDERROR_EVENTID\n", DBGARG));
1005 status = wmi_errorEvent_rx(wmip, datap, len);
1007 case (WMI_REPORT_STATISTICS_EVENTID):
1008 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_STATISTICS_EVENTID\n", DBGARG));
1009 status = wmi_statsEvent_rx(wmip, datap, len);
1011 case (WMI_RSSI_THRESHOLD_EVENTID):
1012 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_RSSI_THRESHOLD_EVENTID\n", DBGARG));
1013 status = wmi_rssiThresholdEvent_rx(wmip, datap, len);
1015 case (WMI_ERROR_REPORT_EVENTID):
1016 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_ERROR_REPORT_EVENTID\n", DBGARG));
1017 status = wmi_reportErrorEvent_rx(wmip, datap, len);
1019 case (WMI_OPT_RX_FRAME_EVENTID):
1020 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_OPT_RX_FRAME_EVENTID\n", DBGARG));
1021 status = wmi_opt_frame_event_rx(wmip, datap, len);
1023 case (WMI_REPORT_ROAM_TBL_EVENTID):
1024 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_ROAM_TBL_EVENTID\n", DBGARG));
1025 status = wmi_roam_tbl_event_rx(wmip, datap, len);
1027 case (WMI_EXTENSION_EVENTID):
1028 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_EXTENSION_EVENTID\n", DBGARG));
1029 status = wmi_control_rx_xtnd(wmip, osbuf);
1031 case (WMI_CAC_EVENTID):
1032 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CAC_EVENTID\n", DBGARG));
1033 status = wmi_cac_event_rx(wmip, datap, len);
1035 case (WMI_CHANNEL_CHANGE_EVENTID):
1036 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CHANNEL_CHANGE_EVENTID\n", DBGARG));
1037 status = wmi_channel_change_event_rx(wmip, datap, len);
1039 case (WMI_REPORT_ROAM_DATA_EVENTID):
1040 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_ROAM_DATA_EVENTID\n", DBGARG));
1041 status = wmi_roam_data_event_rx(wmip, datap, len);
1043 #ifdef CONFIG_HOST_TCMD_SUPPORT
1044 case (WMI_TEST_EVENTID):
1045 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TEST_EVENTID\n", DBGARG));
1046 status = wmi_tcmd_test_report_rx(wmip, datap, len);
1049 case (WMI_GET_FIXRATES_CMDID):
1050 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_FIXRATES_CMDID\n", DBGARG));
1051 status = wmi_ratemask_reply_rx(wmip, datap, len);
1053 case (WMI_TX_RETRY_ERR_EVENTID):
1054 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TX_RETRY_ERR_EVENTID\n", DBGARG));
1055 status = wmi_txRetryErrEvent_rx(wmip, datap, len);
1057 case (WMI_SNR_THRESHOLD_EVENTID):
1058 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SNR_THRESHOLD_EVENTID\n", DBGARG));
1059 status = wmi_snrThresholdEvent_rx(wmip, datap, len);
1061 case (WMI_LQ_THRESHOLD_EVENTID):
1062 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_LQ_THRESHOLD_EVENTID\n", DBGARG));
1063 status = wmi_lqThresholdEvent_rx(wmip, datap, len);
1065 case (WMI_APLIST_EVENTID):
1066 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Received APLIST Event\n"));
1067 status = wmi_aplistEvent_rx(wmip, datap, len);
1069 case (WMI_GET_KEEPALIVE_CMDID):
1070 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_KEEPALIVE_CMDID\n", DBGARG));
1071 status = wmi_keepalive_reply_rx(wmip, datap, len);
1073 case (WMI_GET_WOW_LIST_EVENTID):
1074 status = wmi_get_wow_list_event_rx(wmip, datap, len);
1076 case (WMI_GET_PMKID_LIST_EVENTID):
1077 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_PMKID_LIST Event\n", DBGARG));
1078 status = wmi_get_pmkid_list_event_rx(wmip, datap, len);
1080 case (WMI_PSPOLL_EVENTID):
1081 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_PSPOLL_EVENT\n", DBGARG));
1082 status = wmi_pspoll_event_rx(wmip, datap, len);
1084 case (WMI_DTIMEXPIRY_EVENTID):
1085 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_DTIMEXPIRY_EVENT\n", DBGARG));
1086 status = wmi_dtimexpiry_event_rx(wmip, datap, len);
1088 case (WMI_SET_PARAMS_REPLY_EVENTID):
1089 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SET_PARAMS_REPLY Event\n", DBGARG));
1090 status = wmi_set_params_event_rx(wmip, datap, len);
1092 case (WMI_ADDBA_REQ_EVENTID):
1093 status = wmi_addba_req_event_rx(wmip, datap, len);
1095 case (WMI_ADDBA_RESP_EVENTID):
1096 status = wmi_addba_resp_event_rx(wmip, datap, len);
1098 case (WMI_DELBA_REQ_EVENTID):
1099 status = wmi_delba_req_event_rx(wmip, datap, len);
1101 case (WMI_REPORT_BTCOEX_CONFIG_EVENTID):
1102 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BTCOEX_CONFIG_EVENTID", DBGARG));
1103 status = wmi_btcoex_config_event_rx(wmip, datap, len);
1105 case (WMI_REPORT_BTCOEX_STATS_EVENTID):
1106 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BTCOEX_STATS_EVENTID", DBGARG));
1107 status = wmi_btcoex_stats_event_rx(wmip, datap, len);
1109 case (WMI_TX_COMPLETE_EVENTID):
1112 TX_COMPLETE_MSG_V1 *pV1;
1113 WMI_TX_COMPLETE_EVENT *pEv = (WMI_TX_COMPLETE_EVENT *)datap;
1114 A_PRINTF("comp: %d %d %d\n", pEv->numMessages, pEv->msgLen, pEv->msgType);
1116 for(index = 0 ; index < pEv->numMessages ; index++) {
1117 pV1 = (TX_COMPLETE_MSG_V1 *)(datap + sizeof(WMI_TX_COMPLETE_EVENT) + index*sizeof(TX_COMPLETE_MSG_V1));
1118 A_PRINTF("msg: %d %d %d %d\n", pV1->status, pV1->pktID, pV1->rateIdx, pV1->ackFailures);
1122 case (WMI_HCI_EVENT_EVENTID):
1123 status = wmi_hci_event_rx(wmip, datap, len);
1126 case (WMI_WAPI_REKEY_EVENTID):
1127 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_WAPI_REKEY_EVENTID", DBGARG));
1128 status = wmi_wapi_rekey_event_rx(wmip, datap, len);
1132 A_DPRINTF(DBG_WMI|DBG_ERROR,
1133 (DBGFMT "Unknown id 0x%x\n", DBGARG, id));
1134 wmip->wmi_stats.cmd_id_err++;
1139 A_NETBUF_FREE(osbuf);
1144 /* Send a "simple" wmi command -- one with no arguments */
1146 wmi_simple_cmd(struct wmi_t *wmip, WMI_COMMAND_ID cmdid)
1150 osbuf = A_NETBUF_ALLOC(0);
1151 if (osbuf == NULL) {
1155 return (wmi_cmd_send(wmip, osbuf, cmdid, NO_SYNC_WMIFLAG));
1158 /* Send a "simple" extended wmi command -- one with no arguments.
1159 Enabling this command only if GPIO or profiling support is enabled.
1160 This is to suppress warnings on some platforms */
1161 #if defined(CONFIG_TARGET_PROFILE_SUPPORT)
1163 wmi_simple_cmd_xtnd(struct wmi_t *wmip, WMIX_COMMAND_ID cmdid)
1167 osbuf = A_NETBUF_ALLOC(0);
1168 if (osbuf == NULL) {
1172 return (wmi_cmd_send_xtnd(wmip, osbuf, cmdid, NO_SYNC_WMIFLAG));
1177 wmi_ready_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1179 WMI_READY_EVENT *ev = (WMI_READY_EVENT *)datap;
1181 if (len < sizeof(WMI_READY_EVENT)) {
1184 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1185 wmip->wmi_ready = true;
1186 A_WMI_READY_EVENT(wmip->wmi_devt, ev->macaddr, ev->phyCapability,
1187 ev->sw_version, ev->abi_version);
1192 #define LE_READ_4(p) \
1194 ((((u8 *)(p))[0] ) | (((u8 *)(p))[1] << 8) | \
1195 (((u8 *)(p))[2] << 16) | (((u8 *)(p))[3] << 24)))
1198 iswmmoui(const u8 *frm)
1200 return frm[1] > 3 && LE_READ_4(frm+2) == ((WMM_OUI_TYPE<<24)|WMM_OUI);
1204 iswmmparam(const u8 *frm)
1206 return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE;
1211 wmi_connect_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1213 WMI_CONNECT_EVENT *ev;
1216 if (len < sizeof(WMI_CONNECT_EVENT))
1220 ev = (WMI_CONNECT_EVENT *)datap;
1223 (DBGFMT "freq %d bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
1224 DBGARG, ev->channel,
1225 ev->bssid[0], ev->bssid[1], ev->bssid[2],
1226 ev->bssid[3], ev->bssid[4], ev->bssid[5]));
1228 memcpy(wmip->wmi_bssid, ev->bssid, ATH_MAC_LEN);
1230 /* initialize pointer to start of assoc rsp IEs */
1231 pie = ev->assocInfo + ev->beaconIeLen + ev->assocReqLen +
1232 sizeof(u16) + /* capinfo*/
1233 sizeof(u16) + /* status Code */
1234 sizeof(u16) ; /* associd */
1236 /* initialize pointer to end of assoc rsp IEs */
1237 peie = ev->assocInfo + ev->beaconIeLen + ev->assocReqLen + ev->assocRespLen;
1243 case IEEE80211_ELEMID_VENDOR:
1246 if(iswmmparam (pie))
1248 wmip->wmi_is_wmm_enabled = true;
1254 if (wmip->wmi_is_wmm_enabled)
1261 A_WMI_CONNECT_EVENT(wmip->wmi_devt, ev->channel, ev->bssid,
1262 ev->listenInterval, ev->beaconInterval,
1263 (NETWORK_TYPE) ev->networkType, ev->beaconIeLen,
1264 ev->assocReqLen, ev->assocRespLen,
1271 wmi_regDomain_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1273 WMI_REG_DOMAIN_EVENT *ev;
1275 if (len < sizeof(*ev)) {
1278 ev = (WMI_REG_DOMAIN_EVENT *)datap;
1280 A_WMI_REGDOMAIN_EVENT(wmip->wmi_devt, ev->regDomain);
1286 wmi_neighborReport_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1288 WMI_NEIGHBOR_REPORT_EVENT *ev;
1291 if (len < sizeof(*ev)) {
1294 ev = (WMI_NEIGHBOR_REPORT_EVENT *)datap;
1295 numAps = ev->numberOfAps;
1297 if (len < (int)(sizeof(*ev) + ((numAps - 1) * sizeof(WMI_NEIGHBOR_INFO)))) {
1301 A_WMI_NEIGHBORREPORT_EVENT(wmip->wmi_devt, numAps, ev->neighbor);
1307 wmi_disconnect_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1309 WMI_DISCONNECT_EVENT *ev;
1310 wmip->wmi_traffic_class = 100;
1312 if (len < sizeof(WMI_DISCONNECT_EVENT)) {
1315 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1317 ev = (WMI_DISCONNECT_EVENT *)datap;
1319 A_MEMZERO(wmip->wmi_bssid, sizeof(wmip->wmi_bssid));
1321 wmip->wmi_is_wmm_enabled = false;
1322 wmip->wmi_pair_crypto_type = NONE_CRYPT;
1323 wmip->wmi_grp_crypto_type = NONE_CRYPT;
1325 A_WMI_DISCONNECT_EVENT(wmip->wmi_devt, ev->disconnectReason, ev->bssid,
1326 ev->assocRespLen, ev->assocInfo, ev->protocolReasonStatus);
1332 wmi_peer_node_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1334 WMI_PEER_NODE_EVENT *ev;
1336 if (len < sizeof(WMI_PEER_NODE_EVENT)) {
1339 ev = (WMI_PEER_NODE_EVENT *)datap;
1340 if (ev->eventCode == PEER_NODE_JOIN_EVENT) {
1341 A_DPRINTF (DBG_WMI, (DBGFMT "Joined node with Macaddr: ", DBGARG));
1342 } else if(ev->eventCode == PEER_NODE_LEAVE_EVENT) {
1343 A_DPRINTF (DBG_WMI, (DBGFMT "left node with Macaddr: ", DBGARG));
1346 A_WMI_PEER_EVENT (wmip->wmi_devt, ev->eventCode, ev->peerMacAddr);
1352 wmi_tkip_micerr_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1354 WMI_TKIP_MICERR_EVENT *ev;
1356 if (len < sizeof(*ev)) {
1359 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1361 ev = (WMI_TKIP_MICERR_EVENT *)datap;
1362 A_WMI_TKIP_MICERR_EVENT(wmip->wmi_devt, ev->keyid, ev->ismcast);
1368 wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1371 WMI_BSS_INFO_HDR *bih;
1373 u32 nodeCachingAllowed = 1;
1374 u8 cached_ssid_len = 0;
1375 u8 cached_ssid_buf[IEEE80211_NWID_LEN] = {0};
1376 u8 beacon_ssid_len = 0;
1378 if (len <= sizeof(WMI_BSS_INFO_HDR)) {
1382 bih = (WMI_BSS_INFO_HDR *)datap;
1383 bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid);
1385 if (bih->rssi > 0) {
1387 return 0; //no node found in the table, just drop the node with incorrect RSSI
1389 bih->rssi = bss->ni_rssi; //Adjust RSSI in datap in case it is used in A_WMI_BSSINFO_EVENT_RX
1392 A_WMI_BSSINFO_EVENT_RX(wmip->wmi_devt, datap, len);
1393 /* What is driver config for wlan node caching? */
1394 if(ar6000_get_driver_cfg(wmip->wmi_devt,
1395 AR6000_DRIVER_CFG_GET_WLANNODECACHING,
1396 &nodeCachingAllowed) != 0) {
1397 wmi_node_return(wmip, bss);
1401 if(!nodeCachingAllowed) {
1402 wmi_node_return(wmip, bss);
1406 buf = datap + sizeof(WMI_BSS_INFO_HDR);
1407 len -= sizeof(WMI_BSS_INFO_HDR);
1409 A_DPRINTF(DBG_WMI2, (DBGFMT "bssInfo event - ch %u, rssi %02x, "
1410 "bssid \"%pM\"\n", DBGARG, bih->channel,
1411 (unsigned char) bih->rssi, bih->bssid));
1413 if(wps_enable && (bih->frameType == PROBERESP_FTYPE) ) {
1414 wmi_node_return(wmip, bss);
1420 * Free up the node. Not the most efficient process given
1421 * we are about to allocate a new node but it is simple and should be
1425 /* In case of hidden AP, beacon will not have ssid,
1426 * but a directed probe response will have it,
1427 * so cache the probe-resp-ssid if already present. */
1428 if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType))
1432 ie_ssid = bss->ni_cie.ie_ssid;
1433 if(ie_ssid && (ie_ssid[1] <= IEEE80211_NWID_LEN) && (ie_ssid[2] != 0))
1435 cached_ssid_len = ie_ssid[1];
1436 memcpy(cached_ssid_buf, ie_ssid + 2, cached_ssid_len);
1441 * Use the current average rssi of associated AP base on assumpiton
1442 * 1. Most os with GUI will update RSSI by wmi_get_stats_cmd() periodically
1443 * 2. wmi_get_stats_cmd(..) will be called when calling wmi_startscan_cmd(...)
1444 * The average value of RSSI give end-user better feeling for instance value of scan result
1445 * It also sync up RSSI info in GUI between scan result and RSSI signal icon
1447 if (IEEE80211_ADDR_EQ(wmip->wmi_bssid, bih->bssid)) {
1448 bih->rssi = bss->ni_rssi;
1449 bih->snr = bss->ni_snr;
1452 wlan_node_reclaim(&wmip->wmi_scan_table, bss);
1455 /* beacon/probe response frame format
1457 * [2] beacon interval
1458 * [2] capability information
1460 beacon_ssid_len = buf[SSID_IE_LEN_INDEX];
1462 /* If ssid is cached for this hidden AP, then change buffer len accordingly. */
1463 if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) &&
1464 (0 != cached_ssid_len) &&
1465 (0 == beacon_ssid_len || (cached_ssid_len > beacon_ssid_len && 0 == buf[SSID_IE_LEN_INDEX + 1])))
1467 len += (cached_ssid_len - beacon_ssid_len);
1470 bss = wlan_node_alloc(&wmip->wmi_scan_table, len);
1475 bss->ni_snr = bih->snr;
1476 bss->ni_rssi = bih->rssi;
1477 A_ASSERT(bss->ni_buf != NULL);
1479 /* In case of hidden AP, beacon will not have ssid,
1480 * but a directed probe response will have it,
1481 * so place the cached-ssid(probe-resp) in the bssinfo. */
1482 if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) &&
1483 (0 != cached_ssid_len) &&
1484 (0 == beacon_ssid_len || (beacon_ssid_len && 0 == buf[SSID_IE_LEN_INDEX + 1])))
1486 u8 *ni_buf = bss->ni_buf;
1489 /* copy the first 14 bytes such as
1490 * time-stamp(8), beacon-interval(2), cap-info(2), ssid-id(1), ssid-len(1). */
1491 memcpy(ni_buf, buf, SSID_IE_LEN_INDEX + 1);
1493 ni_buf[SSID_IE_LEN_INDEX] = cached_ssid_len;
1494 ni_buf += (SSID_IE_LEN_INDEX + 1);
1496 buf += (SSID_IE_LEN_INDEX + 1);
1497 buf_len -= (SSID_IE_LEN_INDEX + 1);
1499 /* copy the cached ssid */
1500 memcpy(ni_buf, cached_ssid_buf, cached_ssid_len);
1501 ni_buf += cached_ssid_len;
1503 buf += beacon_ssid_len;
1504 buf_len -= beacon_ssid_len;
1506 if (cached_ssid_len > beacon_ssid_len)
1507 buf_len -= (cached_ssid_len - beacon_ssid_len);
1509 /* now copy the rest of bytes */
1510 memcpy(ni_buf, buf, buf_len);
1513 memcpy(bss->ni_buf, buf, len);
1515 bss->ni_framelen = len;
1516 if (wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie) != 0) {
1517 wlan_node_free(bss);
1522 * Update the frequency in ie_chan, overwriting of channel number
1523 * which is done in wlan_parse_beacon
1525 bss->ni_cie.ie_chan = bih->channel;
1526 wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid);
1532 wmi_opt_frame_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1535 WMI_OPT_RX_INFO_HDR *bih;
1538 if (len <= sizeof(WMI_OPT_RX_INFO_HDR)) {
1542 bih = (WMI_OPT_RX_INFO_HDR *)datap;
1543 buf = datap + sizeof(WMI_OPT_RX_INFO_HDR);
1544 len -= sizeof(WMI_OPT_RX_INFO_HDR);
1546 A_DPRINTF(DBG_WMI2, (DBGFMT "opt frame event %2.2x:%2.2x\n", DBGARG,
1547 bih->bssid[4], bih->bssid[5]));
1549 bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid);
1552 * Free up the node. Not the most efficient process given
1553 * we are about to allocate a new node but it is simple and should be
1556 wlan_node_reclaim(&wmip->wmi_scan_table, bss);
1559 bss = wlan_node_alloc(&wmip->wmi_scan_table, len);
1564 bss->ni_snr = bih->snr;
1565 bss->ni_cie.ie_chan = bih->channel;
1566 A_ASSERT(bss->ni_buf != NULL);
1567 memcpy(bss->ni_buf, buf, len);
1568 wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid);
1573 /* This event indicates inactivity timeout of a fatpipe(pstream)
1577 wmi_pstream_timeout_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1579 WMI_PSTREAM_TIMEOUT_EVENT *ev;
1581 if (len < sizeof(WMI_PSTREAM_TIMEOUT_EVENT)) {
1585 A_DPRINTF(DBG_WMI, (DBGFMT "wmi_pstream_timeout_event_rx\n", DBGARG));
1587 ev = (WMI_PSTREAM_TIMEOUT_EVENT *)datap;
1589 /* When the pstream (fat pipe == AC) timesout, it means there were no
1590 * thinStreams within this pstream & it got implicitly created due to
1591 * data flow on this AC. We start the inactivity timer only for
1592 * implicitly created pstream. Just reset the host state.
1594 /* Set the activeTsids for this AC to 0 */
1596 wmip->wmi_streamExistsForAC[ev->trafficClass]=0;
1597 wmip->wmi_fatPipeExists &= ~(1 << ev->trafficClass);
1600 /*Indicate inactivity to driver layer for this fatpipe (pstream)*/
1601 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, ev->trafficClass);
1607 wmi_bitrate_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1609 WMI_BIT_RATE_REPLY *reply;
1613 * WMI_BIT_RATE_CMD structure is changed to WMI_BIT_RATE_REPLY.
1614 * since there is difference in the length and to avoid returning
1617 if (len < sizeof(WMI_BIT_RATE_REPLY)) {
1620 reply = (WMI_BIT_RATE_REPLY *)datap;
1622 (DBGFMT "Enter - rateindex %d\n", DBGARG, reply->rateIndex));
1624 if (reply->rateIndex == (s8) RATE_AUTO) {
1627 // the SGI state is stored as the MSb of the rateIndex
1628 index = reply->rateIndex & 0x7f;
1629 sgi = (reply->rateIndex & 0x80)? 1:0;
1630 rate = wmi_rateTable[index][sgi];
1633 A_WMI_BITRATE_RX(wmip->wmi_devt, rate);
1638 wmi_ratemask_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1640 WMI_FIX_RATES_REPLY *reply;
1642 if (len < sizeof(WMI_FIX_RATES_REPLY)) {
1645 reply = (WMI_FIX_RATES_REPLY *)datap;
1647 (DBGFMT "Enter - fixed rate mask %x\n", DBGARG, reply->fixRateMask));
1649 A_WMI_RATEMASK_RX(wmip->wmi_devt, reply->fixRateMask);
1655 wmi_channelList_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1657 WMI_CHANNEL_LIST_REPLY *reply;
1659 if (len < sizeof(WMI_CHANNEL_LIST_REPLY)) {
1662 reply = (WMI_CHANNEL_LIST_REPLY *)datap;
1663 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1665 A_WMI_CHANNELLIST_RX(wmip->wmi_devt, reply->numChannels,
1666 reply->channelList);
1672 wmi_txPwr_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1674 WMI_TX_PWR_REPLY *reply;
1676 if (len < sizeof(*reply)) {
1679 reply = (WMI_TX_PWR_REPLY *)datap;
1680 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1682 A_WMI_TXPWR_RX(wmip->wmi_devt, reply->dbM);
1687 wmi_keepalive_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1689 WMI_GET_KEEPALIVE_CMD *reply;
1691 if (len < sizeof(*reply)) {
1694 reply = (WMI_GET_KEEPALIVE_CMD *)datap;
1695 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1697 A_WMI_KEEPALIVE_RX(wmip->wmi_devt, reply->configured);
1704 wmi_dset_open_req_rx(struct wmi_t *wmip, u8 *datap, int len)
1706 WMIX_DSETOPENREQ_EVENT *dsetopenreq;
1708 if (len < sizeof(WMIX_DSETOPENREQ_EVENT)) {
1711 dsetopenreq = (WMIX_DSETOPENREQ_EVENT *)datap;
1713 (DBGFMT "Enter - dset_id=0x%x\n", DBGARG, dsetopenreq->dset_id));
1714 A_WMI_DSET_OPEN_REQ(wmip->wmi_devt,
1715 dsetopenreq->dset_id,
1716 dsetopenreq->targ_dset_handle,
1717 dsetopenreq->targ_reply_fn,
1718 dsetopenreq->targ_reply_arg);
1723 #ifdef CONFIG_HOST_DSET_SUPPORT
1725 wmi_dset_close_rx(struct wmi_t *wmip, u8 *datap, int len)
1727 WMIX_DSETCLOSE_EVENT *dsetclose;
1729 if (len < sizeof(WMIX_DSETCLOSE_EVENT)) {
1732 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1734 dsetclose = (WMIX_DSETCLOSE_EVENT *)datap;
1735 A_WMI_DSET_CLOSE(wmip->wmi_devt, dsetclose->access_cookie);
1741 wmi_dset_data_req_rx(struct wmi_t *wmip, u8 *datap, int len)
1743 WMIX_DSETDATAREQ_EVENT *dsetdatareq;
1745 if (len < sizeof(WMIX_DSETDATAREQ_EVENT)) {
1748 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1750 dsetdatareq = (WMIX_DSETDATAREQ_EVENT *)datap;
1751 A_WMI_DSET_DATA_REQ(wmip->wmi_devt,
1752 dsetdatareq->access_cookie,
1753 dsetdatareq->offset,
1754 dsetdatareq->length,
1755 dsetdatareq->targ_buf,
1756 dsetdatareq->targ_reply_fn,
1757 dsetdatareq->targ_reply_arg);
1761 #endif /* CONFIG_HOST_DSET_SUPPORT */
1764 wmi_scanComplete_rx(struct wmi_t *wmip, u8 *datap, int len)
1766 WMI_SCAN_COMPLETE_EVENT *ev;
1768 ev = (WMI_SCAN_COMPLETE_EVENT *)datap;
1769 if ((int)ev->status == 0) {
1770 wlan_refresh_inactive_nodes(&wmip->wmi_scan_table);
1772 A_WMI_SCANCOMPLETE_EVENT(wmip->wmi_devt, (int) ev->status);
1773 is_probe_ssid = false;
1779 * Target is reporting a programming error. This is for
1780 * developer aid only. Target only checks a few common violations
1781 * and it is responsibility of host to do all error checking.
1782 * Behavior of target after wmi error event is undefined.
1783 * A reset is recommended.
1786 wmi_errorEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
1788 WMI_CMD_ERROR_EVENT *ev;
1790 ev = (WMI_CMD_ERROR_EVENT *)datap;
1791 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Programming Error: cmd=%d ", ev->commandId));
1792 switch (ev->errorCode) {
1793 case (INVALID_PARAM):
1794 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal Parameter\n"));
1796 case (ILLEGAL_STATE):
1797 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal State\n"));
1799 case (INTERNAL_ERROR):
1800 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Internal Error\n"));
1809 wmi_statsEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
1811 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1813 A_WMI_TARGETSTATS_EVENT(wmip->wmi_devt, datap, len);
1819 wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
1821 WMI_RSSI_THRESHOLD_EVENT *reply;
1822 WMI_RSSI_THRESHOLD_VAL newThreshold;
1823 WMI_RSSI_THRESHOLD_PARAMS_CMD cmd;
1824 SQ_THRESHOLD_PARAMS *sq_thresh =
1825 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI];
1826 u8 upper_rssi_threshold, lower_rssi_threshold;
1829 if (len < sizeof(*reply)) {
1832 reply = (WMI_RSSI_THRESHOLD_EVENT *)datap;
1833 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1834 newThreshold = (WMI_RSSI_THRESHOLD_VAL) reply->range;
1838 * Identify the threshold breached and communicate that to the app. After
1839 * that install a new set of thresholds based on the signal quality
1840 * reported by the target
1843 /* Upper threshold breached */
1844 if (rssi < sq_thresh->upper_threshold[0]) {
1845 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious upper RSSI threshold event: "
1846 " %d\n", DBGARG, rssi));
1847 } else if ((rssi < sq_thresh->upper_threshold[1]) &&
1848 (rssi >= sq_thresh->upper_threshold[0]))
1850 newThreshold = WMI_RSSI_THRESHOLD1_ABOVE;
1851 } else if ((rssi < sq_thresh->upper_threshold[2]) &&
1852 (rssi >= sq_thresh->upper_threshold[1]))
1854 newThreshold = WMI_RSSI_THRESHOLD2_ABOVE;
1855 } else if ((rssi < sq_thresh->upper_threshold[3]) &&
1856 (rssi >= sq_thresh->upper_threshold[2]))
1858 newThreshold = WMI_RSSI_THRESHOLD3_ABOVE;
1859 } else if ((rssi < sq_thresh->upper_threshold[4]) &&
1860 (rssi >= sq_thresh->upper_threshold[3]))
1862 newThreshold = WMI_RSSI_THRESHOLD4_ABOVE;
1863 } else if ((rssi < sq_thresh->upper_threshold[5]) &&
1864 (rssi >= sq_thresh->upper_threshold[4]))
1866 newThreshold = WMI_RSSI_THRESHOLD5_ABOVE;
1867 } else if (rssi >= sq_thresh->upper_threshold[5]) {
1868 newThreshold = WMI_RSSI_THRESHOLD6_ABOVE;
1871 /* Lower threshold breached */
1872 if (rssi > sq_thresh->lower_threshold[0]) {
1873 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious lower RSSI threshold event: "
1874 "%d %d\n", DBGARG, rssi, sq_thresh->lower_threshold[0]));
1875 } else if ((rssi > sq_thresh->lower_threshold[1]) &&
1876 (rssi <= sq_thresh->lower_threshold[0]))
1878 newThreshold = WMI_RSSI_THRESHOLD6_BELOW;
1879 } else if ((rssi > sq_thresh->lower_threshold[2]) &&
1880 (rssi <= sq_thresh->lower_threshold[1]))
1882 newThreshold = WMI_RSSI_THRESHOLD5_BELOW;
1883 } else if ((rssi > sq_thresh->lower_threshold[3]) &&
1884 (rssi <= sq_thresh->lower_threshold[2]))
1886 newThreshold = WMI_RSSI_THRESHOLD4_BELOW;
1887 } else if ((rssi > sq_thresh->lower_threshold[4]) &&
1888 (rssi <= sq_thresh->lower_threshold[3]))
1890 newThreshold = WMI_RSSI_THRESHOLD3_BELOW;
1891 } else if ((rssi > sq_thresh->lower_threshold[5]) &&
1892 (rssi <= sq_thresh->lower_threshold[4]))
1894 newThreshold = WMI_RSSI_THRESHOLD2_BELOW;
1895 } else if (rssi <= sq_thresh->lower_threshold[5]) {
1896 newThreshold = WMI_RSSI_THRESHOLD1_BELOW;
1899 /* Calculate and install the next set of thresholds */
1900 lower_rssi_threshold = ar6000_get_lower_threshold(rssi, sq_thresh,
1901 sq_thresh->lower_threshold_valid_count);
1902 upper_rssi_threshold = ar6000_get_upper_threshold(rssi, sq_thresh,
1903 sq_thresh->upper_threshold_valid_count);
1904 /* Issue a wmi command to install the thresholds */
1905 cmd.thresholdAbove1_Val = upper_rssi_threshold;
1906 cmd.thresholdBelow1_Val = lower_rssi_threshold;
1907 cmd.weight = sq_thresh->weight;
1908 cmd.pollTime = sq_thresh->polling_interval;
1910 rssi_event_value = rssi;
1912 if (wmi_send_rssi_threshold_params(wmip, &cmd) != 0) {
1913 A_DPRINTF(DBG_WMI, (DBGFMT "Unable to configure the RSSI thresholds\n",
1917 A_WMI_RSSI_THRESHOLD_EVENT(wmip->wmi_devt, newThreshold, reply->rssi);
1924 wmi_reportErrorEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
1926 WMI_TARGET_ERROR_REPORT_EVENT *reply;
1928 if (len < sizeof(*reply)) {
1931 reply = (WMI_TARGET_ERROR_REPORT_EVENT *)datap;
1932 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1934 A_WMI_REPORT_ERROR_EVENT(wmip->wmi_devt, (WMI_TARGET_ERROR_VAL) reply->errorVal);
1940 wmi_cac_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1942 WMI_CAC_EVENT *reply;
1943 WMM_TSPEC_IE *tspec_ie;
1946 if (len < sizeof(*reply)) {
1949 reply = (WMI_CAC_EVENT *)datap;
1951 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1953 if ((reply->cac_indication == CAC_INDICATION_ADMISSION_RESP) &&
1954 (reply->statusCode != TSPEC_STATUS_CODE_ADMISSION_ACCEPTED)) {
1955 tspec_ie = (WMM_TSPEC_IE *) &(reply->tspecSuggestion);
1957 wmi_delete_pstream_cmd(wmip, reply->ac,
1958 (tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK);
1960 else if (reply->cac_indication == CAC_INDICATION_NO_RESP) {
1963 /* following assumes that there is only one outstanding ADDTS request
1964 when this event is received */
1966 activeTsids = wmip->wmi_streamExistsForAC[reply->ac];
1969 for (i = 0; i < sizeof(activeTsids) * 8; i++) {
1970 if ((activeTsids >> i) & 1) {
1974 if (i < (sizeof(activeTsids) * 8)) {
1975 wmi_delete_pstream_cmd(wmip, reply->ac, i);
1979 * Ev#72990: Clear active tsids and Add missing handling
1980 * for delete qos stream from AP
1982 else if (reply->cac_indication == CAC_INDICATION_DELETE) {
1985 tspec_ie = (WMM_TSPEC_IE *) &(reply->tspecSuggestion);
1986 tsid= ((tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK);
1988 wmip->wmi_streamExistsForAC[reply->ac] &= ~(1<<tsid);
1989 activeTsids = wmip->wmi_streamExistsForAC[reply->ac];
1993 /* Indicate stream inactivity to driver layer only if all tsids
1994 * within this AC are deleted.
1997 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, reply->ac);
1998 wmip->wmi_fatPipeExists &= ~(1 << reply->ac);
2002 A_WMI_CAC_EVENT(wmip->wmi_devt, reply->ac,
2003 reply->cac_indication, reply->statusCode,
2004 reply->tspecSuggestion);
2010 wmi_channel_change_event_rx(struct wmi_t *wmip, u8 *datap, int len)
2012 WMI_CHANNEL_CHANGE_EVENT *reply;
2014 if (len < sizeof(*reply)) {
2017 reply = (WMI_CHANNEL_CHANGE_EVENT *)datap;
2018 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2020 A_WMI_CHANNEL_CHANGE_EVENT(wmip->wmi_devt, reply->oldChannel,
2027 wmi_hbChallengeResp_rx(struct wmi_t *wmip, u8 *datap, int len)
2029 WMIX_HB_CHALLENGE_RESP_EVENT *reply;
2031 if (len < sizeof(*reply)) {
2034 reply = (WMIX_HB_CHALLENGE_RESP_EVENT *)datap;
2035 A_DPRINTF(DBG_WMI, (DBGFMT "wmi: challenge response event\n", DBGARG));
2037 A_WMI_HBCHALLENGERESP_EVENT(wmip->wmi_devt, reply->cookie, reply->source);
2043 wmi_roam_tbl_event_rx(struct wmi_t *wmip, u8 *datap, int len)
2045 WMI_TARGET_ROAM_TBL *reply;
2047 if (len < sizeof(*reply)) {
2050 reply = (WMI_TARGET_ROAM_TBL *)datap;
2051 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2053 A_WMI_ROAM_TABLE_EVENT(wmip->wmi_devt, reply);
2059 wmi_roam_data_event_rx(struct wmi_t *wmip, u8 *datap, int len)
2061 WMI_TARGET_ROAM_DATA *reply;
2063 if (len < sizeof(*reply)) {
2066 reply = (WMI_TARGET_ROAM_DATA *)datap;
2067 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2069 A_WMI_ROAM_DATA_EVENT(wmip->wmi_devt, reply);
2075 wmi_txRetryErrEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
2077 if (len < sizeof(WMI_TX_RETRY_ERR_EVENT)) {
2080 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2082 A_WMI_TX_RETRY_ERR_EVENT(wmip->wmi_devt);
2088 wmi_snrThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
2090 WMI_SNR_THRESHOLD_EVENT *reply;
2091 SQ_THRESHOLD_PARAMS *sq_thresh =
2092 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_SNR];
2093 WMI_SNR_THRESHOLD_VAL newThreshold;
2094 WMI_SNR_THRESHOLD_PARAMS_CMD cmd;
2095 u8 upper_snr_threshold, lower_snr_threshold;
2098 if (len < sizeof(*reply)) {
2101 reply = (WMI_SNR_THRESHOLD_EVENT *)datap;
2102 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2104 newThreshold = (WMI_SNR_THRESHOLD_VAL) reply->range;
2107 * Identify the threshold breached and communicate that to the app. After
2108 * that install a new set of thresholds based on the signal quality
2109 * reported by the target
2112 /* Upper threshold breached */
2113 if (snr < sq_thresh->upper_threshold[0]) {
2114 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious upper SNR threshold event: "
2115 "%d\n", DBGARG, snr));
2116 } else if ((snr < sq_thresh->upper_threshold[1]) &&
2117 (snr >= sq_thresh->upper_threshold[0]))
2119 newThreshold = WMI_SNR_THRESHOLD1_ABOVE;
2120 } else if ((snr < sq_thresh->upper_threshold[2]) &&
2121 (snr >= sq_thresh->upper_threshold[1]))
2123 newThreshold = WMI_SNR_THRESHOLD2_ABOVE;
2124 } else if ((snr < sq_thresh->upper_threshold[3]) &&
2125 (snr >= sq_thresh->upper_threshold[2]))
2127 newThreshold = WMI_SNR_THRESHOLD3_ABOVE;
2128 } else if (snr >= sq_thresh->upper_threshold[3]) {
2129 newThreshold = WMI_SNR_THRESHOLD4_ABOVE;
2132 /* Lower threshold breached */
2133 if (snr > sq_thresh->lower_threshold[0]) {
2134 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious lower SNR threshold event: "
2135 "%d %d\n", DBGARG, snr, sq_thresh->lower_threshold[0]));
2136 } else if ((snr > sq_thresh->lower_threshold[1]) &&
2137 (snr <= sq_thresh->lower_threshold[0]))
2139 newThreshold = WMI_SNR_THRESHOLD4_BELOW;
2140 } else if ((snr > sq_thresh->lower_threshold[2]) &&
2141 (snr <= sq_thresh->lower_threshold[1]))
2143 newThreshold = WMI_SNR_THRESHOLD3_BELOW;
2144 } else if ((snr > sq_thresh->lower_threshold[3]) &&
2145 (snr <= sq_thresh->lower_threshold[2]))
2147 newThreshold = WMI_SNR_THRESHOLD2_BELOW;
2148 } else if (snr <= sq_thresh->lower_threshold[3]) {
2149 newThreshold = WMI_SNR_THRESHOLD1_BELOW;
2153 /* Calculate and install the next set of thresholds */
2154 lower_snr_threshold = ar6000_get_lower_threshold(snr, sq_thresh,
2155 sq_thresh->lower_threshold_valid_count);
2156 upper_snr_threshold = ar6000_get_upper_threshold(snr, sq_thresh,
2157 sq_thresh->upper_threshold_valid_count);
2159 /* Issue a wmi command to install the thresholds */
2160 cmd.thresholdAbove1_Val = upper_snr_threshold;
2161 cmd.thresholdBelow1_Val = lower_snr_threshold;
2162 cmd.weight = sq_thresh->weight;
2163 cmd.pollTime = sq_thresh->polling_interval;
2165 A_DPRINTF(DBG_WMI, (DBGFMT "snr: %d, threshold: %d, lower: %d, upper: %d\n"
2166 ,DBGARG, snr, newThreshold, lower_snr_threshold,
2167 upper_snr_threshold));
2169 snr_event_value = snr;
2171 if (wmi_send_snr_threshold_params(wmip, &cmd) != 0) {
2172 A_DPRINTF(DBG_WMI, (DBGFMT "Unable to configure the SNR thresholds\n",
2175 A_WMI_SNR_THRESHOLD_EVENT_RX(wmip->wmi_devt, newThreshold, reply->snr);
2181 wmi_lqThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
2183 WMI_LQ_THRESHOLD_EVENT *reply;
2185 if (len < sizeof(*reply)) {
2188 reply = (WMI_LQ_THRESHOLD_EVENT *)datap;
2189 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2191 A_WMI_LQ_THRESHOLD_EVENT_RX(wmip->wmi_devt,
2192 (WMI_LQ_THRESHOLD_VAL) reply->range,
2199 wmi_aplistEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
2201 u16 ap_info_entry_size;
2202 WMI_APLIST_EVENT *ev = (WMI_APLIST_EVENT *)datap;
2203 WMI_AP_INFO_V1 *ap_info_v1;
2206 if (len < sizeof(WMI_APLIST_EVENT)) {
2210 if (ev->apListVer == APLIST_VER1) {
2211 ap_info_entry_size = sizeof(WMI_AP_INFO_V1);
2212 ap_info_v1 = (WMI_AP_INFO_V1 *)ev->apList;
2217 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Number of APs in APLIST Event is %d\n", ev->numAP));
2218 if (len < (int)(sizeof(WMI_APLIST_EVENT) +
2219 (ev->numAP - 1) * ap_info_entry_size))
2225 * AP List Ver1 Contents
2227 for (i = 0; i < ev->numAP; i++) {
2228 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("AP#%d BSSID %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x "\
2230 ap_info_v1->bssid[0], ap_info_v1->bssid[1],
2231 ap_info_v1->bssid[2], ap_info_v1->bssid[3],
2232 ap_info_v1->bssid[4], ap_info_v1->bssid[5],
2233 ap_info_v1->channel));
2240 wmi_dbglog_event_rx(struct wmi_t *wmip, u8 *datap, int len)
2244 dropped = *((u32 *)datap);
2245 datap += sizeof(dropped);
2246 len -= sizeof(dropped);
2247 A_WMI_DBGLOG_EVENT(wmip->wmi_devt, dropped, (s8 *)datap, len);
2252 * Called to send a wmi command. Command specific data is already built
2253 * on osbuf and current osbuf->data points to it.
2256 wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId,
2257 WMI_SYNC_FLAG syncflag)
2260 #define IS_OPT_TX_CMD(cmdId) ((cmdId == WMI_OPT_TX_FRAME_CMDID))
2262 HTC_ENDPOINT_ID eid = wmip->wmi_endpoint_id;
2264 A_ASSERT(osbuf != NULL);
2266 if (syncflag >= END_WMIFLAG) {
2267 A_NETBUF_FREE(osbuf);
2271 if ((syncflag == SYNC_BEFORE_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) {
2273 * We want to make sure all data currently queued is transmitted before
2274 * the cmd execution. Establish a new sync point.
2276 wmi_sync_point(wmip);
2279 if (A_NETBUF_PUSH(osbuf, sizeof(WMI_CMD_HDR)) != 0) {
2280 A_NETBUF_FREE(osbuf);
2284 cHdr = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf);
2285 cHdr->commandId = (u16) cmdId;
2286 cHdr->info1 = 0; // added for virtual interface
2289 * Only for OPT_TX_CMD, use BE endpoint.
2291 if (IS_OPT_TX_CMD(cmdId)) {
2292 if ((status=wmi_data_hdr_add(wmip, osbuf, OPT_MSGTYPE, false, false,0,NULL)) != 0) {
2293 A_NETBUF_FREE(osbuf);
2296 eid = A_WMI_Ac2EndpointID(wmip->wmi_devt, WMM_AC_BE);
2298 A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid);
2300 if ((syncflag == SYNC_AFTER_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) {
2302 * We want to make sure all new data queued waits for the command to
2303 * execute. Establish a new sync point.
2305 wmi_sync_point(wmip);
2308 #undef IS_OPT_TX_CMD
2312 wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId,
2313 WMI_SYNC_FLAG syncflag)
2317 if (A_NETBUF_PUSH(osbuf, sizeof(WMIX_CMD_HDR)) != 0) {
2318 A_NETBUF_FREE(osbuf);
2322 cHdr = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf);
2323 cHdr->commandId = (u32) cmdId;
2325 return wmi_cmd_send(wmip, osbuf, WMI_EXTENSION_CMDID, syncflag);
2329 wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType,
2330 DOT11_AUTH_MODE dot11AuthMode, AUTH_MODE authMode,
2331 CRYPTO_TYPE pairwiseCrypto, u8 pairwiseCryptoLen,
2332 CRYPTO_TYPE groupCrypto, u8 groupCryptoLen,
2333 int ssidLength, u8 *ssid,
2334 u8 *bssid, u16 channel, u32 ctrl_flags)
2337 WMI_CONNECT_CMD *cc;
2338 wmip->wmi_traffic_class = 100;
2340 if ((pairwiseCrypto == NONE_CRYPT) && (groupCrypto != NONE_CRYPT)) {
2343 if ((pairwiseCrypto != NONE_CRYPT) && (groupCrypto == NONE_CRYPT)) {
2347 osbuf = A_NETBUF_ALLOC(sizeof(WMI_CONNECT_CMD));
2348 if (osbuf == NULL) {
2352 A_NETBUF_PUT(osbuf, sizeof(WMI_CONNECT_CMD));
2354 cc = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf));
2355 A_MEMZERO(cc, sizeof(*cc));
2359 memcpy(cc->ssid, ssid, ssidLength);
2362 cc->ssidLength = ssidLength;
2363 cc->networkType = netType;
2364 cc->dot11AuthMode = dot11AuthMode;
2365 cc->authMode = authMode;
2366 cc->pairwiseCryptoType = pairwiseCrypto;
2367 cc->pairwiseCryptoLen = pairwiseCryptoLen;
2368 cc->groupCryptoType = groupCrypto;
2369 cc->groupCryptoLen = groupCryptoLen;
2370 cc->channel = channel;
2371 cc->ctrl_flags = ctrl_flags;
2373 if (bssid != NULL) {
2374 memcpy(cc->bssid, bssid, ATH_MAC_LEN);
2377 wmip->wmi_pair_crypto_type = pairwiseCrypto;
2378 wmip->wmi_grp_crypto_type = groupCrypto;
2380 return (wmi_cmd_send(wmip, osbuf, WMI_CONNECT_CMDID, NO_SYNC_WMIFLAG));
2384 wmi_reconnect_cmd(struct wmi_t *wmip, u8 *bssid, u16 channel)
2387 WMI_RECONNECT_CMD *cc;
2388 wmip->wmi_traffic_class = 100;
2390 osbuf = A_NETBUF_ALLOC(sizeof(WMI_RECONNECT_CMD));
2391 if (osbuf == NULL) {
2395 A_NETBUF_PUT(osbuf, sizeof(WMI_RECONNECT_CMD));
2397 cc = (WMI_RECONNECT_CMD *)(A_NETBUF_DATA(osbuf));
2398 A_MEMZERO(cc, sizeof(*cc));
2400 cc->channel = channel;
2402 if (bssid != NULL) {
2403 memcpy(cc->bssid, bssid, ATH_MAC_LEN);
2406 return (wmi_cmd_send(wmip, osbuf, WMI_RECONNECT_CMDID, NO_SYNC_WMIFLAG));
2410 wmi_disconnect_cmd(struct wmi_t *wmip)
2413 wmip->wmi_traffic_class = 100;
2415 /* Bug fix for 24817(elevator bug) - the disconnect command does not
2416 need to do a SYNC before.*/
2417 status = wmi_simple_cmd(wmip, WMI_DISCONNECT_CMDID);
2423 wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType,
2424 u32 forceFgScan, u32 isLegacy,
2425 u32 homeDwellTime, u32 forceScanInterval,
2426 s8 numChan, u16 *channelList)
2429 WMI_START_SCAN_CMD *sc;
2432 size = sizeof (*sc);
2434 if ((scanType != WMI_LONG_SCAN) && (scanType != WMI_SHORT_SCAN)) {
2439 if (numChan > WMI_MAX_CHANNELS) {
2442 size += sizeof(u16) * (numChan - 1);
2445 osbuf = A_NETBUF_ALLOC(size);
2446 if (osbuf == NULL) {
2450 A_NETBUF_PUT(osbuf, size);
2452 sc = (WMI_START_SCAN_CMD *)(A_NETBUF_DATA(osbuf));
2453 sc->scanType = scanType;
2454 sc->forceFgScan = forceFgScan;
2455 sc->isLegacy = isLegacy;
2456 sc->homeDwellTime = homeDwellTime;
2457 sc->forceScanInterval = forceScanInterval;
2458 sc->numChannels = numChan;
2460 memcpy(sc->channelList, channelList, numChan * sizeof(u16));
2463 return (wmi_cmd_send(wmip, osbuf, WMI_START_SCAN_CMDID, NO_SYNC_WMIFLAG));
2467 wmi_scanparams_cmd(struct wmi_t *wmip, u16 fg_start_sec,
2468 u16 fg_end_sec, u16 bg_sec,
2469 u16 minact_chdw_msec, u16 maxact_chdw_msec,
2471 u8 shScanRatio, u8 scanCtrlFlags,
2472 u32 max_dfsch_act_time, u16 maxact_scan_per_ssid)
2475 WMI_SCAN_PARAMS_CMD *sc;
2477 osbuf = A_NETBUF_ALLOC(sizeof(*sc));
2478 if (osbuf == NULL) {
2482 A_NETBUF_PUT(osbuf, sizeof(*sc));
2484 sc = (WMI_SCAN_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
2485 A_MEMZERO(sc, sizeof(*sc));
2486 sc->fg_start_period = fg_start_sec;
2487 sc->fg_end_period = fg_end_sec;
2488 sc->bg_period = bg_sec;
2489 sc->minact_chdwell_time = minact_chdw_msec;
2490 sc->maxact_chdwell_time = maxact_chdw_msec;
2491 sc->pas_chdwell_time = pas_chdw_msec;
2492 sc->shortScanRatio = shScanRatio;
2493 sc->scanCtrlFlags = scanCtrlFlags;
2494 sc->max_dfsch_act_time = max_dfsch_act_time;
2495 sc->maxact_scan_per_ssid = maxact_scan_per_ssid;
2497 return (wmi_cmd_send(wmip, osbuf, WMI_SET_SCAN_PARAMS_CMDID,
2502 wmi_bssfilter_cmd(struct wmi_t *wmip, u8 filter, u32 ieMask)
2505 WMI_BSS_FILTER_CMD *cmd;
2507 if (filter >= LAST_BSS_FILTER) {
2511 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2512 if (osbuf == NULL) {
2516 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2518 cmd = (WMI_BSS_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
2519 A_MEMZERO(cmd, sizeof(*cmd));
2520 cmd->bssFilter = filter;
2521 cmd->ieMask = ieMask;
2523 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BSS_FILTER_CMDID,
2528 wmi_probedSsid_cmd(struct wmi_t *wmip, u8 index, u8 flag,
2529 u8 ssidLength, u8 *ssid)
2532 WMI_PROBED_SSID_CMD *cmd;
2534 if (index > MAX_PROBED_SSID_INDEX) {
2537 if (ssidLength > sizeof(cmd->ssid)) {
2540 if ((flag & (DISABLE_SSID_FLAG | ANY_SSID_FLAG)) && (ssidLength > 0)) {
2543 if ((flag & SPECIFIC_SSID_FLAG) && !ssidLength) {
2547 if (flag & SPECIFIC_SSID_FLAG) {
2548 is_probe_ssid = true;
2551 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2552 if (osbuf == NULL) {
2556 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2558 cmd = (WMI_PROBED_SSID_CMD *)(A_NETBUF_DATA(osbuf));
2559 A_MEMZERO(cmd, sizeof(*cmd));
2560 cmd->entryIndex = index;
2562 cmd->ssidLength = ssidLength;
2563 memcpy(cmd->ssid, ssid, ssidLength);
2565 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PROBED_SSID_CMDID,
2570 wmi_listeninterval_cmd(struct wmi_t *wmip, u16 listenInterval, u16 listenBeacons)
2573 WMI_LISTEN_INT_CMD *cmd;
2575 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2576 if (osbuf == NULL) {
2580 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2582 cmd = (WMI_LISTEN_INT_CMD *)(A_NETBUF_DATA(osbuf));
2583 A_MEMZERO(cmd, sizeof(*cmd));
2584 cmd->listenInterval = listenInterval;
2585 cmd->numBeacons = listenBeacons;
2587 return (wmi_cmd_send(wmip, osbuf, WMI_SET_LISTEN_INT_CMDID,
2592 wmi_bmisstime_cmd(struct wmi_t *wmip, u16 bmissTime, u16 bmissBeacons)
2595 WMI_BMISS_TIME_CMD *cmd;
2597 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2598 if (osbuf == NULL) {
2602 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2604 cmd = (WMI_BMISS_TIME_CMD *)(A_NETBUF_DATA(osbuf));
2605 A_MEMZERO(cmd, sizeof(*cmd));
2606 cmd->bmissTime = bmissTime;
2607 cmd->numBeacons = bmissBeacons;
2609 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BMISS_TIME_CMDID,
2614 wmi_associnfo_cmd(struct wmi_t *wmip, u8 ieType,
2615 u8 ieLen, u8 *ieInfo)
2618 WMI_SET_ASSOC_INFO_CMD *cmd;
2621 cmdLen = sizeof(*cmd) + ieLen - 1;
2622 osbuf = A_NETBUF_ALLOC(cmdLen);
2623 if (osbuf == NULL) {
2627 A_NETBUF_PUT(osbuf, cmdLen);
2629 cmd = (WMI_SET_ASSOC_INFO_CMD *)(A_NETBUF_DATA(osbuf));
2630 A_MEMZERO(cmd, cmdLen);
2631 cmd->ieType = ieType;
2632 cmd->bufferSize = ieLen;
2633 memcpy(cmd->assocInfo, ieInfo, ieLen);
2635 return (wmi_cmd_send(wmip, osbuf, WMI_SET_ASSOC_INFO_CMDID,
2640 wmi_powermode_cmd(struct wmi_t *wmip, u8 powerMode)
2643 WMI_POWER_MODE_CMD *cmd;
2645 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2646 if (osbuf == NULL) {
2650 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2652 cmd = (WMI_POWER_MODE_CMD *)(A_NETBUF_DATA(osbuf));
2653 A_MEMZERO(cmd, sizeof(*cmd));
2654 cmd->powerMode = powerMode;
2655 wmip->wmi_powerMode = powerMode;
2657 return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_MODE_CMDID,
2662 wmi_ibsspmcaps_cmd(struct wmi_t *wmip, u8 pmEnable, u8 ttl,
2663 u16 atim_windows, u16 timeout_value)
2666 WMI_IBSS_PM_CAPS_CMD *cmd;
2668 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2669 if (osbuf == NULL) {
2673 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2675 cmd = (WMI_IBSS_PM_CAPS_CMD *)(A_NETBUF_DATA(osbuf));
2676 A_MEMZERO(cmd, sizeof(*cmd));
2677 cmd->power_saving = pmEnable;
2679 cmd->atim_windows = atim_windows;
2680 cmd->timeout_value = timeout_value;
2682 return (wmi_cmd_send(wmip, osbuf, WMI_SET_IBSS_PM_CAPS_CMDID,
2687 wmi_apps_cmd(struct wmi_t *wmip, u8 psType, u32 idle_time,
2688 u32 ps_period, u8 sleep_period)
2693 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2694 if (osbuf == NULL) {
2698 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2700 cmd = (WMI_AP_PS_CMD *)(A_NETBUF_DATA(osbuf));
2701 A_MEMZERO(cmd, sizeof(*cmd));
2702 cmd->psType = psType;
2703 cmd->idle_time = idle_time;
2704 cmd->ps_period = ps_period;
2705 cmd->sleep_period = sleep_period;
2707 return (wmi_cmd_send(wmip, osbuf, WMI_SET_AP_PS_CMDID,
2712 wmi_pmparams_cmd(struct wmi_t *wmip, u16 idlePeriod,
2713 u16 psPollNum, u16 dtimPolicy,
2714 u16 tx_wakeup_policy, u16 num_tx_to_wakeup,
2715 u16 ps_fail_event_policy)
2718 WMI_POWER_PARAMS_CMD *pm;
2720 osbuf = A_NETBUF_ALLOC(sizeof(*pm));
2721 if (osbuf == NULL) {
2725 A_NETBUF_PUT(osbuf, sizeof(*pm));
2727 pm = (WMI_POWER_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
2728 A_MEMZERO(pm, sizeof(*pm));
2729 pm->idle_period = idlePeriod;
2730 pm->pspoll_number = psPollNum;
2731 pm->dtim_policy = dtimPolicy;
2732 pm->tx_wakeup_policy = tx_wakeup_policy;
2733 pm->num_tx_to_wakeup = num_tx_to_wakeup;
2734 pm->ps_fail_event_policy = ps_fail_event_policy;
2736 return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_PARAMS_CMDID,
2741 wmi_disctimeout_cmd(struct wmi_t *wmip, u8 timeout)
2744 WMI_DISC_TIMEOUT_CMD *cmd;
2746 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2747 if (osbuf == NULL) {
2751 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2753 cmd = (WMI_DISC_TIMEOUT_CMD *)(A_NETBUF_DATA(osbuf));
2754 A_MEMZERO(cmd, sizeof(*cmd));
2755 cmd->disconnectTimeout = timeout;
2757 return (wmi_cmd_send(wmip, osbuf, WMI_SET_DISC_TIMEOUT_CMDID,
2762 wmi_addKey_cmd(struct wmi_t *wmip, u8 keyIndex, CRYPTO_TYPE keyType,
2763 u8 keyUsage, u8 keyLength, u8 *keyRSC,
2764 u8 *keyMaterial, u8 key_op_ctrl, u8 *macAddr,
2765 WMI_SYNC_FLAG sync_flag)
2768 WMI_ADD_CIPHER_KEY_CMD *cmd;
2770 if ((keyIndex > WMI_MAX_KEY_INDEX) || (keyLength > WMI_MAX_KEY_LEN) ||
2771 (keyMaterial == NULL))
2776 if ((WEP_CRYPT != keyType) && (NULL == keyRSC)) {
2780 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2781 if (osbuf == NULL) {
2785 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2787 cmd = (WMI_ADD_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf));
2788 A_MEMZERO(cmd, sizeof(*cmd));
2789 cmd->keyIndex = keyIndex;
2790 cmd->keyType = keyType;
2791 cmd->keyUsage = keyUsage;
2792 cmd->keyLength = keyLength;
2793 memcpy(cmd->key, keyMaterial, keyLength);
2795 if (NULL != keyRSC && key_op_ctrl != KEY_OP_INIT_WAPIPN) {
2797 if (NULL != keyRSC) {
2798 #endif // WAPI_ENABLE
2799 memcpy(cmd->keyRSC, keyRSC, sizeof(cmd->keyRSC));
2801 cmd->key_op_ctrl = key_op_ctrl;
2804 memcpy(cmd->key_macaddr,macAddr,IEEE80211_ADDR_LEN);
2807 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_CIPHER_KEY_CMDID, sync_flag));
2811 wmi_add_krk_cmd(struct wmi_t *wmip, u8 *krk)
2814 WMI_ADD_KRK_CMD *cmd;
2816 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2817 if (osbuf == NULL) {
2821 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2823 cmd = (WMI_ADD_KRK_CMD *)(A_NETBUF_DATA(osbuf));
2824 A_MEMZERO(cmd, sizeof(*cmd));
2825 memcpy(cmd->krk, krk, WMI_KRK_LEN);
2827 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_KRK_CMDID, NO_SYNC_WMIFLAG));
2831 wmi_delete_krk_cmd(struct wmi_t *wmip)
2833 return wmi_simple_cmd(wmip, WMI_DELETE_KRK_CMDID);
2837 wmi_deleteKey_cmd(struct wmi_t *wmip, u8 keyIndex)
2840 WMI_DELETE_CIPHER_KEY_CMD *cmd;
2842 if (keyIndex > WMI_MAX_KEY_INDEX) {
2846 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2847 if (osbuf == NULL) {
2851 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2853 cmd = (WMI_DELETE_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf));
2854 A_MEMZERO(cmd, sizeof(*cmd));
2855 cmd->keyIndex = keyIndex;
2857 return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_CIPHER_KEY_CMDID,
2862 wmi_setPmkid_cmd(struct wmi_t *wmip, u8 *bssid, u8 *pmkId,
2866 WMI_SET_PMKID_CMD *cmd;
2868 if (bssid == NULL) {
2872 if ((set == true) && (pmkId == NULL)) {
2876 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2877 if (osbuf == NULL) {
2881 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2883 cmd = (WMI_SET_PMKID_CMD *)(A_NETBUF_DATA(osbuf));
2884 memcpy(cmd->bssid, bssid, sizeof(cmd->bssid));
2886 memcpy(cmd->pmkid, pmkId, sizeof(cmd->pmkid));
2887 cmd->enable = PMKID_ENABLE;
2889 A_MEMZERO(cmd->pmkid, sizeof(cmd->pmkid));
2890 cmd->enable = PMKID_DISABLE;
2893 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_CMDID, NO_SYNC_WMIFLAG));
2897 wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, bool en)
2900 WMI_SET_TKIP_COUNTERMEASURES_CMD *cmd;
2902 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2903 if (osbuf == NULL) {
2907 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2909 cmd = (WMI_SET_TKIP_COUNTERMEASURES_CMD *)(A_NETBUF_DATA(osbuf));
2910 cmd->cm_en = (en == true)? WMI_TKIP_CM_ENABLE : WMI_TKIP_CM_DISABLE;
2912 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TKIP_COUNTERMEASURES_CMDID,
2917 wmi_set_akmp_params_cmd(struct wmi_t *wmip,
2918 WMI_SET_AKMP_PARAMS_CMD *akmpParams)
2921 WMI_SET_AKMP_PARAMS_CMD *cmd;
2923 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2924 if (osbuf == NULL) {
2928 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2929 cmd = (WMI_SET_AKMP_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
2930 cmd->akmpInfo = akmpParams->akmpInfo;
2932 return (wmi_cmd_send(wmip, osbuf, WMI_SET_AKMP_PARAMS_CMDID,
2937 wmi_set_pmkid_list_cmd(struct wmi_t *wmip,
2938 WMI_SET_PMKID_LIST_CMD *pmkInfo)
2941 WMI_SET_PMKID_LIST_CMD *cmd;
2945 cmdLen = sizeof(pmkInfo->numPMKID) +
2946 pmkInfo->numPMKID * sizeof(WMI_PMKID);
2948 osbuf = A_NETBUF_ALLOC(cmdLen);
2949 if (osbuf == NULL) {
2953 A_NETBUF_PUT(osbuf, cmdLen);
2954 cmd = (WMI_SET_PMKID_LIST_CMD *)(A_NETBUF_DATA(osbuf));
2955 cmd->numPMKID = pmkInfo->numPMKID;
2957 for (i = 0; i < cmd->numPMKID; i++) {
2958 memcpy(&cmd->pmkidList[i], &pmkInfo->pmkidList[i],
2962 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_LIST_CMDID,
2967 wmi_get_pmkid_list_cmd(struct wmi_t *wmip)
2969 return wmi_simple_cmd(wmip, WMI_GET_PMKID_LIST_CMDID);
2973 wmi_dataSync_send(struct wmi_t *wmip, void *osbuf, HTC_ENDPOINT_ID eid)
2975 WMI_DATA_HDR *dtHdr;
2977 A_ASSERT( eid != wmip->wmi_endpoint_id);
2978 A_ASSERT(osbuf != NULL);
2980 if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != 0) {
2984 dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf);
2986 (SYNC_MSGTYPE & WMI_DATA_HDR_MSG_TYPE_MASK) << WMI_DATA_HDR_MSG_TYPE_SHIFT;
2989 A_DPRINTF(DBG_WMI, (DBGFMT "Enter - eid %d\n", DBGARG, eid));
2991 return (A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid));
2994 typedef struct _WMI_DATA_SYNC_BUFS {
2997 }WMI_DATA_SYNC_BUFS;
3000 wmi_sync_point(struct wmi_t *wmip)
3004 WMI_DATA_SYNC_BUFS dataSyncBufs[WMM_NUM_AC];
3005 u8 i,numPriStreams=0;
3008 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
3010 memset(dataSyncBufs,0,sizeof(dataSyncBufs));
3012 /* lock out while we walk through the priority list and assemble our local array */
3015 for (i=0; i < WMM_NUM_AC ; i++) {
3016 if (wmip->wmi_fatPipeExists & (1 << i)) {
3018 dataSyncBufs[numPriStreams-1].trafficClass = i;
3024 /* dataSyncBufs is now filled with entries (starting at index 0) containing valid streamIDs */
3028 * We allocate all network buffers needed so we will be able to
3029 * send all required frames.
3031 cmd_osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3032 if (cmd_osbuf == NULL) {
3033 status = A_NO_MEMORY;
3037 A_NETBUF_PUT(cmd_osbuf, sizeof(*cmd));
3039 cmd = (WMI_SYNC_CMD *)(A_NETBUF_DATA(cmd_osbuf));
3040 A_MEMZERO(cmd, sizeof(*cmd));
3042 /* In the SYNC cmd sent on the control Ep, send a bitmap of the data
3043 * eps on which the Data Sync will be sent
3045 cmd->dataSyncMap = wmip->wmi_fatPipeExists;
3047 for (i=0; i < numPriStreams ; i++) {
3048 dataSyncBufs[i].osbuf = A_NETBUF_ALLOC(0);
3049 if (dataSyncBufs[i].osbuf == NULL) {
3050 status = A_NO_MEMORY;
3055 /* if Buffer allocation for any of the dataSync fails, then do not
3056 * send the Synchronize cmd on the control ep
3063 * Send sync cmd followed by sync data messages on all endpoints being
3066 status = wmi_cmd_send(wmip, cmd_osbuf, WMI_SYNCHRONIZE_CMDID,
3072 /* cmd buffer sent, we no longer own it */
3075 for(i=0; i < numPriStreams; i++) {
3076 A_ASSERT(dataSyncBufs[i].osbuf != NULL);
3077 status = wmi_dataSync_send(wmip,
3078 dataSyncBufs[i].osbuf,
3079 A_WMI_Ac2EndpointID(wmip->wmi_devt,
3087 /* we don't own this buffer anymore, NULL it out of the array so it
3088 * won't get cleaned up */
3089 dataSyncBufs[i].osbuf = NULL;
3094 /* free up any resources left over (possibly due to an error) */
3096 if (cmd_osbuf != NULL) {
3097 A_NETBUF_FREE(cmd_osbuf);
3100 for (i = 0; i < numPriStreams; i++) {
3101 if (dataSyncBufs[i].osbuf != NULL) {
3102 A_NETBUF_FREE(dataSyncBufs[i].osbuf);
3110 wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *params)
3113 WMI_CREATE_PSTREAM_CMD *cmd;
3114 u8 fatPipeExistsForAC=0;
3118 /* Validate all the parameters. */
3119 if( !((params->userPriority < 8) &&
3120 (params->userPriority <= 0x7) &&
3121 (convert_userPriority_to_trafficClass(params->userPriority) == params->trafficClass) &&
3122 (params->trafficDirection == UPLINK_TRAFFIC ||
3123 params->trafficDirection == DNLINK_TRAFFIC ||
3124 params->trafficDirection == BIDIR_TRAFFIC) &&
3125 (params->trafficType == TRAFFIC_TYPE_APERIODIC ||
3126 params->trafficType == TRAFFIC_TYPE_PERIODIC ) &&
3127 (params->voicePSCapability == DISABLE_FOR_THIS_AC ||
3128 params->voicePSCapability == ENABLE_FOR_THIS_AC ||
3129 params->voicePSCapability == ENABLE_FOR_ALL_AC) &&
3130 (params->tsid == WMI_IMPLICIT_PSTREAM || params->tsid <= WMI_MAX_THINSTREAM)) )
3136 // check nominal PHY rate is >= minimalPHY, so that DUT
3137 // can allow TSRS IE
3140 // get the physical rate
3141 minimalPHY = ((params->minPhyRate / 1000)/1000); // unit of bps
3143 // check minimal phy < nominal phy rate
3145 if (params->nominalPHY >= minimalPHY)
3147 nominalPHY = (params->nominalPHY * 1000)/500; // unit of 500 kbps
3149 (DBGFMT "TSRS IE Enabled::MinPhy %x->NominalPhy ===> %x\n", DBGARG,
3150 minimalPHY, nominalPHY));
3152 params->nominalPHY = nominalPHY;
3156 params->nominalPHY = 0;
3159 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3160 if (osbuf == NULL) {
3164 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3167 (DBGFMT "Sending create_pstream_cmd: ac=%d tsid:%d\n", DBGARG,
3168 params->trafficClass, params->tsid));
3170 cmd = (WMI_CREATE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf));
3171 A_MEMZERO(cmd, sizeof(*cmd));
3172 memcpy(cmd, params, sizeof(*cmd));
3174 /* this is an implicitly created Fat pipe */
3175 if ((u32)params->tsid == (u32)WMI_IMPLICIT_PSTREAM) {
3177 fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass));
3178 wmip->wmi_fatPipeExists |= (1<<params->trafficClass);
3181 /* this is an explicitly created thin stream within a fat pipe */
3183 fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass));
3184 wmip->wmi_streamExistsForAC[params->trafficClass] |= (1<<params->tsid);
3185 /* if a thinstream becomes active, the fat pipe automatically
3188 wmip->wmi_fatPipeExists |= (1<<params->trafficClass);
3192 /* Indicate activty change to driver layer only if this is the
3193 * first TSID to get created in this AC explicitly or an implicit
3194 * fat pipe is getting created.
3196 if (!fatPipeExistsForAC) {
3197 A_WMI_STREAM_TX_ACTIVE(wmip->wmi_devt, params->trafficClass);
3200 /* mike: should be SYNC_BEFORE_WMIFLAG */
3201 return (wmi_cmd_send(wmip, osbuf, WMI_CREATE_PSTREAM_CMDID,
3206 wmi_delete_pstream_cmd(struct wmi_t *wmip, u8 trafficClass, u8 tsid)
3209 WMI_DELETE_PSTREAM_CMD *cmd;
3213 /* validate the parameters */
3214 if (trafficClass > 3) {
3215 A_DPRINTF(DBG_WMI, (DBGFMT "Invalid trafficClass: %d\n", DBGARG, trafficClass));
3219 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3220 if (osbuf == NULL) {
3224 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3226 cmd = (WMI_DELETE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf));
3227 A_MEMZERO(cmd, sizeof(*cmd));
3229 cmd->trafficClass = trafficClass;
3233 activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
3236 /* Check if the tsid was created & exists */
3237 if (!(activeTsids & (1<<tsid))) {
3239 A_NETBUF_FREE(osbuf);
3241 (DBGFMT "TSID %d does'nt exist for trafficClass: %d\n", DBGARG, tsid, trafficClass));
3242 /* TODO: return a more appropriate err code */
3247 (DBGFMT "Sending delete_pstream_cmd: trafficClass: %d tsid=%d\n", DBGARG, trafficClass, tsid));
3249 status = (wmi_cmd_send(wmip, osbuf, WMI_DELETE_PSTREAM_CMDID,
3250 SYNC_BEFORE_WMIFLAG));
3253 wmip->wmi_streamExistsForAC[trafficClass] &= ~(1<<tsid);
3254 activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
3258 /* Indicate stream inactivity to driver layer only if all tsids
3259 * within this AC are deleted.
3262 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, trafficClass);
3263 wmip->wmi_fatPipeExists &= ~(1<<trafficClass);
3270 wmi_set_framerate_cmd(struct wmi_t *wmip, u8 bEnable, u8 type, u8 subType, u16 rateMask)
3273 WMI_FRAME_RATES_CMD *cmd;
3277 (DBGFMT " type %02X, subType %02X, rateMask %04x\n", DBGARG, type, subType, rateMask));
3279 if((type != IEEE80211_FRAME_TYPE_MGT && type != IEEE80211_FRAME_TYPE_CTL) ||
3285 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3286 if (osbuf == NULL) {
3290 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3292 cmd = (WMI_FRAME_RATES_CMD *)(A_NETBUF_DATA(osbuf));
3293 A_MEMZERO(cmd, sizeof(*cmd));
3295 frameType = (u8)((subType << 4) | type);
3297 cmd->bEnableMask = bEnable;
3298 cmd->frameType = frameType;
3299 cmd->frameRateMask = rateMask;
3301 return (wmi_cmd_send(wmip, osbuf, WMI_SET_FRAMERATES_CMDID, NO_SYNC_WMIFLAG));
3305 * used to set the bit rate. rate is in Kbps. If rate == -1
3306 * then auto selection is used.
3309 wmi_set_bitrate_cmd(struct wmi_t *wmip, s32 dataRate, s32 mgmtRate, s32 ctlRate)
3312 WMI_BIT_RATE_CMD *cmd;
3313 s8 drix, mrix, crix, ret_val;
3315 if (dataRate != -1) {
3316 ret_val = wmi_validate_bitrate(wmip, dataRate, &drix);
3317 if(ret_val == A_EINVAL){
3324 if (mgmtRate != -1) {
3325 ret_val = wmi_validate_bitrate(wmip, mgmtRate, &mrix);
3326 if(ret_val == A_EINVAL){
3332 if (ctlRate != -1) {
3333 ret_val = wmi_validate_bitrate(wmip, ctlRate, &crix);
3334 if(ret_val == A_EINVAL){
3340 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3341 if (osbuf == NULL) {
3345 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3347 cmd = (WMI_BIT_RATE_CMD *)(A_NETBUF_DATA(osbuf));
3348 A_MEMZERO(cmd, sizeof(*cmd));
3350 cmd->rateIndex = drix;
3351 cmd->mgmtRateIndex = mrix;
3352 cmd->ctlRateIndex = crix;
3355 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BITRATE_CMDID, NO_SYNC_WMIFLAG));
3359 wmi_get_bitrate_cmd(struct wmi_t *wmip)
3361 return wmi_simple_cmd(wmip, WMI_GET_BITRATE_CMDID);
3365 * Returns true iff the given rate index is legal in the current PHY mode.
3368 wmi_is_bitrate_index_valid(struct wmi_t *wmip, s32 rateIndex)
3370 WMI_PHY_MODE phyMode = (WMI_PHY_MODE) wmip->wmi_phyMode;
3371 bool isValid = true;
3374 if (wmip->wmi_ht_allowed[A_BAND_5GHZ]){
3375 if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
3379 if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_A_SUPPORT_RATE_STOP)) {
3386 if ((rateIndex < MODE_B_SUPPORT_RATE_START) || (rateIndex > MODE_B_SUPPORT_RATE_STOP)) {
3391 case WMI_11GONLY_MODE:
3392 if (wmip->wmi_ht_allowed[A_BAND_24GHZ]){
3393 if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
3397 if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE_GONLY_SUPPORT_RATE_STOP)) {
3405 if (wmip->wmi_ht_allowed[A_BAND_24GHZ]){
3406 if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
3410 if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_G_SUPPORT_RATE_STOP)) {
3423 s8 wmi_validate_bitrate(struct wmi_t *wmip, s32 rate, s8 *rate_idx)
3429 if (wmi_rateTable[(u32) i][0] == 0) {
3432 if (wmi_rateTable[(u32) i][0] == rate) {
3437 if(wmi_is_bitrate_index_valid(wmip, (s32) i) != true) {
3446 wmi_set_fixrates_cmd(struct wmi_t *wmip, u32 fixRatesMask)
3449 WMI_FIX_RATES_CMD *cmd;
3452 /* This check does not work for AR6003 as the HT modes are enabled only when
3453 * the STA is connected to a HT_BSS and is not based only on channel. It is
3454 * safe to skip this check however because rate control will only use rates
3455 * that are permitted by the valid rate mask and the fix rate mask. Meaning
3456 * the fix rate mask is not sufficient by itself to cause an invalid rate
3458 /* Make sure all rates in the mask are valid in the current PHY mode */
3459 for(rateIndex = 0; rateIndex < MAX_NUMBER_OF_SUPPORT_RATES; rateIndex++) {
3460 if((1 << rateIndex) & (u32)fixRatesMask) {
3461 if(wmi_is_bitrate_index_valid(wmip, rateIndex) != true) {
3462 A_DPRINTF(DBG_WMI, (DBGFMT "Set Fix Rates command failed: Given rate is illegal in current PHY mode\n", DBGARG));
3470 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3471 if (osbuf == NULL) {
3475 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3477 cmd = (WMI_FIX_RATES_CMD *)(A_NETBUF_DATA(osbuf));
3478 A_MEMZERO(cmd, sizeof(*cmd));
3480 cmd->fixRateMask = fixRatesMask;
3482 return (wmi_cmd_send(wmip, osbuf, WMI_SET_FIXRATES_CMDID, NO_SYNC_WMIFLAG));
3486 wmi_get_ratemask_cmd(struct wmi_t *wmip)
3488 return wmi_simple_cmd(wmip, WMI_GET_FIXRATES_CMDID);
3492 wmi_get_channelList_cmd(struct wmi_t *wmip)
3494 return wmi_simple_cmd(wmip, WMI_GET_CHANNEL_LIST_CMDID);
3498 * used to generate a wmi sey channel Parameters cmd.
3499 * mode should always be specified and corresponds to the phy mode of the
3501 * numChan should alway sbe specified. If zero indicates that all available
3502 * channels should be used.
3503 * channelList is an array of channel frequencies (in Mhz) which the radio
3504 * should limit its operation to. It should be NULL if numChan == 0. Size of
3505 * array should correspond to numChan entries.
3508 wmi_set_channelParams_cmd(struct wmi_t *wmip, u8 scanParam,
3509 WMI_PHY_MODE mode, s8 numChan,
3513 WMI_CHANNEL_PARAMS_CMD *cmd;
3516 size = sizeof (*cmd);
3519 if (numChan > WMI_MAX_CHANNELS) {
3522 size += sizeof(u16) * (numChan - 1);
3525 osbuf = A_NETBUF_ALLOC(size);
3526 if (osbuf == NULL) {
3530 A_NETBUF_PUT(osbuf, size);
3532 cmd = (WMI_CHANNEL_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
3533 A_MEMZERO(cmd, size);
3535 wmip->wmi_phyMode = mode;
3536 cmd->scanParam = scanParam;
3537 cmd->phyMode = mode;
3538 cmd->numChannels = numChan;
3539 memcpy(cmd->channelList, channelList, numChan * sizeof(u16));
3541 return (wmi_cmd_send(wmip, osbuf, WMI_SET_CHANNEL_PARAMS_CMDID,
3546 wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
3548 SQ_THRESHOLD_PARAMS *sq_thresh =
3549 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI];
3551 * Parse the command and store the threshold values here. The checks
3552 * for valid values can be put here
3554 sq_thresh->weight = rssiCmd->weight;
3555 sq_thresh->polling_interval = rssiCmd->pollTime;
3557 sq_thresh->upper_threshold[0] = rssiCmd->thresholdAbove1_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3558 sq_thresh->upper_threshold[1] = rssiCmd->thresholdAbove2_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3559 sq_thresh->upper_threshold[2] = rssiCmd->thresholdAbove3_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3560 sq_thresh->upper_threshold[3] = rssiCmd->thresholdAbove4_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3561 sq_thresh->upper_threshold[4] = rssiCmd->thresholdAbove5_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3562 sq_thresh->upper_threshold[5] = rssiCmd->thresholdAbove6_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3563 sq_thresh->upper_threshold_valid_count = 6;
3565 /* List sorted in descending order */
3566 sq_thresh->lower_threshold[0] = rssiCmd->thresholdBelow6_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3567 sq_thresh->lower_threshold[1] = rssiCmd->thresholdBelow5_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3568 sq_thresh->lower_threshold[2] = rssiCmd->thresholdBelow4_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3569 sq_thresh->lower_threshold[3] = rssiCmd->thresholdBelow3_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3570 sq_thresh->lower_threshold[4] = rssiCmd->thresholdBelow2_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3571 sq_thresh->lower_threshold[5] = rssiCmd->thresholdBelow1_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3572 sq_thresh->lower_threshold_valid_count = 6;
3574 if (!rssi_event_value) {
3576 * Configuring the thresholds to their extremes allows the host to get an
3577 * event from the target which is used for the configuring the correct
3580 rssiCmd->thresholdAbove1_Val = sq_thresh->upper_threshold[0];
3581 rssiCmd->thresholdBelow1_Val = sq_thresh->lower_threshold[0];
3584 * In case the user issues multiple times of rssi_threshold_setting,
3585 * we should not use the extreames anymore, the target does not expect that.
3587 rssiCmd->thresholdAbove1_Val = ar6000_get_upper_threshold(rssi_event_value, sq_thresh,
3588 sq_thresh->upper_threshold_valid_count);
3589 rssiCmd->thresholdBelow1_Val = ar6000_get_lower_threshold(rssi_event_value, sq_thresh,
3590 sq_thresh->lower_threshold_valid_count);
3595 wmi_set_rssi_threshold_params(struct wmi_t *wmip,
3596 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
3599 /* Check these values are in ascending order */
3600 if( rssiCmd->thresholdAbove6_Val <= rssiCmd->thresholdAbove5_Val ||
3601 rssiCmd->thresholdAbove5_Val <= rssiCmd->thresholdAbove4_Val ||
3602 rssiCmd->thresholdAbove4_Val <= rssiCmd->thresholdAbove3_Val ||
3603 rssiCmd->thresholdAbove3_Val <= rssiCmd->thresholdAbove2_Val ||
3604 rssiCmd->thresholdAbove2_Val <= rssiCmd->thresholdAbove1_Val ||
3605 rssiCmd->thresholdBelow6_Val <= rssiCmd->thresholdBelow5_Val ||
3606 rssiCmd->thresholdBelow5_Val <= rssiCmd->thresholdBelow4_Val ||
3607 rssiCmd->thresholdBelow4_Val <= rssiCmd->thresholdBelow3_Val ||
3608 rssiCmd->thresholdBelow3_Val <= rssiCmd->thresholdBelow2_Val ||
3609 rssiCmd->thresholdBelow2_Val <= rssiCmd->thresholdBelow1_Val)
3614 wmi_cache_configure_rssithreshold(wmip, rssiCmd);
3616 return (wmi_send_rssi_threshold_params(wmip, rssiCmd));
3620 wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *ipCmd)
3623 WMI_SET_IP_CMD *cmd;
3625 /* Multicast address are not valid */
3626 if((*((u8 *)&ipCmd->ips[0]) >= 0xE0) ||
3627 (*((u8 *)&ipCmd->ips[1]) >= 0xE0)) {
3631 osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_IP_CMD));
3632 if (osbuf == NULL) {
3636 A_NETBUF_PUT(osbuf, sizeof(WMI_SET_IP_CMD));
3637 cmd = (WMI_SET_IP_CMD *)(A_NETBUF_DATA(osbuf));
3638 memcpy(cmd, ipCmd, sizeof(WMI_SET_IP_CMD));
3640 return (wmi_cmd_send(wmip, osbuf, WMI_SET_IP_CMDID,
3645 wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip,
3646 WMI_SET_HOST_SLEEP_MODE_CMD *hostModeCmd)
3650 WMI_SET_HOST_SLEEP_MODE_CMD *cmd;
3655 if( hostModeCmd->awake == hostModeCmd->asleep) {
3659 size = sizeof (*cmd);
3661 osbuf = A_NETBUF_ALLOC(size);
3662 if (osbuf == NULL) {
3666 A_NETBUF_PUT(osbuf, size);
3668 cmd = (WMI_SET_HOST_SLEEP_MODE_CMD *)(A_NETBUF_DATA(osbuf));
3669 A_MEMZERO(cmd, size);
3670 memcpy(cmd, hostModeCmd, sizeof(WMI_SET_HOST_SLEEP_MODE_CMD));
3672 if(hostModeCmd->asleep) {
3674 * Relinquish credits from all implicitly created pstreams since when we
3675 * go to sleep. If user created explicit thinstreams exists with in a
3676 * fatpipe leave them intact for the user to delete
3679 streamExists = wmip->wmi_fatPipeExists;
3682 for(i=0;i< WMM_NUM_AC;i++) {
3683 if (streamExists & (1<<i)) {
3685 activeTsids = wmip->wmi_streamExistsForAC[i];
3687 /* If there are no user created thin streams delete the fatpipe */
3689 streamExists &= ~(1<<i);
3690 /*Indicate inactivity to drv layer for this fatpipe(pstream)*/
3691 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt,i);
3696 /* Update the fatpipes that exists*/
3698 wmip->wmi_fatPipeExists = streamExists;
3702 return (wmi_cmd_send(wmip, osbuf, WMI_SET_HOST_SLEEP_MODE_CMDID,
3707 wmi_set_wow_mode_cmd(struct wmi_t *wmip,
3708 WMI_SET_WOW_MODE_CMD *wowModeCmd)
3712 WMI_SET_WOW_MODE_CMD *cmd;
3714 size = sizeof (*cmd);
3716 osbuf = A_NETBUF_ALLOC(size);
3717 if (osbuf == NULL) {
3721 A_NETBUF_PUT(osbuf, size);
3723 cmd = (WMI_SET_WOW_MODE_CMD *)(A_NETBUF_DATA(osbuf));
3724 A_MEMZERO(cmd, size);
3725 memcpy(cmd, wowModeCmd, sizeof(WMI_SET_WOW_MODE_CMD));
3727 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WOW_MODE_CMDID,
3733 wmi_get_wow_list_cmd(struct wmi_t *wmip,
3734 WMI_GET_WOW_LIST_CMD *wowListCmd)
3738 WMI_GET_WOW_LIST_CMD *cmd;
3740 size = sizeof (*cmd);
3742 osbuf = A_NETBUF_ALLOC(size);
3743 if (osbuf == NULL) {
3747 A_NETBUF_PUT(osbuf, size);
3749 cmd = (WMI_GET_WOW_LIST_CMD *)(A_NETBUF_DATA(osbuf));
3750 A_MEMZERO(cmd, size);
3751 memcpy(cmd, wowListCmd, sizeof(WMI_GET_WOW_LIST_CMD));
3753 return (wmi_cmd_send(wmip, osbuf, WMI_GET_WOW_LIST_CMDID,
3759 wmi_get_wow_list_event_rx(struct wmi_t *wmip, u8 *datap, int len)
3761 WMI_GET_WOW_LIST_REPLY *reply;
3763 if (len < sizeof(WMI_GET_WOW_LIST_REPLY)) {
3766 reply = (WMI_GET_WOW_LIST_REPLY *)datap;
3768 A_WMI_WOW_LIST_EVENT(wmip->wmi_devt, reply->num_filters,
3774 int wmi_add_wow_pattern_cmd(struct wmi_t *wmip,
3775 WMI_ADD_WOW_PATTERN_CMD *addWowCmd,
3776 u8 *pattern, u8 *mask,
3781 WMI_ADD_WOW_PATTERN_CMD *cmd;
3782 u8 *filter_mask = NULL;
3784 size = sizeof (*cmd);
3786 size += ((2 * addWowCmd->filter_size)* sizeof(u8));
3787 osbuf = A_NETBUF_ALLOC(size);
3788 if (osbuf == NULL) {
3792 A_NETBUF_PUT(osbuf, size);
3794 cmd = (WMI_ADD_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf));
3795 cmd->filter_list_id = addWowCmd->filter_list_id;
3796 cmd->filter_offset = addWowCmd->filter_offset;
3797 cmd->filter_size = addWowCmd->filter_size;
3799 memcpy(cmd->filter, pattern, addWowCmd->filter_size);
3801 filter_mask = (u8 *)(cmd->filter + cmd->filter_size);
3802 memcpy(filter_mask, mask, addWowCmd->filter_size);
3805 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_WOW_PATTERN_CMDID,
3810 wmi_del_wow_pattern_cmd(struct wmi_t *wmip,
3811 WMI_DEL_WOW_PATTERN_CMD *delWowCmd)
3815 WMI_DEL_WOW_PATTERN_CMD *cmd;
3817 size = sizeof (*cmd);
3819 osbuf = A_NETBUF_ALLOC(size);
3820 if (osbuf == NULL) {
3824 A_NETBUF_PUT(osbuf, size);
3826 cmd = (WMI_DEL_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf));
3827 A_MEMZERO(cmd, size);
3828 memcpy(cmd, delWowCmd, sizeof(WMI_DEL_WOW_PATTERN_CMD));
3830 return (wmi_cmd_send(wmip, osbuf, WMI_DEL_WOW_PATTERN_CMDID,
3836 wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
3838 SQ_THRESHOLD_PARAMS *sq_thresh =
3839 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_SNR];
3841 * Parse the command and store the threshold values here. The checks
3842 * for valid values can be put here
3844 sq_thresh->weight = snrCmd->weight;
3845 sq_thresh->polling_interval = snrCmd->pollTime;
3847 sq_thresh->upper_threshold[0] = snrCmd->thresholdAbove1_Val;
3848 sq_thresh->upper_threshold[1] = snrCmd->thresholdAbove2_Val;
3849 sq_thresh->upper_threshold[2] = snrCmd->thresholdAbove3_Val;
3850 sq_thresh->upper_threshold[3] = snrCmd->thresholdAbove4_Val;
3851 sq_thresh->upper_threshold_valid_count = 4;
3853 /* List sorted in descending order */
3854 sq_thresh->lower_threshold[0] = snrCmd->thresholdBelow4_Val;
3855 sq_thresh->lower_threshold[1] = snrCmd->thresholdBelow3_Val;
3856 sq_thresh->lower_threshold[2] = snrCmd->thresholdBelow2_Val;
3857 sq_thresh->lower_threshold[3] = snrCmd->thresholdBelow1_Val;
3858 sq_thresh->lower_threshold_valid_count = 4;
3860 if (!snr_event_value) {
3862 * Configuring the thresholds to their extremes allows the host to get an
3863 * event from the target which is used for the configuring the correct
3866 snrCmd->thresholdAbove1_Val = (u8)sq_thresh->upper_threshold[0];
3867 snrCmd->thresholdBelow1_Val = (u8)sq_thresh->lower_threshold[0];
3870 * In case the user issues multiple times of snr_threshold_setting,
3871 * we should not use the extreames anymore, the target does not expect that.
3873 snrCmd->thresholdAbove1_Val = ar6000_get_upper_threshold(snr_event_value, sq_thresh,
3874 sq_thresh->upper_threshold_valid_count);
3875 snrCmd->thresholdBelow1_Val = ar6000_get_lower_threshold(snr_event_value, sq_thresh,
3876 sq_thresh->lower_threshold_valid_count);
3881 wmi_set_snr_threshold_params(struct wmi_t *wmip,
3882 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
3884 if( snrCmd->thresholdAbove4_Val <= snrCmd->thresholdAbove3_Val ||
3885 snrCmd->thresholdAbove3_Val <= snrCmd->thresholdAbove2_Val ||
3886 snrCmd->thresholdAbove2_Val <= snrCmd->thresholdAbove1_Val ||
3887 snrCmd->thresholdBelow4_Val <= snrCmd->thresholdBelow3_Val ||
3888 snrCmd->thresholdBelow3_Val <= snrCmd->thresholdBelow2_Val ||
3889 snrCmd->thresholdBelow2_Val <= snrCmd->thresholdBelow1_Val)
3893 wmi_cache_configure_snrthreshold(wmip, snrCmd);
3894 return (wmi_send_snr_threshold_params(wmip, snrCmd));
3898 wmi_clr_rssi_snr(struct wmi_t *wmip)
3902 osbuf = A_NETBUF_ALLOC(sizeof(int));
3903 if (osbuf == NULL) {
3907 return (wmi_cmd_send(wmip, osbuf, WMI_CLR_RSSI_SNR_CMDID,
3912 wmi_set_lq_threshold_params(struct wmi_t *wmip,
3913 WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd)
3917 WMI_LQ_THRESHOLD_PARAMS_CMD *cmd;
3918 /* These values are in ascending order */
3919 if( lqCmd->thresholdAbove4_Val <= lqCmd->thresholdAbove3_Val ||
3920 lqCmd->thresholdAbove3_Val <= lqCmd->thresholdAbove2_Val ||
3921 lqCmd->thresholdAbove2_Val <= lqCmd->thresholdAbove1_Val ||
3922 lqCmd->thresholdBelow4_Val <= lqCmd->thresholdBelow3_Val ||
3923 lqCmd->thresholdBelow3_Val <= lqCmd->thresholdBelow2_Val ||
3924 lqCmd->thresholdBelow2_Val <= lqCmd->thresholdBelow1_Val ) {
3929 size = sizeof (*cmd);
3931 osbuf = A_NETBUF_ALLOC(size);
3932 if (osbuf == NULL) {
3936 A_NETBUF_PUT(osbuf, size);
3938 cmd = (WMI_LQ_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
3939 A_MEMZERO(cmd, size);
3940 memcpy(cmd, lqCmd, sizeof(WMI_LQ_THRESHOLD_PARAMS_CMD));
3942 return (wmi_cmd_send(wmip, osbuf, WMI_LQ_THRESHOLD_PARAMS_CMDID,
3947 wmi_set_error_report_bitmask(struct wmi_t *wmip, u32 mask)
3951 WMI_TARGET_ERROR_REPORT_BITMASK *cmd;
3953 size = sizeof (*cmd);
3955 osbuf = A_NETBUF_ALLOC(size);
3956 if (osbuf == NULL) {
3960 A_NETBUF_PUT(osbuf, size);
3962 cmd = (WMI_TARGET_ERROR_REPORT_BITMASK *)(A_NETBUF_DATA(osbuf));
3963 A_MEMZERO(cmd, size);
3965 cmd->bitmask = mask;
3967 return (wmi_cmd_send(wmip, osbuf, WMI_TARGET_ERROR_REPORT_BITMASK_CMDID,
3972 wmi_get_challenge_resp_cmd(struct wmi_t *wmip, u32 cookie, u32 source)
3975 WMIX_HB_CHALLENGE_RESP_CMD *cmd;
3977 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3978 if (osbuf == NULL) {
3982 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3984 cmd = (WMIX_HB_CHALLENGE_RESP_CMD *)(A_NETBUF_DATA(osbuf));
3985 cmd->cookie = cookie;
3986 cmd->source = source;
3988 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_HB_CHALLENGE_RESP_CMDID,
3993 wmi_config_debug_module_cmd(struct wmi_t *wmip, u16 mmask,
3994 u16 tsr, bool rep, u16 size,
3998 WMIX_DBGLOG_CFG_MODULE_CMD *cmd;
4000 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4001 if (osbuf == NULL) {
4005 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4007 cmd = (WMIX_DBGLOG_CFG_MODULE_CMD *)(A_NETBUF_DATA(osbuf));
4008 cmd->config.cfgmmask = mmask;
4009 cmd->config.cfgtsr = tsr;
4010 cmd->config.cfgrep = rep;
4011 cmd->config.cfgsize = size;
4012 cmd->config.cfgvalid = valid;
4014 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DBGLOG_CFG_MODULE_CMDID,
4019 wmi_get_stats_cmd(struct wmi_t *wmip)
4021 return wmi_simple_cmd(wmip, WMI_GET_STATISTICS_CMDID);
4025 wmi_addBadAp_cmd(struct wmi_t *wmip, u8 apIndex, u8 *bssid)
4028 WMI_ADD_BAD_AP_CMD *cmd;
4030 if ((bssid == NULL) || (apIndex > WMI_MAX_BAD_AP_INDEX)) {
4034 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4035 if (osbuf == NULL) {
4039 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4041 cmd = (WMI_ADD_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf));
4042 cmd->badApIndex = apIndex;
4043 memcpy(cmd->bssid, bssid, sizeof(cmd->bssid));
4045 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_BAD_AP_CMDID, SYNC_BEFORE_WMIFLAG));
4049 wmi_deleteBadAp_cmd(struct wmi_t *wmip, u8 apIndex)
4052 WMI_DELETE_BAD_AP_CMD *cmd;
4054 if (apIndex > WMI_MAX_BAD_AP_INDEX) {
4058 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4059 if (osbuf == NULL) {
4063 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4065 cmd = (WMI_DELETE_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf));
4066 cmd->badApIndex = apIndex;
4068 return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_BAD_AP_CMDID,
4073 wmi_abort_scan_cmd(struct wmi_t *wmip)
4075 return wmi_simple_cmd(wmip, WMI_ABORT_SCAN_CMDID);
4079 wmi_set_txPwr_cmd(struct wmi_t *wmip, u8 dbM)
4082 WMI_SET_TX_PWR_CMD *cmd;
4084 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4085 if (osbuf == NULL) {
4089 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4091 cmd = (WMI_SET_TX_PWR_CMD *)(A_NETBUF_DATA(osbuf));
4094 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_PWR_CMDID, NO_SYNC_WMIFLAG));
4098 wmi_get_txPwr_cmd(struct wmi_t *wmip)
4100 return wmi_simple_cmd(wmip, WMI_GET_TX_PWR_CMDID);
4103 u16 wmi_get_mapped_qos_queue(struct wmi_t *wmip, u8 trafficClass)
4108 activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
4115 wmi_get_roam_tbl_cmd(struct wmi_t *wmip)
4117 return wmi_simple_cmd(wmip, WMI_GET_ROAM_TBL_CMDID);
4121 wmi_get_roam_data_cmd(struct wmi_t *wmip, u8 roamDataType)
4124 u32 size = sizeof(u8);
4125 WMI_TARGET_ROAM_DATA *cmd;
4127 osbuf = A_NETBUF_ALLOC(size); /* no payload */
4128 if (osbuf == NULL) {
4132 A_NETBUF_PUT(osbuf, size);
4134 cmd = (WMI_TARGET_ROAM_DATA *)(A_NETBUF_DATA(osbuf));
4135 cmd->roamDataType = roamDataType;
4137 return (wmi_cmd_send(wmip, osbuf, WMI_GET_ROAM_DATA_CMDID,
4142 wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p,
4146 WMI_SET_ROAM_CTRL_CMD *cmd;
4148 osbuf = A_NETBUF_ALLOC(size);
4149 if (osbuf == NULL) {
4153 A_NETBUF_PUT(osbuf, size);
4155 cmd = (WMI_SET_ROAM_CTRL_CMD *)(A_NETBUF_DATA(osbuf));
4156 A_MEMZERO(cmd, size);
4158 memcpy(cmd, p, size);
4160 return (wmi_cmd_send(wmip, osbuf, WMI_SET_ROAM_CTRL_CMDID,
4165 wmi_set_powersave_timers_cmd(struct wmi_t *wmip,
4166 WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd,
4170 WMI_POWERSAVE_TIMERS_POLICY_CMD *cmd;
4172 /* These timers can't be zero */
4173 if(!pCmd->psPollTimeout || !pCmd->triggerTimeout ||
4174 !(pCmd->apsdTimPolicy == IGNORE_TIM_ALL_QUEUES_APSD ||
4175 pCmd->apsdTimPolicy == PROCESS_TIM_ALL_QUEUES_APSD) ||
4176 !(pCmd->simulatedAPSDTimPolicy == IGNORE_TIM_SIMULATED_APSD ||
4177 pCmd->simulatedAPSDTimPolicy == PROCESS_TIM_SIMULATED_APSD))
4180 osbuf = A_NETBUF_ALLOC(size);
4181 if (osbuf == NULL) {
4185 A_NETBUF_PUT(osbuf, size);
4187 cmd = (WMI_POWERSAVE_TIMERS_POLICY_CMD *)(A_NETBUF_DATA(osbuf));
4188 A_MEMZERO(cmd, size);
4190 memcpy(cmd, pCmd, size);
4192 return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID,
4197 wmi_set_access_params_cmd(struct wmi_t *wmip, u8 ac, u16 txop, u8 eCWmin,
4198 u8 eCWmax, u8 aifsn)
4201 WMI_SET_ACCESS_PARAMS_CMD *cmd;
4203 if ((eCWmin > WMI_MAX_CW_ACPARAM) || (eCWmax > WMI_MAX_CW_ACPARAM) ||
4204 (aifsn > WMI_MAX_AIFSN_ACPARAM) || (ac >= WMM_NUM_AC))
4209 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4210 if (osbuf == NULL) {
4214 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4216 cmd = (WMI_SET_ACCESS_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
4218 cmd->eCWmin = eCWmin;
4219 cmd->eCWmax = eCWmax;
4223 return (wmi_cmd_send(wmip, osbuf, WMI_SET_ACCESS_PARAMS_CMDID,
4228 wmi_set_retry_limits_cmd(struct wmi_t *wmip, u8 frameType,
4229 u8 trafficClass, u8 maxRetries,
4233 WMI_SET_RETRY_LIMITS_CMD *cmd;
4235 if ((frameType != MGMT_FRAMETYPE) && (frameType != CONTROL_FRAMETYPE) &&
4236 (frameType != DATA_FRAMETYPE))
4241 if (maxRetries > WMI_MAX_RETRIES) {
4245 if (frameType != DATA_FRAMETYPE) {
4249 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4250 if (osbuf == NULL) {
4254 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4256 cmd = (WMI_SET_RETRY_LIMITS_CMD *)(A_NETBUF_DATA(osbuf));
4257 cmd->frameType = frameType;
4258 cmd->trafficClass = trafficClass;
4259 cmd->maxRetries = maxRetries;
4260 cmd->enableNotify = enableNotify;
4262 return (wmi_cmd_send(wmip, osbuf, WMI_SET_RETRY_LIMITS_CMDID,
4267 wmi_get_current_bssid(struct wmi_t *wmip, u8 *bssid)
4269 if (bssid != NULL) {
4270 memcpy(bssid, wmip->wmi_bssid, ATH_MAC_LEN);
4275 wmi_set_opt_mode_cmd(struct wmi_t *wmip, u8 optMode)
4278 WMI_SET_OPT_MODE_CMD *cmd;
4280 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4281 if (osbuf == NULL) {
4285 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4287 cmd = (WMI_SET_OPT_MODE_CMD *)(A_NETBUF_DATA(osbuf));
4288 A_MEMZERO(cmd, sizeof(*cmd));
4289 cmd->optMode = optMode;
4291 return (wmi_cmd_send(wmip, osbuf, WMI_SET_OPT_MODE_CMDID,
4292 SYNC_BOTH_WMIFLAG));
4296 wmi_opt_tx_frame_cmd(struct wmi_t *wmip,
4304 WMI_OPT_TX_FRAME_CMD *cmd;
4305 osbuf = A_NETBUF_ALLOC(optIEDataLen + sizeof(*cmd));
4306 if (osbuf == NULL) {
4310 A_NETBUF_PUT(osbuf, (optIEDataLen + sizeof(*cmd)));
4312 cmd = (WMI_OPT_TX_FRAME_CMD *)(A_NETBUF_DATA(osbuf));
4313 A_MEMZERO(cmd, (optIEDataLen + sizeof(*cmd)-1));
4315 cmd->frmType = frmType;
4316 cmd->optIEDataLen = optIEDataLen;
4317 //cmd->optIEData = (u8 *)((int)cmd + sizeof(*cmd));
4318 memcpy(cmd->bssid, bssid, sizeof(cmd->bssid));
4319 memcpy(cmd->dstAddr, dstMacAddr, sizeof(cmd->dstAddr));
4320 memcpy(&cmd->optIEData[0], optIEData, optIEDataLen);
4322 return (wmi_cmd_send(wmip, osbuf, WMI_OPT_TX_FRAME_CMDID,
4327 wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, u16 intvl)
4330 WMI_BEACON_INT_CMD *cmd;
4332 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4333 if (osbuf == NULL) {
4337 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4339 cmd = (WMI_BEACON_INT_CMD *)(A_NETBUF_DATA(osbuf));
4340 A_MEMZERO(cmd, sizeof(*cmd));
4341 cmd->beaconInterval = intvl;
4343 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BEACON_INT_CMDID,
4349 wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, u16 voicePktSize)
4352 WMI_SET_VOICE_PKT_SIZE_CMD *cmd;
4354 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4355 if (osbuf == NULL) {
4359 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4361 cmd = (WMI_SET_VOICE_PKT_SIZE_CMD *)(A_NETBUF_DATA(osbuf));
4362 A_MEMZERO(cmd, sizeof(*cmd));
4363 cmd->voicePktSize = voicePktSize;
4365 return (wmi_cmd_send(wmip, osbuf, WMI_SET_VOICE_PKT_SIZE_CMDID,
4371 wmi_set_max_sp_len_cmd(struct wmi_t *wmip, u8 maxSPLen)
4374 WMI_SET_MAX_SP_LEN_CMD *cmd;
4376 /* maxSPLen is a two-bit value. If user trys to set anything
4377 * other than this, then its invalid
4379 if(maxSPLen & ~0x03)
4382 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4383 if (osbuf == NULL) {
4387 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4389 cmd = (WMI_SET_MAX_SP_LEN_CMD *)(A_NETBUF_DATA(osbuf));
4390 A_MEMZERO(cmd, sizeof(*cmd));
4391 cmd->maxSPLen = maxSPLen;
4393 return (wmi_cmd_send(wmip, osbuf, WMI_SET_MAX_SP_LEN_CMDID,
4397 u8 wmi_determine_userPriority(
4402 iphdr *ipHdr = (iphdr *)pkt;
4404 /* Determine IPTOS priority */
4407 * (Refer Pg 57 WMM-test-plan-v1.2)
4409 * : DSCP(6-bits) ECN(2-bits)
4410 * : DSCP - P2 P1 P0 X X X
4411 * where (P2 P1 P0) form 802.1D
4413 ipPri = ipHdr->ip_tos >> 5;
4416 if ((layer2Pri & 0x7) > ipPri)
4417 return ((u8)layer2Pri & 0x7);
4422 u8 convert_userPriority_to_trafficClass(u8 userPriority)
4424 return (up_to_ac[userPriority & 0x7]);
4427 u8 wmi_get_power_mode_cmd(struct wmi_t *wmip)
4429 return wmip->wmi_powerMode;
4433 wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, int tspecCompliance)
4437 #define TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF (~0)
4438 #define TSPEC_SERVICE_START_TIME_ATHEROS_DEF 0
4439 #define TSPEC_MAX_BURST_SIZE_ATHEROS_DEF 0
4440 #define TSPEC_DELAY_BOUND_ATHEROS_DEF 0
4441 #define TSPEC_MEDIUM_TIME_ATHEROS_DEF 0
4442 #define TSPEC_SBA_ATHEROS_DEF 0x2000 /* factor is 1 */
4444 /* Verify TSPEC params for ATHEROS compliance */
4445 if(tspecCompliance == ATHEROS_COMPLIANCE) {
4446 if ((pCmd->suspensionInt != TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF) ||
4447 (pCmd->serviceStartTime != TSPEC_SERVICE_START_TIME_ATHEROS_DEF) ||
4448 (pCmd->minDataRate != pCmd->meanDataRate) ||
4449 (pCmd->minDataRate != pCmd->peakDataRate) ||
4450 (pCmd->maxBurstSize != TSPEC_MAX_BURST_SIZE_ATHEROS_DEF) ||
4451 (pCmd->delayBound != TSPEC_DELAY_BOUND_ATHEROS_DEF) ||
4452 (pCmd->sba != TSPEC_SBA_ATHEROS_DEF) ||
4453 (pCmd->mediumTime != TSPEC_MEDIUM_TIME_ATHEROS_DEF)) {
4455 A_DPRINTF(DBG_WMI, (DBGFMT "Invalid TSPEC params\n", DBGARG));
4456 //A_PRINTF("%s: Invalid TSPEC params\n", __func__);
4464 #ifdef CONFIG_HOST_TCMD_SUPPORT
4466 wmi_tcmd_test_report_rx(struct wmi_t *wmip, u8 *datap, int len)
4469 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
4474 #endif /* CONFIG_HOST_TCMD_SUPPORT*/
4477 wmi_set_authmode_cmd(struct wmi_t *wmip, u8 mode)
4480 WMI_SET_AUTH_MODE_CMD *cmd;
4482 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4483 if (osbuf == NULL) {
4487 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4489 cmd = (WMI_SET_AUTH_MODE_CMD *)(A_NETBUF_DATA(osbuf));
4490 A_MEMZERO(cmd, sizeof(*cmd));
4493 return (wmi_cmd_send(wmip, osbuf, WMI_SET_AUTH_MODE_CMDID,
4498 wmi_set_reassocmode_cmd(struct wmi_t *wmip, u8 mode)
4501 WMI_SET_REASSOC_MODE_CMD *cmd;
4503 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4504 if (osbuf == NULL) {
4508 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4510 cmd = (WMI_SET_REASSOC_MODE_CMD *)(A_NETBUF_DATA(osbuf));
4511 A_MEMZERO(cmd, sizeof(*cmd));
4514 return (wmi_cmd_send(wmip, osbuf, WMI_SET_REASSOC_MODE_CMDID,
4519 wmi_set_lpreamble_cmd(struct wmi_t *wmip, u8 status, u8 preamblePolicy)
4522 WMI_SET_LPREAMBLE_CMD *cmd;
4524 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4525 if (osbuf == NULL) {
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,
4541 wmi_set_rts_cmd(struct wmi_t *wmip, u16 threshold)
4544 WMI_SET_RTS_CMD *cmd;
4546 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4547 if (osbuf == NULL) {
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,
4562 wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status)
4565 WMI_SET_WMM_CMD *cmd;
4567 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4568 if (osbuf == NULL) {
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,
4584 wmi_set_qos_supp_cmd(struct wmi_t *wmip, u8 status)
4587 WMI_SET_QOS_SUPP_CMD *cmd;
4589 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4590 if (osbuf == NULL) {
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,
4605 wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG cfg)
4608 WMI_SET_WMM_TXOP_CMD *cmd;
4610 if( !((cfg == WMI_TXOP_DISABLED) || (cfg == WMI_TXOP_ENABLED)) )
4613 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4614 if (osbuf == NULL) {
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,
4630 wmi_set_country(struct wmi_t *wmip, u8 *countryCode)
4633 WMI_AP_SET_COUNTRY_CMD *cmd;
4635 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4636 if (osbuf == NULL) {
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,
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)
4661 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
4663 osbuf= A_NETBUF_ALLOC(len);
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,
4679 wmi_set_bt_status_cmd(struct wmi_t *wmip, u8 streamType, u8 status)
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) {
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,
4703 wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd)
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) {
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,
4765 wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd)
4768 WMI_SET_BTCOEX_FE_ANT_CMD *alloc_cmd;
4770 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4771 if (osbuf == NULL) {
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,
4785 wmi_set_btcoex_colocated_bt_dev_cmd(struct wmi_t *wmip,
4786 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD * cmd)
4789 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD *alloc_cmd;
4791 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4792 if (osbuf == NULL) {
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,
4806 wmi_set_btcoex_btinquiry_page_config_cmd(struct wmi_t *wmip,
4807 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD* cmd)
4810 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *alloc_cmd;
4812 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4813 if (osbuf == NULL) {
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,
4826 wmi_set_btcoex_sco_config_cmd(struct wmi_t *wmip,
4827 WMI_SET_BTCOEX_SCO_CONFIG_CMD * cmd)
4830 WMI_SET_BTCOEX_SCO_CONFIG_CMD *alloc_cmd;
4832 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4833 if (osbuf == NULL) {
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 ,
4846 wmi_set_btcoex_a2dp_config_cmd(struct wmi_t *wmip,
4847 WMI_SET_BTCOEX_A2DP_CONFIG_CMD * cmd)
4850 WMI_SET_BTCOEX_A2DP_CONFIG_CMD *alloc_cmd;
4852 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4853 if (osbuf == NULL) {
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 ,
4866 wmi_set_btcoex_aclcoex_config_cmd(struct wmi_t *wmip,
4867 WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD * cmd)
4870 WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD *alloc_cmd;
4872 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4873 if (osbuf == NULL) {
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 ,
4886 wmi_set_btcoex_debug_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_DEBUG_CMD * cmd)
4889 WMI_SET_BTCOEX_DEBUG_CMD *alloc_cmd;
4891 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4892 if (osbuf == NULL) {
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 ,
4905 wmi_set_btcoex_bt_operating_status_cmd(struct wmi_t * wmip,
4906 WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD * cmd)
4909 WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *alloc_cmd;
4911 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4912 if (osbuf == NULL) {
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 ,
4925 wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * cmd)
4928 WMI_GET_BTCOEX_CONFIG_CMD *alloc_cmd;
4930 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4931 if (osbuf == NULL) {
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 ,
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)
4955 WMI_GET_KEEPALIVE_CMD *cmd;
4956 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4957 if (osbuf == NULL) {
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,
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)
4976 WMI_SET_KEEPALIVE_CMD *cmd;
4978 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4979 if (osbuf == NULL) {
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,
4995 wmi_set_params_cmd(struct wmi_t *wmip, u32 opcode, u32 length, char *buffer)
4998 WMI_SET_PARAMS_CMD *cmd;
5000 osbuf = A_NETBUF_ALLOC(sizeof(*cmd) + length);
5001 if (osbuf == NULL) {
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,
5019 wmi_set_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4)
5022 WMI_SET_MCAST_FILTER_CMD *cmd;
5024 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5025 if (osbuf == NULL) {
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,
5045 wmi_del_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4)
5048 WMI_SET_MCAST_FILTER_CMD *cmd;
5050 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5051 if (osbuf == NULL) {
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,
5070 wmi_mcast_filter_cmd(struct wmi_t *wmip, u8 enable)
5073 WMI_MCAST_FILTER_CMD *cmd;
5075 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5076 if (osbuf == NULL) {
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,
5090 wmi_set_appie_cmd(struct wmi_t *wmip, u8 mgmtFrmType, u8 ieLen,
5094 WMI_SET_APPIE_CMD *cmd;
5097 cmdLen = sizeof(*cmd) + ieLen - 1;
5098 osbuf = A_NETBUF_ALLOC(cmdLen);
5099 if (osbuf == NULL) {
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;
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)
5121 osbuf = A_NETBUF_ALLOC(dataLen);
5122 if (osbuf == NULL) {
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) {
5140 return(wmi_rateTable[(u32) rateindex][0]);
5145 wmi_node_return (struct wmi_t *wmip, bss_t *bss)
5149 wlan_node_return (&wmip->wmi_scan_table, bss);
5154 wmi_set_nodeage(struct wmi_t *wmip, u32 nodeAge)
5156 wlan_set_nodeage(&wmip->wmi_scan_table,nodeAge);
5160 wmi_find_Ssidnode (struct wmi_t *wmip, u8 *pSsid,
5161 u32 ssidLength, bool bIsWPA2, bool bMatchSSID)
5164 node = wlan_find_Ssidnode (&wmip->wmi_scan_table, pSsid,
5165 ssidLength, bIsWPA2, bMatchSSID);
5172 wmi_refresh_scan_table (struct wmi_t *wmip)
5174 wlan_refresh_inactive_nodes (&wmip->wmi_scan_table);
5179 wmi_free_allnodes(struct wmi_t *wmip)
5181 wlan_free_allnodes(&wmip->wmi_scan_table);
5185 wmi_find_node(struct wmi_t *wmip, const u8 *macaddr)
5188 ni=wlan_find_node(&wmip->wmi_scan_table,macaddr);
5193 wmi_free_node(struct wmi_t *wmip, const u8 *macaddr)
5197 ni=wlan_find_node(&wmip->wmi_scan_table,macaddr);
5199 wlan_node_reclaim(&wmip->wmi_scan_table, ni);
5206 wmi_dset_open_reply(struct wmi_t *wmip,
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) {
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,
5241 wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, u8 *datap, u32 len)
5243 WMI_PMKID_LIST_REPLY *reply;
5246 if (len < sizeof(WMI_PMKID_LIST_REPLY)) {
5249 reply = (WMI_PMKID_LIST_REPLY *)datap;
5250 expected_len = sizeof(reply->numPMKID) + reply->numPMKID * WMI_PMKID_LEN;
5252 if (len < expected_len) {
5256 A_WMI_PMKID_LIST_EVENT(wmip->wmi_devt, reply->numPMKID,
5257 reply->pmkidList, reply->bssidList[0]);
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)) {
5271 reply = (WMI_SET_PARAMS_REPLY *)datap;
5273 if (0 == reply->status)
5286 #ifdef CONFIG_HOST_DSET_SUPPORT
5288 wmi_dset_data_reply(struct wmi_t *wmip,
5297 WMIX_DSETDATA_REPLY_CMD *data_reply;
5300 size = sizeof(*data_reply) + length;
5302 if (size <= length) {
5307 (DBGFMT "Enter - length=%d status=%d\n", DBGARG, length, status));
5309 osbuf = A_NETBUF_ALLOC(size);
5310 if (osbuf == NULL) {
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;
5323 if (a_copy_from_user(data_reply->buf, user_buf, length)) {
5324 A_NETBUF_FREE(osbuf);
5329 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETDATA_REPLY_CMDID,
5332 #endif /* CONFIG_HOST_DSET_SUPPORT */
5335 wmi_set_wsc_status_cmd(struct wmi_t *wmip, u32 status)
5340 wps_enable = status;
5342 osbuf = a_netbuf_alloc(sizeof(1));
5343 if (osbuf == NULL) {
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,
5357 #if defined(CONFIG_TARGET_PROFILE_SUPPORT)
5359 wmi_prof_cfg_cmd(struct wmi_t *wmip,
5364 WMIX_PROF_CFG_CMD *cmd;
5366 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5367 if (osbuf == NULL) {
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;
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)
5385 WMIX_PROF_ADDR_SET_CMD *cmd;
5387 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5388 if (osbuf == NULL) {
5392 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5394 cmd = (WMIX_PROF_ADDR_SET_CMD *)(A_NETBUF_DATA(osbuf));
5395 A_MEMZERO(cmd, sizeof(*cmd));
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 */
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;
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);
5433 #endif /* CONFIG_TARGET_PROFILE_SUPPORT */
5435 #ifdef OS_ROAM_MANAGEMENT
5437 #define ETHERNET_MAC_ADDRESS_LENGTH 6
5440 wmi_scan_indication (struct wmi_t *wmip)
5442 struct ieee80211_node_table *nt;
5448 PNDIS_802_11_BSSID_SCAN_INFO psi;
5450 NDIS_802_11_FIXED_IEs *pFixed;
5451 NDIS_802_11_VARIABLE_IEs *pVar;
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;
5465 gen = nt->nt_si_gen;
5467 size = offsetof(struct ar6kScanIndication, slist) +
5468 offsetof(NDIS_802_11_BSSID_SCAN_INFO_LIST, BssidScanInfo);
5472 IEEE80211_NODE_LOCK(nt);
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);
5481 if (bss->ni_cie.ie_rsn) {
5482 bsssize = bsssize + bss->ni_cie.ie_rsn[1] + 2;
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;
5500 // RETAILMSG(1, (L"AR6K: scan indication: 0 bss\n"));
5501 ar6000_scan_indication (wmip->wmi_devt, NULL, 0);
5502 IEEE80211_NODE_UNLOCK (nt);
5506 pAr6kScanIndEvent = A_MALLOC(size);
5508 if (NULL == pAr6kScanIndEvent)
5510 IEEE80211_NODE_UNLOCK(nt);
5514 A_MEMZERO(pAr6kScanIndEvent, size);
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;
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);
5536 if (bss->ni_cie.ie_rsn) {
5537 bsssize = bsssize + bss->ni_cie.ie_rsn[1] + 2;
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;
5560 // Format of SSID IE is:
5563 // SSID (Length octets)
5565 // Validation of the IE should have occurred within WMI.
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;
5583 psi->Bssid.NetworkTypeInUse = Ndis802_11DS;
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;
5597 pie = bss->ni_cie.ie_rates;
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));
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);
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);
5654 u8 ar6000_get_upper_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh,
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];
5671 u8 ar6000_get_lower_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh,
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];
5688 wmi_send_rssi_threshold_params(struct wmi_t *wmip,
5689 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
5693 WMI_RSSI_THRESHOLD_PARAMS_CMD *cmd;
5695 size = sizeof (*cmd);
5697 osbuf = A_NETBUF_ALLOC(size);
5698 if (osbuf == NULL) {
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,
5712 wmi_send_snr_threshold_params(struct wmi_t *wmip,
5713 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
5717 WMI_SNR_THRESHOLD_PARAMS_CMD *cmd;
5719 size = sizeof (*cmd);
5721 osbuf = A_NETBUF_ALLOC(size);
5722 if (osbuf == NULL) {
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,
5736 wmi_set_target_event_report_cmd(struct wmi_t *wmip, WMI_SET_TARGET_EVENT_REPORT_CMD* cmd)
5739 WMI_SET_TARGET_EVENT_REPORT_CMD* alloc_cmd;
5741 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5742 if (osbuf == NULL) {
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,
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);
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);
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);
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);
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);
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);
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);
5830 ////////////////////////////////////////////////////////////////////////////////
5832 //// AP mode functions ////
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)
5849 WMI_CONNECT_CMD *cm;
5851 osbuf = A_NETBUF_ALLOC(sizeof(*cm));
5852 if (osbuf == NULL) {
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)
5875 WMI_AP_HIDDEN_SSID_CMD *hs;
5877 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_HIDDEN_SSID_CMD));
5878 if (osbuf == NULL) {
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
5901 wmi_ap_set_num_sta(struct wmi_t *wmip, u8 num_sta)
5904 WMI_AP_SET_NUM_STA_CMD *ns;
5906 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_NUM_STA_CMD));
5907 if (osbuf == NULL) {
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)
5932 WMI_AP_ACL_MAC_CMD *a;
5934 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_ACL_MAC_CMD));
5935 if (osbuf == NULL) {
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)
5958 WMI_AP_SET_MLME_CMD *mlme;
5960 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_MLME_CMD));
5961 if (osbuf == NULL) {
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));
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));
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)) {
5984 ev = (WMI_PSPOLL_EVENT *)datap;
5986 A_WMI_PSPOLL_EVENT(wmip->wmi_devt, ev->aid);
5991 wmi_dtimexpiry_event_rx(struct wmi_t *wmip, u8 *datap,int len)
5993 A_WMI_DTIMEXPIRY_EVENT(wmip->wmi_devt);
5999 wmi_wapi_rekey_event_rx(struct wmi_t *wmip, u8 *datap,int len)
6008 A_WMI_WAPI_REKEY_EVENT(wmip->wmi_devt, *ev, &ev[1]);
6014 wmi_set_pvb_cmd(struct wmi_t *wmip, u16 aid, bool flag)
6016 WMI_AP_SET_PVB_CMD *cmd;
6019 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_PVB_CMD));
6020 if (osbuf == NULL) {
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));
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;
6040 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_CONN_INACT_CMD));
6041 if (osbuf == NULL) {
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;
6060 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_PROT_SCAN_TIME_CMD));
6061 if (osbuf == NULL) {
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;
6081 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_DTIM_CMD));
6082 if (osbuf == NULL) {
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));
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)
6107 WMI_AP_ACL_POLICY_CMD *po;
6109 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_ACL_POLICY_CMD));
6110 if (osbuf == NULL) {
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)
6127 WMI_AP_SET_11BG_RATESET_CMD *rs;
6129 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_11BG_RATESET_CMD));
6130 if (osbuf == NULL) {
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)
6147 WMI_SET_HT_CAP_CMD *htCap;
6150 osbuf = A_NETBUF_ALLOC(sizeof(*htCap));
6151 if (osbuf == NULL) {
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,
6169 wmi_set_ht_op_cmd(struct wmi_t *wmip, u8 sta_chan_width)
6172 WMI_SET_HT_OP_CMD *htInfo;
6174 osbuf = A_NETBUF_ALLOC(sizeof(*htInfo));
6175 if (osbuf == NULL) {
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,
6190 wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, u32 *pMaskArray)
6193 WMI_SET_TX_SELECT_RATES_CMD *pData;
6195 osbuf = A_NETBUF_ALLOC(sizeof(*pData));
6196 if (osbuf == NULL) {
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,
6211 wmi_send_hci_cmd(struct wmi_t *wmip, u8 *buf, u16 sz)
6216 osbuf = A_NETBUF_ALLOC(sizeof(*cmd) + sz);
6217 if (osbuf == NULL) {
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)
6233 WMI_ALLOW_AGGR_CMD *cmd;
6235 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6236 if (osbuf == NULL) {
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)
6253 WMI_ADDBA_REQ_CMD *cmd;
6255 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6256 if (osbuf == NULL) {
6260 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6262 cmd = (WMI_ADDBA_REQ_CMD *)(A_NETBUF_DATA(osbuf));
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)
6272 WMI_DELBA_REQ_CMD *cmd;
6274 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6275 if (osbuf == NULL) {
6279 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6281 cmd = (WMI_DELBA_REQ_CMD *)(A_NETBUF_DATA(osbuf));
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)
6294 WMI_RX_FRAME_FORMAT_CMD *cmd;
6296 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6297 if (osbuf == NULL) {
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)
6317 WMI_SET_THIN_MODE_CMD *cmd;
6319 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6320 if (osbuf == NULL) {
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)
6338 WMI_SET_BT_WLAN_CONN_PRECEDENCE *cmd;
6340 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6341 if (osbuf == NULL) {
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,
6356 wmi_set_pmk_cmd(struct wmi_t *wmip, u8 *pmk)
6361 osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_PMK_CMD));
6362 if (osbuf == NULL) {
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)
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) {
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)
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,
6419 wmi_find_matching_Ssidnode (struct wmi_t *wmip, u8 *pSsid,
6421 u32 dot11AuthMode, u32 authMode,
6422 u32 pairwiseCryptoType, u32 grpwiseCryptoTyp)
6425 node = wlan_find_matching_Ssidnode (&wmip->wmi_scan_table, pSsid,
6426 ssidLength, dot11AuthMode, authMode, pairwiseCryptoType, grpwiseCryptoTyp);
6431 u16 wmi_ieee2freq (int chan)
6434 freq = wlan_ieee2freq (chan);
6439 u32 wmi_freq2ieee (u16 freq)
6442 chan = wlan_freq2ieee (freq);