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 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, A_UINT8 *datap, int len);
75 static int wmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
77 static int wmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
80 static int wmi_tkip_micerr_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
82 static int wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
84 static int wmi_opt_frame_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
86 static int wmi_pstream_timeout_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
88 static int wmi_sync_point(struct wmi_t *wmip);
90 static int wmi_bitrate_reply_rx(struct wmi_t *wmip, A_UINT8 *datap,
92 static int wmi_ratemask_reply_rx(struct wmi_t *wmip, A_UINT8 *datap,
94 static int wmi_channelList_reply_rx(struct wmi_t *wmip, A_UINT8 *datap,
96 static int wmi_regDomain_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
98 static int wmi_txPwr_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
99 static int wmi_neighborReport_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
102 static int wmi_dset_open_req_rx(struct wmi_t *wmip, A_UINT8 *datap,
104 #ifdef CONFIG_HOST_DSET_SUPPORT
105 static int wmi_dset_close_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
106 static int wmi_dset_data_req_rx(struct wmi_t *wmip, A_UINT8 *datap,
108 #endif /* CONFIG_HOST_DSET_SUPPORT */
111 static int wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap,
113 static int wmi_errorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
114 static int wmi_statsEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
115 static int wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
116 static int wmi_hbChallengeResp_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
117 static int wmi_reportErrorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
118 static int wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
119 static int wmi_channel_change_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
120 static int wmi_roam_tbl_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
122 static int wmi_roam_data_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
124 static int wmi_get_wow_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
127 wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len);
130 wmi_set_params_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len);
133 wmi_acm_reject_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len);
135 #ifdef CONFIG_HOST_GPIO_SUPPORT
136 static int wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
137 static int wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
138 static int wmi_gpio_ack_rx(struct wmi_t *wmip, A_UINT8 *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, A_UINT8 *datap, int len);
147 wmi_txRetryErrEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
150 wmi_snrThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
153 wmi_lqThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
156 wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_INT32 rateIndex);
159 wmi_aplistEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
162 wmi_dbglog_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
164 static int wmi_keepalive_reply_rx(struct wmi_t *wmip, A_UINT8 *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 A_UINT8 ar6000_get_upper_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, A_UINT32 size);
170 A_UINT8 ar6000_get_lower_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, A_UINT32 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, A_UINT8 *datap, int len);
181 #endif /* CONFIG_TARGET_PROFILE_SUPPORT */
183 static int wmi_pspoll_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
185 static int wmi_dtimexpiry_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
188 static int wmi_peer_node_event_rx (struct wmi_t *wmip, A_UINT8 *datap,
190 #ifdef ATH_AR6K_11N_SUPPORT
191 static int wmi_addba_req_event_rx(struct wmi_t *, A_UINT8 *, int);
192 static int wmi_addba_resp_event_rx(struct wmi_t *, A_UINT8 *, int);
193 static int wmi_delba_req_event_rx(struct wmi_t *, A_UINT8 *, int);
194 static int wmi_btcoex_config_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
195 static int wmi_btcoex_stats_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
197 static int wmi_hci_event_rx(struct wmi_t *, A_UINT8 *, int);
200 static int wmi_wapi_rekey_event_rx(struct wmi_t *wmip, A_UINT8 *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 A_INT32 wmi_rateTable[][2] = {
216 //{W/O SGI, with SGI}
247 #define MODE_A_SUPPORT_RATE_START ((A_INT32) 4)
248 #define MODE_A_SUPPORT_RATE_STOP ((A_INT32) 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 ((A_INT32) 0)
254 #define MODE_B_SUPPORT_RATE_STOP ((A_INT32) 3)
256 #define MODE_G_SUPPORT_RATE_START ((A_INT32) 0)
257 #define MODE_G_SUPPORT_RATE_STOP ((A_INT32) 11)
259 #define MODE_GHT20_SUPPORT_RATE_START ((A_INT32) 0)
260 #define MODE_GHT20_SUPPORT_RATE_STOP ((A_INT32) 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 A_UINT8 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 A_UINT8 ip_ver_hdrlen; /* version and hdr length */
281 A_UINT8 ip_tos; /* type of service */
282 A_UINT16 ip_len; /* total length */
283 A_UINT16 ip_id; /* identification */
284 A_INT16 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 A_UINT8 ip_ttl; /* time to live */
289 A_UINT8 ip_p; /* protocol */
290 A_UINT16 ip_sum; /* checksum */
291 A_UINT8 ip_src[4]; /* source and dest address */
295 #include "athendpack.h"
297 static A_INT16 rssi_event_value = 0;
298 static A_INT16 snr_event_value = 0;
300 A_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 = *(A_UINT16 *)(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 A_MEMCPY(macHdr.dstMac, datap, ATH_MAC_LEN);
426 A_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)) != A_OK) {
436 datap = A_NETBUF_DATA(osbuf);
438 A_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, A_UINT8 *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) != A_OK) {
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) != A_OK) {
486 pV2 = (WMI_TX_META_V2 *)A_NETBUF_DATA(osbuf);
487 A_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, A_UINT8 msgType, A_BOOL bMoreData,
499 WMI_DATA_HDR_DATA_TYPE data_type,A_UINT8 metaVersion, void *pTxMetaS)
502 // A_UINT8 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)) != A_OK) {
513 if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != A_OK) {
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 A_UINT8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 layer2Priority, A_BOOL wmmEnabled)
537 A_UINT8 trafficClass = WMM_AC_BE;
538 A_UINT16 ipType = IP_ETHERTYPE;
540 A_BOOL streamExists = FALSE;
541 A_UINT8 userPriority;
542 A_UINT32 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(A_UINT32));
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 (((A_UINT8 *)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 = *(A_UINT16 *)(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 A_MEMCPY(macHdr.dstMac, datap, ATH_MAC_LEN);
658 A_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)) != A_OK) {
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(A_UINT32));
686 if (A_NETBUF_PUSH(osbuf, hdrsize) != A_OK)
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(A_UINT32));
696 if (A_NETBUF_PUSH(osbuf, hdrsize) != A_OK)
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;
721 A_UINT8 type,subtype;
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 A_MEMCPY((A_UINT8 *)&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(A_UINT32));
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 A_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 A_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)) != A_OK) {
802 datap = A_NETBUF_DATA(osbuf);
804 A_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)) != A_OK) {
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 A_UINT32 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)) != A_OK) {
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 A_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 A_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, A_UINT8 *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 ((((A_UINT8 *)(p))[0] ) | (((A_UINT8 *)(p))[1] << 8) | \
1245 (((A_UINT8 *)(p))[2] << 16) | (((A_UINT8 *)(p))[3] << 24)))
1248 iswmmoui(const A_UINT8 *frm)
1250 return frm[1] > 3 && LE_READ_4(frm+2) == ((WMM_OUI_TYPE<<24)|WMM_OUI);
1254 iswmmparam(const A_UINT8 *frm)
1256 return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE;
1261 wmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *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 A_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(A_UINT16) + /* capinfo*/
1283 sizeof(A_UINT16) + /* status Code */
1284 sizeof(A_UINT16) ; /* 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, A_UINT8 *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, A_UINT8 *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, A_UINT8 *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, A_UINT8 *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, A_UINT8 *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, A_UINT8 *datap, int len)
1421 WMI_BSS_INFO_HDR *bih;
1423 A_UINT32 nodeCachingAllowed = 1;
1424 A_UCHAR cached_ssid_len = 0;
1425 A_UCHAR cached_ssid_buf[IEEE80211_NWID_LEN] = {0};
1426 A_UINT8 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 A_OK; //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) != A_OK) {
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 A_UINT8 *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 A_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 A_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 A_MEMCPY(ni_buf, buf, buf_len);
1563 A_MEMCPY(bss->ni_buf, buf, len);
1565 bss->ni_framelen = len;
1566 if (wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie) != A_OK) {
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, A_UINT8 *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 A_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, A_UINT8 *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, A_UINT8 *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 == (A_INT8) 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, A_UINT8 *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, A_UINT8 *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, A_UINT8 *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, A_UINT8 *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, A_UINT8 *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, A_UINT8 *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, A_UINT8 *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, A_UINT8 *datap, int len)
1816 WMI_SCAN_COMPLETE_EVENT *ev;
1818 ev = (WMI_SCAN_COMPLETE_EVENT *)datap;
1819 if ((int)ev->status == A_OK) {
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, A_UINT8 *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, A_UINT8 *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, A_UINT8 *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 A_UINT8 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) != A_OK) {
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, A_UINT8 *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, A_UINT8 *datap, int len)
1992 WMI_CAC_EVENT *reply;
1993 WMM_TSPEC_IE *tspec_ie;
1994 A_UINT16 activeTsids;
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, A_UINT8 *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, A_UINT8 *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, A_UINT8 *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, A_UINT8 *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, A_UINT8 *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, A_UINT8 *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 A_UINT8 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) != A_OK) {
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, A_UINT8 *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, A_UINT8 *datap, int len)
2251 A_UINT16 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, A_UINT8 *datap, int len)
2294 dropped = *((A_UINT32 *)datap);
2295 datap += sizeof(dropped);
2296 len -= sizeof(dropped);
2297 A_WMI_DBGLOG_EVENT(wmip->wmi_devt, dropped, (A_INT8*)datap, len);
2301 #ifdef CONFIG_HOST_GPIO_SUPPORT
2303 wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *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, A_UINT8 *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, A_UINT8 *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)) != A_OK) {
2370 A_NETBUF_FREE(osbuf);
2374 cHdr = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf);
2375 cHdr->commandId = (A_UINT16) 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)) != A_OK) {
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)) != A_OK) {
2408 A_NETBUF_FREE(osbuf);
2412 cHdr = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf);
2413 cHdr->commandId = (A_UINT32) 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, A_UINT8 pairwiseCryptoLen,
2422 CRYPTO_TYPE groupCrypto, A_UINT8 groupCryptoLen,
2423 int ssidLength, A_UCHAR *ssid,
2424 A_UINT8 *bssid, A_UINT16 channel, A_UINT32 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 A_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 A_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, A_UINT8 *bssid, A_UINT16 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 A_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 A_BOOL forceFgScan, A_BOOL isLegacy,
2515 A_UINT32 homeDwellTime, A_UINT32 forceScanInterval,
2516 A_INT8 numChan, A_UINT16 *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(A_UINT16) * (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 A_MEMCPY(sc->channelList, channelList, numChan * sizeof(A_UINT16));
2553 return (wmi_cmd_send(wmip, osbuf, WMI_START_SCAN_CMDID, NO_SYNC_WMIFLAG));
2557 wmi_scanparams_cmd(struct wmi_t *wmip, A_UINT16 fg_start_sec,
2558 A_UINT16 fg_end_sec, A_UINT16 bg_sec,
2559 A_UINT16 minact_chdw_msec, A_UINT16 maxact_chdw_msec,
2560 A_UINT16 pas_chdw_msec,
2561 A_UINT8 shScanRatio, A_UINT8 scanCtrlFlags,
2562 A_UINT32 max_dfsch_act_time, A_UINT16 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, A_UINT8 filter, A_UINT32 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, A_UINT8 index, A_UINT8 flag,
2619 A_UINT8 ssidLength, A_UCHAR *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 A_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, A_UINT16 listenInterval, A_UINT16 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, A_UINT16 bmissTime, A_UINT16 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, A_UINT8 ieType,
2705 A_UINT8 ieLen, A_UINT8 *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 A_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, A_UINT8 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, A_UINT8 pmEnable, A_UINT8 ttl,
2753 A_UINT16 atim_windows, A_UINT16 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, A_UINT8 psType, A_UINT32 idle_time,
2778 A_UINT32 ps_period, A_UINT8 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, A_UINT16 idlePeriod,
2803 A_UINT16 psPollNum, A_UINT16 dtimPolicy,
2804 A_UINT16 tx_wakeup_policy, A_UINT16 num_tx_to_wakeup,
2805 A_UINT16 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, A_UINT8 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, A_UINT8 keyIndex, CRYPTO_TYPE keyType,
2853 A_UINT8 keyUsage, A_UINT8 keyLength, A_UINT8 *keyRSC,
2854 A_UINT8 *keyMaterial, A_UINT8 key_op_ctrl, A_UINT8 *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 A_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 A_MEMCPY(cmd->keyRSC, keyRSC, sizeof(cmd->keyRSC));
2891 cmd->key_op_ctrl = key_op_ctrl;
2894 A_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, A_UINT8 *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 A_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, A_UINT8 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, A_UINT8 *bssid, A_UINT8 *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 A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid));
2976 A_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, A_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 A_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)) != A_OK) {
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 {
3084 A_UINT8 trafficClass;
3086 }WMI_DATA_SYNC_BUFS;
3089 wmi_sync_point(struct wmi_t *wmip)
3093 WMI_DATA_SYNC_BUFS dataSyncBufs[WMM_NUM_AC];
3094 A_UINT8 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 A_UINT8 fatPipeExistsForAC=0;
3204 A_INT32 minimalPHY = 0;
3205 A_INT32 nominalPHY = 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 A_MEMCPY(cmd, params, sizeof(*cmd));
3263 /* this is an implicitly created Fat pipe */
3264 if ((A_UINT32)params->tsid == (A_UINT32)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, A_UINT8 trafficClass, A_UINT8 tsid)
3298 WMI_DELETE_PSTREAM_CMD *cmd;
3300 A_UINT16 activeTsids=0;
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, A_UINT8 bEnable, A_UINT8 type, A_UINT8 subType, A_UINT16 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 = (A_UINT8)((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, A_INT32 dataRate, A_INT32 mgmtRate, A_INT32 ctlRate)
3401 WMI_BIT_RATE_CMD *cmd;
3402 A_INT8 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, A_INT32 rateIndex)
3459 WMI_PHY_MODE phyMode = (WMI_PHY_MODE) wmip->wmi_phyMode;
3460 A_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)) {
3513 wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate, A_INT8 *rate_idx)
3519 if (wmi_rateTable[(A_UINT32) i][0] == 0) {
3522 if (wmi_rateTable[(A_UINT32) i][0] == rate) {
3527 if(wmi_is_bitrate_index_valid(wmip, (A_INT32) i) != TRUE) {
3536 wmi_set_fixrates_cmd(struct wmi_t *wmip, A_UINT32 fixRatesMask)
3539 WMI_FIX_RATES_CMD *cmd;
3542 /* This check does not work for AR6003 as the HT modes are enabled only when
3543 * the STA is connected to a HT_BSS and is not based only on channel. It is
3544 * safe to skip this check however because rate control will only use rates
3545 * that are permitted by the valid rate mask and the fix rate mask. Meaning
3546 * the fix rate mask is not sufficient by itself to cause an invalid rate
3548 /* Make sure all rates in the mask are valid in the current PHY mode */
3549 for(rateIndex = 0; rateIndex < MAX_NUMBER_OF_SUPPORT_RATES; rateIndex++) {
3550 if((1 << rateIndex) & (A_UINT32)fixRatesMask) {
3551 if(wmi_is_bitrate_index_valid(wmip, rateIndex) != TRUE) {
3552 A_DPRINTF(DBG_WMI, (DBGFMT "Set Fix Rates command failed: Given rate is illegal in current PHY mode\n", DBGARG));
3560 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
3561 if (osbuf == NULL) {
3565 A_NETBUF_PUT(osbuf, sizeof(*cmd));
3567 cmd = (WMI_FIX_RATES_CMD *)(A_NETBUF_DATA(osbuf));
3568 A_MEMZERO(cmd, sizeof(*cmd));
3570 cmd->fixRateMask = fixRatesMask;
3572 return (wmi_cmd_send(wmip, osbuf, WMI_SET_FIXRATES_CMDID, NO_SYNC_WMIFLAG));
3576 wmi_get_ratemask_cmd(struct wmi_t *wmip)
3578 return wmi_simple_cmd(wmip, WMI_GET_FIXRATES_CMDID);
3582 wmi_get_channelList_cmd(struct wmi_t *wmip)
3584 return wmi_simple_cmd(wmip, WMI_GET_CHANNEL_LIST_CMDID);
3588 * used to generate a wmi sey channel Parameters cmd.
3589 * mode should always be specified and corresponds to the phy mode of the
3591 * numChan should alway sbe specified. If zero indicates that all available
3592 * channels should be used.
3593 * channelList is an array of channel frequencies (in Mhz) which the radio
3594 * should limit its operation to. It should be NULL if numChan == 0. Size of
3595 * array should correspond to numChan entries.
3598 wmi_set_channelParams_cmd(struct wmi_t *wmip, A_UINT8 scanParam,
3599 WMI_PHY_MODE mode, A_INT8 numChan,
3600 A_UINT16 *channelList)
3603 WMI_CHANNEL_PARAMS_CMD *cmd;
3606 size = sizeof (*cmd);
3609 if (numChan > WMI_MAX_CHANNELS) {
3612 size += sizeof(A_UINT16) * (numChan - 1);
3615 osbuf = A_NETBUF_ALLOC(size);
3616 if (osbuf == NULL) {
3620 A_NETBUF_PUT(osbuf, size);
3622 cmd = (WMI_CHANNEL_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
3623 A_MEMZERO(cmd, size);
3625 wmip->wmi_phyMode = mode;
3626 cmd->scanParam = scanParam;
3627 cmd->phyMode = mode;
3628 cmd->numChannels = numChan;
3629 A_MEMCPY(cmd->channelList, channelList, numChan * sizeof(A_UINT16));
3631 return (wmi_cmd_send(wmip, osbuf, WMI_SET_CHANNEL_PARAMS_CMDID,
3636 wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
3638 SQ_THRESHOLD_PARAMS *sq_thresh =
3639 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI];
3641 * Parse the command and store the threshold values here. The checks
3642 * for valid values can be put here
3644 sq_thresh->weight = rssiCmd->weight;
3645 sq_thresh->polling_interval = rssiCmd->pollTime;
3647 sq_thresh->upper_threshold[0] = rssiCmd->thresholdAbove1_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3648 sq_thresh->upper_threshold[1] = rssiCmd->thresholdAbove2_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3649 sq_thresh->upper_threshold[2] = rssiCmd->thresholdAbove3_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3650 sq_thresh->upper_threshold[3] = rssiCmd->thresholdAbove4_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3651 sq_thresh->upper_threshold[4] = rssiCmd->thresholdAbove5_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3652 sq_thresh->upper_threshold[5] = rssiCmd->thresholdAbove6_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3653 sq_thresh->upper_threshold_valid_count = 6;
3655 /* List sorted in descending order */
3656 sq_thresh->lower_threshold[0] = rssiCmd->thresholdBelow6_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3657 sq_thresh->lower_threshold[1] = rssiCmd->thresholdBelow5_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3658 sq_thresh->lower_threshold[2] = rssiCmd->thresholdBelow4_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3659 sq_thresh->lower_threshold[3] = rssiCmd->thresholdBelow3_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3660 sq_thresh->lower_threshold[4] = rssiCmd->thresholdBelow2_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3661 sq_thresh->lower_threshold[5] = rssiCmd->thresholdBelow1_Val - SIGNAL_QUALITY_NOISE_FLOOR;
3662 sq_thresh->lower_threshold_valid_count = 6;
3664 if (!rssi_event_value) {
3666 * Configuring the thresholds to their extremes allows the host to get an
3667 * event from the target which is used for the configuring the correct
3670 rssiCmd->thresholdAbove1_Val = sq_thresh->upper_threshold[0];
3671 rssiCmd->thresholdBelow1_Val = sq_thresh->lower_threshold[0];
3674 * In case the user issues multiple times of rssi_threshold_setting,
3675 * we should not use the extreames anymore, the target does not expect that.
3677 rssiCmd->thresholdAbove1_Val = ar6000_get_upper_threshold(rssi_event_value, sq_thresh,
3678 sq_thresh->upper_threshold_valid_count);
3679 rssiCmd->thresholdBelow1_Val = ar6000_get_lower_threshold(rssi_event_value, sq_thresh,
3680 sq_thresh->lower_threshold_valid_count);
3685 wmi_set_rssi_threshold_params(struct wmi_t *wmip,
3686 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
3689 /* Check these values are in ascending order */
3690 if( rssiCmd->thresholdAbove6_Val <= rssiCmd->thresholdAbove5_Val ||
3691 rssiCmd->thresholdAbove5_Val <= rssiCmd->thresholdAbove4_Val ||
3692 rssiCmd->thresholdAbove4_Val <= rssiCmd->thresholdAbove3_Val ||
3693 rssiCmd->thresholdAbove3_Val <= rssiCmd->thresholdAbove2_Val ||
3694 rssiCmd->thresholdAbove2_Val <= rssiCmd->thresholdAbove1_Val ||
3695 rssiCmd->thresholdBelow6_Val <= rssiCmd->thresholdBelow5_Val ||
3696 rssiCmd->thresholdBelow5_Val <= rssiCmd->thresholdBelow4_Val ||
3697 rssiCmd->thresholdBelow4_Val <= rssiCmd->thresholdBelow3_Val ||
3698 rssiCmd->thresholdBelow3_Val <= rssiCmd->thresholdBelow2_Val ||
3699 rssiCmd->thresholdBelow2_Val <= rssiCmd->thresholdBelow1_Val)
3704 wmi_cache_configure_rssithreshold(wmip, rssiCmd);
3706 return (wmi_send_rssi_threshold_params(wmip, rssiCmd));
3710 wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *ipCmd)
3713 WMI_SET_IP_CMD *cmd;
3715 /* Multicast address are not valid */
3716 if((*((A_UINT8*)&ipCmd->ips[0]) >= 0xE0) ||
3717 (*((A_UINT8*)&ipCmd->ips[1]) >= 0xE0)) {
3721 osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_IP_CMD));
3722 if (osbuf == NULL) {
3726 A_NETBUF_PUT(osbuf, sizeof(WMI_SET_IP_CMD));
3727 cmd = (WMI_SET_IP_CMD *)(A_NETBUF_DATA(osbuf));
3728 A_MEMCPY(cmd, ipCmd, sizeof(WMI_SET_IP_CMD));
3730 return (wmi_cmd_send(wmip, osbuf, WMI_SET_IP_CMDID,
3735 wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip,
3736 WMI_SET_HOST_SLEEP_MODE_CMD *hostModeCmd)
3740 WMI_SET_HOST_SLEEP_MODE_CMD *cmd;
3741 A_UINT16 activeTsids=0;
3742 A_UINT8 streamExists=0;
3745 if( hostModeCmd->awake == hostModeCmd->asleep) {
3749 size = sizeof (*cmd);
3751 osbuf = A_NETBUF_ALLOC(size);
3752 if (osbuf == NULL) {
3756 A_NETBUF_PUT(osbuf, size);
3758 cmd = (WMI_SET_HOST_SLEEP_MODE_CMD *)(A_NETBUF_DATA(osbuf));
3759 A_MEMZERO(cmd, size);
3760 A_MEMCPY(cmd, hostModeCmd, sizeof(WMI_SET_HOST_SLEEP_MODE_CMD));
3762 if(hostModeCmd->asleep) {
3764 * Relinquish credits from all implicitly created pstreams since when we
3765 * go to sleep. If user created explicit thinstreams exists with in a
3766 * fatpipe leave them intact for the user to delete
3769 streamExists = wmip->wmi_fatPipeExists;
3772 for(i=0;i< WMM_NUM_AC;i++) {
3773 if (streamExists & (1<<i)) {
3775 activeTsids = wmip->wmi_streamExistsForAC[i];
3777 /* If there are no user created thin streams delete the fatpipe */
3779 streamExists &= ~(1<<i);
3780 /*Indicate inactivity to drv layer for this fatpipe(pstream)*/
3781 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt,i);
3786 /* Update the fatpipes that exists*/
3788 wmip->wmi_fatPipeExists = streamExists;
3792 return (wmi_cmd_send(wmip, osbuf, WMI_SET_HOST_SLEEP_MODE_CMDID,
3797 wmi_set_wow_mode_cmd(struct wmi_t *wmip,
3798 WMI_SET_WOW_MODE_CMD *wowModeCmd)
3802 WMI_SET_WOW_MODE_CMD *cmd;
3804 size = sizeof (*cmd);
3806 osbuf = A_NETBUF_ALLOC(size);
3807 if (osbuf == NULL) {
3811 A_NETBUF_PUT(osbuf, size);
3813 cmd = (WMI_SET_WOW_MODE_CMD *)(A_NETBUF_DATA(osbuf));
3814 A_MEMZERO(cmd, size);
3815 A_MEMCPY(cmd, wowModeCmd, sizeof(WMI_SET_WOW_MODE_CMD));
3817 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WOW_MODE_CMDID,
3823 wmi_get_wow_list_cmd(struct wmi_t *wmip,
3824 WMI_GET_WOW_LIST_CMD *wowListCmd)
3828 WMI_GET_WOW_LIST_CMD *cmd;
3830 size = sizeof (*cmd);
3832 osbuf = A_NETBUF_ALLOC(size);
3833 if (osbuf == NULL) {
3837 A_NETBUF_PUT(osbuf, size);
3839 cmd = (WMI_GET_WOW_LIST_CMD *)(A_NETBUF_DATA(osbuf));
3840 A_MEMZERO(cmd, size);
3841 A_MEMCPY(cmd, wowListCmd, sizeof(WMI_GET_WOW_LIST_CMD));
3843 return (wmi_cmd_send(wmip, osbuf, WMI_GET_WOW_LIST_CMDID,
3849 wmi_get_wow_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
3851 WMI_GET_WOW_LIST_REPLY *reply;
3853 if (len < sizeof(WMI_GET_WOW_LIST_REPLY)) {
3856 reply = (WMI_GET_WOW_LIST_REPLY *)datap;
3858 A_WMI_WOW_LIST_EVENT(wmip->wmi_devt, reply->num_filters,
3864 int wmi_add_wow_pattern_cmd(struct wmi_t *wmip,
3865 WMI_ADD_WOW_PATTERN_CMD *addWowCmd,
3866 A_UINT8* pattern, A_UINT8* mask,
3867 A_UINT8 pattern_size)
3871 WMI_ADD_WOW_PATTERN_CMD *cmd;
3872 A_UINT8 *filter_mask = NULL;
3874 size = sizeof (*cmd);
3876 size += ((2 * addWowCmd->filter_size)* sizeof(A_UINT8));
3877 osbuf = A_NETBUF_ALLOC(size);
3878 if (osbuf == NULL) {
3882 A_NETBUF_PUT(osbuf, size);
3884 cmd = (WMI_ADD_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf));
3885 cmd->filter_list_id = addWowCmd->filter_list_id;
3886 cmd->filter_offset = addWowCmd->filter_offset;
3887 cmd->filter_size = addWowCmd->filter_size;
3889 A_MEMCPY(cmd->filter, pattern, addWowCmd->filter_size);
3891 filter_mask = (A_UINT8*)(cmd->filter + cmd->filter_size);
3892 A_MEMCPY(filter_mask, mask, addWowCmd->filter_size);
3895 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_WOW_PATTERN_CMDID,
3900 wmi_del_wow_pattern_cmd(struct wmi_t *wmip,
3901 WMI_DEL_WOW_PATTERN_CMD *delWowCmd)
3905 WMI_DEL_WOW_PATTERN_CMD *cmd;
3907 size = sizeof (*cmd);
3909 osbuf = A_NETBUF_ALLOC(size);
3910 if (osbuf == NULL) {
3914 A_NETBUF_PUT(osbuf, size);
3916 cmd = (WMI_DEL_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf));
3917 A_MEMZERO(cmd, size);
3918 A_MEMCPY(cmd, delWowCmd, sizeof(WMI_DEL_WOW_PATTERN_CMD));
3920 return (wmi_cmd_send(wmip, osbuf, WMI_DEL_WOW_PATTERN_CMDID,
3926 wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
3928 SQ_THRESHOLD_PARAMS *sq_thresh =
3929 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_SNR];
3931 * Parse the command and store the threshold values here. The checks
3932 * for valid values can be put here
3934 sq_thresh->weight = snrCmd->weight;
3935 sq_thresh->polling_interval = snrCmd->pollTime;
3937 sq_thresh->upper_threshold[0] = snrCmd->thresholdAbove1_Val;
3938 sq_thresh->upper_threshold[1] = snrCmd->thresholdAbove2_Val;
3939 sq_thresh->upper_threshold[2] = snrCmd->thresholdAbove3_Val;
3940 sq_thresh->upper_threshold[3] = snrCmd->thresholdAbove4_Val;
3941 sq_thresh->upper_threshold_valid_count = 4;
3943 /* List sorted in descending order */
3944 sq_thresh->lower_threshold[0] = snrCmd->thresholdBelow4_Val;
3945 sq_thresh->lower_threshold[1] = snrCmd->thresholdBelow3_Val;
3946 sq_thresh->lower_threshold[2] = snrCmd->thresholdBelow2_Val;
3947 sq_thresh->lower_threshold[3] = snrCmd->thresholdBelow1_Val;
3948 sq_thresh->lower_threshold_valid_count = 4;
3950 if (!snr_event_value) {
3952 * Configuring the thresholds to their extremes allows the host to get an
3953 * event from the target which is used for the configuring the correct
3956 snrCmd->thresholdAbove1_Val = (A_UINT8)sq_thresh->upper_threshold[0];
3957 snrCmd->thresholdBelow1_Val = (A_UINT8)sq_thresh->lower_threshold[0];
3960 * In case the user issues multiple times of snr_threshold_setting,
3961 * we should not use the extreames anymore, the target does not expect that.
3963 snrCmd->thresholdAbove1_Val = ar6000_get_upper_threshold(snr_event_value, sq_thresh,
3964 sq_thresh->upper_threshold_valid_count);
3965 snrCmd->thresholdBelow1_Val = ar6000_get_lower_threshold(snr_event_value, sq_thresh,
3966 sq_thresh->lower_threshold_valid_count);
3971 wmi_set_snr_threshold_params(struct wmi_t *wmip,
3972 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
3974 if( snrCmd->thresholdAbove4_Val <= snrCmd->thresholdAbove3_Val ||
3975 snrCmd->thresholdAbove3_Val <= snrCmd->thresholdAbove2_Val ||
3976 snrCmd->thresholdAbove2_Val <= snrCmd->thresholdAbove1_Val ||
3977 snrCmd->thresholdBelow4_Val <= snrCmd->thresholdBelow3_Val ||
3978 snrCmd->thresholdBelow3_Val <= snrCmd->thresholdBelow2_Val ||
3979 snrCmd->thresholdBelow2_Val <= snrCmd->thresholdBelow1_Val)
3983 wmi_cache_configure_snrthreshold(wmip, snrCmd);
3984 return (wmi_send_snr_threshold_params(wmip, snrCmd));
3988 wmi_clr_rssi_snr(struct wmi_t *wmip)
3992 osbuf = A_NETBUF_ALLOC(sizeof(int));
3993 if (osbuf == NULL) {
3997 return (wmi_cmd_send(wmip, osbuf, WMI_CLR_RSSI_SNR_CMDID,
4002 wmi_set_lq_threshold_params(struct wmi_t *wmip,
4003 WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd)
4007 WMI_LQ_THRESHOLD_PARAMS_CMD *cmd;
4008 /* These values are in ascending order */
4009 if( lqCmd->thresholdAbove4_Val <= lqCmd->thresholdAbove3_Val ||
4010 lqCmd->thresholdAbove3_Val <= lqCmd->thresholdAbove2_Val ||
4011 lqCmd->thresholdAbove2_Val <= lqCmd->thresholdAbove1_Val ||
4012 lqCmd->thresholdBelow4_Val <= lqCmd->thresholdBelow3_Val ||
4013 lqCmd->thresholdBelow3_Val <= lqCmd->thresholdBelow2_Val ||
4014 lqCmd->thresholdBelow2_Val <= lqCmd->thresholdBelow1_Val ) {
4019 size = sizeof (*cmd);
4021 osbuf = A_NETBUF_ALLOC(size);
4022 if (osbuf == NULL) {
4026 A_NETBUF_PUT(osbuf, size);
4028 cmd = (WMI_LQ_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
4029 A_MEMZERO(cmd, size);
4030 A_MEMCPY(cmd, lqCmd, sizeof(WMI_LQ_THRESHOLD_PARAMS_CMD));
4032 return (wmi_cmd_send(wmip, osbuf, WMI_LQ_THRESHOLD_PARAMS_CMDID,
4037 wmi_set_error_report_bitmask(struct wmi_t *wmip, A_UINT32 mask)
4041 WMI_TARGET_ERROR_REPORT_BITMASK *cmd;
4043 size = sizeof (*cmd);
4045 osbuf = A_NETBUF_ALLOC(size);
4046 if (osbuf == NULL) {
4050 A_NETBUF_PUT(osbuf, size);
4052 cmd = (WMI_TARGET_ERROR_REPORT_BITMASK *)(A_NETBUF_DATA(osbuf));
4053 A_MEMZERO(cmd, size);
4055 cmd->bitmask = mask;
4057 return (wmi_cmd_send(wmip, osbuf, WMI_TARGET_ERROR_REPORT_BITMASK_CMDID,
4062 wmi_get_challenge_resp_cmd(struct wmi_t *wmip, A_UINT32 cookie, A_UINT32 source)
4065 WMIX_HB_CHALLENGE_RESP_CMD *cmd;
4067 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4068 if (osbuf == NULL) {
4072 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4074 cmd = (WMIX_HB_CHALLENGE_RESP_CMD *)(A_NETBUF_DATA(osbuf));
4075 cmd->cookie = cookie;
4076 cmd->source = source;
4078 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_HB_CHALLENGE_RESP_CMDID,
4083 wmi_config_debug_module_cmd(struct wmi_t *wmip, A_UINT16 mmask,
4084 A_UINT16 tsr, A_BOOL rep, A_UINT16 size,
4088 WMIX_DBGLOG_CFG_MODULE_CMD *cmd;
4090 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4091 if (osbuf == NULL) {
4095 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4097 cmd = (WMIX_DBGLOG_CFG_MODULE_CMD *)(A_NETBUF_DATA(osbuf));
4098 cmd->config.cfgmmask = mmask;
4099 cmd->config.cfgtsr = tsr;
4100 cmd->config.cfgrep = rep;
4101 cmd->config.cfgsize = size;
4102 cmd->config.cfgvalid = valid;
4104 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DBGLOG_CFG_MODULE_CMDID,
4109 wmi_get_stats_cmd(struct wmi_t *wmip)
4111 return wmi_simple_cmd(wmip, WMI_GET_STATISTICS_CMDID);
4115 wmi_addBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex, A_UINT8 *bssid)
4118 WMI_ADD_BAD_AP_CMD *cmd;
4120 if ((bssid == NULL) || (apIndex > WMI_MAX_BAD_AP_INDEX)) {
4124 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4125 if (osbuf == NULL) {
4129 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4131 cmd = (WMI_ADD_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf));
4132 cmd->badApIndex = apIndex;
4133 A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid));
4135 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_BAD_AP_CMDID, SYNC_BEFORE_WMIFLAG));
4139 wmi_deleteBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex)
4142 WMI_DELETE_BAD_AP_CMD *cmd;
4144 if (apIndex > WMI_MAX_BAD_AP_INDEX) {
4148 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4149 if (osbuf == NULL) {
4153 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4155 cmd = (WMI_DELETE_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf));
4156 cmd->badApIndex = apIndex;
4158 return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_BAD_AP_CMDID,
4163 wmi_abort_scan_cmd(struct wmi_t *wmip)
4165 return wmi_simple_cmd(wmip, WMI_ABORT_SCAN_CMDID);
4169 wmi_set_txPwr_cmd(struct wmi_t *wmip, A_UINT8 dbM)
4172 WMI_SET_TX_PWR_CMD *cmd;
4174 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4175 if (osbuf == NULL) {
4179 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4181 cmd = (WMI_SET_TX_PWR_CMD *)(A_NETBUF_DATA(osbuf));
4184 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_PWR_CMDID, NO_SYNC_WMIFLAG));
4188 wmi_get_txPwr_cmd(struct wmi_t *wmip)
4190 return wmi_simple_cmd(wmip, WMI_GET_TX_PWR_CMDID);
4194 wmi_get_mapped_qos_queue(struct wmi_t *wmip, A_UINT8 trafficClass)
4196 A_UINT16 activeTsids=0;
4199 activeTsids = wmip->wmi_streamExistsForAC[trafficClass];
4206 wmi_get_roam_tbl_cmd(struct wmi_t *wmip)
4208 return wmi_simple_cmd(wmip, WMI_GET_ROAM_TBL_CMDID);
4212 wmi_get_roam_data_cmd(struct wmi_t *wmip, A_UINT8 roamDataType)
4215 A_UINT32 size = sizeof(A_UINT8);
4216 WMI_TARGET_ROAM_DATA *cmd;
4218 osbuf = A_NETBUF_ALLOC(size); /* no payload */
4219 if (osbuf == NULL) {
4223 A_NETBUF_PUT(osbuf, size);
4225 cmd = (WMI_TARGET_ROAM_DATA *)(A_NETBUF_DATA(osbuf));
4226 cmd->roamDataType = roamDataType;
4228 return (wmi_cmd_send(wmip, osbuf, WMI_GET_ROAM_DATA_CMDID,
4233 wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p,
4237 WMI_SET_ROAM_CTRL_CMD *cmd;
4239 osbuf = A_NETBUF_ALLOC(size);
4240 if (osbuf == NULL) {
4244 A_NETBUF_PUT(osbuf, size);
4246 cmd = (WMI_SET_ROAM_CTRL_CMD *)(A_NETBUF_DATA(osbuf));
4247 A_MEMZERO(cmd, size);
4249 A_MEMCPY(cmd, p, size);
4251 return (wmi_cmd_send(wmip, osbuf, WMI_SET_ROAM_CTRL_CMDID,
4256 wmi_set_powersave_timers_cmd(struct wmi_t *wmip,
4257 WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd,
4261 WMI_POWERSAVE_TIMERS_POLICY_CMD *cmd;
4263 /* These timers can't be zero */
4264 if(!pCmd->psPollTimeout || !pCmd->triggerTimeout ||
4265 !(pCmd->apsdTimPolicy == IGNORE_TIM_ALL_QUEUES_APSD ||
4266 pCmd->apsdTimPolicy == PROCESS_TIM_ALL_QUEUES_APSD) ||
4267 !(pCmd->simulatedAPSDTimPolicy == IGNORE_TIM_SIMULATED_APSD ||
4268 pCmd->simulatedAPSDTimPolicy == PROCESS_TIM_SIMULATED_APSD))
4271 osbuf = A_NETBUF_ALLOC(size);
4272 if (osbuf == NULL) {
4276 A_NETBUF_PUT(osbuf, size);
4278 cmd = (WMI_POWERSAVE_TIMERS_POLICY_CMD *)(A_NETBUF_DATA(osbuf));
4279 A_MEMZERO(cmd, size);
4281 A_MEMCPY(cmd, pCmd, size);
4283 return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID,
4287 #ifdef CONFIG_HOST_GPIO_SUPPORT
4288 /* Send a command to Target to change GPIO output pins. */
4290 wmi_gpio_output_set(struct wmi_t *wmip,
4292 A_UINT32 clear_mask,
4293 A_UINT32 enable_mask,
4294 A_UINT32 disable_mask)
4297 WMIX_GPIO_OUTPUT_SET_CMD *output_set;
4300 size = sizeof(*output_set);
4303 (DBGFMT "Enter - set=0x%x clear=0x%x enb=0x%x dis=0x%x\n", DBGARG,
4304 set_mask, clear_mask, enable_mask, disable_mask));
4306 osbuf = A_NETBUF_ALLOC(size);
4307 if (osbuf == NULL) {
4310 A_NETBUF_PUT(osbuf, size);
4311 output_set = (WMIX_GPIO_OUTPUT_SET_CMD *)(A_NETBUF_DATA(osbuf));
4313 output_set->set_mask = set_mask;
4314 output_set->clear_mask = clear_mask;
4315 output_set->enable_mask = enable_mask;
4316 output_set->disable_mask = disable_mask;
4318 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_OUTPUT_SET_CMDID,
4322 /* Send a command to the Target requesting state of the GPIO input pins */
4324 wmi_gpio_input_get(struct wmi_t *wmip)
4326 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
4328 return wmi_simple_cmd_xtnd(wmip, WMIX_GPIO_INPUT_GET_CMDID);
4331 /* Send a command to the Target that changes the value of a GPIO register. */
4333 wmi_gpio_register_set(struct wmi_t *wmip,
4334 A_UINT32 gpioreg_id,
4338 WMIX_GPIO_REGISTER_SET_CMD *register_set;
4341 size = sizeof(*register_set);
4344 (DBGFMT "Enter - reg=%d value=0x%x\n", DBGARG, gpioreg_id, value));
4346 osbuf = A_NETBUF_ALLOC(size);
4347 if (osbuf == NULL) {
4350 A_NETBUF_PUT(osbuf, size);
4351 register_set = (WMIX_GPIO_REGISTER_SET_CMD *)(A_NETBUF_DATA(osbuf));
4353 register_set->gpioreg_id = gpioreg_id;
4354 register_set->value = value;
4356 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_REGISTER_SET_CMDID,
4360 /* Send a command to the Target to fetch the value of a GPIO register. */
4362 wmi_gpio_register_get(struct wmi_t *wmip,
4363 A_UINT32 gpioreg_id)
4366 WMIX_GPIO_REGISTER_GET_CMD *register_get;
4369 size = sizeof(*register_get);
4371 A_DPRINTF(DBG_WMI, (DBGFMT "Enter - reg=%d\n", DBGARG, gpioreg_id));
4373 osbuf = A_NETBUF_ALLOC(size);
4374 if (osbuf == NULL) {
4377 A_NETBUF_PUT(osbuf, size);
4378 register_get = (WMIX_GPIO_REGISTER_GET_CMD *)(A_NETBUF_DATA(osbuf));
4380 register_get->gpioreg_id = gpioreg_id;
4382 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_REGISTER_GET_CMDID,
4386 /* Send a command to the Target acknowledging some GPIO interrupts. */
4388 wmi_gpio_intr_ack(struct wmi_t *wmip,
4392 WMIX_GPIO_INTR_ACK_CMD *intr_ack;
4395 size = sizeof(*intr_ack);
4397 A_DPRINTF(DBG_WMI, (DBGFMT "Enter ack_mask=0x%x\n", DBGARG, ack_mask));
4399 osbuf = A_NETBUF_ALLOC(size);
4400 if (osbuf == NULL) {
4403 A_NETBUF_PUT(osbuf, size);
4404 intr_ack = (WMIX_GPIO_INTR_ACK_CMD *)(A_NETBUF_DATA(osbuf));
4406 intr_ack->ack_mask = ack_mask;
4408 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_INTR_ACK_CMDID,
4411 #endif /* CONFIG_HOST_GPIO_SUPPORT */
4414 wmi_set_access_params_cmd(struct wmi_t *wmip, A_UINT8 ac, A_UINT16 txop, A_UINT8 eCWmin,
4415 A_UINT8 eCWmax, A_UINT8 aifsn)
4418 WMI_SET_ACCESS_PARAMS_CMD *cmd;
4420 if ((eCWmin > WMI_MAX_CW_ACPARAM) || (eCWmax > WMI_MAX_CW_ACPARAM) ||
4421 (aifsn > WMI_MAX_AIFSN_ACPARAM) || (ac >= WMM_NUM_AC))
4426 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4427 if (osbuf == NULL) {
4431 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4433 cmd = (WMI_SET_ACCESS_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
4435 cmd->eCWmin = eCWmin;
4436 cmd->eCWmax = eCWmax;
4440 return (wmi_cmd_send(wmip, osbuf, WMI_SET_ACCESS_PARAMS_CMDID,
4445 wmi_set_retry_limits_cmd(struct wmi_t *wmip, A_UINT8 frameType,
4446 A_UINT8 trafficClass, A_UINT8 maxRetries,
4447 A_UINT8 enableNotify)
4450 WMI_SET_RETRY_LIMITS_CMD *cmd;
4452 if ((frameType != MGMT_FRAMETYPE) && (frameType != CONTROL_FRAMETYPE) &&
4453 (frameType != DATA_FRAMETYPE))
4458 if (maxRetries > WMI_MAX_RETRIES) {
4462 if (frameType != DATA_FRAMETYPE) {
4466 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4467 if (osbuf == NULL) {
4471 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4473 cmd = (WMI_SET_RETRY_LIMITS_CMD *)(A_NETBUF_DATA(osbuf));
4474 cmd->frameType = frameType;
4475 cmd->trafficClass = trafficClass;
4476 cmd->maxRetries = maxRetries;
4477 cmd->enableNotify = enableNotify;
4479 return (wmi_cmd_send(wmip, osbuf, WMI_SET_RETRY_LIMITS_CMDID,
4484 wmi_get_current_bssid(struct wmi_t *wmip, A_UINT8 *bssid)
4486 if (bssid != NULL) {
4487 A_MEMCPY(bssid, wmip->wmi_bssid, ATH_MAC_LEN);
4492 wmi_set_opt_mode_cmd(struct wmi_t *wmip, A_UINT8 optMode)
4495 WMI_SET_OPT_MODE_CMD *cmd;
4497 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4498 if (osbuf == NULL) {
4502 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4504 cmd = (WMI_SET_OPT_MODE_CMD *)(A_NETBUF_DATA(osbuf));
4505 A_MEMZERO(cmd, sizeof(*cmd));
4506 cmd->optMode = optMode;
4508 return (wmi_cmd_send(wmip, osbuf, WMI_SET_OPT_MODE_CMDID,
4509 SYNC_BOTH_WMIFLAG));
4513 wmi_opt_tx_frame_cmd(struct wmi_t *wmip,
4515 A_UINT8 *dstMacAddr,
4517 A_UINT16 optIEDataLen,
4521 WMI_OPT_TX_FRAME_CMD *cmd;
4522 osbuf = A_NETBUF_ALLOC(optIEDataLen + sizeof(*cmd));
4523 if (osbuf == NULL) {
4527 A_NETBUF_PUT(osbuf, (optIEDataLen + sizeof(*cmd)));
4529 cmd = (WMI_OPT_TX_FRAME_CMD *)(A_NETBUF_DATA(osbuf));
4530 A_MEMZERO(cmd, (optIEDataLen + sizeof(*cmd)-1));
4532 cmd->frmType = frmType;
4533 cmd->optIEDataLen = optIEDataLen;
4534 //cmd->optIEData = (A_UINT8 *)((int)cmd + sizeof(*cmd));
4535 A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid));
4536 A_MEMCPY(cmd->dstAddr, dstMacAddr, sizeof(cmd->dstAddr));
4537 A_MEMCPY(&cmd->optIEData[0], optIEData, optIEDataLen);
4539 return (wmi_cmd_send(wmip, osbuf, WMI_OPT_TX_FRAME_CMDID,
4544 wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, A_UINT16 intvl)
4547 WMI_BEACON_INT_CMD *cmd;
4549 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4550 if (osbuf == NULL) {
4554 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4556 cmd = (WMI_BEACON_INT_CMD *)(A_NETBUF_DATA(osbuf));
4557 A_MEMZERO(cmd, sizeof(*cmd));
4558 cmd->beaconInterval = intvl;
4560 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BEACON_INT_CMDID,
4566 wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, A_UINT16 voicePktSize)
4569 WMI_SET_VOICE_PKT_SIZE_CMD *cmd;
4571 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4572 if (osbuf == NULL) {
4576 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4578 cmd = (WMI_SET_VOICE_PKT_SIZE_CMD *)(A_NETBUF_DATA(osbuf));
4579 A_MEMZERO(cmd, sizeof(*cmd));
4580 cmd->voicePktSize = voicePktSize;
4582 return (wmi_cmd_send(wmip, osbuf, WMI_SET_VOICE_PKT_SIZE_CMDID,
4588 wmi_set_max_sp_len_cmd(struct wmi_t *wmip, A_UINT8 maxSPLen)
4591 WMI_SET_MAX_SP_LEN_CMD *cmd;
4593 /* maxSPLen is a two-bit value. If user trys to set anything
4594 * other than this, then its invalid
4596 if(maxSPLen & ~0x03)
4599 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4600 if (osbuf == NULL) {
4604 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4606 cmd = (WMI_SET_MAX_SP_LEN_CMD *)(A_NETBUF_DATA(osbuf));
4607 A_MEMZERO(cmd, sizeof(*cmd));
4608 cmd->maxSPLen = maxSPLen;
4610 return (wmi_cmd_send(wmip, osbuf, WMI_SET_MAX_SP_LEN_CMDID,
4615 wmi_determine_userPriority(
4620 iphdr *ipHdr = (iphdr *)pkt;
4622 /* Determine IPTOS priority */
4625 * (Refer Pg 57 WMM-test-plan-v1.2)
4627 * : DSCP(6-bits) ECN(2-bits)
4628 * : DSCP - P2 P1 P0 X X X
4629 * where (P2 P1 P0) form 802.1D
4631 ipPri = ipHdr->ip_tos >> 5;
4634 if ((layer2Pri & 0x7) > ipPri)
4635 return ((A_UINT8)layer2Pri & 0x7);
4641 convert_userPriority_to_trafficClass(A_UINT8 userPriority)
4643 return (up_to_ac[userPriority & 0x7]);
4647 wmi_get_power_mode_cmd(struct wmi_t *wmip)
4649 return wmip->wmi_powerMode;
4653 wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, A_BOOL tspecCompliance)
4657 #define TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF (~0)
4658 #define TSPEC_SERVICE_START_TIME_ATHEROS_DEF 0
4659 #define TSPEC_MAX_BURST_SIZE_ATHEROS_DEF 0
4660 #define TSPEC_DELAY_BOUND_ATHEROS_DEF 0
4661 #define TSPEC_MEDIUM_TIME_ATHEROS_DEF 0
4662 #define TSPEC_SBA_ATHEROS_DEF 0x2000 /* factor is 1 */
4664 /* Verify TSPEC params for ATHEROS compliance */
4665 if(tspecCompliance == ATHEROS_COMPLIANCE) {
4666 if ((pCmd->suspensionInt != TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF) ||
4667 (pCmd->serviceStartTime != TSPEC_SERVICE_START_TIME_ATHEROS_DEF) ||
4668 (pCmd->minDataRate != pCmd->meanDataRate) ||
4669 (pCmd->minDataRate != pCmd->peakDataRate) ||
4670 (pCmd->maxBurstSize != TSPEC_MAX_BURST_SIZE_ATHEROS_DEF) ||
4671 (pCmd->delayBound != TSPEC_DELAY_BOUND_ATHEROS_DEF) ||
4672 (pCmd->sba != TSPEC_SBA_ATHEROS_DEF) ||
4673 (pCmd->mediumTime != TSPEC_MEDIUM_TIME_ATHEROS_DEF)) {
4675 A_DPRINTF(DBG_WMI, (DBGFMT "Invalid TSPEC params\n", DBGARG));
4676 //A_PRINTF("%s: Invalid TSPEC params\n", __func__);
4684 #ifdef CONFIG_HOST_TCMD_SUPPORT
4686 wmi_tcmd_test_report_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
4689 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
4691 A_WMI_TCMD_RX_REPORT_EVENT(wmip->wmi_devt, datap, len);
4696 #endif /* CONFIG_HOST_TCMD_SUPPORT*/
4699 wmi_set_authmode_cmd(struct wmi_t *wmip, A_UINT8 mode)
4702 WMI_SET_AUTH_MODE_CMD *cmd;
4704 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4705 if (osbuf == NULL) {
4709 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4711 cmd = (WMI_SET_AUTH_MODE_CMD *)(A_NETBUF_DATA(osbuf));
4712 A_MEMZERO(cmd, sizeof(*cmd));
4715 return (wmi_cmd_send(wmip, osbuf, WMI_SET_AUTH_MODE_CMDID,
4720 wmi_set_reassocmode_cmd(struct wmi_t *wmip, A_UINT8 mode)
4723 WMI_SET_REASSOC_MODE_CMD *cmd;
4725 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4726 if (osbuf == NULL) {
4730 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4732 cmd = (WMI_SET_REASSOC_MODE_CMD *)(A_NETBUF_DATA(osbuf));
4733 A_MEMZERO(cmd, sizeof(*cmd));
4736 return (wmi_cmd_send(wmip, osbuf, WMI_SET_REASSOC_MODE_CMDID,
4741 wmi_set_lpreamble_cmd(struct wmi_t *wmip, A_UINT8 status, A_UINT8 preamblePolicy)
4744 WMI_SET_LPREAMBLE_CMD *cmd;
4746 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4747 if (osbuf == NULL) {
4751 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4753 cmd = (WMI_SET_LPREAMBLE_CMD *)(A_NETBUF_DATA(osbuf));
4754 A_MEMZERO(cmd, sizeof(*cmd));
4755 cmd->status = status;
4756 cmd->preamblePolicy = preamblePolicy;
4758 return (wmi_cmd_send(wmip, osbuf, WMI_SET_LPREAMBLE_CMDID,
4763 wmi_set_rts_cmd(struct wmi_t *wmip, A_UINT16 threshold)
4766 WMI_SET_RTS_CMD *cmd;
4768 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4769 if (osbuf == NULL) {
4773 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4775 cmd = (WMI_SET_RTS_CMD*)(A_NETBUF_DATA(osbuf));
4776 A_MEMZERO(cmd, sizeof(*cmd));
4777 cmd->threshold = threshold;
4779 return (wmi_cmd_send(wmip, osbuf, WMI_SET_RTS_CMDID,
4784 wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status)
4787 WMI_SET_WMM_CMD *cmd;
4789 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4790 if (osbuf == NULL) {
4794 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4796 cmd = (WMI_SET_WMM_CMD*)(A_NETBUF_DATA(osbuf));
4797 A_MEMZERO(cmd, sizeof(*cmd));
4798 cmd->status = status;
4800 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_CMDID,
4806 wmi_set_qos_supp_cmd(struct wmi_t *wmip, A_UINT8 status)
4809 WMI_SET_QOS_SUPP_CMD *cmd;
4811 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4812 if (osbuf == NULL) {
4816 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4818 cmd = (WMI_SET_QOS_SUPP_CMD*)(A_NETBUF_DATA(osbuf));
4819 A_MEMZERO(cmd, sizeof(*cmd));
4820 cmd->status = status;
4821 return (wmi_cmd_send(wmip, osbuf, WMI_SET_QOS_SUPP_CMDID,
4827 wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG cfg)
4830 WMI_SET_WMM_TXOP_CMD *cmd;
4832 if( !((cfg == WMI_TXOP_DISABLED) || (cfg == WMI_TXOP_ENABLED)) )
4835 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4836 if (osbuf == NULL) {
4840 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4842 cmd = (WMI_SET_WMM_TXOP_CMD *)(A_NETBUF_DATA(osbuf));
4843 A_MEMZERO(cmd, sizeof(*cmd));
4844 cmd->txopEnable = cfg;
4846 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_TXOP_CMDID,
4852 wmi_set_country(struct wmi_t *wmip, A_UCHAR *countryCode)
4855 WMI_AP_SET_COUNTRY_CMD *cmd;
4857 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4858 if (osbuf == NULL) {
4862 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4864 cmd = (WMI_AP_SET_COUNTRY_CMD *)(A_NETBUF_DATA(osbuf));
4865 A_MEMZERO(cmd, sizeof(*cmd));
4866 A_MEMCPY(cmd->countryCode,countryCode,3);
4868 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_COUNTRY_CMDID,
4872 #ifdef CONFIG_HOST_TCMD_SUPPORT
4873 /* WMI layer doesn't need to know the data type of the test cmd.
4874 This would be beneficial for customers like Qualcomm, who might
4875 have different test command requirements from differnt manufacturers
4878 wmi_test_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT32 len)
4883 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
4885 osbuf= A_NETBUF_ALLOC(len);
4890 A_NETBUF_PUT(osbuf, len);
4891 data = A_NETBUF_DATA(osbuf);
4892 A_MEMCPY(data, buf, len);
4894 return(wmi_cmd_send(wmip, osbuf, WMI_TEST_CMDID,
4901 wmi_set_bt_status_cmd(struct wmi_t *wmip, A_UINT8 streamType, A_UINT8 status)
4904 WMI_SET_BT_STATUS_CMD *cmd;
4906 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Enter - streamType=%d, status=%d\n", streamType, status));
4908 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4909 if (osbuf == NULL) {
4913 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4915 cmd = (WMI_SET_BT_STATUS_CMD *)(A_NETBUF_DATA(osbuf));
4916 A_MEMZERO(cmd, sizeof(*cmd));
4917 cmd->streamType = streamType;
4918 cmd->status = status;
4920 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_STATUS_CMDID,
4925 wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd)
4928 WMI_SET_BT_PARAMS_CMD* alloc_cmd;
4930 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("cmd params is %d\n", cmd->paramType));
4932 if (cmd->paramType == BT_PARAM_SCO) {
4933 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,
4934 cmd->info.scoParams.dataResponseTimeout,
4935 cmd->info.scoParams.stompScoRules,
4936 cmd->info.scoParams.scoOptFlags,
4937 cmd->info.scoParams.stompDutyCyleVal,
4938 cmd->info.scoParams.stompDutyCyleMaxVal,
4939 cmd->info.scoParams.psPollLatencyFraction,
4940 cmd->info.scoParams.noSCOSlots,
4941 cmd->info.scoParams.noIdleSlots,
4942 cmd->info.scoParams.scoOptOffRssi,
4943 cmd->info.scoParams.scoOptOnRssi,
4944 cmd->info.scoParams.scoOptRtsCount));
4946 else if (cmd->paramType == BT_PARAM_A2DP) {
4947 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("A2DP params %d %d %d %d %d %d %d %d\n", cmd->info.a2dpParams.a2dpWlanUsageLimit,
4948 cmd->info.a2dpParams.a2dpBurstCntMin,
4949 cmd->info.a2dpParams.a2dpDataRespTimeout,
4950 cmd->info.a2dpParams.a2dpOptFlags,
4951 cmd->info.a2dpParams.isCoLocatedBtRoleMaster,
4952 cmd->info.a2dpParams.a2dpOptOffRssi,
4953 cmd->info.a2dpParams.a2dpOptOnRssi,
4954 cmd->info.a2dpParams.a2dpOptRtsCount));
4956 else if (cmd->paramType == BT_PARAM_ANTENNA_CONFIG) {
4957 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Ant config %d\n", cmd->info.antType));
4959 else if (cmd->paramType == BT_PARAM_COLOCATED_BT_DEVICE) {
4960 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("co-located BT %d\n", cmd->info.coLocatedBtDev));
4962 else if (cmd->paramType == BT_PARAM_ACLCOEX) {
4963 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("ACL params %d %d %d\n", cmd->info.aclCoexParams.aclWlanMediumUsageTime,
4964 cmd->info.aclCoexParams.aclBtMediumUsageTime,
4965 cmd->info.aclCoexParams.aclDataRespTimeout));
4967 else if (cmd->paramType == BT_PARAM_11A_SEPARATE_ANT) {
4968 A_DPRINTF(DBG_WMI, (DBGFMT "11A ant\n", DBGARG));
4971 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4972 if (osbuf == NULL) {
4976 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4978 alloc_cmd = (WMI_SET_BT_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
4979 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4980 A_MEMCPY(alloc_cmd, cmd, sizeof(*cmd));
4982 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_PARAMS_CMDID,
4987 wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd)
4990 WMI_SET_BTCOEX_FE_ANT_CMD *alloc_cmd;
4992 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
4993 if (osbuf == NULL) {
4996 A_NETBUF_PUT(osbuf, sizeof(*cmd));
4997 alloc_cmd = (WMI_SET_BTCOEX_FE_ANT_CMD *)(A_NETBUF_DATA(osbuf));
4998 A_MEMZERO(alloc_cmd, sizeof(*cmd));
4999 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_FE_ANT_CMD));
5000 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_FE_ANT_CMDID,
5007 wmi_set_btcoex_colocated_bt_dev_cmd(struct wmi_t *wmip,
5008 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD * cmd)
5011 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD *alloc_cmd;
5013 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5014 if (osbuf == NULL) {
5017 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5018 alloc_cmd = (WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD *)(A_NETBUF_DATA(osbuf));
5019 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5020 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD));
5021 A_PRINTF("colocated bt = %d\n", alloc_cmd->btcoexCoLocatedBTdev);
5022 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID,
5028 wmi_set_btcoex_btinquiry_page_config_cmd(struct wmi_t *wmip,
5029 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD* cmd)
5032 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *alloc_cmd;
5034 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5035 if (osbuf == NULL) {
5038 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5039 alloc_cmd = (WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
5040 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5041 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD));
5042 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID,
5048 wmi_set_btcoex_sco_config_cmd(struct wmi_t *wmip,
5049 WMI_SET_BTCOEX_SCO_CONFIG_CMD * cmd)
5052 WMI_SET_BTCOEX_SCO_CONFIG_CMD *alloc_cmd;
5054 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5055 if (osbuf == NULL) {
5058 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5059 alloc_cmd = (WMI_SET_BTCOEX_SCO_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
5060 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5061 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_SCO_CONFIG_CMD));
5062 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_SCO_CONFIG_CMDID ,
5068 wmi_set_btcoex_a2dp_config_cmd(struct wmi_t *wmip,
5069 WMI_SET_BTCOEX_A2DP_CONFIG_CMD * cmd)
5072 WMI_SET_BTCOEX_A2DP_CONFIG_CMD *alloc_cmd;
5074 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5075 if (osbuf == NULL) {
5078 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5079 alloc_cmd = (WMI_SET_BTCOEX_A2DP_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
5080 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5081 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_A2DP_CONFIG_CMD));
5082 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_A2DP_CONFIG_CMDID ,
5088 wmi_set_btcoex_aclcoex_config_cmd(struct wmi_t *wmip,
5089 WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD * cmd)
5092 WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD *alloc_cmd;
5094 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5095 if (osbuf == NULL) {
5098 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5099 alloc_cmd = (WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
5100 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5101 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD));
5102 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID ,
5108 wmi_set_btcoex_debug_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_DEBUG_CMD * cmd)
5111 WMI_SET_BTCOEX_DEBUG_CMD *alloc_cmd;
5113 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5114 if (osbuf == NULL) {
5117 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5118 alloc_cmd = (WMI_SET_BTCOEX_DEBUG_CMD *)(A_NETBUF_DATA(osbuf));
5119 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5120 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_DEBUG_CMD));
5121 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_DEBUG_CMDID ,
5127 wmi_set_btcoex_bt_operating_status_cmd(struct wmi_t * wmip,
5128 WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD * cmd)
5131 WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *alloc_cmd;
5133 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5134 if (osbuf == NULL) {
5137 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5138 alloc_cmd = (WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *)(A_NETBUF_DATA(osbuf));
5139 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5140 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD));
5141 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID ,
5147 wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * cmd)
5150 WMI_GET_BTCOEX_CONFIG_CMD *alloc_cmd;
5152 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5153 if (osbuf == NULL) {
5156 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5157 alloc_cmd = (WMI_GET_BTCOEX_CONFIG_CMD *)(A_NETBUF_DATA(osbuf));
5158 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5159 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_GET_BTCOEX_CONFIG_CMD));
5160 return (wmi_cmd_send(wmip, osbuf, WMI_GET_BTCOEX_CONFIG_CMDID ,
5166 wmi_get_btcoex_stats_cmd(struct wmi_t *wmip)
5169 return wmi_simple_cmd(wmip, WMI_GET_BTCOEX_STATS_CMDID);
5174 wmi_get_keepalive_configured(struct wmi_t *wmip)
5177 WMI_GET_KEEPALIVE_CMD *cmd;
5178 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5179 if (osbuf == NULL) {
5182 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5183 cmd = (WMI_GET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf));
5184 A_MEMZERO(cmd, sizeof(*cmd));
5185 return (wmi_cmd_send(wmip, osbuf, WMI_GET_KEEPALIVE_CMDID,
5190 wmi_get_keepalive_cmd(struct wmi_t *wmip)
5192 return wmip->wmi_keepaliveInterval;
5196 wmi_set_keepalive_cmd(struct wmi_t *wmip, A_UINT8 keepaliveInterval)
5199 WMI_SET_KEEPALIVE_CMD *cmd;
5201 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5202 if (osbuf == NULL) {
5206 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5208 cmd = (WMI_SET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf));
5209 A_MEMZERO(cmd, sizeof(*cmd));
5210 cmd->keepaliveInterval = keepaliveInterval;
5211 wmip->wmi_keepaliveInterval = keepaliveInterval;
5213 return (wmi_cmd_send(wmip, osbuf, WMI_SET_KEEPALIVE_CMDID,
5218 wmi_set_params_cmd(struct wmi_t *wmip, A_UINT32 opcode, A_UINT32 length, A_CHAR* buffer)
5221 WMI_SET_PARAMS_CMD *cmd;
5223 osbuf = A_NETBUF_ALLOC(sizeof(*cmd) + length);
5224 if (osbuf == NULL) {
5228 A_NETBUF_PUT(osbuf, sizeof(*cmd) + length);
5230 cmd = (WMI_SET_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
5231 A_MEMZERO(cmd, sizeof(*cmd));
5232 cmd->opcode = opcode;
5233 cmd->length = length;
5234 A_MEMCPY(cmd->buffer, buffer, length);
5236 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PARAMS_CMDID,
5242 wmi_set_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8 dot3, A_UINT8 dot4)
5245 WMI_SET_MCAST_FILTER_CMD *cmd;
5247 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5248 if (osbuf == NULL) {
5252 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5254 cmd = (WMI_SET_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
5255 cmd->multicast_mac[0] = 0x01;
5256 cmd->multicast_mac[1] = 0x00;
5257 cmd->multicast_mac[2] = 0x5e;
5258 cmd->multicast_mac[3] = dot2&0x7F;
5259 cmd->multicast_mac[4] = dot3;
5260 cmd->multicast_mac[5] = dot4;
5262 return (wmi_cmd_send(wmip, osbuf, WMI_SET_MCAST_FILTER_CMDID,
5268 wmi_del_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8 dot3, A_UINT8 dot4)
5271 WMI_SET_MCAST_FILTER_CMD *cmd;
5273 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5274 if (osbuf == NULL) {
5278 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5280 cmd = (WMI_SET_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
5281 cmd->multicast_mac[0] = 0x01;
5282 cmd->multicast_mac[1] = 0x00;
5283 cmd->multicast_mac[2] = 0x5e;
5284 cmd->multicast_mac[3] = dot2&0x7F;
5285 cmd->multicast_mac[4] = dot3;
5286 cmd->multicast_mac[5] = dot4;
5288 return (wmi_cmd_send(wmip, osbuf, WMI_DEL_MCAST_FILTER_CMDID,
5293 wmi_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 enable)
5296 WMI_MCAST_FILTER_CMD *cmd;
5298 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5299 if (osbuf == NULL) {
5303 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5305 cmd = (WMI_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf));
5306 cmd->enable = enable;
5308 return (wmi_cmd_send(wmip, osbuf, WMI_MCAST_FILTER_CMDID,
5313 wmi_set_appie_cmd(struct wmi_t *wmip, A_UINT8 mgmtFrmType, A_UINT8 ieLen,
5317 WMI_SET_APPIE_CMD *cmd;
5320 cmdLen = sizeof(*cmd) + ieLen - 1;
5321 osbuf = A_NETBUF_ALLOC(cmdLen);
5322 if (osbuf == NULL) {
5326 A_NETBUF_PUT(osbuf, cmdLen);
5328 cmd = (WMI_SET_APPIE_CMD *)(A_NETBUF_DATA(osbuf));
5329 A_MEMZERO(cmd, cmdLen);
5331 cmd->mgmtFrmType = mgmtFrmType;
5333 A_MEMCPY(cmd->ieInfo, ieInfo, ieLen);
5335 return (wmi_cmd_send(wmip, osbuf, WMI_SET_APPIE_CMDID, NO_SYNC_WMIFLAG));
5339 wmi_set_halparam_cmd(struct wmi_t *wmip, A_UINT8 *cmd, A_UINT16 dataLen)
5344 osbuf = A_NETBUF_ALLOC(dataLen);
5345 if (osbuf == NULL) {
5349 A_NETBUF_PUT(osbuf, dataLen);
5351 data = A_NETBUF_DATA(osbuf);
5353 A_MEMCPY(data, cmd, dataLen);
5355 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WHALPARAM_CMDID, NO_SYNC_WMIFLAG));
5359 wmi_get_rate(A_INT8 rateindex)
5361 if (rateindex == RATE_AUTO) {
5364 return(wmi_rateTable[(A_UINT32) rateindex][0]);
5369 wmi_node_return (struct wmi_t *wmip, bss_t *bss)
5373 wlan_node_return (&wmip->wmi_scan_table, bss);
5378 wmi_set_nodeage(struct wmi_t *wmip, A_UINT32 nodeAge)
5380 wlan_set_nodeage(&wmip->wmi_scan_table,nodeAge);
5384 wmi_find_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid,
5385 A_UINT32 ssidLength, A_BOOL bIsWPA2, A_BOOL bMatchSSID)
5388 node = wlan_find_Ssidnode (&wmip->wmi_scan_table, pSsid,
5389 ssidLength, bIsWPA2, bMatchSSID);
5396 wmi_refresh_scan_table (struct wmi_t *wmip)
5398 wlan_refresh_inactive_nodes (&wmip->wmi_scan_table);
5403 wmi_free_allnodes(struct wmi_t *wmip)
5405 wlan_free_allnodes(&wmip->wmi_scan_table);
5409 wmi_find_node(struct wmi_t *wmip, const A_UINT8 *macaddr)
5412 ni=wlan_find_node(&wmip->wmi_scan_table,macaddr);
5417 wmi_free_node(struct wmi_t *wmip, const A_UINT8 *macaddr)
5421 ni=wlan_find_node(&wmip->wmi_scan_table,macaddr);
5423 wlan_node_reclaim(&wmip->wmi_scan_table, ni);
5430 wmi_dset_open_reply(struct wmi_t *wmip,
5432 A_UINT32 access_cookie,
5434 A_UINT32 dset_version,
5435 A_UINT32 targ_handle,
5436 A_UINT32 targ_reply_fn,
5437 A_UINT32 targ_reply_arg)
5440 WMIX_DSETOPEN_REPLY_CMD *open_reply;
5442 A_DPRINTF(DBG_WMI, (DBGFMT "Enter - wmip=0x%lx\n", DBGARG, (unsigned long)wmip));
5444 osbuf = A_NETBUF_ALLOC(sizeof(*open_reply));
5445 if (osbuf == NULL) {
5449 A_NETBUF_PUT(osbuf, sizeof(*open_reply));
5450 open_reply = (WMIX_DSETOPEN_REPLY_CMD *)(A_NETBUF_DATA(osbuf));
5452 open_reply->status = status;
5453 open_reply->targ_dset_handle = targ_handle;
5454 open_reply->targ_reply_fn = targ_reply_fn;
5455 open_reply->targ_reply_arg = targ_reply_arg;
5456 open_reply->access_cookie = access_cookie;
5457 open_reply->size = dset_size;
5458 open_reply->version = dset_version;
5460 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETOPEN_REPLY_CMDID,
5465 wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len)
5467 WMI_PMKID_LIST_REPLY *reply;
5468 A_UINT32 expected_len;
5470 if (len < sizeof(WMI_PMKID_LIST_REPLY)) {
5473 reply = (WMI_PMKID_LIST_REPLY *)datap;
5474 expected_len = sizeof(reply->numPMKID) + reply->numPMKID * WMI_PMKID_LEN;
5476 if (len < expected_len) {
5480 A_WMI_PMKID_LIST_EVENT(wmip->wmi_devt, reply->numPMKID,
5481 reply->pmkidList, reply->bssidList[0]);
5488 wmi_set_params_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len)
5490 WMI_SET_PARAMS_REPLY *reply;
5492 if (len < sizeof(WMI_SET_PARAMS_REPLY)) {
5495 reply = (WMI_SET_PARAMS_REPLY *)datap;
5497 if (A_OK == reply->status)
5512 wmi_acm_reject_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len)
5514 WMI_ACM_REJECT_EVENT *ev;
5516 ev = (WMI_ACM_REJECT_EVENT *)datap;
5517 wmip->wmi_traffic_class = ev->trafficClass;
5518 printk("ACM REJECT %d\n",wmip->wmi_traffic_class);
5523 #ifdef CONFIG_HOST_DSET_SUPPORT
5525 wmi_dset_data_reply(struct wmi_t *wmip,
5530 A_UINT32 targ_reply_fn,
5531 A_UINT32 targ_reply_arg)
5534 WMIX_DSETDATA_REPLY_CMD *data_reply;
5537 size = sizeof(*data_reply) + length;
5539 if (size <= length) {
5544 (DBGFMT "Enter - length=%d status=%d\n", DBGARG, length, status));
5546 osbuf = A_NETBUF_ALLOC(size);
5547 if (osbuf == NULL) {
5550 A_NETBUF_PUT(osbuf, size);
5551 data_reply = (WMIX_DSETDATA_REPLY_CMD *)(A_NETBUF_DATA(osbuf));
5553 data_reply->status = status;
5554 data_reply->targ_buf = targ_buf;
5555 data_reply->targ_reply_fn = targ_reply_fn;
5556 data_reply->targ_reply_arg = targ_reply_arg;
5557 data_reply->length = length;
5559 if (status == A_OK) {
5560 if (a_copy_from_user(data_reply->buf, user_buf, length)) {
5561 A_NETBUF_FREE(osbuf);
5566 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETDATA_REPLY_CMDID,
5569 #endif /* CONFIG_HOST_DSET_SUPPORT */
5572 wmi_set_wsc_status_cmd(struct wmi_t *wmip, A_UINT32 status)
5577 wps_enable = status;
5579 osbuf = a_netbuf_alloc(sizeof(1));
5580 if (osbuf == NULL) {
5584 a_netbuf_put(osbuf, sizeof(1));
5586 cmd = (char *)(a_netbuf_to_data(osbuf));
5588 A_MEMZERO(cmd, sizeof(*cmd));
5589 cmd[0] = (status?1:0);
5590 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WSC_STATUS_CMDID,
5594 #if defined(CONFIG_TARGET_PROFILE_SUPPORT)
5596 wmi_prof_cfg_cmd(struct wmi_t *wmip,
5601 WMIX_PROF_CFG_CMD *cmd;
5603 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5604 if (osbuf == NULL) {
5608 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5610 cmd = (WMIX_PROF_CFG_CMD *)(A_NETBUF_DATA(osbuf));
5611 A_MEMZERO(cmd, sizeof(*cmd));
5612 cmd->period = period;
5615 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_PROF_CFG_CMDID, NO_SYNC_WMIFLAG));
5619 wmi_prof_addr_set_cmd(struct wmi_t *wmip, A_UINT32 addr)
5622 WMIX_PROF_ADDR_SET_CMD *cmd;
5624 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5625 if (osbuf == NULL) {
5629 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5631 cmd = (WMIX_PROF_ADDR_SET_CMD *)(A_NETBUF_DATA(osbuf));
5632 A_MEMZERO(cmd, sizeof(*cmd));
5635 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_PROF_ADDR_SET_CMDID, NO_SYNC_WMIFLAG));
5639 wmi_prof_start_cmd(struct wmi_t *wmip)
5641 return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_START_CMDID);
5645 wmi_prof_stop_cmd(struct wmi_t *wmip)
5647 return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_STOP_CMDID);
5651 wmi_prof_count_get_cmd(struct wmi_t *wmip)
5653 return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_COUNT_GET_CMDID);
5656 /* Called to handle WMIX_PROF_CONT_EVENTID */
5658 wmi_prof_count_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
5660 WMIX_PROF_COUNT_EVENT *prof_data = (WMIX_PROF_COUNT_EVENT *)datap;
5663 (DBGFMT "Enter - addr=0x%x count=%d\n", DBGARG,
5664 prof_data->addr, prof_data->count));
5666 A_WMI_PROF_COUNT_RX(prof_data->addr, prof_data->count);
5670 #endif /* CONFIG_TARGET_PROFILE_SUPPORT */
5672 #ifdef OS_ROAM_MANAGEMENT
5674 #define ETHERNET_MAC_ADDRESS_LENGTH 6
5677 wmi_scan_indication (struct wmi_t *wmip)
5679 struct ieee80211_node_table *nt;
5685 PNDIS_802_11_BSSID_SCAN_INFO psi;
5687 NDIS_802_11_FIXED_IEs *pFixed;
5688 NDIS_802_11_VARIABLE_IEs *pVar;
5691 struct ar6kScanIndication
5693 NDIS_802_11_STATUS_INDICATION ind;
5694 NDIS_802_11_BSSID_SCAN_INFO_LIST slist;
5695 } *pAr6kScanIndEvent;
5697 nt = &wmip->wmi_scan_table;
5702 gen = nt->nt_si_gen;
5704 size = offsetof(struct ar6kScanIndication, slist) +
5705 offsetof(NDIS_802_11_BSSID_SCAN_INFO_LIST, BssidScanInfo);
5709 IEEE80211_NODE_LOCK(nt);
5712 for (bss = nt->nt_node_first; bss; bss = bss->ni_list_next) {
5713 if (bss->ni_si_gen != gen) {
5714 bsssize = offsetof(NDIS_802_11_BSSID_SCAN_INFO, Bssid) + offsetof(NDIS_WLAN_BSSID_EX, IEs);
5715 bsssize = bsssize + sizeof(NDIS_802_11_FIXED_IEs);
5718 if (bss->ni_cie.ie_rsn) {
5719 bsssize = bsssize + bss->ni_cie.ie_rsn[1] + 2;
5722 if (bss->ni_cie.ie_wpa) {
5723 bsssize = bsssize + bss->ni_cie.ie_wpa[1] + 2;
5726 // bsssize must be a multiple of 4 to maintain alignment.
5727 bsssize = (bsssize + 3) & ~3;
5737 // RETAILMSG(1, (L"AR6K: scan indication: 0 bss\n"));
5738 ar6000_scan_indication (wmip->wmi_devt, NULL, 0);
5739 IEEE80211_NODE_UNLOCK (nt);
5743 pAr6kScanIndEvent = A_MALLOC(size);
5745 if (NULL == pAr6kScanIndEvent)
5747 IEEE80211_NODE_UNLOCK(nt);
5751 A_MEMZERO(pAr6kScanIndEvent, size);
5754 pAr6kScanIndEvent->ind.StatusType = Ndis802_11StatusType_BssidScanInfoList;
5755 pAr6kScanIndEvent->slist.Version = 1;
5756 pAr6kScanIndEvent->slist.NumItems = numbss;
5758 psi = &pAr6kScanIndEvent->slist.BssidScanInfo[0];
5760 for (bss = nt->nt_node_first; bss; bss = bss->ni_list_next) {
5761 if (bss->ni_si_gen != gen) {
5763 bss->ni_si_gen = gen;
5766 psi->ScanTime = bss->ni_tstamp - WLAN_NODE_INACT_TIMEOUT_MSEC;
5768 // Copy data to bssid_ex
5769 bsssize = offsetof(NDIS_WLAN_BSSID_EX, IEs);
5770 bsssize = bsssize + sizeof(NDIS_802_11_FIXED_IEs);
5773 if (bss->ni_cie.ie_rsn) {
5774 bsssize = bsssize + bss->ni_cie.ie_rsn[1] + 2;
5777 if (bss->ni_cie.ie_wpa) {
5778 bsssize = bsssize + bss->ni_cie.ie_wpa[1] + 2;
5781 // bsssize must be a multiple of 4 to maintain alignment.
5782 bsssize = (bsssize + 3) & ~3;
5784 psi->Bssid.Length = bsssize;
5786 memcpy (psi->Bssid.MacAddress, bss->ni_macaddr, ETHERNET_MAC_ADDRESS_LENGTH);
5789 //if (((bss->ni_macaddr[3] == 0xCE) && (bss->ni_macaddr[4] == 0xF0) && (bss->ni_macaddr[5] == 0xE7)) ||
5790 // ((bss->ni_macaddr[3] == 0x03) && (bss->ni_macaddr[4] == 0xE2) && (bss->ni_macaddr[5] == 0x70)))
5791 // RETAILMSG (1, (L"%x\n",bss->ni_macaddr[5]));
5793 psi->Bssid.Ssid.SsidLength = 0;
5794 pie = bss->ni_cie.ie_ssid;
5797 // Format of SSID IE is:
5800 // SSID (Length octets)
5802 // Validation of the IE should have occurred within WMI.
5805 psi->Bssid.Ssid.SsidLength = pie[1];
5806 memcpy(psi->Bssid.Ssid.Ssid, &pie[2], psi->Bssid.Ssid.SsidLength);
5809 psi->Bssid.Privacy = (bss->ni_cie.ie_capInfo & 0x10) ? 1 : 0;
5811 //Post the RSSI value relative to the Standard Noise floor value.
5812 psi->Bssid.Rssi = bss->ni_rssi;
5814 if (bss->ni_cie.ie_chan >= 2412 && bss->ni_cie.ie_chan <= 2484) {
5816 if (bss->ni_cie.ie_rates && bss->ni_cie.ie_xrates) {
5817 psi->Bssid.NetworkTypeInUse = Ndis802_11OFDM24;
5820 psi->Bssid.NetworkTypeInUse = Ndis802_11DS;
5824 psi->Bssid.NetworkTypeInUse = Ndis802_11OFDM5;
5827 psi->Bssid.Configuration.Length = sizeof(psi->Bssid.Configuration);
5828 psi->Bssid.Configuration.BeaconPeriod = bss->ni_cie.ie_beaconInt; // Units are Kmicroseconds (1024 us)
5829 psi->Bssid.Configuration.ATIMWindow = 0;
5830 psi->Bssid.Configuration.DSConfig = bss->ni_cie.ie_chan * 1000;
5831 psi->Bssid.InfrastructureMode = ((bss->ni_cie.ie_capInfo & 0x03) == 0x01 ) ? Ndis802_11Infrastructure : Ndis802_11IBSS;
5834 pie = bss->ni_cie.ie_rates;
5836 RateSize = (pie[1] < NDIS_802_11_LENGTH_RATES_EX) ? pie[1] : NDIS_802_11_LENGTH_RATES_EX;
5837 memcpy(psi->Bssid.SupportedRates, &pie[2], RateSize);
5839 pie = bss->ni_cie.ie_xrates;
5840 if (pie && RateSize < NDIS_802_11_LENGTH_RATES_EX) {
5841 memcpy(psi->Bssid.SupportedRates + RateSize, &pie[2],
5842 (pie[1] < (NDIS_802_11_LENGTH_RATES_EX - RateSize)) ? pie[1] : (NDIS_802_11_LENGTH_RATES_EX - RateSize));
5845 // Copy the fixed IEs
5846 psi->Bssid.IELength = sizeof(NDIS_802_11_FIXED_IEs);
5848 pFixed = (NDIS_802_11_FIXED_IEs *)psi->Bssid.IEs;
5849 memcpy(pFixed->Timestamp, bss->ni_cie.ie_tstamp, sizeof(pFixed->Timestamp));
5850 pFixed->BeaconInterval = bss->ni_cie.ie_beaconInt;
5851 pFixed->Capabilities = bss->ni_cie.ie_capInfo;
5853 // Copy selected variable IEs
5855 pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pFixed + sizeof(NDIS_802_11_FIXED_IEs));
5858 // Copy the WPAv2 IE
5859 if (bss->ni_cie.ie_rsn) {
5860 pie = bss->ni_cie.ie_rsn;
5861 psi->Bssid.IELength += pie[1] + 2;
5862 memcpy(pVar, pie, pie[1] + 2);
5863 pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pVar + pie[1] + 2);
5866 // Copy the WPAv1 IE
5867 if (bss->ni_cie.ie_wpa) {
5868 pie = bss->ni_cie.ie_wpa;
5869 psi->Bssid.IELength += pie[1] + 2;
5870 memcpy(pVar, pie, pie[1] + 2);
5871 pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pVar + pie[1] + 2);
5874 // Advance buffer pointer
5875 psi = (PNDIS_802_11_BSSID_SCAN_INFO)((BYTE*)psi + bsssize + FIELD_OFFSET(NDIS_802_11_BSSID_SCAN_INFO, Bssid));
5879 IEEE80211_NODE_UNLOCK(nt);
5881 // wmi_free_allnodes(wmip);
5883 // RETAILMSG(1, (L"AR6K: scan indication: %u bss\n", numbss));
5885 ar6000_scan_indication (wmip->wmi_devt, pAr6kScanIndEvent, size);
5887 A_FREE(pAr6kScanIndEvent);
5892 ar6000_get_upper_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh,
5896 A_UINT8 threshold = (A_UINT8)sq_thresh->upper_threshold[size - 1];
5898 /* The list is already in sorted order. Get the next lower value */
5899 for (index = 0; index < size; index ++) {
5900 if (rssi < sq_thresh->upper_threshold[index]) {
5901 threshold = (A_UINT8)sq_thresh->upper_threshold[index];
5910 ar6000_get_lower_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh,
5914 A_UINT8 threshold = (A_UINT8)sq_thresh->lower_threshold[size - 1];
5916 /* The list is already in sorted order. Get the next lower value */
5917 for (index = 0; index < size; index ++) {
5918 if (rssi > sq_thresh->lower_threshold[index]) {
5919 threshold = (A_UINT8)sq_thresh->lower_threshold[index];
5927 wmi_send_rssi_threshold_params(struct wmi_t *wmip,
5928 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd)
5932 WMI_RSSI_THRESHOLD_PARAMS_CMD *cmd;
5934 size = sizeof (*cmd);
5936 osbuf = A_NETBUF_ALLOC(size);
5937 if (osbuf == NULL) {
5941 A_NETBUF_PUT(osbuf, size);
5943 cmd = (WMI_RSSI_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
5944 A_MEMZERO(cmd, size);
5945 A_MEMCPY(cmd, rssiCmd, sizeof(WMI_RSSI_THRESHOLD_PARAMS_CMD));
5947 return (wmi_cmd_send(wmip, osbuf, WMI_RSSI_THRESHOLD_PARAMS_CMDID,
5951 wmi_send_snr_threshold_params(struct wmi_t *wmip,
5952 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd)
5956 WMI_SNR_THRESHOLD_PARAMS_CMD *cmd;
5958 size = sizeof (*cmd);
5960 osbuf = A_NETBUF_ALLOC(size);
5961 if (osbuf == NULL) {
5965 A_NETBUF_PUT(osbuf, size);
5966 cmd = (WMI_SNR_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf));
5967 A_MEMZERO(cmd, size);
5968 A_MEMCPY(cmd, snrCmd, sizeof(WMI_SNR_THRESHOLD_PARAMS_CMD));
5970 return (wmi_cmd_send(wmip, osbuf, WMI_SNR_THRESHOLD_PARAMS_CMDID,
5975 wmi_set_target_event_report_cmd(struct wmi_t *wmip, WMI_SET_TARGET_EVENT_REPORT_CMD* cmd)
5978 WMI_SET_TARGET_EVENT_REPORT_CMD* alloc_cmd;
5980 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
5981 if (osbuf == NULL) {
5985 A_NETBUF_PUT(osbuf, sizeof(*cmd));
5987 alloc_cmd = (WMI_SET_TARGET_EVENT_REPORT_CMD *)(A_NETBUF_DATA(osbuf));
5988 A_MEMZERO(alloc_cmd, sizeof(*cmd));
5989 A_MEMCPY(alloc_cmd, cmd, sizeof(*cmd));
5991 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TARGET_EVENT_REPORT_CMDID,
5995 bss_t *wmi_rm_current_bss (struct wmi_t *wmip, A_UINT8 *id)
5997 wmi_get_current_bssid (wmip, id);
5998 return wlan_node_remove (&wmip->wmi_scan_table, id);
6001 int wmi_add_current_bss (struct wmi_t *wmip, A_UINT8 *id, bss_t *bss)
6003 wlan_setup_node (&wmip->wmi_scan_table, bss, id);
6007 #ifdef ATH_AR6K_11N_SUPPORT
6009 wmi_addba_req_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
6011 WMI_ADDBA_REQ_EVENT *cmd = (WMI_ADDBA_REQ_EVENT *)datap;
6013 A_WMI_AGGR_RECV_ADDBA_REQ_EVT(wmip->wmi_devt, cmd);
6020 wmi_addba_resp_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
6022 WMI_ADDBA_RESP_EVENT *cmd = (WMI_ADDBA_RESP_EVENT *)datap;
6024 A_WMI_AGGR_RECV_ADDBA_RESP_EVT(wmip->wmi_devt, cmd);
6030 wmi_delba_req_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
6032 WMI_DELBA_EVENT *cmd = (WMI_DELBA_EVENT *)datap;
6034 A_WMI_AGGR_RECV_DELBA_REQ_EVT(wmip->wmi_devt, cmd);
6040 wmi_btcoex_config_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
6042 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
6044 A_WMI_BTCOEX_CONFIG_EVENT(wmip->wmi_devt, datap, len);
6051 wmi_btcoex_stats_event_rx(struct wmi_t * wmip,A_UINT8 * datap,int len)
6053 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
6055 A_WMI_BTCOEX_STATS_EVENT(wmip->wmi_devt, datap, len);
6063 wmi_hci_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
6065 WMI_HCI_EVENT *cmd = (WMI_HCI_EVENT *)datap;
6066 A_WMI_HCI_EVENT_EVT(wmip->wmi_devt, cmd);
6071 ////////////////////////////////////////////////////////////////////////////////
6073 //// AP mode functions ////
6075 ////////////////////////////////////////////////////////////////////////////////
6077 * IOCTL: AR6000_XIOCTL_AP_COMMIT_CONFIG
6079 * When AR6K in AP mode, This command will be called after
6080 * changing ssid, channel etc. It will pass the profile to
6081 * target with a flag which will indicate which parameter changed,
6082 * also if this flag is 0, there was no change in parametes, so
6083 * commit cmd will not be sent to target. Without calling this IOCTL
6084 * the changes will not take effect.
6087 wmi_ap_profile_commit(struct wmi_t *wmip, WMI_CONNECT_CMD *p)
6090 WMI_CONNECT_CMD *cm;
6092 osbuf = A_NETBUF_ALLOC(sizeof(*cm));
6093 if (osbuf == NULL) {
6097 A_NETBUF_PUT(osbuf, sizeof(*cm));
6098 cm = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf));
6099 A_MEMZERO(cm, sizeof(*cm));
6101 A_MEMCPY(cm,p,sizeof(*cm));
6103 return (wmi_cmd_send(wmip, osbuf, WMI_AP_CONFIG_COMMIT_CMDID, NO_SYNC_WMIFLAG));
6107 * IOCTL: AR6000_XIOCTL_AP_HIDDEN_SSID
6109 * This command will be used to enable/disable hidden ssid functioanlity of
6110 * beacon. If it is enabled, ssid will be NULL in beacon.
6113 wmi_ap_set_hidden_ssid(struct wmi_t *wmip, A_UINT8 hidden_ssid)
6116 WMI_AP_HIDDEN_SSID_CMD *hs;
6118 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_HIDDEN_SSID_CMD));
6119 if (osbuf == NULL) {
6123 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_HIDDEN_SSID_CMD));
6124 hs = (WMI_AP_HIDDEN_SSID_CMD *)(A_NETBUF_DATA(osbuf));
6125 A_MEMZERO(hs, sizeof(*hs));
6127 hs->hidden_ssid = hidden_ssid;
6129 A_DPRINTF(DBG_WMI, (DBGFMT "AR6000_XIOCTL_AP_HIDDEN_SSID %d\n", DBGARG , hidden_ssid));
6130 return (wmi_cmd_send(wmip, osbuf, WMI_AP_HIDDEN_SSID_CMDID, NO_SYNC_WMIFLAG));
6134 * IOCTL: AR6000_XIOCTL_AP_SET_MAX_NUM_STA
6136 * This command is used to limit max num of STA that can connect
6137 * with this AP. This value should not exceed AP_MAX_NUM_STA (this
6138 * is max num of STA supported by AP). Value was already validated
6142 wmi_ap_set_num_sta(struct wmi_t *wmip, A_UINT8 num_sta)
6145 WMI_AP_SET_NUM_STA_CMD *ns;
6147 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_NUM_STA_CMD));
6148 if (osbuf == NULL) {
6152 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_NUM_STA_CMD));
6153 ns = (WMI_AP_SET_NUM_STA_CMD *)(A_NETBUF_DATA(osbuf));
6154 A_MEMZERO(ns, sizeof(*ns));
6156 ns->num_sta = num_sta;
6158 A_DPRINTF(DBG_WMI, (DBGFMT "AR6000_XIOCTL_AP_SET_MAX_NUM_STA %d\n", DBGARG , num_sta));
6159 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_NUM_STA_CMDID, NO_SYNC_WMIFLAG));
6163 * IOCTL: AR6000_XIOCTL_AP_SET_ACL_MAC
6165 * This command is used to send list of mac of STAs which will
6166 * be allowed to connect with this AP. When this list is empty
6167 * firware will allow all STAs till the count reaches AP_MAX_NUM_STA.
6170 wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *acl)
6173 WMI_AP_ACL_MAC_CMD *a;
6175 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_ACL_MAC_CMD));
6176 if (osbuf == NULL) {
6180 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_ACL_MAC_CMD));
6181 a = (WMI_AP_ACL_MAC_CMD *)(A_NETBUF_DATA(osbuf));
6182 A_MEMZERO(a, sizeof(*a));
6183 A_MEMCPY(a,acl,sizeof(*acl));
6185 return (wmi_cmd_send(wmip, osbuf, WMI_AP_ACL_MAC_LIST_CMDID, NO_SYNC_WMIFLAG));
6189 * IOCTL: AR6000_XIOCTL_AP_SET_MLME
6191 * This command is used to send list of mac of STAs which will
6192 * be allowed to connect with this AP. When this list is empty
6193 * firware will allow all STAs till the count reaches AP_MAX_NUM_STA.
6196 wmi_ap_set_mlme(struct wmi_t *wmip, A_UINT8 cmd, A_UINT8 *mac, A_UINT16 reason)
6199 WMI_AP_SET_MLME_CMD *mlme;
6201 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_MLME_CMD));
6202 if (osbuf == NULL) {
6206 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_MLME_CMD));
6207 mlme = (WMI_AP_SET_MLME_CMD *)(A_NETBUF_DATA(osbuf));
6208 A_MEMZERO(mlme, sizeof(*mlme));
6211 A_MEMCPY(mlme->mac, mac, ATH_MAC_LEN);
6212 mlme->reason = reason;
6214 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_MLME_CMDID, NO_SYNC_WMIFLAG));
6218 wmi_pspoll_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
6220 WMI_PSPOLL_EVENT *ev;
6222 if (len < sizeof(WMI_PSPOLL_EVENT)) {
6225 ev = (WMI_PSPOLL_EVENT *)datap;
6227 A_WMI_PSPOLL_EVENT(wmip->wmi_devt, ev->aid);
6232 wmi_dtimexpiry_event_rx(struct wmi_t *wmip, A_UINT8 *datap,int len)
6234 A_WMI_DTIMEXPIRY_EVENT(wmip->wmi_devt);
6240 wmi_wapi_rekey_event_rx(struct wmi_t *wmip, A_UINT8 *datap,int len)
6247 ev = (A_UINT8 *)datap;
6249 A_WMI_WAPI_REKEY_EVENT(wmip->wmi_devt, *ev, &ev[1]);
6255 wmi_set_pvb_cmd(struct wmi_t *wmip, A_UINT16 aid, A_BOOL flag)
6257 WMI_AP_SET_PVB_CMD *cmd;
6260 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_PVB_CMD));
6261 if (osbuf == NULL) {
6265 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_PVB_CMD));
6266 cmd = (WMI_AP_SET_PVB_CMD *)(A_NETBUF_DATA(osbuf));
6267 A_MEMZERO(cmd, sizeof(*cmd));
6272 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_PVB_CMDID, NO_SYNC_WMIFLAG));
6276 wmi_ap_conn_inact_time(struct wmi_t *wmip, A_UINT32 period)
6278 WMI_AP_CONN_INACT_CMD *cmd;
6281 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_CONN_INACT_CMD));
6282 if (osbuf == NULL) {
6286 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_CONN_INACT_CMD));
6287 cmd = (WMI_AP_CONN_INACT_CMD *)(A_NETBUF_DATA(osbuf));
6288 A_MEMZERO(cmd, sizeof(*cmd));
6290 cmd->period = period;
6292 return (wmi_cmd_send(wmip, osbuf, WMI_AP_CONN_INACT_CMDID, NO_SYNC_WMIFLAG));
6296 wmi_ap_bgscan_time(struct wmi_t *wmip, A_UINT32 period, A_UINT32 dwell)
6298 WMI_AP_PROT_SCAN_TIME_CMD *cmd;
6301 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_PROT_SCAN_TIME_CMD));
6302 if (osbuf == NULL) {
6306 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_PROT_SCAN_TIME_CMD));
6307 cmd = (WMI_AP_PROT_SCAN_TIME_CMD *)(A_NETBUF_DATA(osbuf));
6308 A_MEMZERO(cmd, sizeof(*cmd));
6310 cmd->period_min = period;
6311 cmd->dwell_ms = dwell;
6313 return (wmi_cmd_send(wmip, osbuf, WMI_AP_PROT_SCAN_TIME_CMDID, NO_SYNC_WMIFLAG));
6317 wmi_ap_set_dtim(struct wmi_t *wmip, A_UINT8 dtim)
6319 WMI_AP_SET_DTIM_CMD *cmd;
6322 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_DTIM_CMD));
6323 if (osbuf == NULL) {
6327 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_DTIM_CMD));
6328 cmd = (WMI_AP_SET_DTIM_CMD *)(A_NETBUF_DATA(osbuf));
6329 A_MEMZERO(cmd, sizeof(*cmd));
6333 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_DTIM_CMDID, NO_SYNC_WMIFLAG));
6337 * IOCTL: AR6000_XIOCTL_AP_SET_ACL_POLICY
6339 * This command is used to set ACL policay. While changing policy, if you
6340 * want to retain the existing MAC addresses in the ACL list, policy should be
6341 * OR with AP_ACL_RETAIN_LIST_MASK, else the existing list will be cleared.
6342 * If there is no chage in policy, the list will be intact.
6345 wmi_ap_set_acl_policy(struct wmi_t *wmip, A_UINT8 policy)
6348 WMI_AP_ACL_POLICY_CMD *po;
6350 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_ACL_POLICY_CMD));
6351 if (osbuf == NULL) {
6355 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_ACL_POLICY_CMD));
6356 po = (WMI_AP_ACL_POLICY_CMD *)(A_NETBUF_DATA(osbuf));
6357 A_MEMZERO(po, sizeof(*po));
6359 po->policy = policy;
6361 return (wmi_cmd_send(wmip, osbuf, WMI_AP_ACL_POLICY_CMDID, NO_SYNC_WMIFLAG));
6365 wmi_ap_set_rateset(struct wmi_t *wmip, A_UINT8 rateset)
6368 WMI_AP_SET_11BG_RATESET_CMD *rs;
6370 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_11BG_RATESET_CMD));
6371 if (osbuf == NULL) {
6375 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_11BG_RATESET_CMD));
6376 rs = (WMI_AP_SET_11BG_RATESET_CMD *)(A_NETBUF_DATA(osbuf));
6377 A_MEMZERO(rs, sizeof(*rs));
6379 rs->rateset = rateset;
6381 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_11BG_RATESET_CMDID, NO_SYNC_WMIFLAG));
6384 #ifdef ATH_AR6K_11N_SUPPORT
6386 wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd)
6389 WMI_SET_HT_CAP_CMD *htCap;
6392 osbuf = A_NETBUF_ALLOC(sizeof(*htCap));
6393 if (osbuf == NULL) {
6397 A_NETBUF_PUT(osbuf, sizeof(*htCap));
6399 band = (cmd->band)? A_BAND_5GHZ : A_BAND_24GHZ;
6400 wmip->wmi_ht_allowed[band] = (cmd->enable)? 1:0;
6402 htCap = (WMI_SET_HT_CAP_CMD *)(A_NETBUF_DATA(osbuf));
6403 A_MEMZERO(htCap, sizeof(*htCap));
6404 A_MEMCPY(htCap, cmd, sizeof(*htCap));
6406 return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_CAP_CMDID,
6411 wmi_set_ht_op_cmd(struct wmi_t *wmip, A_UINT8 sta_chan_width)
6414 WMI_SET_HT_OP_CMD *htInfo;
6416 osbuf = A_NETBUF_ALLOC(sizeof(*htInfo));
6417 if (osbuf == NULL) {
6421 A_NETBUF_PUT(osbuf, sizeof(*htInfo));
6423 htInfo = (WMI_SET_HT_OP_CMD *)(A_NETBUF_DATA(osbuf));
6424 A_MEMZERO(htInfo, sizeof(*htInfo));
6425 htInfo->sta_chan_width = sta_chan_width;
6427 return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_OP_CMDID,
6433 wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, A_UINT32 *pMaskArray)
6436 WMI_SET_TX_SELECT_RATES_CMD *pData;
6438 osbuf = A_NETBUF_ALLOC(sizeof(*pData));
6439 if (osbuf == NULL) {
6443 A_NETBUF_PUT(osbuf, sizeof(*pData));
6445 pData = (WMI_SET_TX_SELECT_RATES_CMD *)(A_NETBUF_DATA(osbuf));
6446 A_MEMCPY(pData, pMaskArray, sizeof(*pData));
6448 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_SELECT_RATES_CMDID,
6454 wmi_send_hci_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT16 sz)
6459 osbuf = A_NETBUF_ALLOC(sizeof(*cmd) + sz);
6460 if (osbuf == NULL) {
6464 A_NETBUF_PUT(osbuf, sizeof(*cmd) + sz);
6465 cmd = (WMI_HCI_CMD *)(A_NETBUF_DATA(osbuf));
6467 cmd->cmd_buf_sz = sz;
6468 A_MEMCPY(cmd->buf, buf, sz);
6469 return (wmi_cmd_send(wmip, osbuf, WMI_HCI_CMD_CMDID, NO_SYNC_WMIFLAG));
6472 #ifdef ATH_AR6K_11N_SUPPORT
6474 wmi_allow_aggr_cmd(struct wmi_t *wmip, A_UINT16 tx_tidmask, A_UINT16 rx_tidmask)
6477 WMI_ALLOW_AGGR_CMD *cmd;
6479 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6480 if (osbuf == NULL) {
6484 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6486 cmd = (WMI_ALLOW_AGGR_CMD *)(A_NETBUF_DATA(osbuf));
6487 cmd->tx_allow_aggr = tx_tidmask;
6488 cmd->rx_allow_aggr = rx_tidmask;
6490 return (wmi_cmd_send(wmip, osbuf, WMI_ALLOW_AGGR_CMDID, NO_SYNC_WMIFLAG));
6494 wmi_setup_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid)
6497 WMI_ADDBA_REQ_CMD *cmd;
6499 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6500 if (osbuf == NULL) {
6504 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6506 cmd = (WMI_ADDBA_REQ_CMD *)(A_NETBUF_DATA(osbuf));
6509 return (wmi_cmd_send(wmip, osbuf, WMI_ADDBA_REQ_CMDID, NO_SYNC_WMIFLAG));
6513 wmi_delete_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid, A_BOOL uplink)
6516 WMI_DELBA_REQ_CMD *cmd;
6518 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6519 if (osbuf == NULL) {
6523 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6525 cmd = (WMI_DELBA_REQ_CMD *)(A_NETBUF_DATA(osbuf));
6527 cmd->is_sender_initiator = uplink; /* uplink =1 - uplink direction, 0=downlink direction */
6529 /* Delete the local aggr state, on host */
6530 return (wmi_cmd_send(wmip, osbuf, WMI_DELBA_REQ_CMDID, NO_SYNC_WMIFLAG));
6535 wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, A_UINT8 rxMetaVersion,
6536 A_BOOL rxDot11Hdr, A_BOOL defragOnHost)
6539 WMI_RX_FRAME_FORMAT_CMD *cmd;
6541 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6542 if (osbuf == NULL) {
6546 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6548 cmd = (WMI_RX_FRAME_FORMAT_CMD *)(A_NETBUF_DATA(osbuf));
6549 cmd->dot11Hdr = (rxDot11Hdr==TRUE)? 1:0;
6550 cmd->defragOnHost = (defragOnHost==TRUE)? 1:0;
6551 cmd->metaVersion = rxMetaVersion; /* */
6553 /* Delete the local aggr state, on host */
6554 return (wmi_cmd_send(wmip, osbuf, WMI_RX_FRAME_FORMAT_CMDID, NO_SYNC_WMIFLAG));
6559 wmi_set_thin_mode_cmd(struct wmi_t *wmip, A_BOOL bThinMode)
6562 WMI_SET_THIN_MODE_CMD *cmd;
6564 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6565 if (osbuf == NULL) {
6569 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6571 cmd = (WMI_SET_THIN_MODE_CMD *)(A_NETBUF_DATA(osbuf));
6572 cmd->enable = (bThinMode==TRUE)? 1:0;
6574 /* Delete the local aggr state, on host */
6575 return (wmi_cmd_send(wmip, osbuf, WMI_SET_THIN_MODE_CMDID, NO_SYNC_WMIFLAG));
6580 wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE precedence)
6583 WMI_SET_BT_WLAN_CONN_PRECEDENCE *cmd;
6585 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6586 if (osbuf == NULL) {
6590 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6592 cmd = (WMI_SET_BT_WLAN_CONN_PRECEDENCE *)(A_NETBUF_DATA(osbuf));
6593 A_MEMZERO(cmd, sizeof(*cmd));
6594 cmd->precedence = precedence;
6596 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID,
6601 wmi_set_pmk_cmd(struct wmi_t *wmip, A_UINT8 *pmk)
6606 osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_PMK_CMD));
6607 if (osbuf == NULL) {
6611 A_NETBUF_PUT(osbuf, sizeof(WMI_SET_PMK_CMD));
6613 p = (WMI_SET_PMK_CMD *)(A_NETBUF_DATA(osbuf));
6614 A_MEMZERO(p, sizeof(*p));
6616 A_MEMCPY(p->pmk, pmk, WMI_PMK_LEN);
6618 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMK_CMDID, NO_SYNC_WMIFLAG));
6622 wmi_SGI_cmd(struct wmi_t *wmip, A_UINT32 sgiMask, A_UINT8 sgiPERThreshold)
6625 WMI_SET_TX_SGI_PARAM_CMD *cmd;
6627 osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
6628 if (osbuf == NULL) {
6629 return A_NO_MEMORY ;
6632 A_NETBUF_PUT(osbuf, sizeof(*cmd));
6634 cmd = (WMI_SET_TX_SGI_PARAM_CMD *)(A_NETBUF_DATA(osbuf));
6635 A_MEMZERO(cmd, sizeof(*cmd));
6636 cmd->sgiMask = sgiMask;
6637 cmd->sgiPERThreshold = sgiPERThreshold;
6638 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_SGI_PARAM_CMDID,
6643 wmi_find_matching_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid,
6644 A_UINT32 ssidLength,
6645 A_UINT32 dot11AuthMode, A_UINT32 authMode,
6646 A_UINT32 pairwiseCryptoType, A_UINT32 grpwiseCryptoTyp)
6649 node = wlan_find_matching_Ssidnode (&wmip->wmi_scan_table, pSsid,
6650 ssidLength, dot11AuthMode, authMode, pairwiseCryptoType, grpwiseCryptoTyp);
6656 wmi_ieee2freq (int chan)
6659 freq = wlan_ieee2freq (chan);
6665 wmi_freq2ieee (A_UINT16 freq)
6668 chan = wlan_freq2ieee (freq);