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 //==============================================================================
35 #include <ieee80211.h>
36 #include <ieee80211_node.h>
41 #include "a_drv_api.h"
42 #define ATH_MODULE_NAME wmi
44 #include "dbglog_api.h"
47 #define ATH_DEBUG_WMI ATH_DEBUG_MAKE_MODULE_MASK(0)
49 #ifdef ATH_DEBUG_MODULE
51 static struct ath_debug_mask_description wmi_debug_desc[] = {
52 { ATH_DEBUG_WMI , "General WMI Tracing"},
55 ATH_DEBUG_INSTANTIATE_MODULE_VAR(wmi,
57 "Wireless Module Interface",
58 ATH_DEBUG_MASK_DEFAULTS,
59 ATH_DEBUG_DESCRIPTION_COUNT(wmi_debug_desc),
65 #define DBGARG _A_FUNCNAME_
66 #define DBGFMT "%s() : "
67 #define DBG_WMI ATH_DEBUG_WMI
68 #define DBG_ERROR ATH_DEBUG_ERR
69 #define DBG_WMI2 ATH_DEBUG_WMI
70 #define A_DPRINTF AR_DEBUG_PRINTF
73 static int wmi_ready_event_rx(struct wmi_t *wmip, u8 *datap, int len);
75 static int wmi_connect_event_rx(struct wmi_t *wmip, u8 *datap,
77 static int wmi_disconnect_event_rx(struct wmi_t *wmip, u8 *datap,
80 static int wmi_tkip_micerr_event_rx(struct wmi_t *wmip, u8 *datap,
82 static int wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap,
84 static int wmi_opt_frame_event_rx(struct wmi_t *wmip, u8 *datap,
86 static int wmi_pstream_timeout_event_rx(struct wmi_t *wmip, u8 *datap,
88 static int wmi_sync_point(struct wmi_t *wmip);
90 static int wmi_bitrate_reply_rx(struct wmi_t *wmip, u8 *datap,
92 static int wmi_ratemask_reply_rx(struct wmi_t *wmip, u8 *datap,
94 static int wmi_channelList_reply_rx(struct wmi_t *wmip, u8 *datap,
96 static int wmi_regDomain_event_rx(struct wmi_t *wmip, u8 *datap,
98 static int wmi_txPwr_reply_rx(struct wmi_t *wmip, u8 *datap, int len);
99 static int wmi_neighborReport_event_rx(struct wmi_t *wmip, u8 *datap,
102 static int wmi_dset_open_req_rx(struct wmi_t *wmip, u8 *datap,
104 #ifdef CONFIG_HOST_DSET_SUPPORT
105 static int wmi_dset_close_rx(struct wmi_t *wmip, u8 *datap, int len);
106 static int wmi_dset_data_req_rx(struct wmi_t *wmip, u8 *datap,
108 #endif /* CONFIG_HOST_DSET_SUPPORT */
111 static int wmi_scanComplete_rx(struct wmi_t *wmip, u8 *datap,
113 static int wmi_errorEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
114 static int wmi_statsEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
115 static int wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
116 static int wmi_hbChallengeResp_rx(struct wmi_t *wmip, u8 *datap, int len);
117 static int wmi_reportErrorEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
118 static int wmi_cac_event_rx(struct wmi_t *wmip, u8 *datap, int len);
119 static int wmi_channel_change_event_rx(struct wmi_t *wmip, u8 *datap, int len);
120 static int wmi_roam_tbl_event_rx(struct wmi_t *wmip, u8 *datap,
122 static int wmi_roam_data_event_rx(struct wmi_t *wmip, u8 *datap,
124 static int wmi_get_wow_list_event_rx(struct wmi_t *wmip, u8 *datap,
127 wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, u8 *datap, u32 len);
130 wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, u32 len);
133 wmi_acm_reject_event_rx(struct wmi_t *wmip, u8 *datap, u32 len);
135 #ifdef CONFIG_HOST_GPIO_SUPPORT
136 static int wmi_gpio_intr_rx(struct wmi_t *wmip, u8 *datap, int len);
137 static int wmi_gpio_data_rx(struct wmi_t *wmip, u8 *datap, int len);
138 static int wmi_gpio_ack_rx(struct wmi_t *wmip, u8 *datap, int len);
139 #endif /* CONFIG_HOST_GPIO_SUPPORT */
141 #ifdef CONFIG_HOST_TCMD_SUPPORT
143 wmi_tcmd_test_report_rx(struct wmi_t *wmip, u8 *datap, int len);
147 wmi_txRetryErrEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
150 wmi_snrThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
153 wmi_lqThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
156 wmi_is_bitrate_index_valid(struct wmi_t *wmip, s32 rateIndex);
159 wmi_aplistEvent_rx(struct wmi_t *wmip, u8 *datap, int len);
162 wmi_dbglog_event_rx(struct wmi_t *wmip, u8 *datap, int len);
164 static int wmi_keepalive_reply_rx(struct wmi_t *wmip, u8 *datap, int len);
166 int wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId,
167 WMI_SYNC_FLAG syncflag);
169 u8 ar6000_get_upper_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, u32 size);
170 u8 ar6000_get_lower_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, u32 size);
172 void wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd);
173 void wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd);
174 static int wmi_send_rssi_threshold_params(struct wmi_t *wmip,
175 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd);
176 static int wmi_send_snr_threshold_params(struct wmi_t *wmip,
177 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd);
178 #if defined(CONFIG_TARGET_PROFILE_SUPPORT)
180 wmi_prof_count_rx(struct wmi_t *wmip, u8 *datap, int len);
181 #endif /* CONFIG_TARGET_PROFILE_SUPPORT */
183 static int wmi_pspoll_event_rx(struct wmi_t *wmip, u8 *datap,
185 static int wmi_dtimexpiry_event_rx(struct wmi_t *wmip, u8 *datap,
188 static int wmi_peer_node_event_rx (struct wmi_t *wmip, u8 *datap,
190 #ifdef ATH_AR6K_11N_SUPPORT
191 static int wmi_addba_req_event_rx(struct wmi_t *, u8 *, int);
192 static int wmi_addba_resp_event_rx(struct wmi_t *, u8 *, int);
193 static int wmi_delba_req_event_rx(struct wmi_t *, u8 *, int);
194 static int wmi_btcoex_config_event_rx(struct wmi_t *wmip, u8 *datap, int len);
195 static int wmi_btcoex_stats_event_rx(struct wmi_t *wmip, u8 *datap, int len);
197 static int wmi_hci_event_rx(struct wmi_t *, u8 *, int);
200 static int wmi_wapi_rekey_event_rx(struct wmi_t *wmip, u8 *datap,
204 #if defined(UNDER_CE)
205 #if defined(NDIS51_MINIPORT)
206 unsigned int processDot11Hdr = 0;
208 unsigned int processDot11Hdr = 1;
211 extern unsigned int processDot11Hdr;
215 static const s32 wmi_rateTable[][2] = {
216 //{W/O SGI, with SGI}
247 #define MODE_A_SUPPORT_RATE_START ((s32) 4)
248 #define MODE_A_SUPPORT_RATE_STOP ((s32) 11)
250 #define MODE_GONLY_SUPPORT_RATE_START MODE_A_SUPPORT_RATE_START
251 #define MODE_GONLY_SUPPORT_RATE_STOP MODE_A_SUPPORT_RATE_STOP
253 #define MODE_B_SUPPORT_RATE_START ((s32) 0)
254 #define MODE_B_SUPPORT_RATE_STOP ((s32) 3)
256 #define MODE_G_SUPPORT_RATE_START ((s32) 0)
257 #define MODE_G_SUPPORT_RATE_STOP ((s32) 11)
259 #define MODE_GHT20_SUPPORT_RATE_START ((s32) 0)
260 #define MODE_GHT20_SUPPORT_RATE_STOP ((s32) 19)
262 #define MAX_NUMBER_OF_SUPPORT_RATES (MODE_GHT20_SUPPORT_RATE_STOP + 1)
264 /* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */
265 const u8 up_to_ac[]= {
276 #include "athstartpack.h"
278 /* This stuff is used when we want a simple layer-3 visibility */
279 typedef PREPACK struct _iphdr {
280 u8 ip_ver_hdrlen; /* version and hdr length */
281 u8 ip_tos; /* type of service */
282 u16 ip_len; /* total length */
283 u16 ip_id; /* identification */
284 s16 ip_off; /* fragment offset field */
285 #define IP_DF 0x4000 /* dont fragment flag */
286 #define IP_MF 0x2000 /* more fragments flag */
287 #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
288 u8 ip_ttl; /* time to live */
289 u8 ip_p; /* protocol */
290 u16 ip_sum; /* checksum */
291 u8 ip_src[4]; /* source and dest address */
295 #include "athendpack.h"
297 static s16 rssi_event_value = 0;
298 static s16 snr_event_value = 0;
300 bool is_probe_ssid = false;
307 A_REGISTER_MODULE_DEBUG_INFO(wmi);
309 wmip = A_MALLOC (sizeof(struct wmi_t));
313 A_MEMZERO(wmip, sizeof(struct wmi_t ));
317 A_MUTEX_INIT(&wmip->wmi_lock);
319 wmip->wmi_devt = devt;
320 wlan_node_table_init(wmip, &wmip->wmi_scan_table);
321 wmi_qos_state_init(wmip);
323 wmip->wmi_powerMode = REC_POWER;
324 wmip->wmi_phyMode = WMI_11G_MODE;
326 wmip->wmi_pair_crypto_type = NONE_CRYPT;
327 wmip->wmi_grp_crypto_type = NONE_CRYPT;
329 wmip->wmi_ht_allowed[A_BAND_24GHZ] = 1;
330 wmip->wmi_ht_allowed[A_BAND_5GHZ] = 1;
336 wmi_qos_state_init(struct wmi_t *wmip)
345 /* Initialize QoS States */
346 wmip->wmi_numQoSStream = 0;
348 wmip->wmi_fatPipeExists = 0;
350 for (i=0; i < WMM_NUM_AC; i++) {
351 wmip->wmi_streamExistsForAC[i]=0;
356 A_WMI_SET_NUMDATAENDPTS(wmip->wmi_devt, 1);
360 wmi_set_control_ep(struct wmi_t * wmip, HTC_ENDPOINT_ID eid)
362 A_ASSERT( eid != ENDPOINT_UNUSED);
363 wmip->wmi_endpoint_id = eid;
367 wmi_get_control_ep(struct wmi_t * wmip)
369 return(wmip->wmi_endpoint_id);
373 wmi_shutdown(struct wmi_t *wmip)
376 wlan_node_table_cleanup(&wmip->wmi_scan_table);
377 if (A_IS_MUTEX_VALID(&wmip->wmi_lock)) {
379 DELETE_WMI_LOCK(&wmip);
381 A_MUTEX_DELETE(&wmip->wmi_lock);
389 * performs DIX to 802.3 encapsulation for transmit packets.
390 * uses passed in buffer. Returns buffer or NULL if failed.
391 * Assumes the entire DIX header is contigous and that there is
392 * enough room in the buffer for a 802.3 mac header and LLC+SNAP headers.
395 wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf)
400 ATH_LLC_SNAP_HDR *llcHdr;
402 A_ASSERT(osbuf != NULL);
404 if (A_NETBUF_HEADROOM(osbuf) <
405 (sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR)))
410 datap = A_NETBUF_DATA(osbuf);
412 typeorlen = *(u16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN);
414 if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) {
416 * packet is already in 802.3 format - return success
418 A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG));
423 * Save mac fields and length to be inserted later
425 memcpy(macHdr.dstMac, datap, ATH_MAC_LEN);
426 memcpy(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN);
427 macHdr.typeOrLen = A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) +
428 sizeof(ATH_LLC_SNAP_HDR));
431 * Make room for LLC+SNAP headers
433 if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != 0) {
436 datap = A_NETBUF_DATA(osbuf);
438 memcpy(datap, &macHdr, sizeof (ATH_MAC_HDR));
440 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR));
444 llcHdr->orgCode[0] = 0x0;
445 llcHdr->orgCode[1] = 0x0;
446 llcHdr->orgCode[2] = 0x0;
447 llcHdr->etherType = typeorlen;
452 int wmi_meta_add(struct wmi_t *wmip, void *osbuf, u8 *pVersion,void *pTxMetaS)
457 case WMI_META_VERSION_1:
459 WMI_TX_META_V1 *pV1= NULL;
460 A_ASSERT(osbuf != NULL);
461 if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != 0) {
465 pV1 = (WMI_TX_META_V1 *)A_NETBUF_DATA(osbuf);
466 /* the pktID is used in conjunction with txComplete messages
467 * allowing the target to notify which tx requests have been
468 * completed and how. */
470 /* the ratePolicyID allows the host to specify which rate policy
471 * to use for transmitting this packet. 0 means use default behavior. */
472 pV1->ratePolicyID = 0;
473 A_ASSERT(pVersion != NULL);
474 /* the version must be used to populate the meta field of the WMI_DATA_HDR */
475 *pVersion = WMI_META_VERSION_1;
478 #ifdef CONFIG_CHECKSUM_OFFLOAD
479 case WMI_META_VERSION_2:
481 WMI_TX_META_V2 *pV2 ;
482 A_ASSERT(osbuf != NULL);
483 if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != 0) {
486 pV2 = (WMI_TX_META_V2 *)A_NETBUF_DATA(osbuf);
487 memcpy(pV2,(WMI_TX_META_V2 *)pTxMetaS,sizeof(WMI_TX_META_V2));
496 /* Adds a WMI data header */
498 wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, u8 msgType, bool bMoreData,
499 WMI_DATA_HDR_DATA_TYPE data_type,u8 metaVersion, void *pTxMetaS)
502 // u8 metaVersion = 0;
505 A_ASSERT(osbuf != NULL);
507 /* adds the meta data field after the wmi data hdr. If metaVersion
508 * is returns 0 then no meta field was added. */
509 if ((status = wmi_meta_add(wmip, osbuf, &metaVersion,pTxMetaS)) != 0) {
513 if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != 0) {
517 dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf);
518 A_MEMZERO(dtHdr, sizeof(WMI_DATA_HDR));
520 WMI_DATA_HDR_SET_MSG_TYPE(dtHdr, msgType);
521 WMI_DATA_HDR_SET_DATA_TYPE(dtHdr, data_type);
524 WMI_DATA_HDR_SET_MORE_BIT(dtHdr);
527 WMI_DATA_HDR_SET_META(dtHdr, metaVersion);
534 u8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, u32 layer2Priority, bool wmmEnabled)
537 u8 trafficClass = WMM_AC_BE;
538 u16 ipType = IP_ETHERTYPE;
542 u32 hdrsize, metasize;
543 ATH_LLC_SNAP_HDR *llcHdr;
545 WMI_CREATE_PSTREAM_CMD cmd;
547 A_ASSERT(osbuf != NULL);
550 // Initialize header size
554 datap = A_NETBUF_DATA(osbuf);
555 dtHdr = (WMI_DATA_HDR *)datap;
556 metasize = (WMI_DATA_HDR_GET_META(dtHdr))? WMI_MAX_TX_META_SZ : 0;
560 /* If WMM is disabled all traffic goes as BE traffic */
567 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32));
568 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) + metasize +
575 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) + metasize +
576 sizeof(ATH_MAC_HDR));
579 if (llcHdr->etherType == A_CPU2BE16(ipType))
581 /* Extract the endpoint info from the TOS field in the IP header */
583 userPriority = wmi_determine_userPriority (((u8 *)llcHdr) + sizeof(ATH_LLC_SNAP_HDR),layer2Priority);
587 userPriority = layer2Priority & 0x7;
592 /* workaround for WMM S5 */
593 if ((WMM_AC_VI == wmip->wmi_traffic_class) && ((5 == userPriority) || (4 == userPriority)))
598 trafficClass = convert_userPriority_to_trafficClass(userPriority);
600 WMI_DATA_HDR_SET_UP(dtHdr, userPriority);
601 /* lower 3-bits are 802.1d priority */
602 //dtHdr->info |= (userPriority & WMI_DATA_HDR_UP_MASK) << WMI_DATA_HDR_UP_SHIFT;
605 streamExists = wmip->wmi_fatPipeExists;
608 if (!(streamExists & (1 << trafficClass)))
611 A_MEMZERO(&cmd, sizeof(cmd));
612 cmd.trafficClass = trafficClass;
613 cmd.userPriority = userPriority;
614 cmd.inactivityInt = WMI_IMPLICIT_PSTREAM_INACTIVITY_INT;
615 /* Implicit streams are created with TSID 0xFF */
617 cmd.tsid = WMI_IMPLICIT_PSTREAM;
618 wmi_create_pstream_cmd(wmip, &cmd);
625 wmi_dot11_hdr_add (struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode)
630 ATH_LLC_SNAP_HDR *llcHdr;
631 struct ieee80211_frame *wh;
634 A_ASSERT(osbuf != NULL);
636 if (A_NETBUF_HEADROOM(osbuf) <
637 (sizeof(struct ieee80211_qosframe) + sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR)))
642 datap = A_NETBUF_DATA(osbuf);
644 typeorlen = *(u16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN);
646 if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) {
648 * packet is already in 802.3 format - return success
650 A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG));
655 * Save mac fields and length to be inserted later
657 memcpy(macHdr.dstMac, datap, ATH_MAC_LEN);
658 memcpy(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN);
659 macHdr.typeOrLen = A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) +
660 sizeof(ATH_LLC_SNAP_HDR));
662 // Remove the Ethernet hdr
663 A_NETBUF_PULL(osbuf, sizeof(ATH_MAC_HDR));
665 * Make room for LLC+SNAP headers
667 if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != 0) {
670 datap = A_NETBUF_DATA(osbuf);
672 llcHdr = (ATH_LLC_SNAP_HDR *)(datap);
676 llcHdr->orgCode[0] = 0x0;
677 llcHdr->orgCode[1] = 0x0;
678 llcHdr->orgCode[2] = 0x0;
679 llcHdr->etherType = typeorlen;
682 /* Make room for 802.11 hdr */
683 if (wmip->wmi_is_wmm_enabled)
685 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32));
686 if (A_NETBUF_PUSH(osbuf, hdrsize) != 0)
690 wh = (struct ieee80211_frame *) A_NETBUF_DATA(osbuf);
691 wh->i_fc[0] = IEEE80211_FC0_SUBTYPE_QOS;
695 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_frame),sizeof(u32));
696 if (A_NETBUF_PUSH(osbuf, hdrsize) != 0)
700 wh = (struct ieee80211_frame *) A_NETBUF_DATA(osbuf);
701 wh->i_fc[0] = IEEE80211_FC0_SUBTYPE_DATA;
703 /* Setup the SA & DA */
704 IEEE80211_ADDR_COPY(wh->i_addr2, macHdr.srcMac);
706 if (mode == INFRA_NETWORK) {
707 IEEE80211_ADDR_COPY(wh->i_addr3, macHdr.dstMac);
709 else if (mode == ADHOC_NETWORK) {
710 IEEE80211_ADDR_COPY(wh->i_addr1, macHdr.dstMac);
717 wmi_dot11_hdr_remove(struct wmi_t *wmip, void *osbuf)
720 struct ieee80211_frame *pwh,wh;
722 ATH_LLC_SNAP_HDR *llcHdr;
726 A_ASSERT(osbuf != NULL);
727 datap = A_NETBUF_DATA(osbuf);
729 pwh = (struct ieee80211_frame *)datap;
730 type = pwh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
731 subtype = pwh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
733 memcpy((u8 *)&wh, datap, sizeof(struct ieee80211_frame));
735 /* strip off the 802.11 hdr*/
736 if (subtype == IEEE80211_FC0_SUBTYPE_QOS) {
737 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32));
738 A_NETBUF_PULL(osbuf, hdrsize);
739 } else if (subtype == IEEE80211_FC0_SUBTYPE_DATA) {
740 A_NETBUF_PULL(osbuf, sizeof(struct ieee80211_frame));
743 datap = A_NETBUF_DATA(osbuf);
744 llcHdr = (ATH_LLC_SNAP_HDR *)(datap);
746 macHdr.typeOrLen = llcHdr->etherType;
747 A_MEMZERO(macHdr.dstMac, sizeof(macHdr.dstMac));
748 A_MEMZERO(macHdr.srcMac, sizeof(macHdr.srcMac));
750 switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) {
751 case IEEE80211_FC1_DIR_NODS:
752 IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr1);
753 IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr2);
755 case IEEE80211_FC1_DIR_TODS:
756 IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr3);
757 IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr2);
759 case IEEE80211_FC1_DIR_FROMDS:
760 IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr1);
761 IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr3);
763 case IEEE80211_FC1_DIR_DSTODS:
767 // Remove the LLC Hdr.
768 A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR));
770 // Insert the ATH MAC hdr.
772 A_NETBUF_PUSH(osbuf, sizeof(ATH_MAC_HDR));
773 datap = A_NETBUF_DATA(osbuf);
775 memcpy (datap, &macHdr, sizeof(ATH_MAC_HDR));
781 * performs 802.3 to DIX encapsulation for received packets.
782 * Assumes the entire 802.3 header is contigous.
785 wmi_dot3_2_dix(void *osbuf)
789 ATH_LLC_SNAP_HDR *llcHdr;
791 A_ASSERT(osbuf != NULL);
792 datap = A_NETBUF_DATA(osbuf);
794 memcpy(&macHdr, datap, sizeof(ATH_MAC_HDR));
795 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR));
796 macHdr.typeOrLen = llcHdr->etherType;
798 if (A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != 0) {
802 datap = A_NETBUF_DATA(osbuf);
804 memcpy(datap, &macHdr, sizeof (ATH_MAC_HDR));
810 * Removes a WMI data header
813 wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf)
815 A_ASSERT(osbuf != NULL);
817 return (A_NETBUF_PULL(osbuf, sizeof(WMI_DATA_HDR)));
821 wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg)
823 wlan_iterate_nodes(&wmip->wmi_scan_table, f, arg);
827 * WMI Extended Event received from Target.
830 wmi_control_rx_xtnd(struct wmi_t *wmip, void *osbuf)
838 if (A_NETBUF_LEN(osbuf) < sizeof(WMIX_CMD_HDR)) {
839 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG));
840 wmip->wmi_stats.cmd_len_err++;
844 cmd = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf);
847 if (A_NETBUF_PULL(osbuf, sizeof(WMIX_CMD_HDR)) != 0) {
848 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG));
849 wmip->wmi_stats.cmd_len_err++;
853 datap = A_NETBUF_DATA(osbuf);
854 len = A_NETBUF_LEN(osbuf);
857 case (WMIX_DSETOPENREQ_EVENTID):
858 status = wmi_dset_open_req_rx(wmip, datap, len);
860 #ifdef CONFIG_HOST_DSET_SUPPORT
861 case (WMIX_DSETCLOSE_EVENTID):
862 status = wmi_dset_close_rx(wmip, datap, len);
864 case (WMIX_DSETDATAREQ_EVENTID):
865 status = wmi_dset_data_req_rx(wmip, datap, len);
867 #endif /* CONFIG_HOST_DSET_SUPPORT */
868 #ifdef CONFIG_HOST_GPIO_SUPPORT
869 case (WMIX_GPIO_INTR_EVENTID):
870 wmi_gpio_intr_rx(wmip, datap, len);
872 case (WMIX_GPIO_DATA_EVENTID):
873 wmi_gpio_data_rx(wmip, datap, len);
875 case (WMIX_GPIO_ACK_EVENTID):
876 wmi_gpio_ack_rx(wmip, datap, len);
878 #endif /* CONFIG_HOST_GPIO_SUPPORT */
879 case (WMIX_HB_CHALLENGE_RESP_EVENTID):
880 wmi_hbChallengeResp_rx(wmip, datap, len);
882 case (WMIX_DBGLOG_EVENTID):
883 wmi_dbglog_event_rx(wmip, datap, len);
885 #if defined(CONFIG_TARGET_PROFILE_SUPPORT)
886 case (WMIX_PROF_COUNT_EVENTID):
887 wmi_prof_count_rx(wmip, datap, len);
889 #endif /* CONFIG_TARGET_PROFILE_SUPPORT */
891 A_DPRINTF(DBG_WMI|DBG_ERROR,
892 (DBGFMT "Unknown id 0x%x\n", DBGARG, id));
893 wmip->wmi_stats.cmd_id_err++;
907 wmi_control_rx(struct wmi_t *wmip, void *osbuf)
912 u32 len, i, loggingReq;
915 A_ASSERT(osbuf != NULL);
916 if (A_NETBUF_LEN(osbuf) < sizeof(WMI_CMD_HDR)) {
917 A_NETBUF_FREE(osbuf);
918 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG));
919 wmip->wmi_stats.cmd_len_err++;
923 cmd = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf);
926 if (A_NETBUF_PULL(osbuf, sizeof(WMI_CMD_HDR)) != 0) {
927 A_NETBUF_FREE(osbuf);
928 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG));
929 wmip->wmi_stats.cmd_len_err++;
933 datap = A_NETBUF_DATA(osbuf);
934 len = A_NETBUF_LEN(osbuf);
938 ar6000_get_driver_cfg(wmip->wmi_devt,
939 AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS,
943 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI %d \n",id));
944 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI recv, MsgNo %d : ", cmdRecvNum));
945 for(i = 0; i < len; i++)
946 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("%x ", datap[i]));
947 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("\n"));
955 case (WMI_GET_BITRATE_CMDID):
956 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_BITRATE_CMDID\n", DBGARG));
957 status = wmi_bitrate_reply_rx(wmip, datap, len);
959 case (WMI_GET_CHANNEL_LIST_CMDID):
960 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_CHANNEL_LIST_CMDID\n", DBGARG));
961 status = wmi_channelList_reply_rx(wmip, datap, len);
963 case (WMI_GET_TX_PWR_CMDID):
964 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_TX_PWR_CMDID\n", DBGARG));
965 status = wmi_txPwr_reply_rx(wmip, datap, len);
967 case (WMI_READY_EVENTID):
968 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_READY_EVENTID\n", DBGARG));
969 status = wmi_ready_event_rx(wmip, datap, len);
970 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
971 A_WMI_DBGLOG_INIT_DONE(wmip->wmi_devt);
973 case (WMI_CONNECT_EVENTID):
974 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CONNECT_EVENTID\n", DBGARG));
975 status = wmi_connect_event_rx(wmip, datap, len);
976 A_WMI_SEND_GENERIC_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
978 case (WMI_DISCONNECT_EVENTID):
979 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_DISCONNECT_EVENTID\n", DBGARG));
980 status = wmi_disconnect_event_rx(wmip, datap, len);
981 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
983 case (WMI_PEER_NODE_EVENTID):
984 A_DPRINTF (DBG_WMI, (DBGFMT "WMI_PEER_NODE_EVENTID\n", DBGARG));
985 status = wmi_peer_node_event_rx(wmip, datap, len);
986 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
988 case (WMI_TKIP_MICERR_EVENTID):
989 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TKIP_MICERR_EVENTID\n", DBGARG));
990 status = wmi_tkip_micerr_event_rx(wmip, datap, len);
992 case (WMI_BSSINFO_EVENTID):
993 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BSSINFO_EVENTID\n", DBGARG));
996 * convert WMI_BSS_INFO_HDR2 to WMI_BSS_INFO_HDR
997 * Take a local copy of the WMI_BSS_INFO_HDR2 from the wmi buffer
998 * and reconstruct the WMI_BSS_INFO_HDR in its place
1000 WMI_BSS_INFO_HDR2 bih2;
1001 WMI_BSS_INFO_HDR *bih;
1002 memcpy(&bih2, datap, sizeof(WMI_BSS_INFO_HDR2));
1004 A_NETBUF_PUSH(osbuf, 4);
1005 datap = A_NETBUF_DATA(osbuf);
1006 len = A_NETBUF_LEN(osbuf);
1007 bih = (WMI_BSS_INFO_HDR *)datap;
1009 bih->channel = bih2.channel;
1010 bih->frameType = bih2.frameType;
1011 bih->snr = bih2.snr;
1012 bih->rssi = bih2.snr - 95;
1013 bih->ieMask = bih2.ieMask;
1014 memcpy(bih->bssid, bih2.bssid, ATH_MAC_LEN);
1016 status = wmi_bssInfo_event_rx(wmip, datap, len);
1017 A_WMI_SEND_GENERIC_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
1020 case (WMI_REGDOMAIN_EVENTID):
1021 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REGDOMAIN_EVENTID\n", DBGARG));
1022 status = wmi_regDomain_event_rx(wmip, datap, len);
1024 case (WMI_PSTREAM_TIMEOUT_EVENTID):
1025 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_PSTREAM_TIMEOUT_EVENTID\n", DBGARG));
1026 status = wmi_pstream_timeout_event_rx(wmip, datap, len);
1027 /* pstreams are fatpipe abstractions that get implicitly created.
1028 * User apps only deal with thinstreams. creation of a thinstream
1029 * by the user or data traffic flow in an AC triggers implicit
1030 * pstream creation. Do we need to send this event to App..?
1031 * no harm in sending it.
1033 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
1035 case (WMI_NEIGHBOR_REPORT_EVENTID):
1036 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_NEIGHBOR_REPORT_EVENTID\n", DBGARG));
1037 status = wmi_neighborReport_event_rx(wmip, datap, len);
1039 case (WMI_SCAN_COMPLETE_EVENTID):
1040 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SCAN_COMPLETE_EVENTID\n", DBGARG));
1041 status = wmi_scanComplete_rx(wmip, datap, len);
1042 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
1044 case (WMI_CMDERROR_EVENTID):
1045 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CMDERROR_EVENTID\n", DBGARG));
1046 status = wmi_errorEvent_rx(wmip, datap, len);
1048 case (WMI_REPORT_STATISTICS_EVENTID):
1049 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_STATISTICS_EVENTID\n", DBGARG));
1050 status = wmi_statsEvent_rx(wmip, datap, len);
1052 case (WMI_RSSI_THRESHOLD_EVENTID):
1053 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_RSSI_THRESHOLD_EVENTID\n", DBGARG));
1054 status = wmi_rssiThresholdEvent_rx(wmip, datap, len);
1056 case (WMI_ERROR_REPORT_EVENTID):
1057 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_ERROR_REPORT_EVENTID\n", DBGARG));
1058 status = wmi_reportErrorEvent_rx(wmip, datap, len);
1059 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
1061 case (WMI_OPT_RX_FRAME_EVENTID):
1062 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_OPT_RX_FRAME_EVENTID\n", DBGARG));
1063 status = wmi_opt_frame_event_rx(wmip, datap, len);
1065 case (WMI_REPORT_ROAM_TBL_EVENTID):
1066 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_ROAM_TBL_EVENTID\n", DBGARG));
1067 status = wmi_roam_tbl_event_rx(wmip, datap, len);
1069 case (WMI_EXTENSION_EVENTID):
1070 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_EXTENSION_EVENTID\n", DBGARG));
1071 status = wmi_control_rx_xtnd(wmip, osbuf);
1073 case (WMI_CAC_EVENTID):
1074 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CAC_EVENTID\n", DBGARG));
1075 status = wmi_cac_event_rx(wmip, datap, len);
1077 case (WMI_CHANNEL_CHANGE_EVENTID):
1078 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CHANNEL_CHANGE_EVENTID\n", DBGARG));
1079 status = wmi_channel_change_event_rx(wmip, datap, len);
1081 case (WMI_REPORT_ROAM_DATA_EVENTID):
1082 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_ROAM_DATA_EVENTID\n", DBGARG));
1083 status = wmi_roam_data_event_rx(wmip, datap, len);
1085 #ifdef CONFIG_HOST_TCMD_SUPPORT
1086 case (WMI_TEST_EVENTID):
1087 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TEST_EVENTID\n", DBGARG));
1088 status = wmi_tcmd_test_report_rx(wmip, datap, len);
1091 case (WMI_GET_FIXRATES_CMDID):
1092 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_FIXRATES_CMDID\n", DBGARG));
1093 status = wmi_ratemask_reply_rx(wmip, datap, len);
1095 case (WMI_TX_RETRY_ERR_EVENTID):
1096 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TX_RETRY_ERR_EVENTID\n", DBGARG));
1097 status = wmi_txRetryErrEvent_rx(wmip, datap, len);
1098 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
1100 case (WMI_SNR_THRESHOLD_EVENTID):
1101 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SNR_THRESHOLD_EVENTID\n", DBGARG));
1102 status = wmi_snrThresholdEvent_rx(wmip, datap, len);
1104 case (WMI_LQ_THRESHOLD_EVENTID):
1105 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_LQ_THRESHOLD_EVENTID\n", DBGARG));
1106 status = wmi_lqThresholdEvent_rx(wmip, datap, len);
1107 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
1109 case (WMI_APLIST_EVENTID):
1110 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Received APLIST Event\n"));
1111 status = wmi_aplistEvent_rx(wmip, datap, len);
1113 case (WMI_GET_KEEPALIVE_CMDID):
1114 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_KEEPALIVE_CMDID\n", DBGARG));
1115 status = wmi_keepalive_reply_rx(wmip, datap, len);
1117 case (WMI_GET_WOW_LIST_EVENTID):
1118 status = wmi_get_wow_list_event_rx(wmip, datap, len);
1120 case (WMI_GET_PMKID_LIST_EVENTID):
1121 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_PMKID_LIST Event\n", DBGARG));
1122 status = wmi_get_pmkid_list_event_rx(wmip, datap, len);
1124 case (WMI_PSPOLL_EVENTID):
1125 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_PSPOLL_EVENT\n", DBGARG));
1126 status = wmi_pspoll_event_rx(wmip, datap, len);
1128 case (WMI_DTIMEXPIRY_EVENTID):
1129 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_DTIMEXPIRY_EVENT\n", DBGARG));
1130 status = wmi_dtimexpiry_event_rx(wmip, datap, len);
1132 case (WMI_SET_PARAMS_REPLY_EVENTID):
1133 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SET_PARAMS_REPLY Event\n", DBGARG));
1134 status = wmi_set_params_event_rx(wmip, datap, len);
1136 case (WMI_ACM_REJECT_EVENTID):
1137 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SET_PARAMS_REPLY Event\n", DBGARG));
1138 status = wmi_acm_reject_event_rx(wmip, datap, len);
1140 #ifdef ATH_AR6K_11N_SUPPORT
1141 case (WMI_ADDBA_REQ_EVENTID):
1142 status = wmi_addba_req_event_rx(wmip, datap, len);
1144 case (WMI_ADDBA_RESP_EVENTID):
1145 status = wmi_addba_resp_event_rx(wmip, datap, len);
1147 case (WMI_DELBA_REQ_EVENTID):
1148 status = wmi_delba_req_event_rx(wmip, datap, len);
1150 case (WMI_REPORT_BTCOEX_CONFIG_EVENTID):
1151 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BTCOEX_CONFIG_EVENTID", DBGARG));
1152 status = wmi_btcoex_config_event_rx(wmip, datap, len);
1154 case (WMI_REPORT_BTCOEX_STATS_EVENTID):
1155 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BTCOEX_STATS_EVENTID", DBGARG));
1156 status = wmi_btcoex_stats_event_rx(wmip, datap, len);
1159 case (WMI_TX_COMPLETE_EVENTID):
1162 TX_COMPLETE_MSG_V1 *pV1;
1163 WMI_TX_COMPLETE_EVENT *pEv = (WMI_TX_COMPLETE_EVENT *)datap;
1164 A_PRINTF("comp: %d %d %d\n", pEv->numMessages, pEv->msgLen, pEv->msgType);
1166 for(index = 0 ; index < pEv->numMessages ; index++) {
1167 pV1 = (TX_COMPLETE_MSG_V1 *)(datap + sizeof(WMI_TX_COMPLETE_EVENT) + index*sizeof(TX_COMPLETE_MSG_V1));
1168 A_PRINTF("msg: %d %d %d %d\n", pV1->status, pV1->pktID, pV1->rateIdx, pV1->ackFailures);
1172 case (WMI_HCI_EVENT_EVENTID):
1173 status = wmi_hci_event_rx(wmip, datap, len);
1176 case (WMI_WAPI_REKEY_EVENTID):
1177 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_WAPI_REKEY_EVENTID", DBGARG));
1178 status = wmi_wapi_rekey_event_rx(wmip, datap, len);
1182 A_DPRINTF(DBG_WMI|DBG_ERROR,
1183 (DBGFMT "Unknown id 0x%x\n", DBGARG, id));
1184 wmip->wmi_stats.cmd_id_err++;
1189 A_NETBUF_FREE(osbuf);
1194 /* Send a "simple" wmi command -- one with no arguments */
1196 wmi_simple_cmd(struct wmi_t *wmip, WMI_COMMAND_ID cmdid)
1200 osbuf = A_NETBUF_ALLOC(0);
1201 if (osbuf == NULL) {
1205 return (wmi_cmd_send(wmip, osbuf, cmdid, NO_SYNC_WMIFLAG));
1208 /* Send a "simple" extended wmi command -- one with no arguments.
1209 Enabling this command only if GPIO or profiling support is enabled.
1210 This is to suppress warnings on some platforms */
1211 #if defined(CONFIG_HOST_GPIO_SUPPORT) || defined(CONFIG_TARGET_PROFILE_SUPPORT)
1213 wmi_simple_cmd_xtnd(struct wmi_t *wmip, WMIX_COMMAND_ID cmdid)
1217 osbuf = A_NETBUF_ALLOC(0);
1218 if (osbuf == NULL) {
1222 return (wmi_cmd_send_xtnd(wmip, osbuf, cmdid, NO_SYNC_WMIFLAG));
1227 wmi_ready_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1229 WMI_READY_EVENT *ev = (WMI_READY_EVENT *)datap;
1231 if (len < sizeof(WMI_READY_EVENT)) {
1234 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1235 wmip->wmi_ready = true;
1236 A_WMI_READY_EVENT(wmip->wmi_devt, ev->macaddr, ev->phyCapability,
1237 ev->sw_version, ev->abi_version);
1242 #define LE_READ_4(p) \
1244 ((((u8 *)(p))[0] ) | (((u8 *)(p))[1] << 8) | \
1245 (((u8 *)(p))[2] << 16) | (((u8 *)(p))[3] << 24)))
1248 iswmmoui(const u8 *frm)
1250 return frm[1] > 3 && LE_READ_4(frm+2) == ((WMM_OUI_TYPE<<24)|WMM_OUI);
1254 iswmmparam(const u8 *frm)
1256 return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE;
1261 wmi_connect_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1263 WMI_CONNECT_EVENT *ev;
1266 if (len < sizeof(WMI_CONNECT_EVENT))
1270 ev = (WMI_CONNECT_EVENT *)datap;
1273 (DBGFMT "freq %d bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
1274 DBGARG, ev->channel,
1275 ev->bssid[0], ev->bssid[1], ev->bssid[2],
1276 ev->bssid[3], ev->bssid[4], ev->bssid[5]));
1278 memcpy(wmip->wmi_bssid, ev->bssid, ATH_MAC_LEN);
1280 /* initialize pointer to start of assoc rsp IEs */
1281 pie = ev->assocInfo + ev->beaconIeLen + ev->assocReqLen +
1282 sizeof(u16) + /* capinfo*/
1283 sizeof(u16) + /* status Code */
1284 sizeof(u16) ; /* associd */
1286 /* initialize pointer to end of assoc rsp IEs */
1287 peie = ev->assocInfo + ev->beaconIeLen + ev->assocReqLen + ev->assocRespLen;
1293 case IEEE80211_ELEMID_VENDOR:
1296 if(iswmmparam (pie))
1298 wmip->wmi_is_wmm_enabled = true;
1304 if (wmip->wmi_is_wmm_enabled)
1311 A_WMI_CONNECT_EVENT(wmip->wmi_devt, ev->channel, ev->bssid,
1312 ev->listenInterval, ev->beaconInterval,
1313 (NETWORK_TYPE) ev->networkType, ev->beaconIeLen,
1314 ev->assocReqLen, ev->assocRespLen,
1321 wmi_regDomain_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1323 WMI_REG_DOMAIN_EVENT *ev;
1325 if (len < sizeof(*ev)) {
1328 ev = (WMI_REG_DOMAIN_EVENT *)datap;
1330 A_WMI_REGDOMAIN_EVENT(wmip->wmi_devt, ev->regDomain);
1336 wmi_neighborReport_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1338 WMI_NEIGHBOR_REPORT_EVENT *ev;
1341 if (len < sizeof(*ev)) {
1344 ev = (WMI_NEIGHBOR_REPORT_EVENT *)datap;
1345 numAps = ev->numberOfAps;
1347 if (len < (int)(sizeof(*ev) + ((numAps - 1) * sizeof(WMI_NEIGHBOR_INFO)))) {
1351 A_WMI_NEIGHBORREPORT_EVENT(wmip->wmi_devt, numAps, ev->neighbor);
1357 wmi_disconnect_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1359 WMI_DISCONNECT_EVENT *ev;
1360 wmip->wmi_traffic_class = 100;
1362 if (len < sizeof(WMI_DISCONNECT_EVENT)) {
1365 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1367 ev = (WMI_DISCONNECT_EVENT *)datap;
1369 A_MEMZERO(wmip->wmi_bssid, sizeof(wmip->wmi_bssid));
1371 wmip->wmi_is_wmm_enabled = false;
1372 wmip->wmi_pair_crypto_type = NONE_CRYPT;
1373 wmip->wmi_grp_crypto_type = NONE_CRYPT;
1375 A_WMI_DISCONNECT_EVENT(wmip->wmi_devt, ev->disconnectReason, ev->bssid,
1376 ev->assocRespLen, ev->assocInfo, ev->protocolReasonStatus);
1382 wmi_peer_node_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1384 WMI_PEER_NODE_EVENT *ev;
1386 if (len < sizeof(WMI_PEER_NODE_EVENT)) {
1389 ev = (WMI_PEER_NODE_EVENT *)datap;
1390 if (ev->eventCode == PEER_NODE_JOIN_EVENT) {
1391 A_DPRINTF (DBG_WMI, (DBGFMT "Joined node with Macaddr: ", DBGARG));
1392 } else if(ev->eventCode == PEER_NODE_LEAVE_EVENT) {
1393 A_DPRINTF (DBG_WMI, (DBGFMT "left node with Macaddr: ", DBGARG));
1396 A_WMI_PEER_EVENT (wmip->wmi_devt, ev->eventCode, ev->peerMacAddr);
1402 wmi_tkip_micerr_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1404 WMI_TKIP_MICERR_EVENT *ev;
1406 if (len < sizeof(*ev)) {
1409 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1411 ev = (WMI_TKIP_MICERR_EVENT *)datap;
1412 A_WMI_TKIP_MICERR_EVENT(wmip->wmi_devt, ev->keyid, ev->ismcast);
1418 wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1421 WMI_BSS_INFO_HDR *bih;
1423 u32 nodeCachingAllowed = 1;
1424 u8 cached_ssid_len = 0;
1425 u8 cached_ssid_buf[IEEE80211_NWID_LEN] = {0};
1426 u8 beacon_ssid_len = 0;
1428 if (len <= sizeof(WMI_BSS_INFO_HDR)) {
1432 bih = (WMI_BSS_INFO_HDR *)datap;
1433 bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid);
1435 if (bih->rssi > 0) {
1437 return 0; //no node found in the table, just drop the node with incorrect RSSI
1439 bih->rssi = bss->ni_rssi; //Adjust RSSI in datap in case it is used in A_WMI_BSSINFO_EVENT_RX
1442 A_WMI_BSSINFO_EVENT_RX(wmip->wmi_devt, datap, len);
1443 /* What is driver config for wlan node caching? */
1444 if(ar6000_get_driver_cfg(wmip->wmi_devt,
1445 AR6000_DRIVER_CFG_GET_WLANNODECACHING,
1446 &nodeCachingAllowed) != 0) {
1447 wmi_node_return(wmip, bss);
1451 if(!nodeCachingAllowed) {
1452 wmi_node_return(wmip, bss);
1456 buf = datap + sizeof(WMI_BSS_INFO_HDR);
1457 len -= sizeof(WMI_BSS_INFO_HDR);
1459 A_DPRINTF(DBG_WMI2, (DBGFMT "bssInfo event - ch %u, rssi %02x, "
1460 "bssid \"%pM\"\n", DBGARG, bih->channel,
1461 (unsigned char) bih->rssi, bih->bssid));
1463 if(wps_enable && (bih->frameType == PROBERESP_FTYPE) ) {
1464 wmi_node_return(wmip, bss);
1470 * Free up the node. Not the most efficient process given
1471 * we are about to allocate a new node but it is simple and should be
1475 /* In case of hidden AP, beacon will not have ssid,
1476 * but a directed probe response will have it,
1477 * so cache the probe-resp-ssid if already present. */
1478 if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType))
1482 ie_ssid = bss->ni_cie.ie_ssid;
1483 if(ie_ssid && (ie_ssid[1] <= IEEE80211_NWID_LEN) && (ie_ssid[2] != 0))
1485 cached_ssid_len = ie_ssid[1];
1486 memcpy(cached_ssid_buf, ie_ssid + 2, cached_ssid_len);
1491 * Use the current average rssi of associated AP base on assumpiton
1492 * 1. Most os with GUI will update RSSI by wmi_get_stats_cmd() periodically
1493 * 2. wmi_get_stats_cmd(..) will be called when calling wmi_startscan_cmd(...)
1494 * The average value of RSSI give end-user better feeling for instance value of scan result
1495 * It also sync up RSSI info in GUI between scan result and RSSI signal icon
1497 if (IEEE80211_ADDR_EQ(wmip->wmi_bssid, bih->bssid)) {
1498 bih->rssi = bss->ni_rssi;
1499 bih->snr = bss->ni_snr;
1502 wlan_node_reclaim(&wmip->wmi_scan_table, bss);
1505 /* beacon/probe response frame format
1507 * [2] beacon interval
1508 * [2] capability information
1510 beacon_ssid_len = buf[SSID_IE_LEN_INDEX];
1512 /* If ssid is cached for this hidden AP, then change buffer len accordingly. */
1513 if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) &&
1514 (0 != cached_ssid_len) &&
1515 (0 == beacon_ssid_len || (cached_ssid_len > beacon_ssid_len && 0 == buf[SSID_IE_LEN_INDEX + 1])))
1517 len += (cached_ssid_len - beacon_ssid_len);
1520 bss = wlan_node_alloc(&wmip->wmi_scan_table, len);
1525 bss->ni_snr = bih->snr;
1526 bss->ni_rssi = bih->rssi;
1527 A_ASSERT(bss->ni_buf != NULL);
1529 /* In case of hidden AP, beacon will not have ssid,
1530 * but a directed probe response will have it,
1531 * so place the cached-ssid(probe-resp) in the bssinfo. */
1532 if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) &&
1533 (0 != cached_ssid_len) &&
1534 (0 == beacon_ssid_len || (beacon_ssid_len && 0 == buf[SSID_IE_LEN_INDEX + 1])))
1536 u8 *ni_buf = bss->ni_buf;
1539 /* copy the first 14 bytes such as
1540 * time-stamp(8), beacon-interval(2), cap-info(2), ssid-id(1), ssid-len(1). */
1541 memcpy(ni_buf, buf, SSID_IE_LEN_INDEX + 1);
1543 ni_buf[SSID_IE_LEN_INDEX] = cached_ssid_len;
1544 ni_buf += (SSID_IE_LEN_INDEX + 1);
1546 buf += (SSID_IE_LEN_INDEX + 1);
1547 buf_len -= (SSID_IE_LEN_INDEX + 1);
1549 /* copy the cached ssid */
1550 memcpy(ni_buf, cached_ssid_buf, cached_ssid_len);
1551 ni_buf += cached_ssid_len;
1553 buf += beacon_ssid_len;
1554 buf_len -= beacon_ssid_len;
1556 if (cached_ssid_len > beacon_ssid_len)
1557 buf_len -= (cached_ssid_len - beacon_ssid_len);
1559 /* now copy the rest of bytes */
1560 memcpy(ni_buf, buf, buf_len);
1563 memcpy(bss->ni_buf, buf, len);
1565 bss->ni_framelen = len;
1566 if (wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie) != 0) {
1567 wlan_node_free(bss);
1572 * Update the frequency in ie_chan, overwriting of channel number
1573 * which is done in wlan_parse_beacon
1575 bss->ni_cie.ie_chan = bih->channel;
1576 wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid);
1582 wmi_opt_frame_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1585 WMI_OPT_RX_INFO_HDR *bih;
1588 if (len <= sizeof(WMI_OPT_RX_INFO_HDR)) {
1592 bih = (WMI_OPT_RX_INFO_HDR *)datap;
1593 buf = datap + sizeof(WMI_OPT_RX_INFO_HDR);
1594 len -= sizeof(WMI_OPT_RX_INFO_HDR);
1596 A_DPRINTF(DBG_WMI2, (DBGFMT "opt frame event %2.2x:%2.2x\n", DBGARG,
1597 bih->bssid[4], bih->bssid[5]));
1599 bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid);
1602 * Free up the node. Not the most efficient process given
1603 * we are about to allocate a new node but it is simple and should be
1606 wlan_node_reclaim(&wmip->wmi_scan_table, bss);
1609 bss = wlan_node_alloc(&wmip->wmi_scan_table, len);
1614 bss->ni_snr = bih->snr;
1615 bss->ni_cie.ie_chan = bih->channel;
1616 A_ASSERT(bss->ni_buf != NULL);
1617 memcpy(bss->ni_buf, buf, len);
1618 wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid);
1623 /* This event indicates inactivity timeout of a fatpipe(pstream)
1627 wmi_pstream_timeout_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1629 WMI_PSTREAM_TIMEOUT_EVENT *ev;
1631 if (len < sizeof(WMI_PSTREAM_TIMEOUT_EVENT)) {
1635 A_DPRINTF(DBG_WMI, (DBGFMT "wmi_pstream_timeout_event_rx\n", DBGARG));
1637 ev = (WMI_PSTREAM_TIMEOUT_EVENT *)datap;
1639 /* When the pstream (fat pipe == AC) timesout, it means there were no
1640 * thinStreams within this pstream & it got implicitly created due to
1641 * data flow on this AC. We start the inactivity timer only for
1642 * implicitly created pstream. Just reset the host state.
1644 /* Set the activeTsids for this AC to 0 */
1646 wmip->wmi_streamExistsForAC[ev->trafficClass]=0;
1647 wmip->wmi_fatPipeExists &= ~(1 << ev->trafficClass);
1650 /*Indicate inactivity to driver layer for this fatpipe (pstream)*/
1651 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, ev->trafficClass);
1657 wmi_bitrate_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1659 WMI_BIT_RATE_REPLY *reply;
1663 * WMI_BIT_RATE_CMD structure is changed to WMI_BIT_RATE_REPLY.
1664 * since there is difference in the length and to avoid returning
1667 if (len < sizeof(WMI_BIT_RATE_REPLY)) {
1670 reply = (WMI_BIT_RATE_REPLY *)datap;
1672 (DBGFMT "Enter - rateindex %d\n", DBGARG, reply->rateIndex));
1674 if (reply->rateIndex == (s8) RATE_AUTO) {
1677 // the SGI state is stored as the MSb of the rateIndex
1678 index = reply->rateIndex & 0x7f;
1679 sgi = (reply->rateIndex & 0x80)? 1:0;
1680 rate = wmi_rateTable[index][sgi];
1683 A_WMI_BITRATE_RX(wmip->wmi_devt, rate);
1688 wmi_ratemask_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1690 WMI_FIX_RATES_REPLY *reply;
1692 if (len < sizeof(WMI_FIX_RATES_REPLY)) {
1695 reply = (WMI_FIX_RATES_REPLY *)datap;
1697 (DBGFMT "Enter - fixed rate mask %x\n", DBGARG, reply->fixRateMask));
1699 A_WMI_RATEMASK_RX(wmip->wmi_devt, reply->fixRateMask);
1705 wmi_channelList_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1707 WMI_CHANNEL_LIST_REPLY *reply;
1709 if (len < sizeof(WMI_CHANNEL_LIST_REPLY)) {
1712 reply = (WMI_CHANNEL_LIST_REPLY *)datap;
1713 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1715 A_WMI_CHANNELLIST_RX(wmip->wmi_devt, reply->numChannels,
1716 reply->channelList);
1722 wmi_txPwr_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1724 WMI_TX_PWR_REPLY *reply;
1726 if (len < sizeof(*reply)) {
1729 reply = (WMI_TX_PWR_REPLY *)datap;
1730 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1732 A_WMI_TXPWR_RX(wmip->wmi_devt, reply->dbM);
1737 wmi_keepalive_reply_rx(struct wmi_t *wmip, u8 *datap, int len)
1739 WMI_GET_KEEPALIVE_CMD *reply;
1741 if (len < sizeof(*reply)) {
1744 reply = (WMI_GET_KEEPALIVE_CMD *)datap;
1745 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1747 A_WMI_KEEPALIVE_RX(wmip->wmi_devt, reply->configured);
1754 wmi_dset_open_req_rx(struct wmi_t *wmip, u8 *datap, int len)
1756 WMIX_DSETOPENREQ_EVENT *dsetopenreq;
1758 if (len < sizeof(WMIX_DSETOPENREQ_EVENT)) {
1761 dsetopenreq = (WMIX_DSETOPENREQ_EVENT *)datap;
1763 (DBGFMT "Enter - dset_id=0x%x\n", DBGARG, dsetopenreq->dset_id));
1764 A_WMI_DSET_OPEN_REQ(wmip->wmi_devt,
1765 dsetopenreq->dset_id,
1766 dsetopenreq->targ_dset_handle,
1767 dsetopenreq->targ_reply_fn,
1768 dsetopenreq->targ_reply_arg);
1773 #ifdef CONFIG_HOST_DSET_SUPPORT
1775 wmi_dset_close_rx(struct wmi_t *wmip, u8 *datap, int len)
1777 WMIX_DSETCLOSE_EVENT *dsetclose;
1779 if (len < sizeof(WMIX_DSETCLOSE_EVENT)) {
1782 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1784 dsetclose = (WMIX_DSETCLOSE_EVENT *)datap;
1785 A_WMI_DSET_CLOSE(wmip->wmi_devt, dsetclose->access_cookie);
1791 wmi_dset_data_req_rx(struct wmi_t *wmip, u8 *datap, int len)
1793 WMIX_DSETDATAREQ_EVENT *dsetdatareq;
1795 if (len < sizeof(WMIX_DSETDATAREQ_EVENT)) {
1798 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1800 dsetdatareq = (WMIX_DSETDATAREQ_EVENT *)datap;
1801 A_WMI_DSET_DATA_REQ(wmip->wmi_devt,
1802 dsetdatareq->access_cookie,
1803 dsetdatareq->offset,
1804 dsetdatareq->length,
1805 dsetdatareq->targ_buf,
1806 dsetdatareq->targ_reply_fn,
1807 dsetdatareq->targ_reply_arg);
1811 #endif /* CONFIG_HOST_DSET_SUPPORT */
1814 wmi_scanComplete_rx(struct wmi_t *wmip, u8 *datap, int len)
1816 WMI_SCAN_COMPLETE_EVENT *ev;
1818 ev = (WMI_SCAN_COMPLETE_EVENT *)datap;
1819 if ((int)ev->status == 0) {
1820 wlan_refresh_inactive_nodes(&wmip->wmi_scan_table);
1822 A_WMI_SCANCOMPLETE_EVENT(wmip->wmi_devt, (int) ev->status);
1823 is_probe_ssid = false;
1829 * Target is reporting a programming error. This is for
1830 * developer aid only. Target only checks a few common violations
1831 * and it is responsibility of host to do all error checking.
1832 * Behavior of target after wmi error event is undefined.
1833 * A reset is recommended.
1836 wmi_errorEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
1838 WMI_CMD_ERROR_EVENT *ev;
1840 ev = (WMI_CMD_ERROR_EVENT *)datap;
1841 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Programming Error: cmd=%d ", ev->commandId));
1842 switch (ev->errorCode) {
1843 case (INVALID_PARAM):
1844 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal Parameter\n"));
1846 case (ILLEGAL_STATE):
1847 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal State\n"));
1849 case (INTERNAL_ERROR):
1850 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Internal Error\n"));
1859 wmi_statsEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
1861 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1863 A_WMI_TARGETSTATS_EVENT(wmip->wmi_devt, datap, len);
1869 wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
1871 WMI_RSSI_THRESHOLD_EVENT *reply;
1872 WMI_RSSI_THRESHOLD_VAL newThreshold;
1873 WMI_RSSI_THRESHOLD_PARAMS_CMD cmd;
1874 SQ_THRESHOLD_PARAMS *sq_thresh =
1875 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI];
1876 u8 upper_rssi_threshold, lower_rssi_threshold;
1879 if (len < sizeof(*reply)) {
1882 reply = (WMI_RSSI_THRESHOLD_EVENT *)datap;
1883 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1884 newThreshold = (WMI_RSSI_THRESHOLD_VAL) reply->range;
1888 * Identify the threshold breached and communicate that to the app. After
1889 * that install a new set of thresholds based on the signal quality
1890 * reported by the target
1893 /* Upper threshold breached */
1894 if (rssi < sq_thresh->upper_threshold[0]) {
1895 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious upper RSSI threshold event: "
1896 " %d\n", DBGARG, rssi));
1897 } else if ((rssi < sq_thresh->upper_threshold[1]) &&
1898 (rssi >= sq_thresh->upper_threshold[0]))
1900 newThreshold = WMI_RSSI_THRESHOLD1_ABOVE;
1901 } else if ((rssi < sq_thresh->upper_threshold[2]) &&
1902 (rssi >= sq_thresh->upper_threshold[1]))
1904 newThreshold = WMI_RSSI_THRESHOLD2_ABOVE;
1905 } else if ((rssi < sq_thresh->upper_threshold[3]) &&
1906 (rssi >= sq_thresh->upper_threshold[2]))
1908 newThreshold = WMI_RSSI_THRESHOLD3_ABOVE;
1909 } else if ((rssi < sq_thresh->upper_threshold[4]) &&
1910 (rssi >= sq_thresh->upper_threshold[3]))
1912 newThreshold = WMI_RSSI_THRESHOLD4_ABOVE;
1913 } else if ((rssi < sq_thresh->upper_threshold[5]) &&
1914 (rssi >= sq_thresh->upper_threshold[4]))
1916 newThreshold = WMI_RSSI_THRESHOLD5_ABOVE;
1917 } else if (rssi >= sq_thresh->upper_threshold[5]) {
1918 newThreshold = WMI_RSSI_THRESHOLD6_ABOVE;
1921 /* Lower threshold breached */
1922 if (rssi > sq_thresh->lower_threshold[0]) {
1923 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious lower RSSI threshold event: "
1924 "%d %d\n", DBGARG, rssi, sq_thresh->lower_threshold[0]));
1925 } else if ((rssi > sq_thresh->lower_threshold[1]) &&
1926 (rssi <= sq_thresh->lower_threshold[0]))
1928 newThreshold = WMI_RSSI_THRESHOLD6_BELOW;
1929 } else if ((rssi > sq_thresh->lower_threshold[2]) &&
1930 (rssi <= sq_thresh->lower_threshold[1]))
1932 newThreshold = WMI_RSSI_THRESHOLD5_BELOW;
1933 } else if ((rssi > sq_thresh->lower_threshold[3]) &&
1934 (rssi <= sq_thresh->lower_threshold[2]))
1936 newThreshold = WMI_RSSI_THRESHOLD4_BELOW;
1937 } else if ((rssi > sq_thresh->lower_threshold[4]) &&
1938 (rssi <= sq_thresh->lower_threshold[3]))
1940 newThreshold = WMI_RSSI_THRESHOLD3_BELOW;
1941 } else if ((rssi > sq_thresh->lower_threshold[5]) &&
1942 (rssi <= sq_thresh->lower_threshold[4]))
1944 newThreshold = WMI_RSSI_THRESHOLD2_BELOW;
1945 } else if (rssi <= sq_thresh->lower_threshold[5]) {
1946 newThreshold = WMI_RSSI_THRESHOLD1_BELOW;
1949 /* Calculate and install the next set of thresholds */
1950 lower_rssi_threshold = ar6000_get_lower_threshold(rssi, sq_thresh,
1951 sq_thresh->lower_threshold_valid_count);
1952 upper_rssi_threshold = ar6000_get_upper_threshold(rssi, sq_thresh,
1953 sq_thresh->upper_threshold_valid_count);
1954 /* Issue a wmi command to install the thresholds */
1955 cmd.thresholdAbove1_Val = upper_rssi_threshold;
1956 cmd.thresholdBelow1_Val = lower_rssi_threshold;
1957 cmd.weight = sq_thresh->weight;
1958 cmd.pollTime = sq_thresh->polling_interval;
1960 rssi_event_value = rssi;
1962 if (wmi_send_rssi_threshold_params(wmip, &cmd) != 0) {
1963 A_DPRINTF(DBG_WMI, (DBGFMT "Unable to configure the RSSI thresholds\n",
1967 A_WMI_RSSI_THRESHOLD_EVENT(wmip->wmi_devt, newThreshold, reply->rssi);
1974 wmi_reportErrorEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
1976 WMI_TARGET_ERROR_REPORT_EVENT *reply;
1978 if (len < sizeof(*reply)) {
1981 reply = (WMI_TARGET_ERROR_REPORT_EVENT *)datap;
1982 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
1984 A_WMI_REPORT_ERROR_EVENT(wmip->wmi_devt, (WMI_TARGET_ERROR_VAL) reply->errorVal);
1990 wmi_cac_event_rx(struct wmi_t *wmip, u8 *datap, int len)
1992 WMI_CAC_EVENT *reply;
1993 WMM_TSPEC_IE *tspec_ie;
1996 if (len < sizeof(*reply)) {
1999 reply = (WMI_CAC_EVENT *)datap;
2001 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2003 if ((reply->cac_indication == CAC_INDICATION_ADMISSION_RESP) &&
2004 (reply->statusCode != TSPEC_STATUS_CODE_ADMISSION_ACCEPTED)) {
2005 tspec_ie = (WMM_TSPEC_IE *) &(reply->tspecSuggestion);
2007 wmi_delete_pstream_cmd(wmip, reply->ac,
2008 (tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK);
2010 else if (reply->cac_indication == CAC_INDICATION_NO_RESP) {
2013 /* following assumes that there is only one outstanding ADDTS request
2014 when this event is received */
2016 activeTsids = wmip->wmi_streamExistsForAC[reply->ac];
2019 for (i = 0; i < sizeof(activeTsids) * 8; i++) {
2020 if ((activeTsids >> i) & 1) {
2024 if (i < (sizeof(activeTsids) * 8)) {
2025 wmi_delete_pstream_cmd(wmip, reply->ac, i);
2029 * Ev#72990: Clear active tsids and Add missing handling
2030 * for delete qos stream from AP
2032 else if (reply->cac_indication == CAC_INDICATION_DELETE) {
2035 tspec_ie = (WMM_TSPEC_IE *) &(reply->tspecSuggestion);
2036 tsid= ((tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK);
2038 wmip->wmi_streamExistsForAC[reply->ac] &= ~(1<<tsid);
2039 activeTsids = wmip->wmi_streamExistsForAC[reply->ac];
2043 /* Indicate stream inactivity to driver layer only if all tsids
2044 * within this AC are deleted.
2047 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, reply->ac);
2048 wmip->wmi_fatPipeExists &= ~(1 << reply->ac);
2052 A_WMI_CAC_EVENT(wmip->wmi_devt, reply->ac,
2053 reply->cac_indication, reply->statusCode,
2054 reply->tspecSuggestion);
2060 wmi_channel_change_event_rx(struct wmi_t *wmip, u8 *datap, int len)
2062 WMI_CHANNEL_CHANGE_EVENT *reply;
2064 if (len < sizeof(*reply)) {
2067 reply = (WMI_CHANNEL_CHANGE_EVENT *)datap;
2068 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2070 A_WMI_CHANNEL_CHANGE_EVENT(wmip->wmi_devt, reply->oldChannel,
2077 wmi_hbChallengeResp_rx(struct wmi_t *wmip, u8 *datap, int len)
2079 WMIX_HB_CHALLENGE_RESP_EVENT *reply;
2081 if (len < sizeof(*reply)) {
2084 reply = (WMIX_HB_CHALLENGE_RESP_EVENT *)datap;
2085 A_DPRINTF(DBG_WMI, (DBGFMT "wmi: challenge response event\n", DBGARG));
2087 A_WMI_HBCHALLENGERESP_EVENT(wmip->wmi_devt, reply->cookie, reply->source);
2093 wmi_roam_tbl_event_rx(struct wmi_t *wmip, u8 *datap, int len)
2095 WMI_TARGET_ROAM_TBL *reply;
2097 if (len < sizeof(*reply)) {
2100 reply = (WMI_TARGET_ROAM_TBL *)datap;
2101 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2103 A_WMI_ROAM_TABLE_EVENT(wmip->wmi_devt, reply);
2109 wmi_roam_data_event_rx(struct wmi_t *wmip, u8 *datap, int len)
2111 WMI_TARGET_ROAM_DATA *reply;
2113 if (len < sizeof(*reply)) {
2116 reply = (WMI_TARGET_ROAM_DATA *)datap;
2117 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2119 A_WMI_ROAM_DATA_EVENT(wmip->wmi_devt, reply);
2125 wmi_txRetryErrEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
2127 if (len < sizeof(WMI_TX_RETRY_ERR_EVENT)) {
2130 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2132 A_WMI_TX_RETRY_ERR_EVENT(wmip->wmi_devt);
2138 wmi_snrThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
2140 WMI_SNR_THRESHOLD_EVENT *reply;
2141 SQ_THRESHOLD_PARAMS *sq_thresh =
2142 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_SNR];
2143 WMI_SNR_THRESHOLD_VAL newThreshold;
2144 WMI_SNR_THRESHOLD_PARAMS_CMD cmd;
2145 u8 upper_snr_threshold, lower_snr_threshold;
2148 if (len < sizeof(*reply)) {
2151 reply = (WMI_SNR_THRESHOLD_EVENT *)datap;
2152 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2154 newThreshold = (WMI_SNR_THRESHOLD_VAL) reply->range;
2157 * Identify the threshold breached and communicate that to the app. After
2158 * that install a new set of thresholds based on the signal quality
2159 * reported by the target
2162 /* Upper threshold breached */
2163 if (snr < sq_thresh->upper_threshold[0]) {
2164 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious upper SNR threshold event: "
2165 "%d\n", DBGARG, snr));
2166 } else if ((snr < sq_thresh->upper_threshold[1]) &&
2167 (snr >= sq_thresh->upper_threshold[0]))
2169 newThreshold = WMI_SNR_THRESHOLD1_ABOVE;
2170 } else if ((snr < sq_thresh->upper_threshold[2]) &&
2171 (snr >= sq_thresh->upper_threshold[1]))
2173 newThreshold = WMI_SNR_THRESHOLD2_ABOVE;
2174 } else if ((snr < sq_thresh->upper_threshold[3]) &&
2175 (snr >= sq_thresh->upper_threshold[2]))
2177 newThreshold = WMI_SNR_THRESHOLD3_ABOVE;
2178 } else if (snr >= sq_thresh->upper_threshold[3]) {
2179 newThreshold = WMI_SNR_THRESHOLD4_ABOVE;
2182 /* Lower threshold breached */
2183 if (snr > sq_thresh->lower_threshold[0]) {
2184 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious lower SNR threshold event: "
2185 "%d %d\n", DBGARG, snr, sq_thresh->lower_threshold[0]));
2186 } else if ((snr > sq_thresh->lower_threshold[1]) &&
2187 (snr <= sq_thresh->lower_threshold[0]))
2189 newThreshold = WMI_SNR_THRESHOLD4_BELOW;
2190 } else if ((snr > sq_thresh->lower_threshold[2]) &&
2191 (snr <= sq_thresh->lower_threshold[1]))
2193 newThreshold = WMI_SNR_THRESHOLD3_BELOW;
2194 } else if ((snr > sq_thresh->lower_threshold[3]) &&
2195 (snr <= sq_thresh->lower_threshold[2]))
2197 newThreshold = WMI_SNR_THRESHOLD2_BELOW;
2198 } else if (snr <= sq_thresh->lower_threshold[3]) {
2199 newThreshold = WMI_SNR_THRESHOLD1_BELOW;
2203 /* Calculate and install the next set of thresholds */
2204 lower_snr_threshold = ar6000_get_lower_threshold(snr, sq_thresh,
2205 sq_thresh->lower_threshold_valid_count);
2206 upper_snr_threshold = ar6000_get_upper_threshold(snr, sq_thresh,
2207 sq_thresh->upper_threshold_valid_count);
2209 /* Issue a wmi command to install the thresholds */
2210 cmd.thresholdAbove1_Val = upper_snr_threshold;
2211 cmd.thresholdBelow1_Val = lower_snr_threshold;
2212 cmd.weight = sq_thresh->weight;
2213 cmd.pollTime = sq_thresh->polling_interval;
2215 A_DPRINTF(DBG_WMI, (DBGFMT "snr: %d, threshold: %d, lower: %d, upper: %d\n"
2216 ,DBGARG, snr, newThreshold, lower_snr_threshold,
2217 upper_snr_threshold));
2219 snr_event_value = snr;
2221 if (wmi_send_snr_threshold_params(wmip, &cmd) != 0) {
2222 A_DPRINTF(DBG_WMI, (DBGFMT "Unable to configure the SNR thresholds\n",
2225 A_WMI_SNR_THRESHOLD_EVENT_RX(wmip->wmi_devt, newThreshold, reply->snr);
2231 wmi_lqThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
2233 WMI_LQ_THRESHOLD_EVENT *reply;
2235 if (len < sizeof(*reply)) {
2238 reply = (WMI_LQ_THRESHOLD_EVENT *)datap;
2239 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2241 A_WMI_LQ_THRESHOLD_EVENT_RX(wmip->wmi_devt,
2242 (WMI_LQ_THRESHOLD_VAL) reply->range,
2249 wmi_aplistEvent_rx(struct wmi_t *wmip, u8 *datap, int len)
2251 u16 ap_info_entry_size;
2252 WMI_APLIST_EVENT *ev = (WMI_APLIST_EVENT *)datap;
2253 WMI_AP_INFO_V1 *ap_info_v1;
2256 if (len < sizeof(WMI_APLIST_EVENT)) {
2260 if (ev->apListVer == APLIST_VER1) {
2261 ap_info_entry_size = sizeof(WMI_AP_INFO_V1);
2262 ap_info_v1 = (WMI_AP_INFO_V1 *)ev->apList;
2267 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Number of APs in APLIST Event is %d\n", ev->numAP));
2268 if (len < (int)(sizeof(WMI_APLIST_EVENT) +
2269 (ev->numAP - 1) * ap_info_entry_size))
2275 * AP List Ver1 Contents
2277 for (i = 0; i < ev->numAP; i++) {
2278 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("AP#%d BSSID %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x "\
2280 ap_info_v1->bssid[0], ap_info_v1->bssid[1],
2281 ap_info_v1->bssid[2], ap_info_v1->bssid[3],
2282 ap_info_v1->bssid[4], ap_info_v1->bssid[5],
2283 ap_info_v1->channel));
2290 wmi_dbglog_event_rx(struct wmi_t *wmip, u8 *datap, int len)
2294 dropped = *((u32 *)datap);
2295 datap += sizeof(dropped);
2296 len -= sizeof(dropped);
2297 A_WMI_DBGLOG_EVENT(wmip->wmi_devt, dropped, (s8 *)datap, len);
2301 #ifdef CONFIG_HOST_GPIO_SUPPORT
2303 wmi_gpio_intr_rx(struct wmi_t *wmip, u8 *datap, int len)
2305 WMIX_GPIO_INTR_EVENT *gpio_intr = (WMIX_GPIO_INTR_EVENT *)datap;
2308 (DBGFMT "Enter - intrmask=0x%x input=0x%x.\n", DBGARG,
2309 gpio_intr->intr_mask, gpio_intr->input_values));
2311 A_WMI_GPIO_INTR_RX(gpio_intr->intr_mask, gpio_intr->input_values);
2317 wmi_gpio_data_rx(struct wmi_t *wmip, u8 *datap, int len)
2319 WMIX_GPIO_DATA_EVENT *gpio_data = (WMIX_GPIO_DATA_EVENT *)datap;
2322 (DBGFMT "Enter - reg=%d value=0x%x\n", DBGARG,
2323 gpio_data->reg_id, gpio_data->value));
2325 A_WMI_GPIO_DATA_RX(gpio_data->reg_id, gpio_data->value);
2331 wmi_gpio_ack_rx(struct wmi_t *wmip, u8 *datap, int len)
2333 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
2335 A_WMI_GPIO_ACK_RX();
2339 #endif /* CONFIG_HOST_GPIO_SUPPORT */
2342 * Called to send a wmi command. Command specific data is already built
2343 * on osbuf and current osbuf->data points to it.
2346 wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId,
2347 WMI_SYNC_FLAG syncflag)
2350 #define IS_OPT_TX_CMD(cmdId) ((cmdId == WMI_OPT_TX_FRAME_CMDID))
2352 HTC_ENDPOINT_ID eid = wmip->wmi_endpoint_id;
2354 A_ASSERT(osbuf != NULL);
2356 if (syncflag >= END_WMIFLAG) {
2357 A_NETBUF_FREE(osbuf);
2361 if ((syncflag == SYNC_BEFORE_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) {
2363 * We want to make sure all data currently queued is transmitted before
2364 * the cmd execution. Establish a new sync point.
2366 wmi_sync_point(wmip);
2369 if (A_NETBUF_PUSH(osbuf, sizeof(WMI_CMD_HDR)) != 0) {
2370 A_NETBUF_FREE(osbuf);
2374 cHdr = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf);
2375 cHdr->commandId = (u16) cmdId;
2376 cHdr->info1 = 0; // added for virtual interface
2379 * Only for OPT_TX_CMD, use BE endpoint.
2381 if (IS_OPT_TX_CMD(cmdId)) {
2382 if ((status=wmi_data_hdr_add(wmip, osbuf, OPT_MSGTYPE, false, false,0,NULL)) != 0) {
2383 A_NETBUF_FREE(osbuf);
2386 eid = A_WMI_Ac2EndpointID(wmip->wmi_devt, WMM_AC_BE);
2388 A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid);
2390 if ((syncflag == SYNC_AFTER_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) {
2392 * We want to make sure all new data queued waits for the command to
2393 * execute. Establish a new sync point.
2395 wmi_sync_point(wmip);
2398 #undef IS_OPT_TX_CMD
2402 wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId,
2403 WMI_SYNC_FLAG syncflag)
2407 if (A_NETBUF_PUSH(osbuf, sizeof(WMIX_CMD_HDR)) != 0) {
2408 A_NETBUF_FREE(osbuf);
2412 cHdr = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf);
2413 cHdr->commandId = (u32) cmdId;
2415 return wmi_cmd_send(wmip, osbuf, WMI_EXTENSION_CMDID, syncflag);
2419 wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType,
2420 DOT11_AUTH_MODE dot11AuthMode, AUTH_MODE authMode,
2421 CRYPTO_TYPE pairwiseCrypto, u8 pairwiseCryptoLen,
2422 CRYPTO_TYPE groupCrypto, u8 groupCryptoLen,
2423 int ssidLength, u8 *ssid,
2424 u8 *bssid, u16 channel, u32 ctrl_flags)
2427 WMI_CONNECT_CMD *cc;
2428 wmip->wmi_traffic_class = 100;
2430 if ((pairwiseCrypto == NONE_CRYPT) && (groupCrypto != NONE_CRYPT)) {
2433 if ((pairwiseCrypto != NONE_CRYPT) && (groupCrypto == NONE_CRYPT)) {
2437 osbuf = A_NETBUF_ALLOC(sizeof(WMI_CONNECT_CMD));
2438 if (osbuf == NULL) {
2442 A_NETBUF_PUT(osbuf, sizeof(WMI_CONNECT_CMD));
2444 cc = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf));
2445 A_MEMZERO(cc, sizeof(*cc));
2449 memcpy(cc->ssid, ssid, ssidLength);
2452 cc->ssidLength = ssidLength;
2453 cc->networkType = netType;
2454 cc->dot11AuthMode = dot11AuthMode;
2455 cc->authMode = authMode;
2456 cc->pairwiseCryptoType = pairwiseCrypto;
2457 cc->pairwiseCryptoLen = pairwiseCryptoLen;
2458 cc->groupCryptoType = groupCrypto;
2459 cc->groupCryptoLen = groupCryptoLen;
2460 cc->channel = channel;
2461 cc->ctrl_flags = ctrl_flags;
2463 if (bssid != NULL) {
2464 memcpy(cc->bssid, bssid, ATH_MAC_LEN);
2467 wmip->wmi_pair_crypto_type = pairwiseCrypto;
2468 wmip->wmi_grp_crypto_type = groupCrypto;
2470 return (wmi_cmd_send(wmip, osbuf, WMI_CONNECT_CMDID, NO_SYNC_WMIFLAG));
2474 wmi_reconnect_cmd(struct wmi_t *wmip, u8 *bssid, u16 channel)
2477 WMI_RECONNECT_CMD *cc;
2478 wmip->wmi_traffic_class = 100;
2480 osbuf = A_NETBUF_ALLOC(sizeof(WMI_RECONNECT_CMD));
2481 if (osbuf == NULL) {
2485 A_NETBUF_PUT(osbuf, sizeof(WMI_RECONNECT_CMD));
2487 cc = (WMI_RECONNECT_CMD *)(A_NETBUF_DATA(osbuf));
2488 A_MEMZERO(cc, sizeof(*cc));
2490 cc->channel = channel;
2492 if (bssid != NULL) {
2493 memcpy(cc->bssid, bssid, ATH_MAC_LEN);
2496 return (wmi_cmd_send(wmip, osbuf, WMI_RECONNECT_CMDID, NO_SYNC_WMIFLAG));
2500 wmi_disconnect_cmd(struct wmi_t *wmip)
2503 wmip->wmi_traffic_class = 100;
2505 /* Bug fix for 24817(elevator bug) - the disconnect command does not
2506 need to do a SYNC before.*/
2507 status = wmi_simple_cmd(wmip, WMI_DISCONNECT_CMDID);
2513 wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType,
2514 u32 forceFgScan, u32 isLegacy,
2515 u32 homeDwellTime, u32 forceScanInterval,
2516 s8 numChan, u16 *channelList)
2519 WMI_START_SCAN_CMD *sc;
2522 size = sizeof (*sc);
2524 if ((scanType != WMI_LONG_SCAN) && (scanType != WMI_SHORT_SCAN)) {
2529 if (numChan > WMI_MAX_CHANNELS) {
2532 size += sizeof(u16) * (numChan - 1);
2535 osbuf = A_NETBUF_ALLOC(size);
2536 if (osbuf == NULL) {
2540 A_NETBUF_PUT(osbuf, size);
2542 sc = (WMI_START_SCAN_CMD *)(A_NETBUF_DATA(osbuf));
2543 sc->scanType = scanType;
2544 sc->forceFgScan = forceFgScan;
2545 sc->isLegacy = isLegacy;
2546 sc->homeDwellTime = homeDwellTime;
2547 sc->forceScanInterval = forceScanInterval;
2548 sc->numChannels = numChan;
2550 memcpy(sc->channelList, channelList, numChan * sizeof(u16));
2553 return (wmi_cmd_send(wmip, osbuf, WMI_START_SCAN_CMDID, NO_SYNC_WMIFLAG));
2557 wmi_scanparams_cmd(struct wmi_t *wmip, u16 fg_start_sec,
2558 u16 fg_end_sec, u16 bg_sec,
2559 u16 minact_chdw_msec, u16 maxact_chdw_msec,
2561 u8 shScanRatio, u8 scanCtrlFlags,
2562 u32 max_dfsch_act_time, u16 maxact_scan_per_ssid)
2565 WMI_SCAN_PARAMS_CMD *sc;
2567 osbuf = A_NETBUF_ALLOC(sizeof(*sc));
2568 if (osbuf == NULL) {
2572 A_NETBUF_PUT(osbuf, sizeof(*sc));
2574 sc = (WMI_SCAN_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
2575 A_MEMZERO(sc, sizeof(*sc));
2576 sc->fg_start_period = fg_start_sec;
2577 sc->fg_end_period = fg_end_sec;
2578 sc->bg_period = bg_sec;
2579 sc->minact_chdwell_time = minact_chdw_msec;
2580 sc->maxact_chdwell_time = maxact_chdw_msec;
2581 sc->pas_chdwell_time = pas_chdw_msec;
2582 sc->shortScanRatio = shScanRatio;
2583 sc->scanCtrlFlags = scanCtrlFlags;
2584 sc->max_dfsch_act_time = max_dfsch_act_time;
2585 sc->maxact_scan_per_ssid = maxact_scan_per_ssid;
2587 return (wmi_cmd_send(wmip, osbuf, WMI_SET_SCAN_PARAMS_CMDID,
2592 wmi_bssfilter_cmd(struct wmi_t *wmip, u8 filter, u32 ieMask)
2595 WMI_BSS_FILTER_CMD *cmd;
2597 if (filter >= LAST_BSS_FILTER) {
2601 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2602 if (osbuf == NULL) {
2606 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2608 cmd = (WMI_BSS_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
2609 A_MEMZERO(cmd, sizeof(*cmd));
2610 cmd->bssFilter = filter;
2611 cmd->ieMask = ieMask;
2613 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BSS_FILTER_CMDID,
2618 wmi_probedSsid_cmd(struct wmi_t *wmip, u8 index, u8 flag,
2619 u8 ssidLength, u8 *ssid)
2622 WMI_PROBED_SSID_CMD *cmd;
2624 if (index > MAX_PROBED_SSID_INDEX) {
2627 if (ssidLength > sizeof(cmd->ssid)) {
2630 if ((flag & (DISABLE_SSID_FLAG | ANY_SSID_FLAG)) && (ssidLength > 0)) {
2633 if ((flag & SPECIFIC_SSID_FLAG) && !ssidLength) {
2637 if (flag & SPECIFIC_SSID_FLAG) {
2638 is_probe_ssid = true;
2641 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2642 if (osbuf == NULL) {
2646 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2648 cmd = (WMI_PROBED_SSID_CMD *)(A_NETBUF_DATA(osbuf));
2649 A_MEMZERO(cmd, sizeof(*cmd));
2650 cmd->entryIndex = index;
2652 cmd->ssidLength = ssidLength;
2653 memcpy(cmd->ssid, ssid, ssidLength);
2655 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PROBED_SSID_CMDID,
2660 wmi_listeninterval_cmd(struct wmi_t *wmip, u16 listenInterval, u16 listenBeacons)
2663 WMI_LISTEN_INT_CMD *cmd;
2665 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2666 if (osbuf == NULL) {
2670 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2672 cmd = (WMI_LISTEN_INT_CMD *)(A_NETBUF_DATA(osbuf));
2673 A_MEMZERO(cmd, sizeof(*cmd));
2674 cmd->listenInterval = listenInterval;
2675 cmd->numBeacons = listenBeacons;
2677 return (wmi_cmd_send(wmip, osbuf, WMI_SET_LISTEN_INT_CMDID,
2682 wmi_bmisstime_cmd(struct wmi_t *wmip, u16 bmissTime, u16 bmissBeacons)
2685 WMI_BMISS_TIME_CMD *cmd;
2687 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2688 if (osbuf == NULL) {
2692 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2694 cmd = (WMI_BMISS_TIME_CMD *)(A_NETBUF_DATA(osbuf));
2695 A_MEMZERO(cmd, sizeof(*cmd));
2696 cmd->bmissTime = bmissTime;
2697 cmd->numBeacons = bmissBeacons;
2699 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BMISS_TIME_CMDID,
2704 wmi_associnfo_cmd(struct wmi_t *wmip, u8 ieType,
2705 u8 ieLen, u8 *ieInfo)
2708 WMI_SET_ASSOC_INFO_CMD *cmd;
2711 cmdLen = sizeof(*cmd) + ieLen - 1;
2712 osbuf = A_NETBUF_ALLOC(cmdLen);
2713 if (osbuf == NULL) {
2717 A_NETBUF_PUT(osbuf, cmdLen);
2719 cmd = (WMI_SET_ASSOC_INFO_CMD *)(A_NETBUF_DATA(osbuf));
2720 A_MEMZERO(cmd, cmdLen);
2721 cmd->ieType = ieType;
2722 cmd->bufferSize = ieLen;
2723 memcpy(cmd->assocInfo, ieInfo, ieLen);
2725 return (wmi_cmd_send(wmip, osbuf, WMI_SET_ASSOC_INFO_CMDID,
2730 wmi_powermode_cmd(struct wmi_t *wmip, u8 powerMode)
2733 WMI_POWER_MODE_CMD *cmd;
2735 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2736 if (osbuf == NULL) {
2740 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2742 cmd = (WMI_POWER_MODE_CMD *)(A_NETBUF_DATA(osbuf));
2743 A_MEMZERO(cmd, sizeof(*cmd));
2744 cmd->powerMode = powerMode;
2745 wmip->wmi_powerMode = powerMode;
2747 return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_MODE_CMDID,
2752 wmi_ibsspmcaps_cmd(struct wmi_t *wmip, u8 pmEnable, u8 ttl,
2753 u16 atim_windows, u16 timeout_value)
2756 WMI_IBSS_PM_CAPS_CMD *cmd;
2758 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2759 if (osbuf == NULL) {
2763 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2765 cmd = (WMI_IBSS_PM_CAPS_CMD *)(A_NETBUF_DATA(osbuf));
2766 A_MEMZERO(cmd, sizeof(*cmd));
2767 cmd->power_saving = pmEnable;
2769 cmd->atim_windows = atim_windows;
2770 cmd->timeout_value = timeout_value;
2772 return (wmi_cmd_send(wmip, osbuf, WMI_SET_IBSS_PM_CAPS_CMDID,
2777 wmi_apps_cmd(struct wmi_t *wmip, u8 psType, u32 idle_time,
2778 u32 ps_period, u8 sleep_period)
2783 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2784 if (osbuf == NULL) {
2788 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2790 cmd = (WMI_AP_PS_CMD *)(A_NETBUF_DATA(osbuf));
2791 A_MEMZERO(cmd, sizeof(*cmd));
2792 cmd->psType = psType;
2793 cmd->idle_time = idle_time;
2794 cmd->ps_period = ps_period;
2795 cmd->sleep_period = sleep_period;
2797 return (wmi_cmd_send(wmip, osbuf, WMI_SET_AP_PS_CMDID,
2802 wmi_pmparams_cmd(struct wmi_t *wmip, u16 idlePeriod,
2803 u16 psPollNum, u16 dtimPolicy,
2804 u16 tx_wakeup_policy, u16 num_tx_to_wakeup,
2805 u16 ps_fail_event_policy)
2808 WMI_POWER_PARAMS_CMD *pm;
2810 osbuf = A_NETBUF_ALLOC(sizeof(*pm));
2811 if (osbuf == NULL) {
2815 A_NETBUF_PUT(osbuf, sizeof(*pm));
2817 pm = (WMI_POWER_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
2818 A_MEMZERO(pm, sizeof(*pm));
2819 pm->idle_period = idlePeriod;
2820 pm->pspoll_number = psPollNum;
2821 pm->dtim_policy = dtimPolicy;
2822 pm->tx_wakeup_policy = tx_wakeup_policy;
2823 pm->num_tx_to_wakeup = num_tx_to_wakeup;
2824 pm->ps_fail_event_policy = ps_fail_event_policy;
2826 return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_PARAMS_CMDID,
2831 wmi_disctimeout_cmd(struct wmi_t *wmip, u8 timeout)
2834 WMI_DISC_TIMEOUT_CMD *cmd;
2836 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2837 if (osbuf == NULL) {
2841 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2843 cmd = (WMI_DISC_TIMEOUT_CMD *)(A_NETBUF_DATA(osbuf));
2844 A_MEMZERO(cmd, sizeof(*cmd));
2845 cmd->disconnectTimeout = timeout;
2847 return (wmi_cmd_send(wmip, osbuf, WMI_SET_DISC_TIMEOUT_CMDID,
2852 wmi_addKey_cmd(struct wmi_t *wmip, u8 keyIndex, CRYPTO_TYPE keyType,
2853 u8 keyUsage, u8 keyLength, u8 *keyRSC,
2854 u8 *keyMaterial, u8 key_op_ctrl, u8 *macAddr,
2855 WMI_SYNC_FLAG sync_flag)
2858 WMI_ADD_CIPHER_KEY_CMD *cmd;
2860 if ((keyIndex > WMI_MAX_KEY_INDEX) || (keyLength > WMI_MAX_KEY_LEN) ||
2861 (keyMaterial == NULL))
2866 if ((WEP_CRYPT != keyType) && (NULL == keyRSC)) {
2870 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2871 if (osbuf == NULL) {
2875 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2877 cmd = (WMI_ADD_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf));
2878 A_MEMZERO(cmd, sizeof(*cmd));
2879 cmd->keyIndex = keyIndex;
2880 cmd->keyType = keyType;
2881 cmd->keyUsage = keyUsage;
2882 cmd->keyLength = keyLength;
2883 memcpy(cmd->key, keyMaterial, keyLength);
2885 if (NULL != keyRSC && key_op_ctrl != KEY_OP_INIT_WAPIPN) {
2887 if (NULL != keyRSC) {
2888 #endif // WAPI_ENABLE
2889 memcpy(cmd->keyRSC, keyRSC, sizeof(cmd->keyRSC));
2891 cmd->key_op_ctrl = key_op_ctrl;
2894 memcpy(cmd->key_macaddr,macAddr,IEEE80211_ADDR_LEN);
2897 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_CIPHER_KEY_CMDID, sync_flag));
2901 wmi_add_krk_cmd(struct wmi_t *wmip, u8 *krk)
2904 WMI_ADD_KRK_CMD *cmd;
2906 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2907 if (osbuf == NULL) {
2911 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2913 cmd = (WMI_ADD_KRK_CMD *)(A_NETBUF_DATA(osbuf));
2914 A_MEMZERO(cmd, sizeof(*cmd));
2915 memcpy(cmd->krk, krk, WMI_KRK_LEN);
2917 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_KRK_CMDID, NO_SYNC_WMIFLAG));
2921 wmi_delete_krk_cmd(struct wmi_t *wmip)
2923 return wmi_simple_cmd(wmip, WMI_DELETE_KRK_CMDID);
2927 wmi_deleteKey_cmd(struct wmi_t *wmip, u8 keyIndex)
2930 WMI_DELETE_CIPHER_KEY_CMD *cmd;
2932 if (keyIndex > WMI_MAX_KEY_INDEX) {
2936 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2937 if (osbuf == NULL) {
2941 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2943 cmd = (WMI_DELETE_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf));
2944 A_MEMZERO(cmd, sizeof(*cmd));
2945 cmd->keyIndex = keyIndex;
2947 return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_CIPHER_KEY_CMDID,
2952 wmi_setPmkid_cmd(struct wmi_t *wmip, u8 *bssid, u8 *pmkId,
2956 WMI_SET_PMKID_CMD *cmd;
2958 if (bssid == NULL) {
2962 if ((set == true) && (pmkId == NULL)) {
2966 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2967 if (osbuf == NULL) {
2971 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2973 cmd = (WMI_SET_PMKID_CMD *)(A_NETBUF_DATA(osbuf));
2974 memcpy(cmd->bssid, bssid, sizeof(cmd->bssid));
2976 memcpy(cmd->pmkid, pmkId, sizeof(cmd->pmkid));
2977 cmd->enable = PMKID_ENABLE;
2979 A_MEMZERO(cmd->pmkid, sizeof(cmd->pmkid));
2980 cmd->enable = PMKID_DISABLE;
2983 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_CMDID, NO_SYNC_WMIFLAG));
2987 wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, bool en)
2990 WMI_SET_TKIP_COUNTERMEASURES_CMD *cmd;
2992 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
2993 if (osbuf == NULL) {
2997 A_NETBUF_PUT(osbuf, sizeof(*cmd));
2999 cmd = (WMI_SET_TKIP_COUNTERMEASURES_CMD *)(A_NETBUF_DATA(osbuf));
3000 cmd->cm_en = (en == true)? WMI_TKIP_CM_ENABLE : WMI_TKIP_CM_DISABLE;
3002 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TKIP_COUNTERMEASURES_CMDID,
3007 wmi_set_akmp_params_cmd(struct wmi_t *wmip,
3008 WMI_SET_AKMP_PARAMS_CMD *akmpParams)
3011 WMI_SET_AKMP_PARAMS_CMD *cmd;
3013 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3014 if (osbuf == NULL) {
3018 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3019 cmd = (WMI_SET_AKMP_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
3020 cmd->akmpInfo = akmpParams->akmpInfo;
3022 return (wmi_cmd_send(wmip, osbuf, WMI_SET_AKMP_PARAMS_CMDID,
3027 wmi_set_pmkid_list_cmd(struct wmi_t *wmip,
3028 WMI_SET_PMKID_LIST_CMD *pmkInfo)
3031 WMI_SET_PMKID_LIST_CMD *cmd;
3035 cmdLen = sizeof(pmkInfo->numPMKID) +
3036 pmkInfo->numPMKID * sizeof(WMI_PMKID);
3038 osbuf = A_NETBUF_ALLOC(cmdLen);
3039 if (osbuf == NULL) {
3043 A_NETBUF_PUT(osbuf, cmdLen);
3044 cmd = (WMI_SET_PMKID_LIST_CMD *)(A_NETBUF_DATA(osbuf));
3045 cmd->numPMKID = pmkInfo->numPMKID;
3047 for (i = 0; i < cmd->numPMKID; i++) {
3048 memcpy(&cmd->pmkidList[i], &pmkInfo->pmkidList[i],
3052 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_LIST_CMDID,
3057 wmi_get_pmkid_list_cmd(struct wmi_t *wmip)
3059 return wmi_simple_cmd(wmip, WMI_GET_PMKID_LIST_CMDID);
3063 wmi_dataSync_send(struct wmi_t *wmip, void *osbuf, HTC_ENDPOINT_ID eid)
3065 WMI_DATA_HDR *dtHdr;
3067 A_ASSERT( eid != wmip->wmi_endpoint_id);
3068 A_ASSERT(osbuf != NULL);
3070 if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != 0) {
3074 dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf);
3076 (SYNC_MSGTYPE & WMI_DATA_HDR_MSG_TYPE_MASK) << WMI_DATA_HDR_MSG_TYPE_SHIFT;
3078 A_DPRINTF(DBG_WMI, (DBGFMT "Enter - eid %d\n", DBGARG, eid));
3080 return (A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid));
3083 typedef struct _WMI_DATA_SYNC_BUFS {
3086 }WMI_DATA_SYNC_BUFS;
3089 wmi_sync_point(struct wmi_t *wmip)
3093 WMI_DATA_SYNC_BUFS dataSyncBufs[WMM_NUM_AC];
3094 u8 i,numPriStreams=0;
3097 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
3099 memset(dataSyncBufs,0,sizeof(dataSyncBufs));
3101 /* lock out while we walk through the priority list and assemble our local array */
3104 for (i=0; i < WMM_NUM_AC ; i++) {
3105 if (wmip->wmi_fatPipeExists & (1 << i)) {
3107 dataSyncBufs[numPriStreams-1].trafficClass = i;
3113 /* dataSyncBufs is now filled with entries (starting at index 0) containing valid streamIDs */
3117 * We allocate all network buffers needed so we will be able to
3118 * send all required frames.
3120 cmd_osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3121 if (cmd_osbuf == NULL) {
3122 status = A_NO_MEMORY;
3126 A_NETBUF_PUT(cmd_osbuf, sizeof(*cmd));
3128 cmd = (WMI_SYNC_CMD *)(A_NETBUF_DATA(cmd_osbuf));
3129 A_MEMZERO(cmd, sizeof(*cmd));
3131 /* In the SYNC cmd sent on the control Ep, send a bitmap of the data
3132 * eps on which the Data Sync will be sent
3134 cmd->dataSyncMap = wmip->wmi_fatPipeExists;
3136 for (i=0; i < numPriStreams ; i++) {
3137 dataSyncBufs[i].osbuf = A_NETBUF_ALLOC(0);
3138 if (dataSyncBufs[i].osbuf == NULL) {
3139 status = A_NO_MEMORY;
3144 /* if Buffer allocation for any of the dataSync fails, then do not
3145 * send the Synchronize cmd on the control ep
3152 * Send sync cmd followed by sync data messages on all endpoints being
3155 status = wmi_cmd_send(wmip, cmd_osbuf, WMI_SYNCHRONIZE_CMDID,
3161 /* cmd buffer sent, we no longer own it */
3164 for(i=0; i < numPriStreams; i++) {
3165 A_ASSERT(dataSyncBufs[i].osbuf != NULL);
3166 status = wmi_dataSync_send(wmip,
3167 dataSyncBufs[i].osbuf,
3168 A_WMI_Ac2EndpointID(wmip->wmi_devt,
3176 /* we don't own this buffer anymore, NULL it out of the array so it
3177 * won't get cleaned up */
3178 dataSyncBufs[i].osbuf = NULL;
3183 /* free up any resources left over (possibly due to an error) */
3185 if (cmd_osbuf != NULL) {
3186 A_NETBUF_FREE(cmd_osbuf);
3189 for (i = 0; i < numPriStreams; i++) {
3190 if (dataSyncBufs[i].osbuf != NULL) {
3191 A_NETBUF_FREE(dataSyncBufs[i].osbuf);
3199 wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *params)
3202 WMI_CREATE_PSTREAM_CMD *cmd;
3203 u8 fatPipeExistsForAC=0;
3207 /* Validate all the parameters. */
3208 if( !((params->userPriority < 8) &&
3209 (params->userPriority <= 0x7) &&
3210 (convert_userPriority_to_trafficClass(params->userPriority) == params->trafficClass) &&
3211 (params->trafficDirection == UPLINK_TRAFFIC ||
3212 params->trafficDirection == DNLINK_TRAFFIC ||
3213 params->trafficDirection == BIDIR_TRAFFIC) &&
3214 (params->trafficType == TRAFFIC_TYPE_APERIODIC ||
3215 params->trafficType == TRAFFIC_TYPE_PERIODIC ) &&
3216 (params->voicePSCapability == DISABLE_FOR_THIS_AC ||
3217 params->voicePSCapability == ENABLE_FOR_THIS_AC ||
3218 params->voicePSCapability == ENABLE_FOR_ALL_AC) &&
3219 (params->tsid == WMI_IMPLICIT_PSTREAM || params->tsid <= WMI_MAX_THINSTREAM)) )
3225 // check nominal PHY rate is >= minimalPHY, so that DUT
3226 // can allow TSRS IE
3229 // get the physical rate
3230 minimalPHY = ((params->minPhyRate / 1000)/1000); // unit of bps
3232 // check minimal phy < nominal phy rate
3234 if (params->nominalPHY >= minimalPHY)
3236 nominalPHY = (params->nominalPHY * 1000)/500; // unit of 500 kbps
3238 (DBGFMT "TSRS IE Enabled::MinPhy %x->NominalPhy ===> %x\n", DBGARG,
3239 minimalPHY, nominalPHY));
3241 params->nominalPHY = nominalPHY;
3245 params->nominalPHY = 0;
3248 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3249 if (osbuf == NULL) {
3253 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3256 (DBGFMT "Sending create_pstream_cmd: ac=%d tsid:%d\n", DBGARG,
3257 params->trafficClass, params->tsid));
3259 cmd = (WMI_CREATE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf));
3260 A_MEMZERO(cmd, sizeof(*cmd));
3261 memcpy(cmd, params, sizeof(*cmd));
3263 /* this is an implicitly created Fat pipe */
3264 if ((u32)params->tsid == (u32)WMI_IMPLICIT_PSTREAM) {
3266 fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass));
3267 wmip->wmi_fatPipeExists |= (1<<params->trafficClass);
3270 /* this is an explicitly created thin stream within a fat pipe */
3272 fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass));
3273 wmip->wmi_streamExistsForAC[params->trafficClass] |= (1<<params->tsid);
3274 /* if a thinstream becomes active, the fat pipe automatically
3277 wmip->wmi_fatPipeExists |= (1<<params->trafficClass);
3281 /* Indicate activty change to driver layer only if this is the
3282 * first TSID to get created in this AC explicitly or an implicit
3283 * fat pipe is getting created.
3285 if (!fatPipeExistsForAC) {
3286 A_WMI_STREAM_TX_ACTIVE(wmip->wmi_devt, params->trafficClass);
3289 /* mike: should be SYNC_BEFORE_WMIFLAG */
3290 return (wmi_cmd_send(wmip, osbuf, WMI_CREATE_PSTREAM_CMDID,
3295 wmi_delete_pstream_cmd(struct wmi_t *wmip, u8 trafficClass, u8 tsid)
3298 WMI_DELETE_PSTREAM_CMD *cmd;
3302 /* validate the parameters */
3303 if (trafficClass > 3) {
3304 A_DPRINTF(DBG_WMI, (DBGFMT "Invalid trafficClass: %d\n", DBGARG, trafficClass));
3308 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3309 if (osbuf == NULL) {
3313 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3315 cmd = (WMI_DELETE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf));
3316 A_MEMZERO(cmd, sizeof(*cmd));
3318 cmd->trafficClass = trafficClass;
3322 activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
3325 /* Check if the tsid was created & exists */
3326 if (!(activeTsids & (1<<tsid))) {
3328 A_NETBUF_FREE(osbuf);
3330 (DBGFMT "TSID %d does'nt exist for trafficClass: %d\n", DBGARG, tsid, trafficClass));
3331 /* TODO: return a more appropriate err code */
3336 (DBGFMT "Sending delete_pstream_cmd: trafficClass: %d tsid=%d\n", DBGARG, trafficClass, tsid));
3338 status = (wmi_cmd_send(wmip, osbuf, WMI_DELETE_PSTREAM_CMDID,
3339 SYNC_BEFORE_WMIFLAG));
3342 wmip->wmi_streamExistsForAC[trafficClass] &= ~(1<<tsid);
3343 activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
3347 /* Indicate stream inactivity to driver layer only if all tsids
3348 * within this AC are deleted.
3351 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, trafficClass);
3352 wmip->wmi_fatPipeExists &= ~(1<<trafficClass);
3359 wmi_set_framerate_cmd(struct wmi_t *wmip, u8 bEnable, u8 type, u8 subType, u16 rateMask)
3362 WMI_FRAME_RATES_CMD *cmd;
3366 (DBGFMT " type %02X, subType %02X, rateMask %04x\n", DBGARG, type, subType, rateMask));
3368 if((type != IEEE80211_FRAME_TYPE_MGT && type != IEEE80211_FRAME_TYPE_CTL) ||
3374 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3375 if (osbuf == NULL) {
3379 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3381 cmd = (WMI_FRAME_RATES_CMD *)(A_NETBUF_DATA(osbuf));
3382 A_MEMZERO(cmd, sizeof(*cmd));
3384 frameType = (u8)((subType << 4) | type);
3386 cmd->bEnableMask = bEnable;
3387 cmd->frameType = frameType;
3388 cmd->frameRateMask = rateMask;
3390 return (wmi_cmd_send(wmip, osbuf, WMI_SET_FRAMERATES_CMDID, NO_SYNC_WMIFLAG));
3394 * used to set the bit rate. rate is in Kbps. If rate == -1
3395 * then auto selection is used.
3398 wmi_set_bitrate_cmd(struct wmi_t *wmip, s32 dataRate, s32 mgmtRate, s32 ctlRate)
3401 WMI_BIT_RATE_CMD *cmd;
3402 s8 drix, mrix, crix, ret_val;
3404 if (dataRate != -1) {
3405 ret_val = wmi_validate_bitrate(wmip, dataRate, &drix);
3406 if(ret_val == A_EINVAL){
3413 if (mgmtRate != -1) {
3414 ret_val = wmi_validate_bitrate(wmip, mgmtRate, &mrix);
3415 if(ret_val == A_EINVAL){
3421 if (ctlRate != -1) {
3422 ret_val = wmi_validate_bitrate(wmip, ctlRate, &crix);
3423 if(ret_val == A_EINVAL){
3429 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3430 if (osbuf == NULL) {
3434 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3436 cmd = (WMI_BIT_RATE_CMD *)(A_NETBUF_DATA(osbuf));
3437 A_MEMZERO(cmd, sizeof(*cmd));
3439 cmd->rateIndex = drix;
3440 cmd->mgmtRateIndex = mrix;
3441 cmd->ctlRateIndex = crix;
3444 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BITRATE_CMDID, NO_SYNC_WMIFLAG));
3448 wmi_get_bitrate_cmd(struct wmi_t *wmip)
3450 return wmi_simple_cmd(wmip, WMI_GET_BITRATE_CMDID);
3454 * Returns true iff the given rate index is legal in the current PHY mode.
3457 wmi_is_bitrate_index_valid(struct wmi_t *wmip, s32 rateIndex)
3459 WMI_PHY_MODE phyMode = (WMI_PHY_MODE) wmip->wmi_phyMode;
3460 bool isValid = true;
3463 if (wmip->wmi_ht_allowed[A_BAND_5GHZ]){
3464 if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
3468 if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_A_SUPPORT_RATE_STOP)) {
3475 if ((rateIndex < MODE_B_SUPPORT_RATE_START) || (rateIndex > MODE_B_SUPPORT_RATE_STOP)) {
3480 case WMI_11GONLY_MODE:
3481 if (wmip->wmi_ht_allowed[A_BAND_24GHZ]){
3482 if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
3486 if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE_GONLY_SUPPORT_RATE_STOP)) {
3494 if (wmip->wmi_ht_allowed[A_BAND_24GHZ]){
3495 if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
3499 if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_G_SUPPORT_RATE_STOP)) {
3512 s8 wmi_validate_bitrate(struct wmi_t *wmip, s32 rate, s8 *rate_idx)
3518 if (wmi_rateTable[(u32) i][0] == 0) {
3521 if (wmi_rateTable[(u32) i][0] == rate) {
3526 if(wmi_is_bitrate_index_valid(wmip, (s32) i) != true) {
3535 wmi_set_fixrates_cmd(struct wmi_t *wmip, u32 fixRatesMask)
3538 WMI_FIX_RATES_CMD *cmd;
3541 /* This check does not work for AR6003 as the HT modes are enabled only when
3542 * the STA is connected to a HT_BSS and is not based only on channel. It is
3543 * safe to skip this check however because rate control will only use rates
3544 * that are permitted by the valid rate mask and the fix rate mask. Meaning
3545 * the fix rate mask is not sufficient by itself to cause an invalid rate
3547 /* Make sure all rates in the mask are valid in the current PHY mode */
3548 for(rateIndex = 0; rateIndex < MAX_NUMBER_OF_SUPPORT_RATES; rateIndex++) {
3549 if((1 << rateIndex) & (u32)fixRatesMask) {
3550 if(wmi_is_bitrate_index_valid(wmip, rateIndex) != true) {
3551 A_DPRINTF(DBG_WMI, (DBGFMT "Set Fix Rates command failed: Given rate is illegal in current PHY mode\n", DBGARG));
3559 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3560 if (osbuf == NULL) {
3564 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3566 cmd = (WMI_FIX_RATES_CMD *)(A_NETBUF_DATA(osbuf));
3567 A_MEMZERO(cmd, sizeof(*cmd));
3569 cmd->fixRateMask = fixRatesMask;
3571 return (wmi_cmd_send(wmip, osbuf, WMI_SET_FIXRATES_CMDID, NO_SYNC_WMIFLAG));
3575 wmi_get_ratemask_cmd(struct wmi_t *wmip)
3577 return wmi_simple_cmd(wmip, WMI_GET_FIXRATES_CMDID);
3581 wmi_get_channelList_cmd(struct wmi_t *wmip)
3583 return wmi_simple_cmd(wmip, WMI_GET_CHANNEL_LIST_CMDID);
3587 * used to generate a wmi sey channel Parameters cmd.
3588 * mode should always be specified and corresponds to the phy mode of the
3590 * numChan should alway sbe specified. If zero indicates that all available
3591 * channels should be used.
3592 * channelList is an array of channel frequencies (in Mhz) which the radio
3593 * should limit its operation to. It should be NULL if numChan == 0. Size of
3594 * array should correspond to numChan entries.
3597 wmi_set_channelParams_cmd(struct wmi_t *wmip, u8 scanParam,
3598 WMI_PHY_MODE mode, s8 numChan,
3602 WMI_CHANNEL_PARAMS_CMD *cmd;
3605 size = sizeof (*cmd);
3608 if (numChan > WMI_MAX_CHANNELS) {
3611 size += sizeof(u16) * (numChan - 1);
3614 osbuf = A_NETBUF_ALLOC(size);
3615 if (osbuf == NULL) {
3619 A_NETBUF_PUT(osbuf, size);
3621 cmd = (WMI_CHANNEL_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
3622 A_MEMZERO(cmd, size);
3624 wmip->wmi_phyMode = mode;
3625 cmd->scanParam = scanParam;
3626 cmd->phyMode = mode;
3627 cmd->numChannels = numChan;
3628 memcpy(cmd->channelList, channelList, numChan * sizeof(u16));
3630 return (wmi_cmd_send(wmip, osbuf, WMI_SET_CHANNEL_PARAMS_CMDID,
3635 wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
3637 SQ_THRESHOLD_PARAMS *sq_thresh =
3638 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI];
3640 * Parse the command and store the threshold values here. The checks
3641 * for valid values can be put here
3643 sq_thresh->weight = rssiCmd->weight;
3644 sq_thresh->polling_interval = rssiCmd->pollTime;
3646 sq_thresh->upper_threshold[0] = rssiCmd->thresholdAbove1_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3647 sq_thresh->upper_threshold[1] = rssiCmd->thresholdAbove2_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3648 sq_thresh->upper_threshold[2] = rssiCmd->thresholdAbove3_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3649 sq_thresh->upper_threshold[3] = rssiCmd->thresholdAbove4_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3650 sq_thresh->upper_threshold[4] = rssiCmd->thresholdAbove5_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3651 sq_thresh->upper_threshold[5] = rssiCmd->thresholdAbove6_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3652 sq_thresh->upper_threshold_valid_count = 6;
3654 /* List sorted in descending order */
3655 sq_thresh->lower_threshold[0] = rssiCmd->thresholdBelow6_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3656 sq_thresh->lower_threshold[1] = rssiCmd->thresholdBelow5_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3657 sq_thresh->lower_threshold[2] = rssiCmd->thresholdBelow4_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3658 sq_thresh->lower_threshold[3] = rssiCmd->thresholdBelow3_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3659 sq_thresh->lower_threshold[4] = rssiCmd->thresholdBelow2_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3660 sq_thresh->lower_threshold[5] = rssiCmd->thresholdBelow1_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3661 sq_thresh->lower_threshold_valid_count = 6;
3663 if (!rssi_event_value) {
3665 * Configuring the thresholds to their extremes allows the host to get an
3666 * event from the target which is used for the configuring the correct
3669 rssiCmd->thresholdAbove1_Val = sq_thresh->upper_threshold[0];
3670 rssiCmd->thresholdBelow1_Val = sq_thresh->lower_threshold[0];
3673 * In case the user issues multiple times of rssi_threshold_setting,
3674 * we should not use the extreames anymore, the target does not expect that.
3676 rssiCmd->thresholdAbove1_Val = ar6000_get_upper_threshold(rssi_event_value, sq_thresh,
3677 sq_thresh->upper_threshold_valid_count);
3678 rssiCmd->thresholdBelow1_Val = ar6000_get_lower_threshold(rssi_event_value, sq_thresh,
3679 sq_thresh->lower_threshold_valid_count);
3684 wmi_set_rssi_threshold_params(struct wmi_t *wmip,
3685 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
3688 /* Check these values are in ascending order */
3689 if( rssiCmd->thresholdAbove6_Val <= rssiCmd->thresholdAbove5_Val ||
3690 rssiCmd->thresholdAbove5_Val <= rssiCmd->thresholdAbove4_Val ||
3691 rssiCmd->thresholdAbove4_Val <= rssiCmd->thresholdAbove3_Val ||
3692 rssiCmd->thresholdAbove3_Val <= rssiCmd->thresholdAbove2_Val ||
3693 rssiCmd->thresholdAbove2_Val <= rssiCmd->thresholdAbove1_Val ||
3694 rssiCmd->thresholdBelow6_Val <= rssiCmd->thresholdBelow5_Val ||
3695 rssiCmd->thresholdBelow5_Val <= rssiCmd->thresholdBelow4_Val ||
3696 rssiCmd->thresholdBelow4_Val <= rssiCmd->thresholdBelow3_Val ||
3697 rssiCmd->thresholdBelow3_Val <= rssiCmd->thresholdBelow2_Val ||
3698 rssiCmd->thresholdBelow2_Val <= rssiCmd->thresholdBelow1_Val)
3703 wmi_cache_configure_rssithreshold(wmip, rssiCmd);
3705 return (wmi_send_rssi_threshold_params(wmip, rssiCmd));
3709 wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *ipCmd)
3712 WMI_SET_IP_CMD *cmd;
3714 /* Multicast address are not valid */
3715 if((*((u8 *)&ipCmd->ips[0]) >= 0xE0) ||
3716 (*((u8 *)&ipCmd->ips[1]) >= 0xE0)) {
3720 osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_IP_CMD));
3721 if (osbuf == NULL) {
3725 A_NETBUF_PUT(osbuf, sizeof(WMI_SET_IP_CMD));
3726 cmd = (WMI_SET_IP_CMD *)(A_NETBUF_DATA(osbuf));
3727 memcpy(cmd, ipCmd, sizeof(WMI_SET_IP_CMD));
3729 return (wmi_cmd_send(wmip, osbuf, WMI_SET_IP_CMDID,
3734 wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip,
3735 WMI_SET_HOST_SLEEP_MODE_CMD *hostModeCmd)
3739 WMI_SET_HOST_SLEEP_MODE_CMD *cmd;
3744 if( hostModeCmd->awake == hostModeCmd->asleep) {
3748 size = sizeof (*cmd);
3750 osbuf = A_NETBUF_ALLOC(size);
3751 if (osbuf == NULL) {
3755 A_NETBUF_PUT(osbuf, size);
3757 cmd = (WMI_SET_HOST_SLEEP_MODE_CMD *)(A_NETBUF_DATA(osbuf));
3758 A_MEMZERO(cmd, size);
3759 memcpy(cmd, hostModeCmd, sizeof(WMI_SET_HOST_SLEEP_MODE_CMD));
3761 if(hostModeCmd->asleep) {
3763 * Relinquish credits from all implicitly created pstreams since when we
3764 * go to sleep. If user created explicit thinstreams exists with in a
3765 * fatpipe leave them intact for the user to delete
3768 streamExists = wmip->wmi_fatPipeExists;
3771 for(i=0;i< WMM_NUM_AC;i++) {
3772 if (streamExists & (1<<i)) {
3774 activeTsids = wmip->wmi_streamExistsForAC[i];
3776 /* If there are no user created thin streams delete the fatpipe */
3778 streamExists &= ~(1<<i);
3779 /*Indicate inactivity to drv layer for this fatpipe(pstream)*/
3780 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt,i);
3785 /* Update the fatpipes that exists*/
3787 wmip->wmi_fatPipeExists = streamExists;
3791 return (wmi_cmd_send(wmip, osbuf, WMI_SET_HOST_SLEEP_MODE_CMDID,
3796 wmi_set_wow_mode_cmd(struct wmi_t *wmip,
3797 WMI_SET_WOW_MODE_CMD *wowModeCmd)
3801 WMI_SET_WOW_MODE_CMD *cmd;
3803 size = sizeof (*cmd);
3805 osbuf = A_NETBUF_ALLOC(size);
3806 if (osbuf == NULL) {
3810 A_NETBUF_PUT(osbuf, size);
3812 cmd = (WMI_SET_WOW_MODE_CMD *)(A_NETBUF_DATA(osbuf));
3813 A_MEMZERO(cmd, size);
3814 memcpy(cmd, wowModeCmd, sizeof(WMI_SET_WOW_MODE_CMD));
3816 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WOW_MODE_CMDID,
3822 wmi_get_wow_list_cmd(struct wmi_t *wmip,
3823 WMI_GET_WOW_LIST_CMD *wowListCmd)
3827 WMI_GET_WOW_LIST_CMD *cmd;
3829 size = sizeof (*cmd);
3831 osbuf = A_NETBUF_ALLOC(size);
3832 if (osbuf == NULL) {
3836 A_NETBUF_PUT(osbuf, size);
3838 cmd = (WMI_GET_WOW_LIST_CMD *)(A_NETBUF_DATA(osbuf));
3839 A_MEMZERO(cmd, size);
3840 memcpy(cmd, wowListCmd, sizeof(WMI_GET_WOW_LIST_CMD));
3842 return (wmi_cmd_send(wmip, osbuf, WMI_GET_WOW_LIST_CMDID,
3848 wmi_get_wow_list_event_rx(struct wmi_t *wmip, u8 *datap, int len)
3850 WMI_GET_WOW_LIST_REPLY *reply;
3852 if (len < sizeof(WMI_GET_WOW_LIST_REPLY)) {
3855 reply = (WMI_GET_WOW_LIST_REPLY *)datap;
3857 A_WMI_WOW_LIST_EVENT(wmip->wmi_devt, reply->num_filters,
3863 int wmi_add_wow_pattern_cmd(struct wmi_t *wmip,
3864 WMI_ADD_WOW_PATTERN_CMD *addWowCmd,
3865 u8 *pattern, u8 *mask,
3870 WMI_ADD_WOW_PATTERN_CMD *cmd;
3871 u8 *filter_mask = NULL;
3873 size = sizeof (*cmd);
3875 size += ((2 * addWowCmd->filter_size)* sizeof(u8));
3876 osbuf = A_NETBUF_ALLOC(size);
3877 if (osbuf == NULL) {
3881 A_NETBUF_PUT(osbuf, size);
3883 cmd = (WMI_ADD_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf));
3884 cmd->filter_list_id = addWowCmd->filter_list_id;
3885 cmd->filter_offset = addWowCmd->filter_offset;
3886 cmd->filter_size = addWowCmd->filter_size;
3888 memcpy(cmd->filter, pattern, addWowCmd->filter_size);
3890 filter_mask = (u8 *)(cmd->filter + cmd->filter_size);
3891 memcpy(filter_mask, mask, addWowCmd->filter_size);
3894 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_WOW_PATTERN_CMDID,
3899 wmi_del_wow_pattern_cmd(struct wmi_t *wmip,
3900 WMI_DEL_WOW_PATTERN_CMD *delWowCmd)
3904 WMI_DEL_WOW_PATTERN_CMD *cmd;
3906 size = sizeof (*cmd);
3908 osbuf = A_NETBUF_ALLOC(size);
3909 if (osbuf == NULL) {
3913 A_NETBUF_PUT(osbuf, size);
3915 cmd = (WMI_DEL_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf));
3916 A_MEMZERO(cmd, size);
3917 memcpy(cmd, delWowCmd, sizeof(WMI_DEL_WOW_PATTERN_CMD));
3919 return (wmi_cmd_send(wmip, osbuf, WMI_DEL_WOW_PATTERN_CMDID,
3925 wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
3927 SQ_THRESHOLD_PARAMS *sq_thresh =
3928 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_SNR];
3930 * Parse the command and store the threshold values here. The checks
3931 * for valid values can be put here
3933 sq_thresh->weight = snrCmd->weight;
3934 sq_thresh->polling_interval = snrCmd->pollTime;
3936 sq_thresh->upper_threshold[0] = snrCmd->thresholdAbove1_Val;
3937 sq_thresh->upper_threshold[1] = snrCmd->thresholdAbove2_Val;
3938 sq_thresh->upper_threshold[2] = snrCmd->thresholdAbove3_Val;
3939 sq_thresh->upper_threshold[3] = snrCmd->thresholdAbove4_Val;
3940 sq_thresh->upper_threshold_valid_count = 4;
3942 /* List sorted in descending order */
3943 sq_thresh->lower_threshold[0] = snrCmd->thresholdBelow4_Val;
3944 sq_thresh->lower_threshold[1] = snrCmd->thresholdBelow3_Val;
3945 sq_thresh->lower_threshold[2] = snrCmd->thresholdBelow2_Val;
3946 sq_thresh->lower_threshold[3] = snrCmd->thresholdBelow1_Val;
3947 sq_thresh->lower_threshold_valid_count = 4;
3949 if (!snr_event_value) {
3951 * Configuring the thresholds to their extremes allows the host to get an
3952 * event from the target which is used for the configuring the correct
3955 snrCmd->thresholdAbove1_Val = (u8)sq_thresh->upper_threshold[0];
3956 snrCmd->thresholdBelow1_Val = (u8)sq_thresh->lower_threshold[0];
3959 * In case the user issues multiple times of snr_threshold_setting,
3960 * we should not use the extreames anymore, the target does not expect that.
3962 snrCmd->thresholdAbove1_Val = ar6000_get_upper_threshold(snr_event_value, sq_thresh,
3963 sq_thresh->upper_threshold_valid_count);
3964 snrCmd->thresholdBelow1_Val = ar6000_get_lower_threshold(snr_event_value, sq_thresh,
3965 sq_thresh->lower_threshold_valid_count);
3970 wmi_set_snr_threshold_params(struct wmi_t *wmip,
3971 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
3973 if( snrCmd->thresholdAbove4_Val <= snrCmd->thresholdAbove3_Val ||
3974 snrCmd->thresholdAbove3_Val <= snrCmd->thresholdAbove2_Val ||
3975 snrCmd->thresholdAbove2_Val <= snrCmd->thresholdAbove1_Val ||
3976 snrCmd->thresholdBelow4_Val <= snrCmd->thresholdBelow3_Val ||
3977 snrCmd->thresholdBelow3_Val <= snrCmd->thresholdBelow2_Val ||
3978 snrCmd->thresholdBelow2_Val <= snrCmd->thresholdBelow1_Val)
3982 wmi_cache_configure_snrthreshold(wmip, snrCmd);
3983 return (wmi_send_snr_threshold_params(wmip, snrCmd));
3987 wmi_clr_rssi_snr(struct wmi_t *wmip)
3991 osbuf = A_NETBUF_ALLOC(sizeof(int));
3992 if (osbuf == NULL) {
3996 return (wmi_cmd_send(wmip, osbuf, WMI_CLR_RSSI_SNR_CMDID,
4001 wmi_set_lq_threshold_params(struct wmi_t *wmip,
4002 WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd)
4006 WMI_LQ_THRESHOLD_PARAMS_CMD *cmd;
4007 /* These values are in ascending order */
4008 if( lqCmd->thresholdAbove4_Val <= lqCmd->thresholdAbove3_Val ||
4009 lqCmd->thresholdAbove3_Val <= lqCmd->thresholdAbove2_Val ||
4010 lqCmd->thresholdAbove2_Val <= lqCmd->thresholdAbove1_Val ||
4011 lqCmd->thresholdBelow4_Val <= lqCmd->thresholdBelow3_Val ||
4012 lqCmd->thresholdBelow3_Val <= lqCmd->thresholdBelow2_Val ||
4013 lqCmd->thresholdBelow2_Val <= lqCmd->thresholdBelow1_Val ) {
4018 size = sizeof (*cmd);
4020 osbuf = A_NETBUF_ALLOC(size);
4021 if (osbuf == NULL) {
4025 A_NETBUF_PUT(osbuf, size);
4027 cmd = (WMI_LQ_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
4028 A_MEMZERO(cmd, size);
4029 memcpy(cmd, lqCmd, sizeof(WMI_LQ_THRESHOLD_PARAMS_CMD));
4031 return (wmi_cmd_send(wmip, osbuf, WMI_LQ_THRESHOLD_PARAMS_CMDID,
4036 wmi_set_error_report_bitmask(struct wmi_t *wmip, u32 mask)
4040 WMI_TARGET_ERROR_REPORT_BITMASK *cmd;
4042 size = sizeof (*cmd);
4044 osbuf = A_NETBUF_ALLOC(size);
4045 if (osbuf == NULL) {
4049 A_NETBUF_PUT(osbuf, size);
4051 cmd = (WMI_TARGET_ERROR_REPORT_BITMASK *)(A_NETBUF_DATA(osbuf));
4052 A_MEMZERO(cmd, size);
4054 cmd->bitmask = mask;
4056 return (wmi_cmd_send(wmip, osbuf, WMI_TARGET_ERROR_REPORT_BITMASK_CMDID,
4061 wmi_get_challenge_resp_cmd(struct wmi_t *wmip, u32 cookie, u32 source)
4064 WMIX_HB_CHALLENGE_RESP_CMD *cmd;
4066 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4067 if (osbuf == NULL) {
4071 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4073 cmd = (WMIX_HB_CHALLENGE_RESP_CMD *)(A_NETBUF_DATA(osbuf));
4074 cmd->cookie = cookie;
4075 cmd->source = source;
4077 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_HB_CHALLENGE_RESP_CMDID,
4082 wmi_config_debug_module_cmd(struct wmi_t *wmip, u16 mmask,
4083 u16 tsr, bool rep, u16 size,
4087 WMIX_DBGLOG_CFG_MODULE_CMD *cmd;
4089 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4090 if (osbuf == NULL) {
4094 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4096 cmd = (WMIX_DBGLOG_CFG_MODULE_CMD *)(A_NETBUF_DATA(osbuf));
4097 cmd->config.cfgmmask = mmask;
4098 cmd->config.cfgtsr = tsr;
4099 cmd->config.cfgrep = rep;
4100 cmd->config.cfgsize = size;
4101 cmd->config.cfgvalid = valid;
4103 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DBGLOG_CFG_MODULE_CMDID,
4108 wmi_get_stats_cmd(struct wmi_t *wmip)
4110 return wmi_simple_cmd(wmip, WMI_GET_STATISTICS_CMDID);
4114 wmi_addBadAp_cmd(struct wmi_t *wmip, u8 apIndex, u8 *bssid)
4117 WMI_ADD_BAD_AP_CMD *cmd;
4119 if ((bssid == NULL) || (apIndex > WMI_MAX_BAD_AP_INDEX)) {
4123 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4124 if (osbuf == NULL) {
4128 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4130 cmd = (WMI_ADD_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf));
4131 cmd->badApIndex = apIndex;
4132 memcpy(cmd->bssid, bssid, sizeof(cmd->bssid));
4134 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_BAD_AP_CMDID, SYNC_BEFORE_WMIFLAG));
4138 wmi_deleteBadAp_cmd(struct wmi_t *wmip, u8 apIndex)
4141 WMI_DELETE_BAD_AP_CMD *cmd;
4143 if (apIndex > WMI_MAX_BAD_AP_INDEX) {
4147 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4148 if (osbuf == NULL) {
4152 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4154 cmd = (WMI_DELETE_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf));
4155 cmd->badApIndex = apIndex;
4157 return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_BAD_AP_CMDID,
4162 wmi_abort_scan_cmd(struct wmi_t *wmip)
4164 return wmi_simple_cmd(wmip, WMI_ABORT_SCAN_CMDID);
4168 wmi_set_txPwr_cmd(struct wmi_t *wmip, u8 dbM)
4171 WMI_SET_TX_PWR_CMD *cmd;
4173 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4174 if (osbuf == NULL) {
4178 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4180 cmd = (WMI_SET_TX_PWR_CMD *)(A_NETBUF_DATA(osbuf));
4183 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_PWR_CMDID, NO_SYNC_WMIFLAG));
4187 wmi_get_txPwr_cmd(struct wmi_t *wmip)
4189 return wmi_simple_cmd(wmip, WMI_GET_TX_PWR_CMDID);
4192 u16 wmi_get_mapped_qos_queue(struct wmi_t *wmip, u8 trafficClass)
4197 activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
4204 wmi_get_roam_tbl_cmd(struct wmi_t *wmip)
4206 return wmi_simple_cmd(wmip, WMI_GET_ROAM_TBL_CMDID);
4210 wmi_get_roam_data_cmd(struct wmi_t *wmip, u8 roamDataType)
4213 u32 size = sizeof(u8);
4214 WMI_TARGET_ROAM_DATA *cmd;
4216 osbuf = A_NETBUF_ALLOC(size); /* no payload */
4217 if (osbuf == NULL) {
4221 A_NETBUF_PUT(osbuf, size);
4223 cmd = (WMI_TARGET_ROAM_DATA *)(A_NETBUF_DATA(osbuf));
4224 cmd->roamDataType = roamDataType;
4226 return (wmi_cmd_send(wmip, osbuf, WMI_GET_ROAM_DATA_CMDID,
4231 wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p,
4235 WMI_SET_ROAM_CTRL_CMD *cmd;
4237 osbuf = A_NETBUF_ALLOC(size);
4238 if (osbuf == NULL) {
4242 A_NETBUF_PUT(osbuf, size);
4244 cmd = (WMI_SET_ROAM_CTRL_CMD *)(A_NETBUF_DATA(osbuf));
4245 A_MEMZERO(cmd, size);
4247 memcpy(cmd, p, size);
4249 return (wmi_cmd_send(wmip, osbuf, WMI_SET_ROAM_CTRL_CMDID,
4254 wmi_set_powersave_timers_cmd(struct wmi_t *wmip,
4255 WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd,
4259 WMI_POWERSAVE_TIMERS_POLICY_CMD *cmd;
4261 /* These timers can't be zero */
4262 if(!pCmd->psPollTimeout || !pCmd->triggerTimeout ||
4263 !(pCmd->apsdTimPolicy == IGNORE_TIM_ALL_QUEUES_APSD ||
4264 pCmd->apsdTimPolicy == PROCESS_TIM_ALL_QUEUES_APSD) ||
4265 !(pCmd->simulatedAPSDTimPolicy == IGNORE_TIM_SIMULATED_APSD ||
4266 pCmd->simulatedAPSDTimPolicy == PROCESS_TIM_SIMULATED_APSD))
4269 osbuf = A_NETBUF_ALLOC(size);
4270 if (osbuf == NULL) {
4274 A_NETBUF_PUT(osbuf, size);
4276 cmd = (WMI_POWERSAVE_TIMERS_POLICY_CMD *)(A_NETBUF_DATA(osbuf));
4277 A_MEMZERO(cmd, size);
4279 memcpy(cmd, pCmd, size);
4281 return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID,
4285 #ifdef CONFIG_HOST_GPIO_SUPPORT
4286 /* Send a command to Target to change GPIO output pins. */
4288 wmi_gpio_output_set(struct wmi_t *wmip,
4295 WMIX_GPIO_OUTPUT_SET_CMD *output_set;
4298 size = sizeof(*output_set);
4301 (DBGFMT "Enter - set=0x%x clear=0x%x enb=0x%x dis=0x%x\n", DBGARG,
4302 set_mask, clear_mask, enable_mask, disable_mask));
4304 osbuf = A_NETBUF_ALLOC(size);
4305 if (osbuf == NULL) {
4308 A_NETBUF_PUT(osbuf, size);
4309 output_set = (WMIX_GPIO_OUTPUT_SET_CMD *)(A_NETBUF_DATA(osbuf));
4311 output_set->set_mask = set_mask;
4312 output_set->clear_mask = clear_mask;
4313 output_set->enable_mask = enable_mask;
4314 output_set->disable_mask = disable_mask;
4316 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_OUTPUT_SET_CMDID,
4320 /* Send a command to the Target requesting state of the GPIO input pins */
4322 wmi_gpio_input_get(struct wmi_t *wmip)
4324 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
4326 return wmi_simple_cmd_xtnd(wmip, WMIX_GPIO_INPUT_GET_CMDID);
4329 /* Send a command to the Target that changes the value of a GPIO register. */
4331 wmi_gpio_register_set(struct wmi_t *wmip,
4336 WMIX_GPIO_REGISTER_SET_CMD *register_set;
4339 size = sizeof(*register_set);
4342 (DBGFMT "Enter - reg=%d value=0x%x\n", DBGARG, gpioreg_id, value));
4344 osbuf = A_NETBUF_ALLOC(size);
4345 if (osbuf == NULL) {
4348 A_NETBUF_PUT(osbuf, size);
4349 register_set = (WMIX_GPIO_REGISTER_SET_CMD *)(A_NETBUF_DATA(osbuf));
4351 register_set->gpioreg_id = gpioreg_id;
4352 register_set->value = value;
4354 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_REGISTER_SET_CMDID,
4358 /* Send a command to the Target to fetch the value of a GPIO register. */
4360 wmi_gpio_register_get(struct wmi_t *wmip,
4364 WMIX_GPIO_REGISTER_GET_CMD *register_get;
4367 size = sizeof(*register_get);
4369 A_DPRINTF(DBG_WMI, (DBGFMT "Enter - reg=%d\n", DBGARG, gpioreg_id));
4371 osbuf = A_NETBUF_ALLOC(size);
4372 if (osbuf == NULL) {
4375 A_NETBUF_PUT(osbuf, size);
4376 register_get = (WMIX_GPIO_REGISTER_GET_CMD *)(A_NETBUF_DATA(osbuf));
4378 register_get->gpioreg_id = gpioreg_id;
4380 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_REGISTER_GET_CMDID,
4384 /* Send a command to the Target acknowledging some GPIO interrupts. */
4386 wmi_gpio_intr_ack(struct wmi_t *wmip,
4390 WMIX_GPIO_INTR_ACK_CMD *intr_ack;
4393 size = sizeof(*intr_ack);
4395 A_DPRINTF(DBG_WMI, (DBGFMT "Enter ack_mask=0x%x\n", DBGARG, ack_mask));
4397 osbuf = A_NETBUF_ALLOC(size);
4398 if (osbuf == NULL) {
4401 A_NETBUF_PUT(osbuf, size);
4402 intr_ack = (WMIX_GPIO_INTR_ACK_CMD *)(A_NETBUF_DATA(osbuf));
4404 intr_ack->ack_mask = ack_mask;
4406 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_INTR_ACK_CMDID,
4409 #endif /* CONFIG_HOST_GPIO_SUPPORT */
4412 wmi_set_access_params_cmd(struct wmi_t *wmip, u8 ac, u16 txop, u8 eCWmin,
4413 u8 eCWmax, u8 aifsn)
4416 WMI_SET_ACCESS_PARAMS_CMD *cmd;
4418 if ((eCWmin > WMI_MAX_CW_ACPARAM) || (eCWmax > WMI_MAX_CW_ACPARAM) ||
4419 (aifsn > WMI_MAX_AIFSN_ACPARAM) || (ac >= WMM_NUM_AC))
4424 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4425 if (osbuf == NULL) {
4429 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4431 cmd = (WMI_SET_ACCESS_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
4433 cmd->eCWmin = eCWmin;
4434 cmd->eCWmax = eCWmax;
4438 return (wmi_cmd_send(wmip, osbuf, WMI_SET_ACCESS_PARAMS_CMDID,
4443 wmi_set_retry_limits_cmd(struct wmi_t *wmip, u8 frameType,
4444 u8 trafficClass, u8 maxRetries,
4448 WMI_SET_RETRY_LIMITS_CMD *cmd;
4450 if ((frameType != MGMT_FRAMETYPE) && (frameType != CONTROL_FRAMETYPE) &&
4451 (frameType != DATA_FRAMETYPE))
4456 if (maxRetries > WMI_MAX_RETRIES) {
4460 if (frameType != DATA_FRAMETYPE) {
4464 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4465 if (osbuf == NULL) {
4469 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4471 cmd = (WMI_SET_RETRY_LIMITS_CMD *)(A_NETBUF_DATA(osbuf));
4472 cmd->frameType = frameType;
4473 cmd->trafficClass = trafficClass;
4474 cmd->maxRetries = maxRetries;
4475 cmd->enableNotify = enableNotify;
4477 return (wmi_cmd_send(wmip, osbuf, WMI_SET_RETRY_LIMITS_CMDID,
4482 wmi_get_current_bssid(struct wmi_t *wmip, u8 *bssid)
4484 if (bssid != NULL) {
4485 memcpy(bssid, wmip->wmi_bssid, ATH_MAC_LEN);
4490 wmi_set_opt_mode_cmd(struct wmi_t *wmip, u8 optMode)
4493 WMI_SET_OPT_MODE_CMD *cmd;
4495 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4496 if (osbuf == NULL) {
4500 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4502 cmd = (WMI_SET_OPT_MODE_CMD *)(A_NETBUF_DATA(osbuf));
4503 A_MEMZERO(cmd, sizeof(*cmd));
4504 cmd->optMode = optMode;
4506 return (wmi_cmd_send(wmip, osbuf, WMI_SET_OPT_MODE_CMDID,
4507 SYNC_BOTH_WMIFLAG));
4511 wmi_opt_tx_frame_cmd(struct wmi_t *wmip,
4519 WMI_OPT_TX_FRAME_CMD *cmd;
4520 osbuf = A_NETBUF_ALLOC(optIEDataLen + sizeof(*cmd));
4521 if (osbuf == NULL) {
4525 A_NETBUF_PUT(osbuf, (optIEDataLen + sizeof(*cmd)));
4527 cmd = (WMI_OPT_TX_FRAME_CMD *)(A_NETBUF_DATA(osbuf));
4528 A_MEMZERO(cmd, (optIEDataLen + sizeof(*cmd)-1));
4530 cmd->frmType = frmType;
4531 cmd->optIEDataLen = optIEDataLen;
4532 //cmd->optIEData = (u8 *)((int)cmd + sizeof(*cmd));
4533 memcpy(cmd->bssid, bssid, sizeof(cmd->bssid));
4534 memcpy(cmd->dstAddr, dstMacAddr, sizeof(cmd->dstAddr));
4535 memcpy(&cmd->optIEData[0], optIEData, optIEDataLen);
4537 return (wmi_cmd_send(wmip, osbuf, WMI_OPT_TX_FRAME_CMDID,
4542 wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, u16 intvl)
4545 WMI_BEACON_INT_CMD *cmd;
4547 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4548 if (osbuf == NULL) {
4552 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4554 cmd = (WMI_BEACON_INT_CMD *)(A_NETBUF_DATA(osbuf));
4555 A_MEMZERO(cmd, sizeof(*cmd));
4556 cmd->beaconInterval = intvl;
4558 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BEACON_INT_CMDID,
4564 wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, u16 voicePktSize)
4567 WMI_SET_VOICE_PKT_SIZE_CMD *cmd;
4569 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4570 if (osbuf == NULL) {
4574 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4576 cmd = (WMI_SET_VOICE_PKT_SIZE_CMD *)(A_NETBUF_DATA(osbuf));
4577 A_MEMZERO(cmd, sizeof(*cmd));
4578 cmd->voicePktSize = voicePktSize;
4580 return (wmi_cmd_send(wmip, osbuf, WMI_SET_VOICE_PKT_SIZE_CMDID,
4586 wmi_set_max_sp_len_cmd(struct wmi_t *wmip, u8 maxSPLen)
4589 WMI_SET_MAX_SP_LEN_CMD *cmd;
4591 /* maxSPLen is a two-bit value. If user trys to set anything
4592 * other than this, then its invalid
4594 if(maxSPLen & ~0x03)
4597 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4598 if (osbuf == NULL) {
4602 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4604 cmd = (WMI_SET_MAX_SP_LEN_CMD *)(A_NETBUF_DATA(osbuf));
4605 A_MEMZERO(cmd, sizeof(*cmd));
4606 cmd->maxSPLen = maxSPLen;
4608 return (wmi_cmd_send(wmip, osbuf, WMI_SET_MAX_SP_LEN_CMDID,
4612 u8 wmi_determine_userPriority(
4617 iphdr *ipHdr = (iphdr *)pkt;
4619 /* Determine IPTOS priority */
4622 * (Refer Pg 57 WMM-test-plan-v1.2)
4624 * : DSCP(6-bits) ECN(2-bits)
4625 * : DSCP - P2 P1 P0 X X X
4626 * where (P2 P1 P0) form 802.1D
4628 ipPri = ipHdr->ip_tos >> 5;
4631 if ((layer2Pri & 0x7) > ipPri)
4632 return ((u8)layer2Pri & 0x7);
4637 u8 convert_userPriority_to_trafficClass(u8 userPriority)
4639 return (up_to_ac[userPriority & 0x7]);
4642 u8 wmi_get_power_mode_cmd(struct wmi_t *wmip)
4644 return wmip->wmi_powerMode;
4648 wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, int tspecCompliance)
4652 #define TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF (~0)
4653 #define TSPEC_SERVICE_START_TIME_ATHEROS_DEF 0
4654 #define TSPEC_MAX_BURST_SIZE_ATHEROS_DEF 0
4655 #define TSPEC_DELAY_BOUND_ATHEROS_DEF 0
4656 #define TSPEC_MEDIUM_TIME_ATHEROS_DEF 0
4657 #define TSPEC_SBA_ATHEROS_DEF 0x2000 /* factor is 1 */
4659 /* Verify TSPEC params for ATHEROS compliance */
4660 if(tspecCompliance == ATHEROS_COMPLIANCE) {
4661 if ((pCmd->suspensionInt != TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF) ||
4662 (pCmd->serviceStartTime != TSPEC_SERVICE_START_TIME_ATHEROS_DEF) ||
4663 (pCmd->minDataRate != pCmd->meanDataRate) ||
4664 (pCmd->minDataRate != pCmd->peakDataRate) ||
4665 (pCmd->maxBurstSize != TSPEC_MAX_BURST_SIZE_ATHEROS_DEF) ||
4666 (pCmd->delayBound != TSPEC_DELAY_BOUND_ATHEROS_DEF) ||
4667 (pCmd->sba != TSPEC_SBA_ATHEROS_DEF) ||
4668 (pCmd->mediumTime != TSPEC_MEDIUM_TIME_ATHEROS_DEF)) {
4670 A_DPRINTF(DBG_WMI, (DBGFMT "Invalid TSPEC params\n", DBGARG));
4671 //A_PRINTF("%s: Invalid TSPEC params\n", __func__);
4679 #ifdef CONFIG_HOST_TCMD_SUPPORT
4681 wmi_tcmd_test_report_rx(struct wmi_t *wmip, u8 *datap, int len)
4684 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
4686 A_WMI_TCMD_RX_REPORT_EVENT(wmip->wmi_devt, datap, len);
4691 #endif /* CONFIG_HOST_TCMD_SUPPORT*/
4694 wmi_set_authmode_cmd(struct wmi_t *wmip, u8 mode)
4697 WMI_SET_AUTH_MODE_CMD *cmd;
4699 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4700 if (osbuf == NULL) {
4704 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4706 cmd = (WMI_SET_AUTH_MODE_CMD *)(A_NETBUF_DATA(osbuf));
4707 A_MEMZERO(cmd, sizeof(*cmd));
4710 return (wmi_cmd_send(wmip, osbuf, WMI_SET_AUTH_MODE_CMDID,
4715 wmi_set_reassocmode_cmd(struct wmi_t *wmip, u8 mode)
4718 WMI_SET_REASSOC_MODE_CMD *cmd;
4720 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4721 if (osbuf == NULL) {
4725 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4727 cmd = (WMI_SET_REASSOC_MODE_CMD *)(A_NETBUF_DATA(osbuf));
4728 A_MEMZERO(cmd, sizeof(*cmd));
4731 return (wmi_cmd_send(wmip, osbuf, WMI_SET_REASSOC_MODE_CMDID,
4736 wmi_set_lpreamble_cmd(struct wmi_t *wmip, u8 status, u8 preamblePolicy)
4739 WMI_SET_LPREAMBLE_CMD *cmd;
4741 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4742 if (osbuf == NULL) {
4746 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4748 cmd = (WMI_SET_LPREAMBLE_CMD *)(A_NETBUF_DATA(osbuf));
4749 A_MEMZERO(cmd, sizeof(*cmd));
4750 cmd->status = status;
4751 cmd->preamblePolicy = preamblePolicy;
4753 return (wmi_cmd_send(wmip, osbuf, WMI_SET_LPREAMBLE_CMDID,
4758 wmi_set_rts_cmd(struct wmi_t *wmip, u16 threshold)
4761 WMI_SET_RTS_CMD *cmd;
4763 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4764 if (osbuf == NULL) {
4768 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4770 cmd = (WMI_SET_RTS_CMD*)(A_NETBUF_DATA(osbuf));
4771 A_MEMZERO(cmd, sizeof(*cmd));
4772 cmd->threshold = threshold;
4774 return (wmi_cmd_send(wmip, osbuf, WMI_SET_RTS_CMDID,
4779 wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status)
4782 WMI_SET_WMM_CMD *cmd;
4784 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4785 if (osbuf == NULL) {
4789 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4791 cmd = (WMI_SET_WMM_CMD*)(A_NETBUF_DATA(osbuf));
4792 A_MEMZERO(cmd, sizeof(*cmd));
4793 cmd->status = status;
4795 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_CMDID,
4801 wmi_set_qos_supp_cmd(struct wmi_t *wmip, u8 status)
4804 WMI_SET_QOS_SUPP_CMD *cmd;
4806 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4807 if (osbuf == NULL) {
4811 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4813 cmd = (WMI_SET_QOS_SUPP_CMD*)(A_NETBUF_DATA(osbuf));
4814 A_MEMZERO(cmd, sizeof(*cmd));
4815 cmd->status = status;
4816 return (wmi_cmd_send(wmip, osbuf, WMI_SET_QOS_SUPP_CMDID,
4822 wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG cfg)
4825 WMI_SET_WMM_TXOP_CMD *cmd;
4827 if( !((cfg == WMI_TXOP_DISABLED) || (cfg == WMI_TXOP_ENABLED)) )
4830 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4831 if (osbuf == NULL) {
4835 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4837 cmd = (WMI_SET_WMM_TXOP_CMD *)(A_NETBUF_DATA(osbuf));
4838 A_MEMZERO(cmd, sizeof(*cmd));
4839 cmd->txopEnable = cfg;
4841 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_TXOP_CMDID,
4847 wmi_set_country(struct wmi_t *wmip, u8 *countryCode)
4850 WMI_AP_SET_COUNTRY_CMD *cmd;
4852 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4853 if (osbuf == NULL) {
4857 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4859 cmd = (WMI_AP_SET_COUNTRY_CMD *)(A_NETBUF_DATA(osbuf));
4860 A_MEMZERO(cmd, sizeof(*cmd));
4861 memcpy(cmd->countryCode,countryCode,3);
4863 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_COUNTRY_CMDID,
4867 #ifdef CONFIG_HOST_TCMD_SUPPORT
4868 /* WMI layer doesn't need to know the data type of the test cmd.
4869 This would be beneficial for customers like Qualcomm, who might
4870 have different test command requirements from different manufacturers
4873 wmi_test_cmd(struct wmi_t *wmip, u8 *buf, u32 len)
4878 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
4880 osbuf= A_NETBUF_ALLOC(len);
4885 A_NETBUF_PUT(osbuf, len);
4886 data = A_NETBUF_DATA(osbuf);
4887 memcpy(data, buf, len);
4889 return(wmi_cmd_send(wmip, osbuf, WMI_TEST_CMDID,
4896 wmi_set_bt_status_cmd(struct wmi_t *wmip, u8 streamType, u8 status)
4899 WMI_SET_BT_STATUS_CMD *cmd;
4901 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Enter - streamType=%d, status=%d\n", streamType, status));
4903 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4904 if (osbuf == NULL) {
4908 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4910 cmd = (WMI_SET_BT_STATUS_CMD *)(A_NETBUF_DATA(osbuf));
4911 A_MEMZERO(cmd, sizeof(*cmd));
4912 cmd->streamType = streamType;
4913 cmd->status = status;
4915 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_STATUS_CMDID,
4920 wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd)
4923 WMI_SET_BT_PARAMS_CMD* alloc_cmd;
4925 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("cmd params is %d\n", cmd->paramType));
4927 if (cmd->paramType == BT_PARAM_SCO) {
4928 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("sco params %d %d %d %d %d %d %d %d %d %d %d %d\n", cmd->info.scoParams.numScoCyclesForceTrigger,
4929 cmd->info.scoParams.dataResponseTimeout,
4930 cmd->info.scoParams.stompScoRules,
4931 cmd->info.scoParams.scoOptFlags,
4932 cmd->info.scoParams.stompDutyCyleVal,
4933 cmd->info.scoParams.stompDutyCyleMaxVal,
4934 cmd->info.scoParams.psPollLatencyFraction,
4935 cmd->info.scoParams.noSCOSlots,
4936 cmd->info.scoParams.noIdleSlots,
4937 cmd->info.scoParams.scoOptOffRssi,
4938 cmd->info.scoParams.scoOptOnRssi,
4939 cmd->info.scoParams.scoOptRtsCount));
4941 else if (cmd->paramType == BT_PARAM_A2DP) {
4942 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("A2DP params %d %d %d %d %d %d %d %d\n", cmd->info.a2dpParams.a2dpWlanUsageLimit,
4943 cmd->info.a2dpParams.a2dpBurstCntMin,
4944 cmd->info.a2dpParams.a2dpDataRespTimeout,
4945 cmd->info.a2dpParams.a2dpOptFlags,
4946 cmd->info.a2dpParams.isCoLocatedBtRoleMaster,
4947 cmd->info.a2dpParams.a2dpOptOffRssi,
4948 cmd->info.a2dpParams.a2dpOptOnRssi,
4949 cmd->info.a2dpParams.a2dpOptRtsCount));
4951 else if (cmd->paramType == BT_PARAM_ANTENNA_CONFIG) {
4952 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Ant config %d\n", cmd->info.antType));
4954 else if (cmd->paramType == BT_PARAM_COLOCATED_BT_DEVICE) {
4955 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("co-located BT %d\n", cmd->info.coLocatedBtDev));
4957 else if (cmd->paramType == BT_PARAM_ACLCOEX) {
4958 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("ACL params %d %d %d\n", cmd->info.aclCoexParams.aclWlanMediumUsageTime,
4959 cmd->info.aclCoexParams.aclBtMediumUsageTime,
4960 cmd->info.aclCoexParams.aclDataRespTimeout));
4962 else if (cmd->paramType == BT_PARAM_11A_SEPARATE_ANT) {
4963 A_DPRINTF(DBG_WMI, (DBGFMT "11A ant\n", DBGARG));
4966 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4967 if (osbuf == NULL) {
4971 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4973 alloc_cmd = (WMI_SET_BT_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
4974 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4975 memcpy(alloc_cmd, cmd, sizeof(*cmd));
4977 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_PARAMS_CMDID,
4982 wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd)
4985 WMI_SET_BTCOEX_FE_ANT_CMD *alloc_cmd;
4987 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4988 if (osbuf == NULL) {
4991 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4992 alloc_cmd = (WMI_SET_BTCOEX_FE_ANT_CMD *)(A_NETBUF_DATA(osbuf));
4993 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4994 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_FE_ANT_CMD));
4995 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_FE_ANT_CMDID,
5002 wmi_set_btcoex_colocated_bt_dev_cmd(struct wmi_t *wmip,
5003 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD * cmd)
5006 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD *alloc_cmd;
5008 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5009 if (osbuf == NULL) {
5012 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5013 alloc_cmd = (WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD *)(A_NETBUF_DATA(osbuf));
5014 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5015 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD));
5016 A_PRINTF("colocated bt = %d\n", alloc_cmd->btcoexCoLocatedBTdev);
5017 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID,
5023 wmi_set_btcoex_btinquiry_page_config_cmd(struct wmi_t *wmip,
5024 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD* cmd)
5027 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *alloc_cmd;
5029 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5030 if (osbuf == NULL) {
5033 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5034 alloc_cmd = (WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
5035 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5036 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD));
5037 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID,
5043 wmi_set_btcoex_sco_config_cmd(struct wmi_t *wmip,
5044 WMI_SET_BTCOEX_SCO_CONFIG_CMD * cmd)
5047 WMI_SET_BTCOEX_SCO_CONFIG_CMD *alloc_cmd;
5049 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5050 if (osbuf == NULL) {
5053 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5054 alloc_cmd = (WMI_SET_BTCOEX_SCO_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
5055 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5056 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_SCO_CONFIG_CMD));
5057 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_SCO_CONFIG_CMDID ,
5063 wmi_set_btcoex_a2dp_config_cmd(struct wmi_t *wmip,
5064 WMI_SET_BTCOEX_A2DP_CONFIG_CMD * cmd)
5067 WMI_SET_BTCOEX_A2DP_CONFIG_CMD *alloc_cmd;
5069 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5070 if (osbuf == NULL) {
5073 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5074 alloc_cmd = (WMI_SET_BTCOEX_A2DP_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
5075 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5076 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_A2DP_CONFIG_CMD));
5077 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_A2DP_CONFIG_CMDID ,
5083 wmi_set_btcoex_aclcoex_config_cmd(struct wmi_t *wmip,
5084 WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD * cmd)
5087 WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD *alloc_cmd;
5089 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5090 if (osbuf == NULL) {
5093 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5094 alloc_cmd = (WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
5095 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5096 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD));
5097 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID ,
5103 wmi_set_btcoex_debug_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_DEBUG_CMD * cmd)
5106 WMI_SET_BTCOEX_DEBUG_CMD *alloc_cmd;
5108 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5109 if (osbuf == NULL) {
5112 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5113 alloc_cmd = (WMI_SET_BTCOEX_DEBUG_CMD *)(A_NETBUF_DATA(osbuf));
5114 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5115 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_DEBUG_CMD));
5116 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_DEBUG_CMDID ,
5122 wmi_set_btcoex_bt_operating_status_cmd(struct wmi_t * wmip,
5123 WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD * cmd)
5126 WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *alloc_cmd;
5128 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5129 if (osbuf == NULL) {
5132 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5133 alloc_cmd = (WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *)(A_NETBUF_DATA(osbuf));
5134 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5135 memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD));
5136 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID ,
5142 wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * cmd)
5145 WMI_GET_BTCOEX_CONFIG_CMD *alloc_cmd;
5147 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5148 if (osbuf == NULL) {
5151 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5152 alloc_cmd = (WMI_GET_BTCOEX_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
5153 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5154 memcpy(alloc_cmd,cmd,sizeof(WMI_GET_BTCOEX_CONFIG_CMD));
5155 return (wmi_cmd_send(wmip, osbuf, WMI_GET_BTCOEX_CONFIG_CMDID ,
5161 wmi_get_btcoex_stats_cmd(struct wmi_t *wmip)
5164 return wmi_simple_cmd(wmip, WMI_GET_BTCOEX_STATS_CMDID);
5169 wmi_get_keepalive_configured(struct wmi_t *wmip)
5172 WMI_GET_KEEPALIVE_CMD *cmd;
5173 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5174 if (osbuf == NULL) {
5177 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5178 cmd = (WMI_GET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf));
5179 A_MEMZERO(cmd, sizeof(*cmd));
5180 return (wmi_cmd_send(wmip, osbuf, WMI_GET_KEEPALIVE_CMDID,
5184 u8 wmi_get_keepalive_cmd(struct wmi_t *wmip)
5186 return wmip->wmi_keepaliveInterval;
5190 wmi_set_keepalive_cmd(struct wmi_t *wmip, u8 keepaliveInterval)
5193 WMI_SET_KEEPALIVE_CMD *cmd;
5195 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5196 if (osbuf == NULL) {
5200 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5202 cmd = (WMI_SET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf));
5203 A_MEMZERO(cmd, sizeof(*cmd));
5204 cmd->keepaliveInterval = keepaliveInterval;
5205 wmip->wmi_keepaliveInterval = keepaliveInterval;
5207 return (wmi_cmd_send(wmip, osbuf, WMI_SET_KEEPALIVE_CMDID,
5212 wmi_set_params_cmd(struct wmi_t *wmip, u32 opcode, u32 length, char *buffer)
5215 WMI_SET_PARAMS_CMD *cmd;
5217 osbuf = A_NETBUF_ALLOC(sizeof(*cmd) + length);
5218 if (osbuf == NULL) {
5222 A_NETBUF_PUT(osbuf, sizeof(*cmd) + length);
5224 cmd = (WMI_SET_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
5225 A_MEMZERO(cmd, sizeof(*cmd));
5226 cmd->opcode = opcode;
5227 cmd->length = length;
5228 memcpy(cmd->buffer, buffer, length);
5230 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PARAMS_CMDID,
5236 wmi_set_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4)
5239 WMI_SET_MCAST_FILTER_CMD *cmd;
5241 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5242 if (osbuf == NULL) {
5246 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5248 cmd = (WMI_SET_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
5249 cmd->multicast_mac[0] = 0x01;
5250 cmd->multicast_mac[1] = 0x00;
5251 cmd->multicast_mac[2] = 0x5e;
5252 cmd->multicast_mac[3] = dot2&0x7F;
5253 cmd->multicast_mac[4] = dot3;
5254 cmd->multicast_mac[5] = dot4;
5256 return (wmi_cmd_send(wmip, osbuf, WMI_SET_MCAST_FILTER_CMDID,
5262 wmi_del_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4)
5265 WMI_SET_MCAST_FILTER_CMD *cmd;
5267 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5268 if (osbuf == NULL) {
5272 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5274 cmd = (WMI_SET_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
5275 cmd->multicast_mac[0] = 0x01;
5276 cmd->multicast_mac[1] = 0x00;
5277 cmd->multicast_mac[2] = 0x5e;
5278 cmd->multicast_mac[3] = dot2&0x7F;
5279 cmd->multicast_mac[4] = dot3;
5280 cmd->multicast_mac[5] = dot4;
5282 return (wmi_cmd_send(wmip, osbuf, WMI_DEL_MCAST_FILTER_CMDID,
5287 wmi_mcast_filter_cmd(struct wmi_t *wmip, u8 enable)
5290 WMI_MCAST_FILTER_CMD *cmd;
5292 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5293 if (osbuf == NULL) {
5297 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5299 cmd = (WMI_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
5300 cmd->enable = enable;
5302 return (wmi_cmd_send(wmip, osbuf, WMI_MCAST_FILTER_CMDID,
5307 wmi_set_appie_cmd(struct wmi_t *wmip, u8 mgmtFrmType, u8 ieLen,
5311 WMI_SET_APPIE_CMD *cmd;
5314 cmdLen = sizeof(*cmd) + ieLen - 1;
5315 osbuf = A_NETBUF_ALLOC(cmdLen);
5316 if (osbuf == NULL) {
5320 A_NETBUF_PUT(osbuf, cmdLen);
5322 cmd = (WMI_SET_APPIE_CMD *)(A_NETBUF_DATA(osbuf));
5323 A_MEMZERO(cmd, cmdLen);
5325 cmd->mgmtFrmType = mgmtFrmType;
5327 memcpy(cmd->ieInfo, ieInfo, ieLen);
5329 return (wmi_cmd_send(wmip, osbuf, WMI_SET_APPIE_CMDID, NO_SYNC_WMIFLAG));
5333 wmi_set_halparam_cmd(struct wmi_t *wmip, u8 *cmd, u16 dataLen)
5338 osbuf = A_NETBUF_ALLOC(dataLen);
5339 if (osbuf == NULL) {
5343 A_NETBUF_PUT(osbuf, dataLen);
5345 data = A_NETBUF_DATA(osbuf);
5347 memcpy(data, cmd, dataLen);
5349 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WHALPARAM_CMDID, NO_SYNC_WMIFLAG));
5352 s32 wmi_get_rate(s8 rateindex)
5354 if (rateindex == RATE_AUTO) {
5357 return(wmi_rateTable[(u32) rateindex][0]);
5362 wmi_node_return (struct wmi_t *wmip, bss_t *bss)
5366 wlan_node_return (&wmip->wmi_scan_table, bss);
5371 wmi_set_nodeage(struct wmi_t *wmip, u32 nodeAge)
5373 wlan_set_nodeage(&wmip->wmi_scan_table,nodeAge);
5377 wmi_find_Ssidnode (struct wmi_t *wmip, u8 *pSsid,
5378 u32 ssidLength, bool bIsWPA2, bool bMatchSSID)
5381 node = wlan_find_Ssidnode (&wmip->wmi_scan_table, pSsid,
5382 ssidLength, bIsWPA2, bMatchSSID);
5389 wmi_refresh_scan_table (struct wmi_t *wmip)
5391 wlan_refresh_inactive_nodes (&wmip->wmi_scan_table);
5396 wmi_free_allnodes(struct wmi_t *wmip)
5398 wlan_free_allnodes(&wmip->wmi_scan_table);
5402 wmi_find_node(struct wmi_t *wmip, const u8 *macaddr)
5405 ni=wlan_find_node(&wmip->wmi_scan_table,macaddr);
5410 wmi_free_node(struct wmi_t *wmip, const u8 *macaddr)
5414 ni=wlan_find_node(&wmip->wmi_scan_table,macaddr);
5416 wlan_node_reclaim(&wmip->wmi_scan_table, ni);
5423 wmi_dset_open_reply(struct wmi_t *wmip,
5433 WMIX_DSETOPEN_REPLY_CMD *open_reply;
5435 A_DPRINTF(DBG_WMI, (DBGFMT "Enter - wmip=0x%lx\n", DBGARG, (unsigned long)wmip));
5437 osbuf = A_NETBUF_ALLOC(sizeof(*open_reply));
5438 if (osbuf == NULL) {
5442 A_NETBUF_PUT(osbuf, sizeof(*open_reply));
5443 open_reply = (WMIX_DSETOPEN_REPLY_CMD *)(A_NETBUF_DATA(osbuf));
5445 open_reply->status = status;
5446 open_reply->targ_dset_handle = targ_handle;
5447 open_reply->targ_reply_fn = targ_reply_fn;
5448 open_reply->targ_reply_arg = targ_reply_arg;
5449 open_reply->access_cookie = access_cookie;
5450 open_reply->size = dset_size;
5451 open_reply->version = dset_version;
5453 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETOPEN_REPLY_CMDID,
5458 wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, u8 *datap, u32 len)
5460 WMI_PMKID_LIST_REPLY *reply;
5463 if (len < sizeof(WMI_PMKID_LIST_REPLY)) {
5466 reply = (WMI_PMKID_LIST_REPLY *)datap;
5467 expected_len = sizeof(reply->numPMKID) + reply->numPMKID * WMI_PMKID_LEN;
5469 if (len < expected_len) {
5473 A_WMI_PMKID_LIST_EVENT(wmip->wmi_devt, reply->numPMKID,
5474 reply->pmkidList, reply->bssidList[0]);
5481 wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, u32 len)
5483 WMI_SET_PARAMS_REPLY *reply;
5485 if (len < sizeof(WMI_SET_PARAMS_REPLY)) {
5488 reply = (WMI_SET_PARAMS_REPLY *)datap;
5490 if (0 == reply->status)
5505 wmi_acm_reject_event_rx(struct wmi_t *wmip, u8 *datap, u32 len)
5507 WMI_ACM_REJECT_EVENT *ev;
5509 ev = (WMI_ACM_REJECT_EVENT *)datap;
5510 wmip->wmi_traffic_class = ev->trafficClass;
5511 printk("ACM REJECT %d\n",wmip->wmi_traffic_class);
5516 #ifdef CONFIG_HOST_DSET_SUPPORT
5518 wmi_dset_data_reply(struct wmi_t *wmip,
5527 WMIX_DSETDATA_REPLY_CMD *data_reply;
5530 size = sizeof(*data_reply) + length;
5532 if (size <= length) {
5537 (DBGFMT "Enter - length=%d status=%d\n", DBGARG, length, status));
5539 osbuf = A_NETBUF_ALLOC(size);
5540 if (osbuf == NULL) {
5543 A_NETBUF_PUT(osbuf, size);
5544 data_reply = (WMIX_DSETDATA_REPLY_CMD *)(A_NETBUF_DATA(osbuf));
5546 data_reply->status = status;
5547 data_reply->targ_buf = targ_buf;
5548 data_reply->targ_reply_fn = targ_reply_fn;
5549 data_reply->targ_reply_arg = targ_reply_arg;
5550 data_reply->length = length;
5553 if (a_copy_from_user(data_reply->buf, user_buf, length)) {
5554 A_NETBUF_FREE(osbuf);
5559 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETDATA_REPLY_CMDID,
5562 #endif /* CONFIG_HOST_DSET_SUPPORT */
5565 wmi_set_wsc_status_cmd(struct wmi_t *wmip, u32 status)
5570 wps_enable = status;
5572 osbuf = a_netbuf_alloc(sizeof(1));
5573 if (osbuf == NULL) {
5577 a_netbuf_put(osbuf, sizeof(1));
5579 cmd = (char *)(a_netbuf_to_data(osbuf));
5581 A_MEMZERO(cmd, sizeof(*cmd));
5582 cmd[0] = (status?1:0);
5583 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WSC_STATUS_CMDID,
5587 #if defined(CONFIG_TARGET_PROFILE_SUPPORT)
5589 wmi_prof_cfg_cmd(struct wmi_t *wmip,
5594 WMIX_PROF_CFG_CMD *cmd;
5596 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5597 if (osbuf == NULL) {
5601 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5603 cmd = (WMIX_PROF_CFG_CMD *)(A_NETBUF_DATA(osbuf));
5604 A_MEMZERO(cmd, sizeof(*cmd));
5605 cmd->period = period;
5608 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_PROF_CFG_CMDID, NO_SYNC_WMIFLAG));
5612 wmi_prof_addr_set_cmd(struct wmi_t *wmip, u32 addr)
5615 WMIX_PROF_ADDR_SET_CMD *cmd;
5617 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5618 if (osbuf == NULL) {
5622 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5624 cmd = (WMIX_PROF_ADDR_SET_CMD *)(A_NETBUF_DATA(osbuf));
5625 A_MEMZERO(cmd, sizeof(*cmd));
5628 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_PROF_ADDR_SET_CMDID, NO_SYNC_WMIFLAG));
5632 wmi_prof_start_cmd(struct wmi_t *wmip)
5634 return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_START_CMDID);
5638 wmi_prof_stop_cmd(struct wmi_t *wmip)
5640 return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_STOP_CMDID);
5644 wmi_prof_count_get_cmd(struct wmi_t *wmip)
5646 return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_COUNT_GET_CMDID);
5649 /* Called to handle WMIX_PROF_CONT_EVENTID */
5651 wmi_prof_count_rx(struct wmi_t *wmip, u8 *datap, int len)
5653 WMIX_PROF_COUNT_EVENT *prof_data = (WMIX_PROF_COUNT_EVENT *)datap;
5656 (DBGFMT "Enter - addr=0x%x count=%d\n", DBGARG,
5657 prof_data->addr, prof_data->count));
5659 A_WMI_PROF_COUNT_RX(prof_data->addr, prof_data->count);
5663 #endif /* CONFIG_TARGET_PROFILE_SUPPORT */
5665 #ifdef OS_ROAM_MANAGEMENT
5667 #define ETHERNET_MAC_ADDRESS_LENGTH 6
5670 wmi_scan_indication (struct wmi_t *wmip)
5672 struct ieee80211_node_table *nt;
5678 PNDIS_802_11_BSSID_SCAN_INFO psi;
5680 NDIS_802_11_FIXED_IEs *pFixed;
5681 NDIS_802_11_VARIABLE_IEs *pVar;
5684 struct ar6kScanIndication
5686 NDIS_802_11_STATUS_INDICATION ind;
5687 NDIS_802_11_BSSID_SCAN_INFO_LIST slist;
5688 } *pAr6kScanIndEvent;
5690 nt = &wmip->wmi_scan_table;
5695 gen = nt->nt_si_gen;
5697 size = offsetof(struct ar6kScanIndication, slist) +
5698 offsetof(NDIS_802_11_BSSID_SCAN_INFO_LIST, BssidScanInfo);
5702 IEEE80211_NODE_LOCK(nt);
5705 for (bss = nt->nt_node_first; bss; bss = bss->ni_list_next) {
5706 if (bss->ni_si_gen != gen) {
5707 bsssize = offsetof(NDIS_802_11_BSSID_SCAN_INFO, Bssid) + offsetof(NDIS_WLAN_BSSID_EX, IEs);
5708 bsssize = bsssize + sizeof(NDIS_802_11_FIXED_IEs);
5711 if (bss->ni_cie.ie_rsn) {
5712 bsssize = bsssize + bss->ni_cie.ie_rsn[1] + 2;
5715 if (bss->ni_cie.ie_wpa) {
5716 bsssize = bsssize + bss->ni_cie.ie_wpa[1] + 2;
5719 // bsssize must be a multiple of 4 to maintain alignment.
5720 bsssize = (bsssize + 3) & ~3;
5730 // RETAILMSG(1, (L"AR6K: scan indication: 0 bss\n"));
5731 ar6000_scan_indication (wmip->wmi_devt, NULL, 0);
5732 IEEE80211_NODE_UNLOCK (nt);
5736 pAr6kScanIndEvent = A_MALLOC(size);
5738 if (NULL == pAr6kScanIndEvent)
5740 IEEE80211_NODE_UNLOCK(nt);
5744 A_MEMZERO(pAr6kScanIndEvent, size);
5747 pAr6kScanIndEvent->ind.StatusType = Ndis802_11StatusType_BssidScanInfoList;
5748 pAr6kScanIndEvent->slist.Version = 1;
5749 pAr6kScanIndEvent->slist.NumItems = numbss;
5751 psi = &pAr6kScanIndEvent->slist.BssidScanInfo[0];
5753 for (bss = nt->nt_node_first; bss; bss = bss->ni_list_next) {
5754 if (bss->ni_si_gen != gen) {
5756 bss->ni_si_gen = gen;
5759 psi->ScanTime = bss->ni_tstamp - WLAN_NODE_INACT_TIMEOUT_MSEC;
5761 // Copy data to bssid_ex
5762 bsssize = offsetof(NDIS_WLAN_BSSID_EX, IEs);
5763 bsssize = bsssize + sizeof(NDIS_802_11_FIXED_IEs);
5766 if (bss->ni_cie.ie_rsn) {
5767 bsssize = bsssize + bss->ni_cie.ie_rsn[1] + 2;
5770 if (bss->ni_cie.ie_wpa) {
5771 bsssize = bsssize + bss->ni_cie.ie_wpa[1] + 2;
5774 // bsssize must be a multiple of 4 to maintain alignment.
5775 bsssize = (bsssize + 3) & ~3;
5777 psi->Bssid.Length = bsssize;
5779 memcpy (psi->Bssid.MacAddress, bss->ni_macaddr, ETHERNET_MAC_ADDRESS_LENGTH);
5782 //if (((bss->ni_macaddr[3] == 0xCE) && (bss->ni_macaddr[4] == 0xF0) && (bss->ni_macaddr[5] == 0xE7)) ||
5783 // ((bss->ni_macaddr[3] == 0x03) && (bss->ni_macaddr[4] == 0xE2) && (bss->ni_macaddr[5] == 0x70)))
5784 // RETAILMSG (1, (L"%x\n",bss->ni_macaddr[5]));
5786 psi->Bssid.Ssid.SsidLength = 0;
5787 pie = bss->ni_cie.ie_ssid;
5790 // Format of SSID IE is:
5793 // SSID (Length octets)
5795 // Validation of the IE should have occurred within WMI.
5798 psi->Bssid.Ssid.SsidLength = pie[1];
5799 memcpy(psi->Bssid.Ssid.Ssid, &pie[2], psi->Bssid.Ssid.SsidLength);
5802 psi->Bssid.Privacy = (bss->ni_cie.ie_capInfo & 0x10) ? 1 : 0;
5804 //Post the RSSI value relative to the Standard Noise floor value.
5805 psi->Bssid.Rssi = bss->ni_rssi;
5807 if (bss->ni_cie.ie_chan >= 2412 && bss->ni_cie.ie_chan <= 2484) {
5809 if (bss->ni_cie.ie_rates && bss->ni_cie.ie_xrates) {
5810 psi->Bssid.NetworkTypeInUse = Ndis802_11OFDM24;
5813 psi->Bssid.NetworkTypeInUse = Ndis802_11DS;
5817 psi->Bssid.NetworkTypeInUse = Ndis802_11OFDM5;
5820 psi->Bssid.Configuration.Length = sizeof(psi->Bssid.Configuration);
5821 psi->Bssid.Configuration.BeaconPeriod = bss->ni_cie.ie_beaconInt; // Units are Kmicroseconds (1024 us)
5822 psi->Bssid.Configuration.ATIMWindow = 0;
5823 psi->Bssid.Configuration.DSConfig = bss->ni_cie.ie_chan * 1000;
5824 psi->Bssid.InfrastructureMode = ((bss->ni_cie.ie_capInfo & 0x03) == 0x01 ) ? Ndis802_11Infrastructure : Ndis802_11IBSS;
5827 pie = bss->ni_cie.ie_rates;
5829 RateSize = (pie[1] < NDIS_802_11_LENGTH_RATES_EX) ? pie[1] : NDIS_802_11_LENGTH_RATES_EX;
5830 memcpy(psi->Bssid.SupportedRates, &pie[2], RateSize);
5832 pie = bss->ni_cie.ie_xrates;
5833 if (pie && RateSize < NDIS_802_11_LENGTH_RATES_EX) {
5834 memcpy(psi->Bssid.SupportedRates + RateSize, &pie[2],
5835 (pie[1] < (NDIS_802_11_LENGTH_RATES_EX - RateSize)) ? pie[1] : (NDIS_802_11_LENGTH_RATES_EX - RateSize));
5838 // Copy the fixed IEs
5839 psi->Bssid.IELength = sizeof(NDIS_802_11_FIXED_IEs);
5841 pFixed = (NDIS_802_11_FIXED_IEs *)psi->Bssid.IEs;
5842 memcpy(pFixed->Timestamp, bss->ni_cie.ie_tstamp, sizeof(pFixed->Timestamp));
5843 pFixed->BeaconInterval = bss->ni_cie.ie_beaconInt;
5844 pFixed->Capabilities = bss->ni_cie.ie_capInfo;
5846 // Copy selected variable IEs
5848 pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pFixed + sizeof(NDIS_802_11_FIXED_IEs));
5851 // Copy the WPAv2 IE
5852 if (bss->ni_cie.ie_rsn) {
5853 pie = bss->ni_cie.ie_rsn;
5854 psi->Bssid.IELength += pie[1] + 2;
5855 memcpy(pVar, pie, pie[1] + 2);
5856 pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pVar + pie[1] + 2);
5859 // Copy the WPAv1 IE
5860 if (bss->ni_cie.ie_wpa) {
5861 pie = bss->ni_cie.ie_wpa;
5862 psi->Bssid.IELength += pie[1] + 2;
5863 memcpy(pVar, pie, pie[1] + 2);
5864 pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pVar + pie[1] + 2);
5867 // Advance buffer pointer
5868 psi = (PNDIS_802_11_BSSID_SCAN_INFO)((BYTE*)psi + bsssize + FIELD_OFFSET(NDIS_802_11_BSSID_SCAN_INFO, Bssid));
5872 IEEE80211_NODE_UNLOCK(nt);
5874 // wmi_free_allnodes(wmip);
5876 // RETAILMSG(1, (L"AR6K: scan indication: %u bss\n", numbss));
5878 ar6000_scan_indication (wmip->wmi_devt, pAr6kScanIndEvent, size);
5880 A_FREE(pAr6kScanIndEvent);
5884 u8 ar6000_get_upper_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh,
5888 u8 threshold = (u8)sq_thresh->upper_threshold[size - 1];
5890 /* The list is already in sorted order. Get the next lower value */
5891 for (index = 0; index < size; index ++) {
5892 if (rssi < sq_thresh->upper_threshold[index]) {
5893 threshold = (u8)sq_thresh->upper_threshold[index];
5901 u8 ar6000_get_lower_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh,
5905 u8 threshold = (u8)sq_thresh->lower_threshold[size - 1];
5907 /* The list is already in sorted order. Get the next lower value */
5908 for (index = 0; index < size; index ++) {
5909 if (rssi > sq_thresh->lower_threshold[index]) {
5910 threshold = (u8)sq_thresh->lower_threshold[index];
5918 wmi_send_rssi_threshold_params(struct wmi_t *wmip,
5919 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
5923 WMI_RSSI_THRESHOLD_PARAMS_CMD *cmd;
5925 size = sizeof (*cmd);
5927 osbuf = A_NETBUF_ALLOC(size);
5928 if (osbuf == NULL) {
5932 A_NETBUF_PUT(osbuf, size);
5934 cmd = (WMI_RSSI_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
5935 A_MEMZERO(cmd, size);
5936 memcpy(cmd, rssiCmd, sizeof(WMI_RSSI_THRESHOLD_PARAMS_CMD));
5938 return (wmi_cmd_send(wmip, osbuf, WMI_RSSI_THRESHOLD_PARAMS_CMDID,
5942 wmi_send_snr_threshold_params(struct wmi_t *wmip,
5943 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
5947 WMI_SNR_THRESHOLD_PARAMS_CMD *cmd;
5949 size = sizeof (*cmd);
5951 osbuf = A_NETBUF_ALLOC(size);
5952 if (osbuf == NULL) {
5956 A_NETBUF_PUT(osbuf, size);
5957 cmd = (WMI_SNR_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
5958 A_MEMZERO(cmd, size);
5959 memcpy(cmd, snrCmd, sizeof(WMI_SNR_THRESHOLD_PARAMS_CMD));
5961 return (wmi_cmd_send(wmip, osbuf, WMI_SNR_THRESHOLD_PARAMS_CMDID,
5966 wmi_set_target_event_report_cmd(struct wmi_t *wmip, WMI_SET_TARGET_EVENT_REPORT_CMD* cmd)
5969 WMI_SET_TARGET_EVENT_REPORT_CMD* alloc_cmd;
5971 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5972 if (osbuf == NULL) {
5976 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5978 alloc_cmd = (WMI_SET_TARGET_EVENT_REPORT_CMD *)(A_NETBUF_DATA(osbuf));
5979 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5980 memcpy(alloc_cmd, cmd, sizeof(*cmd));
5982 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TARGET_EVENT_REPORT_CMDID,
5986 bss_t *wmi_rm_current_bss (struct wmi_t *wmip, u8 *id)
5988 wmi_get_current_bssid (wmip, id);
5989 return wlan_node_remove (&wmip->wmi_scan_table, id);
5992 int wmi_add_current_bss (struct wmi_t *wmip, u8 *id, bss_t *bss)
5994 wlan_setup_node (&wmip->wmi_scan_table, bss, id);
5998 #ifdef ATH_AR6K_11N_SUPPORT
6000 wmi_addba_req_event_rx(struct wmi_t *wmip, u8 *datap, int len)
6002 WMI_ADDBA_REQ_EVENT *cmd = (WMI_ADDBA_REQ_EVENT *)datap;
6004 A_WMI_AGGR_RECV_ADDBA_REQ_EVT(wmip->wmi_devt, cmd);
6011 wmi_addba_resp_event_rx(struct wmi_t *wmip, u8 *datap, int len)
6013 WMI_ADDBA_RESP_EVENT *cmd = (WMI_ADDBA_RESP_EVENT *)datap;
6015 A_WMI_AGGR_RECV_ADDBA_RESP_EVT(wmip->wmi_devt, cmd);
6021 wmi_delba_req_event_rx(struct wmi_t *wmip, u8 *datap, int len)
6023 WMI_DELBA_EVENT *cmd = (WMI_DELBA_EVENT *)datap;
6025 A_WMI_AGGR_RECV_DELBA_REQ_EVT(wmip->wmi_devt, cmd);
6031 wmi_btcoex_config_event_rx(struct wmi_t *wmip, u8 *datap, int len)
6033 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
6035 A_WMI_BTCOEX_CONFIG_EVENT(wmip->wmi_devt, datap, len);
6042 wmi_btcoex_stats_event_rx(struct wmi_t * wmip,u8 *datap,int len)
6044 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
6046 A_WMI_BTCOEX_STATS_EVENT(wmip->wmi_devt, datap, len);
6054 wmi_hci_event_rx(struct wmi_t *wmip, u8 *datap, int len)
6056 WMI_HCI_EVENT *cmd = (WMI_HCI_EVENT *)datap;
6057 A_WMI_HCI_EVENT_EVT(wmip->wmi_devt, cmd);
6062 ////////////////////////////////////////////////////////////////////////////////
6064 //// AP mode functions ////
6066 ////////////////////////////////////////////////////////////////////////////////
6068 * IOCTL: AR6000_XIOCTL_AP_COMMIT_CONFIG
6070 * When AR6K in AP mode, This command will be called after
6071 * changing ssid, channel etc. It will pass the profile to
6072 * target with a flag which will indicate which parameter changed,
6073 * also if this flag is 0, there was no change in parametes, so
6074 * commit cmd will not be sent to target. Without calling this IOCTL
6075 * the changes will not take effect.
6078 wmi_ap_profile_commit(struct wmi_t *wmip, WMI_CONNECT_CMD *p)
6081 WMI_CONNECT_CMD *cm;
6083 osbuf = A_NETBUF_ALLOC(sizeof(*cm));
6084 if (osbuf == NULL) {
6088 A_NETBUF_PUT(osbuf, sizeof(*cm));
6089 cm = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf));
6090 A_MEMZERO(cm, sizeof(*cm));
6092 memcpy(cm,p,sizeof(*cm));
6094 return (wmi_cmd_send(wmip, osbuf, WMI_AP_CONFIG_COMMIT_CMDID, NO_SYNC_WMIFLAG));
6098 * IOCTL: AR6000_XIOCTL_AP_HIDDEN_SSID
6100 * This command will be used to enable/disable hidden ssid functioanlity of
6101 * beacon. If it is enabled, ssid will be NULL in beacon.
6104 wmi_ap_set_hidden_ssid(struct wmi_t *wmip, u8 hidden_ssid)
6107 WMI_AP_HIDDEN_SSID_CMD *hs;
6109 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_HIDDEN_SSID_CMD));
6110 if (osbuf == NULL) {
6114 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_HIDDEN_SSID_CMD));
6115 hs = (WMI_AP_HIDDEN_SSID_CMD *)(A_NETBUF_DATA(osbuf));
6116 A_MEMZERO(hs, sizeof(*hs));
6118 hs->hidden_ssid = hidden_ssid;
6120 A_DPRINTF(DBG_WMI, (DBGFMT "AR6000_XIOCTL_AP_HIDDEN_SSID %d\n", DBGARG , hidden_ssid));
6121 return (wmi_cmd_send(wmip, osbuf, WMI_AP_HIDDEN_SSID_CMDID, NO_SYNC_WMIFLAG));
6125 * IOCTL: AR6000_XIOCTL_AP_SET_MAX_NUM_STA
6127 * This command is used to limit max num of STA that can connect
6128 * with this AP. This value should not exceed AP_MAX_NUM_STA (this
6129 * is max num of STA supported by AP). Value was already validated
6133 wmi_ap_set_num_sta(struct wmi_t *wmip, u8 num_sta)
6136 WMI_AP_SET_NUM_STA_CMD *ns;
6138 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_NUM_STA_CMD));
6139 if (osbuf == NULL) {
6143 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_NUM_STA_CMD));
6144 ns = (WMI_AP_SET_NUM_STA_CMD *)(A_NETBUF_DATA(osbuf));
6145 A_MEMZERO(ns, sizeof(*ns));
6147 ns->num_sta = num_sta;
6149 A_DPRINTF(DBG_WMI, (DBGFMT "AR6000_XIOCTL_AP_SET_MAX_NUM_STA %d\n", DBGARG , num_sta));
6150 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_NUM_STA_CMDID, NO_SYNC_WMIFLAG));
6154 * IOCTL: AR6000_XIOCTL_AP_SET_ACL_MAC
6156 * This command is used to send list of mac of STAs which will
6157 * be allowed to connect with this AP. When this list is empty
6158 * firware will allow all STAs till the count reaches AP_MAX_NUM_STA.
6161 wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *acl)
6164 WMI_AP_ACL_MAC_CMD *a;
6166 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_ACL_MAC_CMD));
6167 if (osbuf == NULL) {
6171 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_ACL_MAC_CMD));
6172 a = (WMI_AP_ACL_MAC_CMD *)(A_NETBUF_DATA(osbuf));
6173 A_MEMZERO(a, sizeof(*a));
6174 memcpy(a,acl,sizeof(*acl));
6176 return (wmi_cmd_send(wmip, osbuf, WMI_AP_ACL_MAC_LIST_CMDID, NO_SYNC_WMIFLAG));
6180 * IOCTL: AR6000_XIOCTL_AP_SET_MLME
6182 * This command is used to send list of mac of STAs which will
6183 * be allowed to connect with this AP. When this list is empty
6184 * firware will allow all STAs till the count reaches AP_MAX_NUM_STA.
6187 wmi_ap_set_mlme(struct wmi_t *wmip, u8 cmd, u8 *mac, u16 reason)
6190 WMI_AP_SET_MLME_CMD *mlme;
6192 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_MLME_CMD));
6193 if (osbuf == NULL) {
6197 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_MLME_CMD));
6198 mlme = (WMI_AP_SET_MLME_CMD *)(A_NETBUF_DATA(osbuf));
6199 A_MEMZERO(mlme, sizeof(*mlme));
6202 memcpy(mlme->mac, mac, ATH_MAC_LEN);
6203 mlme->reason = reason;
6205 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_MLME_CMDID, NO_SYNC_WMIFLAG));
6209 wmi_pspoll_event_rx(struct wmi_t *wmip, u8 *datap, int len)
6211 WMI_PSPOLL_EVENT *ev;
6213 if (len < sizeof(WMI_PSPOLL_EVENT)) {
6216 ev = (WMI_PSPOLL_EVENT *)datap;
6218 A_WMI_PSPOLL_EVENT(wmip->wmi_devt, ev->aid);
6223 wmi_dtimexpiry_event_rx(struct wmi_t *wmip, u8 *datap,int len)
6225 A_WMI_DTIMEXPIRY_EVENT(wmip->wmi_devt);
6231 wmi_wapi_rekey_event_rx(struct wmi_t *wmip, u8 *datap,int len)
6240 A_WMI_WAPI_REKEY_EVENT(wmip->wmi_devt, *ev, &ev[1]);
6246 wmi_set_pvb_cmd(struct wmi_t *wmip, u16 aid, bool flag)
6248 WMI_AP_SET_PVB_CMD *cmd;
6251 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_PVB_CMD));
6252 if (osbuf == NULL) {
6256 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_PVB_CMD));
6257 cmd = (WMI_AP_SET_PVB_CMD *)(A_NETBUF_DATA(osbuf));
6258 A_MEMZERO(cmd, sizeof(*cmd));
6263 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_PVB_CMDID, NO_SYNC_WMIFLAG));
6267 wmi_ap_conn_inact_time(struct wmi_t *wmip, u32 period)
6269 WMI_AP_CONN_INACT_CMD *cmd;
6272 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_CONN_INACT_CMD));
6273 if (osbuf == NULL) {
6277 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_CONN_INACT_CMD));
6278 cmd = (WMI_AP_CONN_INACT_CMD *)(A_NETBUF_DATA(osbuf));
6279 A_MEMZERO(cmd, sizeof(*cmd));
6281 cmd->period = period;
6283 return (wmi_cmd_send(wmip, osbuf, WMI_AP_CONN_INACT_CMDID, NO_SYNC_WMIFLAG));
6287 wmi_ap_bgscan_time(struct wmi_t *wmip, u32 period, u32 dwell)
6289 WMI_AP_PROT_SCAN_TIME_CMD *cmd;
6292 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_PROT_SCAN_TIME_CMD));
6293 if (osbuf == NULL) {
6297 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_PROT_SCAN_TIME_CMD));
6298 cmd = (WMI_AP_PROT_SCAN_TIME_CMD *)(A_NETBUF_DATA(osbuf));
6299 A_MEMZERO(cmd, sizeof(*cmd));
6301 cmd->period_min = period;
6302 cmd->dwell_ms = dwell;
6304 return (wmi_cmd_send(wmip, osbuf, WMI_AP_PROT_SCAN_TIME_CMDID, NO_SYNC_WMIFLAG));
6308 wmi_ap_set_dtim(struct wmi_t *wmip, u8 dtim)
6310 WMI_AP_SET_DTIM_CMD *cmd;
6313 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_DTIM_CMD));
6314 if (osbuf == NULL) {
6318 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_DTIM_CMD));
6319 cmd = (WMI_AP_SET_DTIM_CMD *)(A_NETBUF_DATA(osbuf));
6320 A_MEMZERO(cmd, sizeof(*cmd));
6324 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_DTIM_CMDID, NO_SYNC_WMIFLAG));
6328 * IOCTL: AR6000_XIOCTL_AP_SET_ACL_POLICY
6330 * This command is used to set ACL policay. While changing policy, if you
6331 * want to retain the existing MAC addresses in the ACL list, policy should be
6332 * OR with AP_ACL_RETAIN_LIST_MASK, else the existing list will be cleared.
6333 * If there is no chage in policy, the list will be intact.
6336 wmi_ap_set_acl_policy(struct wmi_t *wmip, u8 policy)
6339 WMI_AP_ACL_POLICY_CMD *po;
6341 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_ACL_POLICY_CMD));
6342 if (osbuf == NULL) {
6346 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_ACL_POLICY_CMD));
6347 po = (WMI_AP_ACL_POLICY_CMD *)(A_NETBUF_DATA(osbuf));
6348 A_MEMZERO(po, sizeof(*po));
6350 po->policy = policy;
6352 return (wmi_cmd_send(wmip, osbuf, WMI_AP_ACL_POLICY_CMDID, NO_SYNC_WMIFLAG));
6356 wmi_ap_set_rateset(struct wmi_t *wmip, u8 rateset)
6359 WMI_AP_SET_11BG_RATESET_CMD *rs;
6361 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_11BG_RATESET_CMD));
6362 if (osbuf == NULL) {
6366 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_11BG_RATESET_CMD));
6367 rs = (WMI_AP_SET_11BG_RATESET_CMD *)(A_NETBUF_DATA(osbuf));
6368 A_MEMZERO(rs, sizeof(*rs));
6370 rs->rateset = rateset;
6372 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_11BG_RATESET_CMDID, NO_SYNC_WMIFLAG));
6375 #ifdef ATH_AR6K_11N_SUPPORT
6377 wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd)
6380 WMI_SET_HT_CAP_CMD *htCap;
6383 osbuf = A_NETBUF_ALLOC(sizeof(*htCap));
6384 if (osbuf == NULL) {
6388 A_NETBUF_PUT(osbuf, sizeof(*htCap));
6390 band = (cmd->band)? A_BAND_5GHZ : A_BAND_24GHZ;
6391 wmip->wmi_ht_allowed[band] = (cmd->enable)? 1:0;
6393 htCap = (WMI_SET_HT_CAP_CMD *)(A_NETBUF_DATA(osbuf));
6394 A_MEMZERO(htCap, sizeof(*htCap));
6395 memcpy(htCap, cmd, sizeof(*htCap));
6397 return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_CAP_CMDID,
6402 wmi_set_ht_op_cmd(struct wmi_t *wmip, u8 sta_chan_width)
6405 WMI_SET_HT_OP_CMD *htInfo;
6407 osbuf = A_NETBUF_ALLOC(sizeof(*htInfo));
6408 if (osbuf == NULL) {
6412 A_NETBUF_PUT(osbuf, sizeof(*htInfo));
6414 htInfo = (WMI_SET_HT_OP_CMD *)(A_NETBUF_DATA(osbuf));
6415 A_MEMZERO(htInfo, sizeof(*htInfo));
6416 htInfo->sta_chan_width = sta_chan_width;
6418 return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_OP_CMDID,
6424 wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, u32 *pMaskArray)
6427 WMI_SET_TX_SELECT_RATES_CMD *pData;
6429 osbuf = A_NETBUF_ALLOC(sizeof(*pData));
6430 if (osbuf == NULL) {
6434 A_NETBUF_PUT(osbuf, sizeof(*pData));
6436 pData = (WMI_SET_TX_SELECT_RATES_CMD *)(A_NETBUF_DATA(osbuf));
6437 memcpy(pData, pMaskArray, sizeof(*pData));
6439 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_SELECT_RATES_CMDID,
6445 wmi_send_hci_cmd(struct wmi_t *wmip, u8 *buf, u16 sz)
6450 osbuf = A_NETBUF_ALLOC(sizeof(*cmd) + sz);
6451 if (osbuf == NULL) {
6455 A_NETBUF_PUT(osbuf, sizeof(*cmd) + sz);
6456 cmd = (WMI_HCI_CMD *)(A_NETBUF_DATA(osbuf));
6458 cmd->cmd_buf_sz = sz;
6459 memcpy(cmd->buf, buf, sz);
6460 return (wmi_cmd_send(wmip, osbuf, WMI_HCI_CMD_CMDID, NO_SYNC_WMIFLAG));
6463 #ifdef ATH_AR6K_11N_SUPPORT
6465 wmi_allow_aggr_cmd(struct wmi_t *wmip, u16 tx_tidmask, u16 rx_tidmask)
6468 WMI_ALLOW_AGGR_CMD *cmd;
6470 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6471 if (osbuf == NULL) {
6475 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6477 cmd = (WMI_ALLOW_AGGR_CMD *)(A_NETBUF_DATA(osbuf));
6478 cmd->tx_allow_aggr = tx_tidmask;
6479 cmd->rx_allow_aggr = rx_tidmask;
6481 return (wmi_cmd_send(wmip, osbuf, WMI_ALLOW_AGGR_CMDID, NO_SYNC_WMIFLAG));
6485 wmi_setup_aggr_cmd(struct wmi_t *wmip, u8 tid)
6488 WMI_ADDBA_REQ_CMD *cmd;
6490 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6491 if (osbuf == NULL) {
6495 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6497 cmd = (WMI_ADDBA_REQ_CMD *)(A_NETBUF_DATA(osbuf));
6500 return (wmi_cmd_send(wmip, osbuf, WMI_ADDBA_REQ_CMDID, NO_SYNC_WMIFLAG));
6504 wmi_delete_aggr_cmd(struct wmi_t *wmip, u8 tid, bool uplink)
6507 WMI_DELBA_REQ_CMD *cmd;
6509 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6510 if (osbuf == NULL) {
6514 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6516 cmd = (WMI_DELBA_REQ_CMD *)(A_NETBUF_DATA(osbuf));
6518 cmd->is_sender_initiator = uplink; /* uplink =1 - uplink direction, 0=downlink direction */
6520 /* Delete the local aggr state, on host */
6521 return (wmi_cmd_send(wmip, osbuf, WMI_DELBA_REQ_CMDID, NO_SYNC_WMIFLAG));
6526 wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, u8 rxMetaVersion,
6527 bool rxDot11Hdr, bool defragOnHost)
6530 WMI_RX_FRAME_FORMAT_CMD *cmd;
6532 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6533 if (osbuf == NULL) {
6537 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6539 cmd = (WMI_RX_FRAME_FORMAT_CMD *)(A_NETBUF_DATA(osbuf));
6540 cmd->dot11Hdr = (rxDot11Hdr==true)? 1:0;
6541 cmd->defragOnHost = (defragOnHost==true)? 1:0;
6542 cmd->metaVersion = rxMetaVersion; /* */
6544 /* Delete the local aggr state, on host */
6545 return (wmi_cmd_send(wmip, osbuf, WMI_RX_FRAME_FORMAT_CMDID, NO_SYNC_WMIFLAG));
6550 wmi_set_thin_mode_cmd(struct wmi_t *wmip, bool bThinMode)
6553 WMI_SET_THIN_MODE_CMD *cmd;
6555 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6556 if (osbuf == NULL) {
6560 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6562 cmd = (WMI_SET_THIN_MODE_CMD *)(A_NETBUF_DATA(osbuf));
6563 cmd->enable = (bThinMode==true)? 1:0;
6565 /* Delete the local aggr state, on host */
6566 return (wmi_cmd_send(wmip, osbuf, WMI_SET_THIN_MODE_CMDID, NO_SYNC_WMIFLAG));
6571 wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE precedence)
6574 WMI_SET_BT_WLAN_CONN_PRECEDENCE *cmd;
6576 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6577 if (osbuf == NULL) {
6581 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6583 cmd = (WMI_SET_BT_WLAN_CONN_PRECEDENCE *)(A_NETBUF_DATA(osbuf));
6584 A_MEMZERO(cmd, sizeof(*cmd));
6585 cmd->precedence = precedence;
6587 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID,
6592 wmi_set_pmk_cmd(struct wmi_t *wmip, u8 *pmk)
6597 osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_PMK_CMD));
6598 if (osbuf == NULL) {
6602 A_NETBUF_PUT(osbuf, sizeof(WMI_SET_PMK_CMD));
6604 p = (WMI_SET_PMK_CMD *)(A_NETBUF_DATA(osbuf));
6605 A_MEMZERO(p, sizeof(*p));
6607 memcpy(p->pmk, pmk, WMI_PMK_LEN);
6609 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMK_CMDID, NO_SYNC_WMIFLAG));
6613 wmi_set_excess_tx_retry_thres_cmd(struct wmi_t *wmip, WMI_SET_EXCESS_TX_RETRY_THRES_CMD *cmd)
6616 WMI_SET_EXCESS_TX_RETRY_THRES_CMD *p;
6618 osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_EXCESS_TX_RETRY_THRES_CMD));
6619 if (osbuf == NULL) {
6623 A_NETBUF_PUT(osbuf, sizeof(WMI_SET_EXCESS_TX_RETRY_THRES_CMD));
6625 p = (WMI_SET_EXCESS_TX_RETRY_THRES_CMD *)(A_NETBUF_DATA(osbuf));
6626 memset(p, 0, sizeof(*p));
6628 p->threshold = cmd->threshold;
6630 return (wmi_cmd_send(wmip, osbuf, WMI_SET_EXCESS_TX_RETRY_THRES_CMDID, NO_SYNC_WMIFLAG));
6634 wmi_SGI_cmd(struct wmi_t *wmip, u32 sgiMask, u8 sgiPERThreshold)
6637 WMI_SET_TX_SGI_PARAM_CMD *cmd;
6639 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6640 if (osbuf == NULL) {
6641 return A_NO_MEMORY ;
6644 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6646 cmd = (WMI_SET_TX_SGI_PARAM_CMD *)(A_NETBUF_DATA(osbuf));
6647 A_MEMZERO(cmd, sizeof(*cmd));
6648 cmd->sgiMask = sgiMask;
6649 cmd->sgiPERThreshold = sgiPERThreshold;
6650 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_SGI_PARAM_CMDID,
6655 wmi_find_matching_Ssidnode (struct wmi_t *wmip, u8 *pSsid,
6657 u32 dot11AuthMode, u32 authMode,
6658 u32 pairwiseCryptoType, u32 grpwiseCryptoTyp)
6661 node = wlan_find_matching_Ssidnode (&wmip->wmi_scan_table, pSsid,
6662 ssidLength, dot11AuthMode, authMode, pairwiseCryptoType, grpwiseCryptoTyp);
6667 u16 wmi_ieee2freq (int chan)
6670 freq = wlan_ieee2freq (chan);
6675 u32 wmi_freq2ieee (u16 freq)
6678 chan = wlan_freq2ieee (freq);