OLD | NEW |
(Empty) | |
| 1 //------------------------------------------------------------------------------ |
| 2 // <copyright file="wmi.c" company="Atheros"> |
| 3 // Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. |
| 4 // |
| 5 // This program is free software; you can redistribute it and/or modify |
| 6 // it under the terms of the GNU General Public License version 2 as |
| 7 // published by the Free Software Foundation; |
| 8 // |
| 9 // Software distributed under the License is distributed on an "AS |
| 10 // IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
| 11 // implied. See the License for the specific language governing |
| 12 // rights and limitations under the License. |
| 13 // |
| 14 // |
| 15 //------------------------------------------------------------------------------ |
| 16 //============================================================================== |
| 17 // This module implements the hardware independent layer of the |
| 18 // Wireless Module Interface (WMI) protocol. |
| 19 // |
| 20 // Author(s): ="Atheros" |
| 21 //============================================================================== |
| 22 #include <a_config.h> |
| 23 #include <athdefs.h> |
| 24 #include <a_types.h> |
| 25 #include <a_osapi.h> |
| 26 #include "htc.h" |
| 27 #include "htc_api.h" |
| 28 #include "wmi.h" |
| 29 #include <wlan_api.h> |
| 30 #include <wmi_api.h> |
| 31 #include <ieee80211.h> |
| 32 #include <ieee80211_node.h> |
| 33 #include "dset_api.h" |
| 34 #include "gpio_api.h" |
| 35 #include "wmi_host.h" |
| 36 #include "a_drv.h" |
| 37 #include "a_drv_api.h" |
| 38 #define ATH_MODULE_NAME wmi |
| 39 #include "a_debug.h" |
| 40 #include "dbglog_api.h" |
| 41 #include "roaming.h" |
| 42 |
| 43 #define ATH_DEBUG_WMI ATH_DEBUG_MAKE_MODULE_MASK(0) |
| 44 |
| 45 #ifdef DEBUG |
| 46 |
| 47 static ATH_DEBUG_MASK_DESCRIPTION wmi_debug_desc[] = { |
| 48 { ATH_DEBUG_WMI , "General WMI Tracing"}, |
| 49 }; |
| 50 |
| 51 ATH_DEBUG_INSTANTIATE_MODULE_VAR(wmi, |
| 52 "wmi", |
| 53 "Wireless Module Interface", |
| 54 ATH_DEBUG_MASK_DEFAULTS, |
| 55 ATH_DEBUG_DESCRIPTION_COUNT(wmi_debug_desc), |
| 56 wmi_debug_desc); |
| 57 |
| 58 #endif |
| 59 |
| 60 #ifndef REXOS |
| 61 #define DBGARG _A_FUNCNAME_ |
| 62 #define DBGFMT "%s() : " |
| 63 #define DBG_WMI ATH_DEBUG_WMI |
| 64 #define DBG_ERROR ATH_DEBUG_ERR |
| 65 #define DBG_WMI2 ATH_DEBUG_WMI |
| 66 #define A_DPRINTF AR_DEBUG_PRINTF |
| 67 #endif |
| 68 |
| 69 static A_STATUS wmi_ready_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); |
| 70 |
| 71 static A_STATUS wmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, |
| 72 int len); |
| 73 static A_STATUS wmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, |
| 74 int len); |
| 75 |
| 76 static A_STATUS wmi_tkip_micerr_event_rx(struct wmi_t *wmip, A_UINT8 *datap, |
| 77 int len); |
| 78 static A_STATUS wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap, |
| 79 int len); |
| 80 static A_STATUS wmi_opt_frame_event_rx(struct wmi_t *wmip, A_UINT8 *datap, |
| 81 int len); |
| 82 static A_STATUS wmi_pstream_timeout_event_rx(struct wmi_t *wmip, A_UINT8 *datap, |
| 83 int len); |
| 84 static A_STATUS wmi_sync_point(struct wmi_t *wmip); |
| 85 |
| 86 static A_STATUS wmi_bitrate_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, |
| 87 int len); |
| 88 static A_STATUS wmi_ratemask_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, |
| 89 int len); |
| 90 static A_STATUS wmi_channelList_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, |
| 91 int len); |
| 92 static A_STATUS wmi_regDomain_event_rx(struct wmi_t *wmip, A_UINT8 *datap, |
| 93 int len); |
| 94 static A_STATUS wmi_txPwr_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); |
| 95 static A_STATUS wmi_neighborReport_event_rx(struct wmi_t *wmip, A_UINT8 *datap, |
| 96 int len); |
| 97 |
| 98 static A_STATUS wmi_dset_open_req_rx(struct wmi_t *wmip, A_UINT8 *datap, |
| 99 int len); |
| 100 #ifdef CONFIG_HOST_DSET_SUPPORT |
| 101 static A_STATUS wmi_dset_close_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); |
| 102 static A_STATUS wmi_dset_data_req_rx(struct wmi_t *wmip, A_UINT8 *datap, |
| 103 int len); |
| 104 #endif /* CONFIG_HOST_DSET_SUPPORT */ |
| 105 |
| 106 |
| 107 static A_STATUS wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap, |
| 108 int len); |
| 109 static A_STATUS wmi_errorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); |
| 110 static A_STATUS wmi_statsEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); |
| 111 static A_STATUS wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, in
t len); |
| 112 static A_STATUS wmi_hbChallengeResp_rx(struct wmi_t *wmip, A_UINT8 *datap, int l
en); |
| 113 static A_STATUS wmi_reportErrorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int
len); |
| 114 static A_STATUS wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); |
| 115 static A_STATUS wmi_channel_change_event_rx(struct wmi_t *wmip, A_UINT8 *datap,
int len); |
| 116 static A_STATUS wmi_roam_tbl_event_rx(struct wmi_t *wmip, A_UINT8 *datap, |
| 117 int len); |
| 118 static A_STATUS wmi_roam_data_event_rx(struct wmi_t *wmip, A_UINT8 *datap, |
| 119 int len); |
| 120 static A_STATUS wmi_get_wow_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, |
| 121 int len); |
| 122 static A_STATUS |
| 123 wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len); |
| 124 |
| 125 static A_STATUS |
| 126 wmi_set_params_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len); |
| 127 |
| 128 #ifdef CONFIG_HOST_GPIO_SUPPORT |
| 129 static A_STATUS wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); |
| 130 static A_STATUS wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); |
| 131 static A_STATUS wmi_gpio_ack_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); |
| 132 #endif /* CONFIG_HOST_GPIO_SUPPORT */ |
| 133 |
| 134 #ifdef CONFIG_HOST_TCMD_SUPPORT |
| 135 static A_STATUS |
| 136 wmi_tcmd_test_report_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); |
| 137 #endif |
| 138 |
| 139 static A_STATUS |
| 140 wmi_txRetryErrEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); |
| 141 |
| 142 static A_STATUS |
| 143 wmi_snrThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); |
| 144 |
| 145 static A_STATUS |
| 146 wmi_lqThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); |
| 147 |
| 148 static A_BOOL |
| 149 wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_INT32 rateIndex); |
| 150 |
| 151 static A_STATUS |
| 152 wmi_aplistEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); |
| 153 |
| 154 static A_STATUS |
| 155 wmi_dbglog_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); |
| 156 |
| 157 static A_STATUS wmi_keepalive_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int l
en); |
| 158 |
| 159 A_STATUS wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdI
d, |
| 160 WMI_SYNC_FLAG syncflag); |
| 161 |
| 162 A_UINT8 ar6000_get_upper_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh,
A_UINT32 size); |
| 163 A_UINT8 ar6000_get_lower_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh,
A_UINT32 size); |
| 164 |
| 165 void wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PA
RAMS_CMD *rssiCmd); |
| 166 void wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARA
MS_CMD *snrCmd); |
| 167 static A_STATUS wmi_send_rssi_threshold_params(struct wmi_t *wmip, |
| 168 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd); |
| 169 static A_STATUS wmi_send_snr_threshold_params(struct wmi_t *wmip, |
| 170 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd); |
| 171 #if defined(CONFIG_TARGET_PROFILE_SUPPORT) |
| 172 static A_STATUS |
| 173 wmi_prof_count_rx(struct wmi_t *wmip, A_UINT8 *datap, int len); |
| 174 #endif /* CONFIG_TARGET_PROFILE_SUPPORT */ |
| 175 |
| 176 static A_STATUS wmi_pspoll_event_rx(struct wmi_t *wmip, A_UINT8 *datap, |
| 177 int len); |
| 178 static A_STATUS wmi_dtimexpiry_event_rx(struct wmi_t *wmip, A_UINT8 *datap, |
| 179 int len); |
| 180 |
| 181 static A_STATUS wmi_peer_node_event_rx (struct wmi_t *wmip, A_UINT8 *datap, |
| 182 int len); |
| 183 #ifdef ATH_AR6K_11N_SUPPORT |
| 184 static A_STATUS wmi_addba_req_event_rx(struct wmi_t *, A_UINT8 *, int); |
| 185 static A_STATUS wmi_addba_resp_event_rx(struct wmi_t *, A_UINT8 *, int); |
| 186 static A_STATUS wmi_delba_req_event_rx(struct wmi_t *, A_UINT8 *, int); |
| 187 static A_STATUS wmi_btcoex_config_event_rx(struct wmi_t *wmip, A_UINT8 *datap, i
nt len); |
| 188 static A_STATUS wmi_btcoex_stats_event_rx(struct wmi_t *wmip, A_UINT8 *datap, in
t len); |
| 189 #endif |
| 190 static A_STATUS wmi_hci_event_rx(struct wmi_t *, A_UINT8 *, int); |
| 191 |
| 192 #ifdef WAPI_ENABLE |
| 193 static A_STATUS wmi_wapi_rekey_event_rx(struct wmi_t *wmip, A_UINT8 *datap, |
| 194 int len); |
| 195 #endif |
| 196 |
| 197 #if defined(UNDER_CE) |
| 198 #if defined(NDIS51_MINIPORT) |
| 199 unsigned int processDot11Hdr = 0; |
| 200 #else |
| 201 unsigned int processDot11Hdr = 1; |
| 202 #endif |
| 203 #else |
| 204 extern unsigned int processDot11Hdr; |
| 205 #endif |
| 206 |
| 207 int wps_enable; |
| 208 static const A_INT32 wmi_rateTable[] = { |
| 209 1000, |
| 210 2000, |
| 211 5500, |
| 212 11000, |
| 213 6000, |
| 214 9000, |
| 215 12000, |
| 216 18000, |
| 217 24000, |
| 218 36000, |
| 219 48000, |
| 220 54000, |
| 221 6500, |
| 222 13000, |
| 223 19500, |
| 224 26000, |
| 225 39000, |
| 226 52000, |
| 227 58500, |
| 228 65000, |
| 229 13500, |
| 230 27000, |
| 231 40500, |
| 232 54000, |
| 233 81000, |
| 234 108000, |
| 235 121500, |
| 236 135000, |
| 237 0}; |
| 238 |
| 239 #define MODE_A_SUPPORT_RATE_START ((A_INT32) 4) |
| 240 #define MODE_A_SUPPORT_RATE_STOP ((A_INT32) 11) |
| 241 |
| 242 #define MODE_GONLY_SUPPORT_RATE_START MODE_A_SUPPORT_RATE_START |
| 243 #define MODE_GONLY_SUPPORT_RATE_STOP MODE_A_SUPPORT_RATE_STOP |
| 244 |
| 245 #define MODE_B_SUPPORT_RATE_START ((A_INT32) 0) |
| 246 #define MODE_B_SUPPORT_RATE_STOP ((A_INT32) 3) |
| 247 |
| 248 #define MODE_G_SUPPORT_RATE_START ((A_INT32) 0) |
| 249 #define MODE_G_SUPPORT_RATE_STOP ((A_INT32) 11) |
| 250 |
| 251 #define MAX_NUMBER_OF_SUPPORT_RATES (MODE_G_SUPPORT_RATE_STOP + 1) |
| 252 |
| 253 /* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */ |
| 254 const A_UINT8 up_to_ac[]= { |
| 255 WMM_AC_BE, |
| 256 WMM_AC_BK, |
| 257 WMM_AC_BK, |
| 258 WMM_AC_BE, |
| 259 WMM_AC_VI, |
| 260 WMM_AC_VI, |
| 261 WMM_AC_VO, |
| 262 WMM_AC_VO, |
| 263 }; |
| 264 |
| 265 #include "athstartpack.h" |
| 266 |
| 267 /* This stuff is used when we want a simple layer-3 visibility */ |
| 268 typedef PREPACK struct _iphdr { |
| 269 A_UINT8 ip_ver_hdrlen; /* version and hdr length */ |
| 270 A_UINT8 ip_tos; /* type of service */ |
| 271 A_UINT16 ip_len; /* total length */ |
| 272 A_UINT16 ip_id; /* identification */ |
| 273 A_INT16 ip_off; /* fragment offset field */ |
| 274 #define IP_DF 0x4000 /* dont fragment flag */ |
| 275 #define IP_MF 0x2000 /* more fragments flag */ |
| 276 #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ |
| 277 A_UINT8 ip_ttl; /* time to live */ |
| 278 A_UINT8 ip_p; /* protocol */ |
| 279 A_UINT16 ip_sum; /* checksum */ |
| 280 A_UINT8 ip_src[4]; /* source and dest address */ |
| 281 A_UINT8 ip_dst[4]; |
| 282 } POSTPACK iphdr; |
| 283 |
| 284 #include "athendpack.h" |
| 285 |
| 286 A_INT16 rssi_event_value = 0; |
| 287 A_INT16 snr_event_value = 0; |
| 288 |
| 289 A_BOOL is_probe_ssid = FALSE; |
| 290 |
| 291 void * |
| 292 wmi_init(void *devt) |
| 293 { |
| 294 struct wmi_t *wmip; |
| 295 |
| 296 A_REGISTER_MODULE_DEBUG_INFO(wmi); |
| 297 |
| 298 wmip = A_MALLOC(sizeof(struct wmi_t)); |
| 299 if (wmip == NULL) { |
| 300 return (NULL); |
| 301 } |
| 302 A_MEMZERO(wmip, sizeof(*wmip)); |
| 303 A_MUTEX_INIT(&wmip->wmi_lock); |
| 304 wmip->wmi_devt = devt; |
| 305 wlan_node_table_init(wmip, &wmip->wmi_scan_table); |
| 306 wmi_qos_state_init(wmip); |
| 307 |
| 308 wmip->wmi_powerMode = REC_POWER; |
| 309 wmip->wmi_phyMode = WMI_11G_MODE; |
| 310 |
| 311 wmip->wmi_pair_crypto_type = NONE_CRYPT; |
| 312 wmip->wmi_grp_crypto_type = NONE_CRYPT; |
| 313 |
| 314 return (wmip); |
| 315 } |
| 316 |
| 317 void |
| 318 wmi_qos_state_init(struct wmi_t *wmip) |
| 319 { |
| 320 A_UINT8 i; |
| 321 |
| 322 if (wmip == NULL) { |
| 323 return; |
| 324 } |
| 325 LOCK_WMI(wmip); |
| 326 |
| 327 /* Initialize QoS States */ |
| 328 wmip->wmi_numQoSStream = 0; |
| 329 |
| 330 wmip->wmi_fatPipeExists = 0; |
| 331 |
| 332 for (i=0; i < WMM_NUM_AC; i++) { |
| 333 wmip->wmi_streamExistsForAC[i]=0; |
| 334 } |
| 335 |
| 336 UNLOCK_WMI(wmip); |
| 337 |
| 338 A_WMI_SET_NUMDATAENDPTS(wmip->wmi_devt, 1); |
| 339 } |
| 340 |
| 341 void |
| 342 wmi_set_control_ep(struct wmi_t * wmip, HTC_ENDPOINT_ID eid) |
| 343 { |
| 344 A_ASSERT( eid != ENDPOINT_UNUSED); |
| 345 wmip->wmi_endpoint_id = eid; |
| 346 } |
| 347 |
| 348 HTC_ENDPOINT_ID |
| 349 wmi_get_control_ep(struct wmi_t * wmip) |
| 350 { |
| 351 return(wmip->wmi_endpoint_id); |
| 352 } |
| 353 |
| 354 void |
| 355 wmi_shutdown(struct wmi_t *wmip) |
| 356 { |
| 357 if (wmip != NULL) { |
| 358 wlan_node_table_cleanup(&wmip->wmi_scan_table); |
| 359 if (A_IS_MUTEX_VALID(&wmip->wmi_lock)) { |
| 360 A_MUTEX_DELETE(&wmip->wmi_lock); |
| 361 } |
| 362 A_FREE(wmip); |
| 363 } |
| 364 } |
| 365 |
| 366 /* |
| 367 * performs DIX to 802.3 encapsulation for transmit packets. |
| 368 * uses passed in buffer. Returns buffer or NULL if failed. |
| 369 * Assumes the entire DIX header is contigous and that there is |
| 370 * enough room in the buffer for a 802.3 mac header and LLC+SNAP headers. |
| 371 */ |
| 372 A_STATUS |
| 373 wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf) |
| 374 { |
| 375 A_UINT8 *datap; |
| 376 A_UINT16 typeorlen; |
| 377 ATH_MAC_HDR macHdr; |
| 378 ATH_LLC_SNAP_HDR *llcHdr; |
| 379 |
| 380 A_ASSERT(osbuf != NULL); |
| 381 |
| 382 if (A_NETBUF_HEADROOM(osbuf) < |
| 383 (sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR))) |
| 384 { |
| 385 return A_NO_MEMORY; |
| 386 } |
| 387 |
| 388 datap = A_NETBUF_DATA(osbuf); |
| 389 |
| 390 typeorlen = *(A_UINT16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN); |
| 391 |
| 392 if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) { |
| 393 /* |
| 394 * packet is already in 802.3 format - return success |
| 395 */ |
| 396 A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG)); |
| 397 return (A_OK); |
| 398 } |
| 399 |
| 400 /* |
| 401 * Save mac fields and length to be inserted later |
| 402 */ |
| 403 A_MEMCPY(macHdr.dstMac, datap, ATH_MAC_LEN); |
| 404 A_MEMCPY(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN); |
| 405 macHdr.typeOrLen = A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) + |
| 406 sizeof(ATH_LLC_SNAP_HDR)); |
| 407 |
| 408 /* |
| 409 * Make room for LLC+SNAP headers |
| 410 */ |
| 411 if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != A_OK) { |
| 412 return A_NO_MEMORY; |
| 413 } |
| 414 datap = A_NETBUF_DATA(osbuf); |
| 415 |
| 416 A_MEMCPY(datap, &macHdr, sizeof (ATH_MAC_HDR)); |
| 417 |
| 418 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR)); |
| 419 llcHdr->dsap = 0xAA; |
| 420 llcHdr->ssap = 0xAA; |
| 421 llcHdr->cntl = 0x03; |
| 422 llcHdr->orgCode[0] = 0x0; |
| 423 llcHdr->orgCode[1] = 0x0; |
| 424 llcHdr->orgCode[2] = 0x0; |
| 425 llcHdr->etherType = typeorlen; |
| 426 |
| 427 return (A_OK); |
| 428 } |
| 429 |
| 430 A_STATUS wmi_meta_add(struct wmi_t *wmip, void *osbuf, A_UINT8 *pVersion,void *p
TxMetaS) |
| 431 { |
| 432 switch(*pVersion){ |
| 433 case 0: |
| 434 return (A_OK); |
| 435 case WMI_META_VERSION_1: |
| 436 { |
| 437 WMI_TX_META_V1 *pV1= NULL; |
| 438 A_ASSERT(osbuf != NULL); |
| 439 if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != A_OK) { |
| 440 return A_NO_MEMORY; |
| 441 } |
| 442 |
| 443 pV1 = (WMI_TX_META_V1 *)A_NETBUF_DATA(osbuf); |
| 444 /* the pktID is used in conjunction with txComplete messages |
| 445 * allowing the target to notify which tx requests have been |
| 446 * completed and how. */ |
| 447 pV1->pktID = 0; |
| 448 /* the ratePolicyID allows the host to specify which rate policy |
| 449 * to use for transmitting this packet. 0 means use default behav
ior. */ |
| 450 pV1->ratePolicyID = 0; |
| 451 A_ASSERT(pVersion != NULL); |
| 452 /* the version must be used to populate the meta field of the WM
I_DATA_HDR */ |
| 453 *pVersion = WMI_META_VERSION_1; |
| 454 return (A_OK); |
| 455 } |
| 456 #ifdef CONFIG_CHECKSUM_OFFLOAD |
| 457 case WMI_META_VERSION_2: |
| 458 { |
| 459 WMI_TX_META_V2 *pV2 ; |
| 460 A_ASSERT(osbuf != NULL); |
| 461 if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != A_OK) { |
| 462 return A_NO_MEMORY; |
| 463 } |
| 464 pV2 = (WMI_TX_META_V2 *)A_NETBUF_DATA(osbuf); |
| 465 A_MEMCPY(pV2,(WMI_TX_META_V2 *)pTxMetaS,sizeof(WMI_TX_META_V2)); |
| 466 return (A_OK); |
| 467 } |
| 468 #endif |
| 469 default: |
| 470 return (A_OK); |
| 471 } |
| 472 } |
| 473 |
| 474 /* |
| 475 * Adds a WMI data header |
| 476 * Assumes there is enough room in the buffer to add header. |
| 477 */ |
| 478 A_STATUS |
| 479 wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, A_UINT8 msgType, A_BOOL bMoreD
ata, |
| 480 WMI_DATA_HDR_DATA_TYPE data_type,A_UINT8 metaVersion, void *
pTxMetaS) |
| 481 { |
| 482 WMI_DATA_HDR *dtHdr; |
| 483 // A_UINT8 metaVersion = 0; |
| 484 A_STATUS status; |
| 485 |
| 486 A_ASSERT(osbuf != NULL); |
| 487 |
| 488 /* adds the meta data field after the wmi data hdr. If metaVersion |
| 489 * is returns 0 then no meta field was added. */ |
| 490 if ((status = wmi_meta_add(wmip, osbuf, &metaVersion,pTxMetaS)) != A_OK) { |
| 491 return status; |
| 492 } |
| 493 |
| 494 if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != A_OK) { |
| 495 return A_NO_MEMORY; |
| 496 } |
| 497 |
| 498 dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf); |
| 499 A_MEMZERO(dtHdr, sizeof(WMI_DATA_HDR)); |
| 500 |
| 501 WMI_DATA_HDR_SET_MSG_TYPE(dtHdr, msgType); |
| 502 WMI_DATA_HDR_SET_DATA_TYPE(dtHdr, data_type); |
| 503 |
| 504 if (bMoreData) { |
| 505 WMI_DATA_HDR_SET_MORE_BIT(dtHdr); |
| 506 } |
| 507 |
| 508 WMI_DATA_HDR_SET_META(dtHdr, metaVersion); |
| 509 //dtHdr->rssi = 0; |
| 510 |
| 511 return (A_OK); |
| 512 } |
| 513 |
| 514 |
| 515 A_UINT8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 la
yer2Priority, A_BOOL wmmEnabled) |
| 516 { |
| 517 A_UINT8 *datap; |
| 518 A_UINT8 trafficClass = WMM_AC_BE; |
| 519 A_UINT16 ipType = IP_ETHERTYPE; |
| 520 WMI_DATA_HDR *dtHdr; |
| 521 A_BOOL streamExists = FALSE; |
| 522 A_UINT8 userPriority; |
| 523 A_UINT32 hdrsize, metasize; |
| 524 ATH_LLC_SNAP_HDR *llcHdr; |
| 525 |
| 526 WMI_CREATE_PSTREAM_CMD cmd; |
| 527 |
| 528 A_ASSERT(osbuf != NULL); |
| 529 |
| 530 // |
| 531 // Initialize header size |
| 532 // |
| 533 hdrsize = 0; |
| 534 |
| 535 datap = A_NETBUF_DATA(osbuf); |
| 536 dtHdr = (WMI_DATA_HDR *)datap; |
| 537 metasize = (WMI_DATA_HDR_GET_META(dtHdr))? WMI_MAX_TX_META_SZ : 0; |
| 538 |
| 539 if (!wmmEnabled) |
| 540 { |
| 541 /* If WMM is disabled all traffic goes as BE traffic */ |
| 542 userPriority = 0; |
| 543 } |
| 544 else |
| 545 { |
| 546 if (processDot11Hdr) |
| 547 { |
| 548 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(A_UIN
T32)); |
| 549 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) + metasi
ze + |
| 550 hdrsize); |
| 551 |
| 552 |
| 553 } |
| 554 else |
| 555 { |
| 556 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) + metasiz
e + |
| 557 sizeof(ATH_MAC_HDR)); |
| 558 } |
| 559 |
| 560 if (llcHdr->etherType == A_CPU2BE16(ipType)) |
| 561 { |
| 562 /* Extract the endpoint info from the TOS field in the IP header */ |
| 563 |
| 564 userPriority = wmi_determine_userPriority (((A_UINT8 *)llcHdr) + siz
eof(ATH_LLC_SNAP_HDR),layer2Priority); |
| 565 } |
| 566 else |
| 567 { |
| 568 userPriority = layer2Priority & 0x7; |
| 569 } |
| 570 } |
| 571 |
| 572 trafficClass = convert_userPriority_to_trafficClass(userPriority); |
| 573 |
| 574 WMI_DATA_HDR_SET_UP(dtHdr, userPriority); |
| 575 //dtHdr->info |= (userPriority & WMI_DATA_HDR_UP_MASK) << WMI_DATA_HDR_UP_SH
IFT; /* lower 3-bits are 802.1d priority */ |
| 576 |
| 577 LOCK_WMI(wmip); |
| 578 streamExists = wmip->wmi_fatPipeExists; |
| 579 UNLOCK_WMI(wmip); |
| 580 |
| 581 if (!(streamExists & (1 << trafficClass))) |
| 582 { |
| 583 |
| 584 A_MEMZERO(&cmd, sizeof(cmd)); |
| 585 cmd.trafficClass = trafficClass; |
| 586 cmd.userPriority = userPriority; |
| 587 cmd.inactivityInt = WMI_IMPLICIT_PSTREAM_INACTIVITY_INT; |
| 588 /* Implicit streams are created with TSID 0xFF */ |
| 589 |
| 590 cmd.tsid = WMI_IMPLICIT_PSTREAM; |
| 591 wmi_create_pstream_cmd(wmip, &cmd); |
| 592 } |
| 593 |
| 594 return trafficClass; |
| 595 } |
| 596 |
| 597 A_STATUS |
| 598 wmi_dot11_hdr_add (struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode) |
| 599 { |
| 600 A_UINT8 *datap; |
| 601 A_UINT16 typeorlen; |
| 602 ATH_MAC_HDR macHdr; |
| 603 ATH_LLC_SNAP_HDR *llcHdr; |
| 604 struct ieee80211_frame *wh; |
| 605 A_UINT32 hdrsize; |
| 606 |
| 607 A_ASSERT(osbuf != NULL); |
| 608 |
| 609 if (A_NETBUF_HEADROOM(osbuf) < |
| 610 (sizeof(struct ieee80211_qosframe) + sizeof(ATH_LLC_SNAP_HDR) + sizeof(
WMI_DATA_HDR))) |
| 611 { |
| 612 return A_NO_MEMORY; |
| 613 } |
| 614 |
| 615 datap = A_NETBUF_DATA(osbuf); |
| 616 |
| 617 typeorlen = *(A_UINT16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN); |
| 618 |
| 619 if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) { |
| 620 /* |
| 621 * packet is already in 802.3 format - return success |
| 622 */ |
| 623 A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG)); |
| 624 goto AddDot11Hdr; |
| 625 } |
| 626 |
| 627 /* |
| 628 * Save mac fields and length to be inserted later |
| 629 */ |
| 630 A_MEMCPY(macHdr.dstMac, datap, ATH_MAC_LEN); |
| 631 A_MEMCPY(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN); |
| 632 macHdr.typeOrLen = A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) + |
| 633 sizeof(ATH_LLC_SNAP_HDR)); |
| 634 |
| 635 // Remove the Ethernet hdr |
| 636 A_NETBUF_PULL(osbuf, sizeof(ATH_MAC_HDR)); |
| 637 /* |
| 638 * Make room for LLC+SNAP headers |
| 639 */ |
| 640 if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != A_OK) { |
| 641 return A_NO_MEMORY; |
| 642 } |
| 643 datap = A_NETBUF_DATA(osbuf); |
| 644 |
| 645 llcHdr = (ATH_LLC_SNAP_HDR *)(datap); |
| 646 llcHdr->dsap = 0xAA; |
| 647 llcHdr->ssap = 0xAA; |
| 648 llcHdr->cntl = 0x03; |
| 649 llcHdr->orgCode[0] = 0x0; |
| 650 llcHdr->orgCode[1] = 0x0; |
| 651 llcHdr->orgCode[2] = 0x0; |
| 652 llcHdr->etherType = typeorlen; |
| 653 |
| 654 AddDot11Hdr: |
| 655 /* Make room for 802.11 hdr */ |
| 656 if (wmip->wmi_is_wmm_enabled) |
| 657 { |
| 658 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(A_UINT32))
; |
| 659 if (A_NETBUF_PUSH(osbuf, hdrsize) != A_OK) |
| 660 { |
| 661 return A_NO_MEMORY; |
| 662 } |
| 663 wh = (struct ieee80211_frame *) A_NETBUF_DATA(osbuf); |
| 664 wh->i_fc[0] = IEEE80211_FC0_SUBTYPE_QOS; |
| 665 } |
| 666 else |
| 667 { |
| 668 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_frame),sizeof(A_UINT32)); |
| 669 if (A_NETBUF_PUSH(osbuf, hdrsize) != A_OK) |
| 670 { |
| 671 return A_NO_MEMORY; |
| 672 } |
| 673 wh = (struct ieee80211_frame *) A_NETBUF_DATA(osbuf); |
| 674 wh->i_fc[0] = IEEE80211_FC0_SUBTYPE_DATA; |
| 675 } |
| 676 /* Setup the SA & DA */ |
| 677 IEEE80211_ADDR_COPY(wh->i_addr2, macHdr.srcMac); |
| 678 |
| 679 if (mode == INFRA_NETWORK) { |
| 680 IEEE80211_ADDR_COPY(wh->i_addr3, macHdr.dstMac); |
| 681 } |
| 682 else if (mode == ADHOC_NETWORK) { |
| 683 IEEE80211_ADDR_COPY(wh->i_addr1, macHdr.dstMac); |
| 684 } |
| 685 |
| 686 return (A_OK); |
| 687 } |
| 688 |
| 689 A_STATUS |
| 690 wmi_dot11_hdr_remove(struct wmi_t *wmip, void *osbuf) |
| 691 { |
| 692 A_UINT8 *datap; |
| 693 struct ieee80211_frame *pwh,wh; |
| 694 A_UINT8 type,subtype; |
| 695 ATH_LLC_SNAP_HDR *llcHdr; |
| 696 ATH_MAC_HDR macHdr; |
| 697 A_UINT32 hdrsize; |
| 698 |
| 699 A_ASSERT(osbuf != NULL); |
| 700 datap = A_NETBUF_DATA(osbuf); |
| 701 |
| 702 pwh = (struct ieee80211_frame *)datap; |
| 703 type = pwh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; |
| 704 subtype = pwh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; |
| 705 |
| 706 A_MEMCPY((A_UINT8 *)&wh, datap, sizeof(struct ieee80211_frame)); |
| 707 |
| 708 /* strip off the 802.11 hdr*/ |
| 709 if (subtype == IEEE80211_FC0_SUBTYPE_QOS) { |
| 710 hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(A_UINT32))
; |
| 711 A_NETBUF_PULL(osbuf, hdrsize); |
| 712 } else if (subtype == IEEE80211_FC0_SUBTYPE_DATA) { |
| 713 A_NETBUF_PULL(osbuf, sizeof(struct ieee80211_frame)); |
| 714 } |
| 715 |
| 716 datap = A_NETBUF_DATA(osbuf); |
| 717 llcHdr = (ATH_LLC_SNAP_HDR *)(datap); |
| 718 |
| 719 macHdr.typeOrLen = llcHdr->etherType; |
| 720 |
| 721 switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) { |
| 722 case IEEE80211_FC1_DIR_NODS: |
| 723 IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr1); |
| 724 IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr2); |
| 725 break; |
| 726 case IEEE80211_FC1_DIR_TODS: |
| 727 IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr3); |
| 728 IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr2); |
| 729 break; |
| 730 case IEEE80211_FC1_DIR_FROMDS: |
| 731 IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr1); |
| 732 IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr3); |
| 733 break; |
| 734 case IEEE80211_FC1_DIR_DSTODS: |
| 735 break; |
| 736 } |
| 737 |
| 738 // Remove the LLC Hdr. |
| 739 A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR)); |
| 740 |
| 741 // Insert the ATH MAC hdr. |
| 742 |
| 743 A_NETBUF_PUSH(osbuf, sizeof(ATH_MAC_HDR)); |
| 744 datap = A_NETBUF_DATA(osbuf); |
| 745 |
| 746 A_MEMCPY (datap, &macHdr, sizeof(ATH_MAC_HDR)); |
| 747 |
| 748 return A_OK; |
| 749 } |
| 750 |
| 751 /* |
| 752 * performs 802.3 to DIX encapsulation for received packets. |
| 753 * Assumes the entire 802.3 header is contigous. |
| 754 */ |
| 755 A_STATUS |
| 756 wmi_dot3_2_dix(void *osbuf) |
| 757 { |
| 758 A_UINT8 *datap; |
| 759 ATH_MAC_HDR macHdr; |
| 760 ATH_LLC_SNAP_HDR *llcHdr; |
| 761 |
| 762 A_ASSERT(osbuf != NULL); |
| 763 datap = A_NETBUF_DATA(osbuf); |
| 764 |
| 765 A_MEMCPY(&macHdr, datap, sizeof(ATH_MAC_HDR)); |
| 766 llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR)); |
| 767 macHdr.typeOrLen = llcHdr->etherType; |
| 768 |
| 769 if (A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != A_OK) { |
| 770 return A_NO_MEMORY; |
| 771 } |
| 772 |
| 773 datap = A_NETBUF_DATA(osbuf); |
| 774 |
| 775 A_MEMCPY(datap, &macHdr, sizeof (ATH_MAC_HDR)); |
| 776 |
| 777 return (A_OK); |
| 778 } |
| 779 |
| 780 /* |
| 781 * Removes a WMI data header |
| 782 */ |
| 783 A_STATUS |
| 784 wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf) |
| 785 { |
| 786 A_ASSERT(osbuf != NULL); |
| 787 |
| 788 return (A_NETBUF_PULL(osbuf, sizeof(WMI_DATA_HDR))); |
| 789 } |
| 790 |
| 791 void |
| 792 wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg) |
| 793 { |
| 794 wlan_iterate_nodes(&wmip->wmi_scan_table, f, arg); |
| 795 } |
| 796 |
| 797 /* |
| 798 * WMI Extended Event received from Target. |
| 799 */ |
| 800 A_STATUS |
| 801 wmi_control_rx_xtnd(struct wmi_t *wmip, void *osbuf) |
| 802 { |
| 803 WMIX_CMD_HDR *cmd; |
| 804 A_UINT16 id; |
| 805 A_UINT8 *datap; |
| 806 A_UINT32 len; |
| 807 A_STATUS status = A_OK; |
| 808 |
| 809 if (A_NETBUF_LEN(osbuf) < sizeof(WMIX_CMD_HDR)) { |
| 810 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG)); |
| 811 wmip->wmi_stats.cmd_len_err++; |
| 812 A_NETBUF_FREE(osbuf); |
| 813 return A_ERROR; |
| 814 } |
| 815 |
| 816 cmd = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf); |
| 817 id = cmd->commandId; |
| 818 |
| 819 if (A_NETBUF_PULL(osbuf, sizeof(WMIX_CMD_HDR)) != A_OK) { |
| 820 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG)); |
| 821 wmip->wmi_stats.cmd_len_err++; |
| 822 A_NETBUF_FREE(osbuf); |
| 823 return A_ERROR; |
| 824 } |
| 825 |
| 826 datap = A_NETBUF_DATA(osbuf); |
| 827 len = A_NETBUF_LEN(osbuf); |
| 828 |
| 829 switch (id) { |
| 830 case (WMIX_DSETOPENREQ_EVENTID): |
| 831 status = wmi_dset_open_req_rx(wmip, datap, len); |
| 832 break; |
| 833 #ifdef CONFIG_HOST_DSET_SUPPORT |
| 834 case (WMIX_DSETCLOSE_EVENTID): |
| 835 status = wmi_dset_close_rx(wmip, datap, len); |
| 836 break; |
| 837 case (WMIX_DSETDATAREQ_EVENTID): |
| 838 status = wmi_dset_data_req_rx(wmip, datap, len); |
| 839 break; |
| 840 #endif /* CONFIG_HOST_DSET_SUPPORT */ |
| 841 #ifdef CONFIG_HOST_GPIO_SUPPORT |
| 842 case (WMIX_GPIO_INTR_EVENTID): |
| 843 wmi_gpio_intr_rx(wmip, datap, len); |
| 844 break; |
| 845 case (WMIX_GPIO_DATA_EVENTID): |
| 846 wmi_gpio_data_rx(wmip, datap, len); |
| 847 break; |
| 848 case (WMIX_GPIO_ACK_EVENTID): |
| 849 wmi_gpio_ack_rx(wmip, datap, len); |
| 850 break; |
| 851 #endif /* CONFIG_HOST_GPIO_SUPPORT */ |
| 852 case (WMIX_HB_CHALLENGE_RESP_EVENTID): |
| 853 wmi_hbChallengeResp_rx(wmip, datap, len); |
| 854 break; |
| 855 case (WMIX_DBGLOG_EVENTID): |
| 856 wmi_dbglog_event_rx(wmip, datap, len); |
| 857 break; |
| 858 #if defined(CONFIG_TARGET_PROFILE_SUPPORT) |
| 859 case (WMIX_PROF_COUNT_EVENTID): |
| 860 wmi_prof_count_rx(wmip, datap, len); |
| 861 break; |
| 862 #endif /* CONFIG_TARGET_PROFILE_SUPPORT */ |
| 863 default: |
| 864 A_DPRINTF(DBG_WMI|DBG_ERROR, |
| 865 (DBGFMT "Unknown id 0x%x\n", DBGARG, id)); |
| 866 wmip->wmi_stats.cmd_id_err++; |
| 867 status = A_ERROR; |
| 868 break; |
| 869 } |
| 870 |
| 871 return status; |
| 872 } |
| 873 |
| 874 /* |
| 875 * Control Path |
| 876 */ |
| 877 A_UINT32 cmdRecvNum; |
| 878 |
| 879 A_STATUS |
| 880 wmi_control_rx(struct wmi_t *wmip, void *osbuf) |
| 881 { |
| 882 WMI_CMD_HDR *cmd; |
| 883 A_UINT16 id; |
| 884 A_UINT8 *datap; |
| 885 A_UINT32 len, i, loggingReq; |
| 886 A_STATUS status = A_OK; |
| 887 |
| 888 A_ASSERT(osbuf != NULL); |
| 889 if (A_NETBUF_LEN(osbuf) < sizeof(WMI_CMD_HDR)) { |
| 890 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG)); |
| 891 wmip->wmi_stats.cmd_len_err++; |
| 892 A_NETBUF_FREE(osbuf); |
| 893 return A_ERROR; |
| 894 } |
| 895 |
| 896 cmd = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf); |
| 897 id = cmd->commandId; |
| 898 |
| 899 if (A_NETBUF_PULL(osbuf, sizeof(WMI_CMD_HDR)) != A_OK) { |
| 900 A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG)); |
| 901 wmip->wmi_stats.cmd_len_err++; |
| 902 A_NETBUF_FREE(osbuf); |
| 903 return A_ERROR; |
| 904 } |
| 905 |
| 906 datap = A_NETBUF_DATA(osbuf); |
| 907 len = A_NETBUF_LEN(osbuf); |
| 908 |
| 909 loggingReq = 0; |
| 910 |
| 911 ar6000_get_driver_cfg(wmip->wmi_devt, |
| 912 AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS, |
| 913 &loggingReq); |
| 914 |
| 915 if(loggingReq) { |
| 916 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI %d \n",id)); |
| 917 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI recv, MsgNo %d : ", cmdRecvNum)); |
| 918 for(i = 0; i < len; i++) |
| 919 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("%x ", datap[i])); |
| 920 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("\n")); |
| 921 } |
| 922 |
| 923 LOCK_WMI(wmip); |
| 924 cmdRecvNum++; |
| 925 UNLOCK_WMI(wmip); |
| 926 |
| 927 switch (id) { |
| 928 case (WMI_GET_BITRATE_CMDID): |
| 929 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_BITRATE_CMDID\n", DBGARG)); |
| 930 status = wmi_bitrate_reply_rx(wmip, datap, len); |
| 931 break; |
| 932 case (WMI_GET_CHANNEL_LIST_CMDID): |
| 933 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_CHANNEL_LIST_CMDID\n", DBGARG)); |
| 934 status = wmi_channelList_reply_rx(wmip, datap, len); |
| 935 break; |
| 936 case (WMI_GET_TX_PWR_CMDID): |
| 937 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_TX_PWR_CMDID\n", DBGARG)); |
| 938 status = wmi_txPwr_reply_rx(wmip, datap, len); |
| 939 break; |
| 940 case (WMI_READY_EVENTID): |
| 941 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_READY_EVENTID\n", DBGARG)); |
| 942 status = wmi_ready_event_rx(wmip, datap, len); |
| 943 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); |
| 944 A_WMI_DBGLOG_INIT_DONE(wmip->wmi_devt); |
| 945 break; |
| 946 case (WMI_CONNECT_EVENTID): |
| 947 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CONNECT_EVENTID\n", DBGARG)); |
| 948 status = wmi_connect_event_rx(wmip, datap, len); |
| 949 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); |
| 950 break; |
| 951 case (WMI_DISCONNECT_EVENTID): |
| 952 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_DISCONNECT_EVENTID\n", DBGARG)); |
| 953 status = wmi_disconnect_event_rx(wmip, datap, len); |
| 954 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); |
| 955 break; |
| 956 case (WMI_PEER_NODE_EVENTID): |
| 957 A_DPRINTF (DBG_WMI, (DBGFMT "WMI_PEER_NODE_EVENTID\n", DBGARG)); |
| 958 status = wmi_peer_node_event_rx(wmip, datap, len); |
| 959 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); |
| 960 break; |
| 961 case (WMI_TKIP_MICERR_EVENTID): |
| 962 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TKIP_MICERR_EVENTID\n", DBGARG)); |
| 963 status = wmi_tkip_micerr_event_rx(wmip, datap, len); |
| 964 break; |
| 965 case (WMI_BSSINFO_EVENTID): |
| 966 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BSSINFO_EVENTID\n", DBGARG)); |
| 967 { |
| 968 /* |
| 969 * convert WMI_BSS_INFO_HDR2 to WMI_BSS_INFO_HDR |
| 970 * Take a local copy of the WMI_BSS_INFO_HDR2 from the wmi buffer |
| 971 * and reconstruct the WMI_BSS_INFO_HDR in its place |
| 972 */ |
| 973 WMI_BSS_INFO_HDR2 bih2; |
| 974 WMI_BSS_INFO_HDR *bih; |
| 975 A_MEMCPY(&bih2, datap, sizeof(WMI_BSS_INFO_HDR2)); |
| 976 |
| 977 A_NETBUF_PUSH(osbuf, 4); |
| 978 datap = A_NETBUF_DATA(osbuf); |
| 979 len = A_NETBUF_LEN(osbuf); |
| 980 bih = (WMI_BSS_INFO_HDR *)datap; |
| 981 |
| 982 bih->channel = bih2.channel; |
| 983 bih->frameType = bih2.frameType; |
| 984 bih->snr = bih2.snr; |
| 985 bih->rssi = bih2.snr - 95; |
| 986 bih->ieMask = bih2.ieMask; |
| 987 A_MEMCPY(bih->bssid, bih2.bssid, ATH_MAC_LEN); |
| 988 |
| 989 status = wmi_bssInfo_event_rx(wmip, datap, len); |
| 990 A_WMI_SEND_GENERIC_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); |
| 991 } |
| 992 break; |
| 993 case (WMI_REGDOMAIN_EVENTID): |
| 994 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REGDOMAIN_EVENTID\n", DBGARG)); |
| 995 status = wmi_regDomain_event_rx(wmip, datap, len); |
| 996 break; |
| 997 case (WMI_PSTREAM_TIMEOUT_EVENTID): |
| 998 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_PSTREAM_TIMEOUT_EVENTID\n", DBGARG)); |
| 999 status = wmi_pstream_timeout_event_rx(wmip, datap, len); |
| 1000 /* pstreams are fatpipe abstractions that get implicitly created. |
| 1001 * User apps only deal with thinstreams. creation of a thinstream |
| 1002 * by the user or data traffic flow in an AC triggers implicit |
| 1003 * pstream creation. Do we need to send this event to App..? |
| 1004 * no harm in sending it. |
| 1005 */ |
| 1006 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); |
| 1007 break; |
| 1008 case (WMI_NEIGHBOR_REPORT_EVENTID): |
| 1009 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_NEIGHBOR_REPORT_EVENTID\n", DBGARG)); |
| 1010 status = wmi_neighborReport_event_rx(wmip, datap, len); |
| 1011 break; |
| 1012 case (WMI_SCAN_COMPLETE_EVENTID): |
| 1013 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SCAN_COMPLETE_EVENTID\n", DBGARG)); |
| 1014 status = wmi_scanComplete_rx(wmip, datap, len); |
| 1015 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); |
| 1016 break; |
| 1017 case (WMI_CMDERROR_EVENTID): |
| 1018 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CMDERROR_EVENTID\n", DBGARG)); |
| 1019 status = wmi_errorEvent_rx(wmip, datap, len); |
| 1020 break; |
| 1021 case (WMI_REPORT_STATISTICS_EVENTID): |
| 1022 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_STATISTICS_EVENTID\n", DBGARG)); |
| 1023 status = wmi_statsEvent_rx(wmip, datap, len); |
| 1024 break; |
| 1025 case (WMI_RSSI_THRESHOLD_EVENTID): |
| 1026 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_RSSI_THRESHOLD_EVENTID\n", DBGARG)); |
| 1027 status = wmi_rssiThresholdEvent_rx(wmip, datap, len); |
| 1028 break; |
| 1029 case (WMI_ERROR_REPORT_EVENTID): |
| 1030 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_ERROR_REPORT_EVENTID\n", DBGARG)); |
| 1031 status = wmi_reportErrorEvent_rx(wmip, datap, len); |
| 1032 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); |
| 1033 break; |
| 1034 case (WMI_OPT_RX_FRAME_EVENTID): |
| 1035 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_OPT_RX_FRAME_EVENTID\n", DBGARG)); |
| 1036 status = wmi_opt_frame_event_rx(wmip, datap, len); |
| 1037 break; |
| 1038 case (WMI_REPORT_ROAM_TBL_EVENTID): |
| 1039 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_ROAM_TBL_EVENTID\n", DBGARG)); |
| 1040 status = wmi_roam_tbl_event_rx(wmip, datap, len); |
| 1041 break; |
| 1042 case (WMI_EXTENSION_EVENTID): |
| 1043 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_EXTENSION_EVENTID\n", DBGARG)); |
| 1044 status = wmi_control_rx_xtnd(wmip, osbuf); |
| 1045 break; |
| 1046 case (WMI_CAC_EVENTID): |
| 1047 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CAC_EVENTID\n", DBGARG)); |
| 1048 status = wmi_cac_event_rx(wmip, datap, len); |
| 1049 break; |
| 1050 case (WMI_CHANNEL_CHANGE_EVENTID): |
| 1051 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CHANNEL_CHANGE_EVENTID\n", DBGARG)); |
| 1052 status = wmi_channel_change_event_rx(wmip, datap, len); |
| 1053 break; |
| 1054 case (WMI_REPORT_ROAM_DATA_EVENTID): |
| 1055 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_ROAM_DATA_EVENTID\n", DBGARG)); |
| 1056 status = wmi_roam_data_event_rx(wmip, datap, len); |
| 1057 break; |
| 1058 #ifdef CONFIG_HOST_TCMD_SUPPORT |
| 1059 case (WMI_TEST_EVENTID): |
| 1060 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TEST_EVENTID\n", DBGARG)); |
| 1061 status = wmi_tcmd_test_report_rx(wmip, datap, len); |
| 1062 break; |
| 1063 #endif |
| 1064 case (WMI_GET_FIXRATES_CMDID): |
| 1065 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_FIXRATES_CMDID\n", DBGARG)); |
| 1066 status = wmi_ratemask_reply_rx(wmip, datap, len); |
| 1067 break; |
| 1068 case (WMI_TX_RETRY_ERR_EVENTID): |
| 1069 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TX_RETRY_ERR_EVENTID\n", DBGARG)); |
| 1070 status = wmi_txRetryErrEvent_rx(wmip, datap, len); |
| 1071 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); |
| 1072 break; |
| 1073 case (WMI_SNR_THRESHOLD_EVENTID): |
| 1074 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SNR_THRESHOLD_EVENTID\n", DBGARG)); |
| 1075 status = wmi_snrThresholdEvent_rx(wmip, datap, len); |
| 1076 break; |
| 1077 case (WMI_LQ_THRESHOLD_EVENTID): |
| 1078 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_LQ_THRESHOLD_EVENTID\n", DBGARG)); |
| 1079 status = wmi_lqThresholdEvent_rx(wmip, datap, len); |
| 1080 A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); |
| 1081 break; |
| 1082 case (WMI_APLIST_EVENTID): |
| 1083 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Received APLIST Event\n")); |
| 1084 status = wmi_aplistEvent_rx(wmip, datap, len); |
| 1085 break; |
| 1086 case (WMI_GET_KEEPALIVE_CMDID): |
| 1087 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_KEEPALIVE_CMDID\n", DBGARG)); |
| 1088 status = wmi_keepalive_reply_rx(wmip, datap, len); |
| 1089 break; |
| 1090 case (WMI_GET_WOW_LIST_EVENTID): |
| 1091 status = wmi_get_wow_list_event_rx(wmip, datap, len); |
| 1092 break; |
| 1093 case (WMI_GET_PMKID_LIST_EVENTID): |
| 1094 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_PMKID_LIST Event\n", DBGARG)); |
| 1095 status = wmi_get_pmkid_list_event_rx(wmip, datap, len); |
| 1096 break; |
| 1097 case (WMI_PSPOLL_EVENTID): |
| 1098 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_PSPOLL_EVENT\n", DBGARG)); |
| 1099 status = wmi_pspoll_event_rx(wmip, datap, len); |
| 1100 break; |
| 1101 case (WMI_DTIMEXPIRY_EVENTID): |
| 1102 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_DTIMEXPIRY_EVENT\n", DBGARG)); |
| 1103 status = wmi_dtimexpiry_event_rx(wmip, datap, len); |
| 1104 break; |
| 1105 case (WMI_SET_PARAMS_REPLY_EVENTID): |
| 1106 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SET_PARAMS_REPLY Event\n", DBGARG)); |
| 1107 status = wmi_set_params_event_rx(wmip, datap, len); |
| 1108 break; |
| 1109 #ifdef ATH_AR6K_11N_SUPPORT |
| 1110 case (WMI_ADDBA_REQ_EVENTID): |
| 1111 status = wmi_addba_req_event_rx(wmip, datap, len); |
| 1112 break; |
| 1113 case (WMI_ADDBA_RESP_EVENTID): |
| 1114 status = wmi_addba_resp_event_rx(wmip, datap, len); |
| 1115 break; |
| 1116 case (WMI_DELBA_REQ_EVENTID): |
| 1117 status = wmi_delba_req_event_rx(wmip, datap, len); |
| 1118 break; |
| 1119 case (WMI_REPORT_BTCOEX_CONFIG_EVENTID): |
| 1120 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BTCOEX_CONFIG_EVENTID", DBGARG)); |
| 1121 status = wmi_btcoex_config_event_rx(wmip, datap, len); |
| 1122 break; |
| 1123 case (WMI_REPORT_BTCOEX_STATS_EVENTID): |
| 1124 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BTCOEX_STATS_EVENTID", DBGARG)); |
| 1125 status = wmi_btcoex_stats_event_rx(wmip, datap, len); |
| 1126 break; |
| 1127 #endif |
| 1128 case (WMI_TX_COMPLETE_EVENTID): |
| 1129 { |
| 1130 int index; |
| 1131 TX_COMPLETE_MSG_V1 *pV1; |
| 1132 WMI_TX_COMPLETE_EVENT *pEv = (WMI_TX_COMPLETE_EVENT *)datap; |
| 1133 A_PRINTF("comp: %d %d %d\n", pEv->numMessages, pEv->msgLen, pEv->msg
Type); |
| 1134 |
| 1135 for(index = 0 ; index < pEv->numMessages ; index++) { |
| 1136 pV1 = (TX_COMPLETE_MSG_V1 *)(datap + sizeof(WMI_TX_COMPLETE_EVEN
T) + index*sizeof(TX_COMPLETE_MSG_V1)); |
| 1137 A_PRINTF("msg: %d %d %d %d\n", pV1->status, pV1->pktID, pV1->rat
eIdx, pV1->ackFailures); |
| 1138 } |
| 1139 } |
| 1140 break; |
| 1141 case (WMI_HCI_EVENT_EVENTID): |
| 1142 status = wmi_hci_event_rx(wmip, datap, len); |
| 1143 break; |
| 1144 #ifdef WAPI_ENABLE |
| 1145 case (WMI_WAPI_REKEY_EVENTID): |
| 1146 A_DPRINTF(DBG_WMI, (DBGFMT "WMI_WAPI_REKEY_EVENTID", DBGARG)); |
| 1147 status = wmi_wapi_rekey_event_rx(wmip, datap, len); |
| 1148 break; |
| 1149 #endif |
| 1150 default: |
| 1151 A_DPRINTF(DBG_WMI|DBG_ERROR, |
| 1152 (DBGFMT "Unknown id 0x%x\n", DBGARG, id)); |
| 1153 wmip->wmi_stats.cmd_id_err++; |
| 1154 status = A_ERROR; |
| 1155 break; |
| 1156 } |
| 1157 |
| 1158 A_NETBUF_FREE(osbuf); |
| 1159 |
| 1160 return status; |
| 1161 } |
| 1162 |
| 1163 /* Send a "simple" wmi command -- one with no arguments */ |
| 1164 static A_STATUS |
| 1165 wmi_simple_cmd(struct wmi_t *wmip, WMI_COMMAND_ID cmdid) |
| 1166 { |
| 1167 void *osbuf; |
| 1168 |
| 1169 osbuf = A_NETBUF_ALLOC(0); |
| 1170 |
| 1171 if (osbuf == NULL) { |
| 1172 return A_NO_MEMORY; |
| 1173 } |
| 1174 |
| 1175 return (wmi_cmd_send(wmip, osbuf, cmdid, NO_SYNC_WMIFLAG)); |
| 1176 } |
| 1177 |
| 1178 /* Send a "simple" extended wmi command -- one with no arguments. |
| 1179 Enabling this command only if GPIO or profiling support is enabled. |
| 1180 This is to suppress warnings on some platforms */ |
| 1181 #if defined(CONFIG_HOST_GPIO_SUPPORT) || defined(CONFIG_TARGET_PROFILE_SUPPORT) |
| 1182 static A_STATUS |
| 1183 wmi_simple_cmd_xtnd(struct wmi_t *wmip, WMIX_COMMAND_ID cmdid) |
| 1184 { |
| 1185 void *osbuf; |
| 1186 |
| 1187 osbuf = A_NETBUF_ALLOC(0); |
| 1188 |
| 1189 if (osbuf == NULL) { |
| 1190 return A_NO_MEMORY; |
| 1191 } |
| 1192 |
| 1193 return (wmi_cmd_send_xtnd(wmip, osbuf, cmdid, NO_SYNC_WMIFLAG)); |
| 1194 } |
| 1195 #endif |
| 1196 |
| 1197 static A_STATUS |
| 1198 wmi_ready_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1199 { |
| 1200 WMI_READY_EVENT *ev = (WMI_READY_EVENT *)datap; |
| 1201 |
| 1202 if (len < sizeof(WMI_READY_EVENT)) { |
| 1203 return A_EINVAL; |
| 1204 } |
| 1205 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 1206 wmip->wmi_ready = TRUE; |
| 1207 A_WMI_READY_EVENT(wmip->wmi_devt, ev->macaddr, ev->phyCapability, |
| 1208 ev->version); |
| 1209 |
| 1210 return A_OK; |
| 1211 } |
| 1212 |
| 1213 #define LE_READ_4(p) \ |
| 1214 ((A_UINT32) \ |
| 1215 ((((A_UINT8 *)(p))[0] ) | (((A_UINT8 *)(p))[1] << 8) | \ |
| 1216 (((A_UINT8 *)(p))[2] << 16) | (((A_UINT8 *)(p))[3] << 24))) |
| 1217 |
| 1218 static int __inline |
| 1219 iswmmoui(const A_UINT8 *frm) |
| 1220 { |
| 1221 return frm[1] > 3 && LE_READ_4(frm+2) == ((WMM_OUI_TYPE<<24)|WMM_OUI); |
| 1222 } |
| 1223 |
| 1224 static int __inline |
| 1225 iswmmparam(const A_UINT8 *frm) |
| 1226 { |
| 1227 return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE; |
| 1228 } |
| 1229 |
| 1230 |
| 1231 static A_STATUS |
| 1232 wmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1233 { |
| 1234 WMI_CONNECT_EVENT *ev; |
| 1235 A_UINT8 *pie,*peie; |
| 1236 |
| 1237 if (len < sizeof(WMI_CONNECT_EVENT)) |
| 1238 { |
| 1239 return A_EINVAL; |
| 1240 } |
| 1241 ev = (WMI_CONNECT_EVENT *)datap; |
| 1242 |
| 1243 A_DPRINTF(DBG_WMI, |
| 1244 (DBGFMT "freq %d bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", |
| 1245 DBGARG, ev->channel, |
| 1246 ev->bssid[0], ev->bssid[1], ev->bssid[2], |
| 1247 ev->bssid[3], ev->bssid[4], ev->bssid[5])); |
| 1248 |
| 1249 A_MEMCPY(wmip->wmi_bssid, ev->bssid, ATH_MAC_LEN); |
| 1250 |
| 1251 /* initialize pointer to start of assoc rsp IEs */ |
| 1252 pie = ev->assocInfo + ev->beaconIeLen + ev->assocReqLen + |
| 1253 sizeof(A_UINT16) + /* capinfo*/ |
| 1254 sizeof(A_UINT16) + /* status Code */ |
| 1255 sizeof(A_UINT16) ; /* associd */ |
| 1256 |
| 1257 /* initialize pointer to end of assoc rsp IEs */ |
| 1258 peie = ev->assocInfo + ev->beaconIeLen + ev->assocReqLen + ev->assocRespLen; |
| 1259 |
| 1260 while (pie < peie) |
| 1261 { |
| 1262 switch (*pie) |
| 1263 { |
| 1264 case IEEE80211_ELEMID_VENDOR: |
| 1265 if (iswmmoui(pie)) |
| 1266 { |
| 1267 if(iswmmparam (pie)) |
| 1268 { |
| 1269 wmip->wmi_is_wmm_enabled = TRUE; |
| 1270 } |
| 1271 } |
| 1272 break; |
| 1273 } |
| 1274 |
| 1275 if (wmip->wmi_is_wmm_enabled) |
| 1276 { |
| 1277 break; |
| 1278 } |
| 1279 pie += pie[1] + 2; |
| 1280 } |
| 1281 |
| 1282 A_WMI_CONNECT_EVENT(wmip->wmi_devt, ev->channel, ev->bssid, |
| 1283 ev->listenInterval, ev->beaconInterval, |
| 1284 (NETWORK_TYPE) ev->networkType, ev->beaconIeLen, |
| 1285 ev->assocReqLen, ev->assocRespLen, |
| 1286 ev->assocInfo); |
| 1287 |
| 1288 return A_OK; |
| 1289 } |
| 1290 |
| 1291 static A_STATUS |
| 1292 wmi_regDomain_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1293 { |
| 1294 WMI_REG_DOMAIN_EVENT *ev; |
| 1295 |
| 1296 if (len < sizeof(*ev)) { |
| 1297 return A_EINVAL; |
| 1298 } |
| 1299 ev = (WMI_REG_DOMAIN_EVENT *)datap; |
| 1300 |
| 1301 A_WMI_REGDOMAIN_EVENT(wmip->wmi_devt, ev->regDomain); |
| 1302 |
| 1303 return A_OK; |
| 1304 } |
| 1305 |
| 1306 static A_STATUS |
| 1307 wmi_neighborReport_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1308 { |
| 1309 WMI_NEIGHBOR_REPORT_EVENT *ev; |
| 1310 int numAps; |
| 1311 |
| 1312 if (len < sizeof(*ev)) { |
| 1313 return A_EINVAL; |
| 1314 } |
| 1315 ev = (WMI_NEIGHBOR_REPORT_EVENT *)datap; |
| 1316 numAps = ev->numberOfAps; |
| 1317 |
| 1318 if (len < (int)(sizeof(*ev) + ((numAps - 1) * sizeof(WMI_NEIGHBOR_INFO)))) { |
| 1319 return A_EINVAL; |
| 1320 } |
| 1321 |
| 1322 A_WMI_NEIGHBORREPORT_EVENT(wmip->wmi_devt, numAps, ev->neighbor); |
| 1323 |
| 1324 return A_OK; |
| 1325 } |
| 1326 |
| 1327 static A_STATUS |
| 1328 wmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1329 { |
| 1330 WMI_DISCONNECT_EVENT *ev; |
| 1331 |
| 1332 if (len < sizeof(WMI_DISCONNECT_EVENT)) { |
| 1333 return A_EINVAL; |
| 1334 } |
| 1335 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 1336 |
| 1337 ev = (WMI_DISCONNECT_EVENT *)datap; |
| 1338 |
| 1339 A_MEMZERO(wmip->wmi_bssid, sizeof(wmip->wmi_bssid)); |
| 1340 |
| 1341 wmip->wmi_is_wmm_enabled = FALSE; |
| 1342 wmip->wmi_pair_crypto_type = NONE_CRYPT; |
| 1343 wmip->wmi_grp_crypto_type = NONE_CRYPT; |
| 1344 |
| 1345 A_WMI_DISCONNECT_EVENT(wmip->wmi_devt, ev->disconnectReason, ev->bssid, |
| 1346 ev->assocRespLen, ev->assocInfo, ev->protocolReasonS
tatus); |
| 1347 |
| 1348 return A_OK; |
| 1349 } |
| 1350 |
| 1351 static A_STATUS |
| 1352 wmi_peer_node_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1353 { |
| 1354 WMI_PEER_NODE_EVENT *ev; |
| 1355 |
| 1356 if (len < sizeof(WMI_PEER_NODE_EVENT)) { |
| 1357 return A_EINVAL; |
| 1358 } |
| 1359 ev = (WMI_PEER_NODE_EVENT *)datap; |
| 1360 if (ev->eventCode == PEER_NODE_JOIN_EVENT) { |
| 1361 A_DPRINTF (DBG_WMI, (DBGFMT "Joined node with Macaddr: ", DBGARG)); |
| 1362 } else if(ev->eventCode == PEER_NODE_LEAVE_EVENT) { |
| 1363 A_DPRINTF (DBG_WMI, (DBGFMT "left node with Macaddr: ", DBGARG)); |
| 1364 } |
| 1365 |
| 1366 A_WMI_PEER_EVENT (wmip->wmi_devt, ev->eventCode, ev->peerMacAddr); |
| 1367 |
| 1368 return A_OK; |
| 1369 } |
| 1370 |
| 1371 static A_STATUS |
| 1372 wmi_tkip_micerr_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1373 { |
| 1374 WMI_TKIP_MICERR_EVENT *ev; |
| 1375 |
| 1376 if (len < sizeof(*ev)) { |
| 1377 return A_EINVAL; |
| 1378 } |
| 1379 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 1380 |
| 1381 ev = (WMI_TKIP_MICERR_EVENT *)datap; |
| 1382 A_WMI_TKIP_MICERR_EVENT(wmip->wmi_devt, ev->keyid, ev->ismcast); |
| 1383 |
| 1384 return A_OK; |
| 1385 } |
| 1386 |
| 1387 static A_STATUS |
| 1388 wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1389 { |
| 1390 bss_t *bss = NULL; |
| 1391 WMI_BSS_INFO_HDR *bih; |
| 1392 A_UINT8 *buf; |
| 1393 A_UINT32 nodeCachingAllowed = 1; |
| 1394 A_UCHAR cached_ssid_len = 0; |
| 1395 A_UCHAR cached_ssid_buf[IEEE80211_NWID_LEN] = {0}; |
| 1396 A_UINT8 beacon_ssid_len = 0; |
| 1397 |
| 1398 if (len <= sizeof(WMI_BSS_INFO_HDR)) { |
| 1399 return A_EINVAL; |
| 1400 } |
| 1401 |
| 1402 bih = (WMI_BSS_INFO_HDR *)datap; |
| 1403 bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid); |
| 1404 |
| 1405 if (bih->rssi > 0) { |
| 1406 if (NULL == bss) |
| 1407 return A_OK; //no node found in the table, just drop the node with
incorrect RSSI |
| 1408 else |
| 1409 bih->rssi = bss->ni_rssi; //Adjust RSSI in datap in case it is used
in A_WMI_BSSINFO_EVENT_RX |
| 1410 } |
| 1411 |
| 1412 A_WMI_BSSINFO_EVENT_RX(wmip->wmi_devt, datap, len); |
| 1413 /* What is driver config for wlan node caching? */ |
| 1414 if(ar6000_get_driver_cfg(wmip->wmi_devt, |
| 1415 AR6000_DRIVER_CFG_GET_WLANNODECACHING, |
| 1416 &nodeCachingAllowed) != A_OK) { |
| 1417 return A_EINVAL; |
| 1418 } |
| 1419 |
| 1420 if(!nodeCachingAllowed) { |
| 1421 return A_OK; |
| 1422 } |
| 1423 |
| 1424 buf = datap + sizeof(WMI_BSS_INFO_HDR); |
| 1425 len -= sizeof(WMI_BSS_INFO_HDR); |
| 1426 |
| 1427 A_DPRINTF(DBG_WMI2, (DBGFMT "bssInfo event - ch %u, rssi %02x, " |
| 1428 "bssid \"%02x:%02x:%02x:%02x:%02x:%02x\"\n", DBGARG, |
| 1429 bih->channel, (unsigned char) bih->rssi, bih->bssid[0], |
| 1430 bih->bssid[1], bih->bssid[2], bih->bssid[3], bih->bssid[4], |
| 1431 bih->bssid[5])); |
| 1432 |
| 1433 if(wps_enable && (bih->frameType == PROBERESP_FTYPE) ) |
| 1434 return A_OK; |
| 1435 |
| 1436 if (bss != NULL) { |
| 1437 /* |
| 1438 * Free up the node. Not the most efficient process given |
| 1439 * we are about to allocate a new node but it is simple and should be |
| 1440 * adequate. |
| 1441 */ |
| 1442 |
| 1443 /* In case of hidden AP, beacon will not have ssid, |
| 1444 * but a directed probe response will have it, |
| 1445 * so cache the probe-resp-ssid if already present. */ |
| 1446 if ((TRUE == is_probe_ssid) && (BEACON_FTYPE == bih->frameType)) |
| 1447 { |
| 1448 A_UCHAR *ie_ssid; |
| 1449 |
| 1450 ie_ssid = bss->ni_cie.ie_ssid; |
| 1451 if(ie_ssid && (ie_ssid[1] <= IEEE80211_NWID_LEN) && (ie_ssid[2] != 0
)) |
| 1452 { |
| 1453 cached_ssid_len = ie_ssid[1]; |
| 1454 memcpy(cached_ssid_buf, ie_ssid + 2, cached_ssid_len); |
| 1455 } |
| 1456 } |
| 1457 |
| 1458 wlan_node_reclaim(&wmip->wmi_scan_table, bss); |
| 1459 } |
| 1460 |
| 1461 /* beacon/probe response frame format |
| 1462 * [8] time stamp |
| 1463 * [2] beacon interval |
| 1464 * [2] capability information |
| 1465 * [tlv] ssid */ |
| 1466 beacon_ssid_len = buf[SSID_IE_LEN_INDEX]; |
| 1467 |
| 1468 /* If ssid is cached for this hidden AP, then change buffer len accordingly.
*/ |
| 1469 if ((TRUE == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) && |
| 1470 (0 != cached_ssid_len) && |
| 1471 (0 == beacon_ssid_len || (cached_ssid_len > beacon_ssid_len && 0 == buf[
SSID_IE_LEN_INDEX + 1]))) |
| 1472 { |
| 1473 len += (cached_ssid_len - beacon_ssid_len); |
| 1474 } |
| 1475 |
| 1476 bss = wlan_node_alloc(&wmip->wmi_scan_table, len); |
| 1477 if (bss == NULL) { |
| 1478 return A_NO_MEMORY; |
| 1479 } |
| 1480 |
| 1481 bss->ni_snr = bih->snr; |
| 1482 bss->ni_rssi = bih->rssi; |
| 1483 A_ASSERT(bss->ni_buf != NULL); |
| 1484 |
| 1485 /* In case of hidden AP, beacon will not have ssid, |
| 1486 * but a directed probe response will have it, |
| 1487 * so place the cached-ssid(probe-resp) in the bssinfo. */ |
| 1488 if ((TRUE == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) && |
| 1489 (0 != cached_ssid_len) && |
| 1490 (0 == beacon_ssid_len || (beacon_ssid_len && 0 == buf[SSID_IE_LEN_INDEX
+ 1]))) |
| 1491 { |
| 1492 A_UINT8 *ni_buf = bss->ni_buf; |
| 1493 int buf_len = len; |
| 1494 |
| 1495 /* copy the first 14 bytes such as |
| 1496 * time-stamp(8), beacon-interval(2), cap-info(2), ssid-id(1), ssid-len(
1). */ |
| 1497 A_MEMCPY(ni_buf, buf, SSID_IE_LEN_INDEX + 1); |
| 1498 |
| 1499 ni_buf[SSID_IE_LEN_INDEX] = cached_ssid_len; |
| 1500 ni_buf += (SSID_IE_LEN_INDEX + 1); |
| 1501 |
| 1502 buf += (SSID_IE_LEN_INDEX + 1); |
| 1503 buf_len -= (SSID_IE_LEN_INDEX + 1); |
| 1504 |
| 1505 /* copy the cached ssid */ |
| 1506 A_MEMCPY(ni_buf, cached_ssid_buf, cached_ssid_len); |
| 1507 ni_buf += cached_ssid_len; |
| 1508 |
| 1509 buf += beacon_ssid_len; |
| 1510 buf_len -= beacon_ssid_len; |
| 1511 |
| 1512 if (cached_ssid_len > beacon_ssid_len) |
| 1513 buf_len -= (cached_ssid_len - beacon_ssid_len); |
| 1514 |
| 1515 /* now copy the rest of bytes */ |
| 1516 A_MEMCPY(ni_buf, buf, buf_len); |
| 1517 } |
| 1518 else |
| 1519 A_MEMCPY(bss->ni_buf, buf, len); |
| 1520 |
| 1521 bss->ni_framelen = len; |
| 1522 if (wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie) != A_OK) { |
| 1523 wlan_node_free(bss); |
| 1524 return A_EINVAL; |
| 1525 } |
| 1526 |
| 1527 /* |
| 1528 * Update the frequency in ie_chan, overwriting of channel number |
| 1529 * which is done in wlan_parse_beacon |
| 1530 */ |
| 1531 bss->ni_cie.ie_chan = bih->channel; |
| 1532 wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid); |
| 1533 |
| 1534 return A_OK; |
| 1535 } |
| 1536 |
| 1537 static A_STATUS |
| 1538 wmi_opt_frame_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1539 { |
| 1540 bss_t *bss; |
| 1541 WMI_OPT_RX_INFO_HDR *bih; |
| 1542 A_UINT8 *buf; |
| 1543 |
| 1544 if (len <= sizeof(WMI_OPT_RX_INFO_HDR)) { |
| 1545 return A_EINVAL; |
| 1546 } |
| 1547 |
| 1548 bih = (WMI_OPT_RX_INFO_HDR *)datap; |
| 1549 buf = datap + sizeof(WMI_OPT_RX_INFO_HDR); |
| 1550 len -= sizeof(WMI_OPT_RX_INFO_HDR); |
| 1551 |
| 1552 A_DPRINTF(DBG_WMI2, (DBGFMT "opt frame event %2.2x:%2.2x\n", DBGARG, |
| 1553 bih->bssid[4], bih->bssid[5])); |
| 1554 |
| 1555 bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid); |
| 1556 if (bss != NULL) { |
| 1557 /* |
| 1558 * Free up the node. Not the most efficient process given |
| 1559 * we are about to allocate a new node but it is simple and should be |
| 1560 * adequate. |
| 1561 */ |
| 1562 wlan_node_reclaim(&wmip->wmi_scan_table, bss); |
| 1563 } |
| 1564 |
| 1565 bss = wlan_node_alloc(&wmip->wmi_scan_table, len); |
| 1566 if (bss == NULL) { |
| 1567 return A_NO_MEMORY; |
| 1568 } |
| 1569 |
| 1570 bss->ni_snr = bih->snr; |
| 1571 bss->ni_cie.ie_chan = bih->channel; |
| 1572 A_ASSERT(bss->ni_buf != NULL); |
| 1573 A_MEMCPY(bss->ni_buf, buf, len); |
| 1574 wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid); |
| 1575 |
| 1576 return A_OK; |
| 1577 } |
| 1578 |
| 1579 /* This event indicates inactivity timeout of a fatpipe(pstream) |
| 1580 * at the target |
| 1581 */ |
| 1582 static A_STATUS |
| 1583 wmi_pstream_timeout_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1584 { |
| 1585 WMI_PSTREAM_TIMEOUT_EVENT *ev; |
| 1586 |
| 1587 if (len < sizeof(WMI_PSTREAM_TIMEOUT_EVENT)) { |
| 1588 return A_EINVAL; |
| 1589 } |
| 1590 |
| 1591 A_DPRINTF(DBG_WMI, (DBGFMT "wmi_pstream_timeout_event_rx\n", DBGARG)); |
| 1592 |
| 1593 ev = (WMI_PSTREAM_TIMEOUT_EVENT *)datap; |
| 1594 |
| 1595 /* When the pstream (fat pipe == AC) timesout, it means there were no |
| 1596 * thinStreams within this pstream & it got implicitly created due to |
| 1597 * data flow on this AC. We start the inactivity timer only for |
| 1598 * implicitly created pstream. Just reset the host state. |
| 1599 */ |
| 1600 /* Set the activeTsids for this AC to 0 */ |
| 1601 LOCK_WMI(wmip); |
| 1602 wmip->wmi_streamExistsForAC[ev->trafficClass]=0; |
| 1603 wmip->wmi_fatPipeExists &= ~(1 << ev->trafficClass); |
| 1604 UNLOCK_WMI(wmip); |
| 1605 |
| 1606 /*Indicate inactivity to driver layer for this fatpipe (pstream)*/ |
| 1607 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, ev->trafficClass); |
| 1608 |
| 1609 return A_OK; |
| 1610 } |
| 1611 |
| 1612 static A_STATUS |
| 1613 wmi_bitrate_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1614 { |
| 1615 WMI_BIT_RATE_REPLY *reply; |
| 1616 A_INT32 rate; |
| 1617 /* 54149: |
| 1618 * WMI_BIT_RATE_CMD structure is changed to WMI_BIT_RATE_REPLY. |
| 1619 * since there is difference in the length and to avoid returning |
| 1620 * error value. |
| 1621 */ |
| 1622 if (len < sizeof(WMI_BIT_RATE_REPLY)) { |
| 1623 return A_EINVAL; |
| 1624 } |
| 1625 reply = (WMI_BIT_RATE_REPLY *)datap; |
| 1626 A_DPRINTF(DBG_WMI, |
| 1627 (DBGFMT "Enter - rateindex %d\n", DBGARG, reply->rateIndex)); |
| 1628 |
| 1629 if (reply->rateIndex == (A_INT8) RATE_AUTO) { |
| 1630 rate = RATE_AUTO; |
| 1631 } else { |
| 1632 rate = wmi_rateTable[(A_UINT32) reply->rateIndex]; |
| 1633 } |
| 1634 |
| 1635 A_WMI_BITRATE_RX(wmip->wmi_devt, rate); |
| 1636 return A_OK; |
| 1637 } |
| 1638 |
| 1639 static A_STATUS |
| 1640 wmi_ratemask_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1641 { |
| 1642 WMI_FIX_RATES_CMD *reply; |
| 1643 |
| 1644 if (len < sizeof(WMI_FIX_RATES_REPLY)) { |
| 1645 return A_EINVAL; |
| 1646 } |
| 1647 reply = (WMI_FIX_RATES_CMD *)datap; |
| 1648 A_DPRINTF(DBG_WMI, |
| 1649 (DBGFMT "Enter - fixed rate mask %x\n", DBGARG, reply->fixRateMask)); |
| 1650 |
| 1651 A_WMI_RATEMASK_RX(wmip->wmi_devt, reply->fixRateMask); |
| 1652 |
| 1653 return A_OK; |
| 1654 } |
| 1655 |
| 1656 static A_STATUS |
| 1657 wmi_channelList_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1658 { |
| 1659 WMI_CHANNEL_LIST_REPLY *reply; |
| 1660 |
| 1661 if (len < sizeof(WMI_CHANNEL_LIST_REPLY)) { |
| 1662 return A_EINVAL; |
| 1663 } |
| 1664 reply = (WMI_CHANNEL_LIST_REPLY *)datap; |
| 1665 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 1666 |
| 1667 A_WMI_CHANNELLIST_RX(wmip->wmi_devt, reply->numChannels, |
| 1668 reply->channelList); |
| 1669 |
| 1670 return A_OK; |
| 1671 } |
| 1672 |
| 1673 static A_STATUS |
| 1674 wmi_txPwr_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1675 { |
| 1676 WMI_TX_PWR_REPLY *reply; |
| 1677 |
| 1678 if (len < sizeof(*reply)) { |
| 1679 return A_EINVAL; |
| 1680 } |
| 1681 reply = (WMI_TX_PWR_REPLY *)datap; |
| 1682 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 1683 |
| 1684 A_WMI_TXPWR_RX(wmip->wmi_devt, reply->dbM); |
| 1685 |
| 1686 return A_OK; |
| 1687 } |
| 1688 static A_STATUS |
| 1689 wmi_keepalive_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1690 { |
| 1691 WMI_GET_KEEPALIVE_CMD *reply; |
| 1692 |
| 1693 if (len < sizeof(*reply)) { |
| 1694 return A_EINVAL; |
| 1695 } |
| 1696 reply = (WMI_GET_KEEPALIVE_CMD *)datap; |
| 1697 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 1698 |
| 1699 A_WMI_KEEPALIVE_RX(wmip->wmi_devt, reply->configured); |
| 1700 |
| 1701 return A_OK; |
| 1702 } |
| 1703 |
| 1704 |
| 1705 static A_STATUS |
| 1706 wmi_dset_open_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1707 { |
| 1708 WMIX_DSETOPENREQ_EVENT *dsetopenreq; |
| 1709 |
| 1710 if (len < sizeof(WMIX_DSETOPENREQ_EVENT)) { |
| 1711 return A_EINVAL; |
| 1712 } |
| 1713 dsetopenreq = (WMIX_DSETOPENREQ_EVENT *)datap; |
| 1714 A_DPRINTF(DBG_WMI, |
| 1715 (DBGFMT "Enter - dset_id=0x%x\n", DBGARG, dsetopenreq->dset_id)); |
| 1716 A_WMI_DSET_OPEN_REQ(wmip->wmi_devt, |
| 1717 dsetopenreq->dset_id, |
| 1718 dsetopenreq->targ_dset_handle, |
| 1719 dsetopenreq->targ_reply_fn, |
| 1720 dsetopenreq->targ_reply_arg); |
| 1721 |
| 1722 return A_OK; |
| 1723 } |
| 1724 |
| 1725 #ifdef CONFIG_HOST_DSET_SUPPORT |
| 1726 static A_STATUS |
| 1727 wmi_dset_close_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1728 { |
| 1729 WMIX_DSETCLOSE_EVENT *dsetclose; |
| 1730 |
| 1731 if (len < sizeof(WMIX_DSETCLOSE_EVENT)) { |
| 1732 return A_EINVAL; |
| 1733 } |
| 1734 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 1735 |
| 1736 dsetclose = (WMIX_DSETCLOSE_EVENT *)datap; |
| 1737 A_WMI_DSET_CLOSE(wmip->wmi_devt, dsetclose->access_cookie); |
| 1738 |
| 1739 return A_OK; |
| 1740 } |
| 1741 |
| 1742 static A_STATUS |
| 1743 wmi_dset_data_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1744 { |
| 1745 WMIX_DSETDATAREQ_EVENT *dsetdatareq; |
| 1746 |
| 1747 if (len < sizeof(WMIX_DSETDATAREQ_EVENT)) { |
| 1748 return A_EINVAL; |
| 1749 } |
| 1750 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 1751 |
| 1752 dsetdatareq = (WMIX_DSETDATAREQ_EVENT *)datap; |
| 1753 A_WMI_DSET_DATA_REQ(wmip->wmi_devt, |
| 1754 dsetdatareq->access_cookie, |
| 1755 dsetdatareq->offset, |
| 1756 dsetdatareq->length, |
| 1757 dsetdatareq->targ_buf, |
| 1758 dsetdatareq->targ_reply_fn, |
| 1759 dsetdatareq->targ_reply_arg); |
| 1760 |
| 1761 return A_OK; |
| 1762 } |
| 1763 #endif /* CONFIG_HOST_DSET_SUPPORT */ |
| 1764 |
| 1765 static A_STATUS |
| 1766 wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1767 { |
| 1768 WMI_SCAN_COMPLETE_EVENT *ev; |
| 1769 |
| 1770 ev = (WMI_SCAN_COMPLETE_EVENT *)datap; |
| 1771 A_WMI_SCANCOMPLETE_EVENT(wmip->wmi_devt, (A_STATUS) ev->status); |
| 1772 is_probe_ssid = FALSE; |
| 1773 |
| 1774 return A_OK; |
| 1775 } |
| 1776 |
| 1777 /* |
| 1778 * Target is reporting a programming error. This is for |
| 1779 * developer aid only. Target only checks a few common violations |
| 1780 * and it is responsibility of host to do all error checking. |
| 1781 * Behavior of target after wmi error event is undefined. |
| 1782 * A reset is recommended. |
| 1783 */ |
| 1784 static A_STATUS |
| 1785 wmi_errorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1786 { |
| 1787 WMI_CMD_ERROR_EVENT *ev; |
| 1788 |
| 1789 ev = (WMI_CMD_ERROR_EVENT *)datap; |
| 1790 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Programming Error: cmd=%d ", ev->commandId)
); |
| 1791 switch (ev->errorCode) { |
| 1792 case (INVALID_PARAM): |
| 1793 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal Parameter\n")); |
| 1794 break; |
| 1795 case (ILLEGAL_STATE): |
| 1796 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal State\n")); |
| 1797 break; |
| 1798 case (INTERNAL_ERROR): |
| 1799 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Internal Error\n")); |
| 1800 break; |
| 1801 } |
| 1802 |
| 1803 return A_OK; |
| 1804 } |
| 1805 |
| 1806 |
| 1807 static A_STATUS |
| 1808 wmi_statsEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1809 { |
| 1810 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 1811 |
| 1812 A_WMI_TARGETSTATS_EVENT(wmip->wmi_devt, datap, len); |
| 1813 |
| 1814 return A_OK; |
| 1815 } |
| 1816 |
| 1817 static A_STATUS |
| 1818 wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1819 { |
| 1820 WMI_RSSI_THRESHOLD_EVENT *reply; |
| 1821 WMI_RSSI_THRESHOLD_VAL newThreshold; |
| 1822 WMI_RSSI_THRESHOLD_PARAMS_CMD cmd; |
| 1823 SQ_THRESHOLD_PARAMS *sq_thresh = |
| 1824 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI]; |
| 1825 A_UINT8 upper_rssi_threshold, lower_rssi_threshold; |
| 1826 A_INT16 rssi; |
| 1827 |
| 1828 if (len < sizeof(*reply)) { |
| 1829 return A_EINVAL; |
| 1830 } |
| 1831 reply = (WMI_RSSI_THRESHOLD_EVENT *)datap; |
| 1832 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 1833 newThreshold = (WMI_RSSI_THRESHOLD_VAL) reply->range; |
| 1834 rssi = reply->rssi; |
| 1835 |
| 1836 /* |
| 1837 * Identify the threshold breached and communicate that to the app. After |
| 1838 * that install a new set of thresholds based on the signal quality |
| 1839 * reported by the target |
| 1840 */ |
| 1841 if (newThreshold) { |
| 1842 /* Upper threshold breached */ |
| 1843 if (rssi < sq_thresh->upper_threshold[0]) { |
| 1844 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious upper RSSI threshold event: " |
| 1845 " %d\n", DBGARG, rssi)); |
| 1846 } else if ((rssi < sq_thresh->upper_threshold[1]) && |
| 1847 (rssi >= sq_thresh->upper_threshold[0])) |
| 1848 { |
| 1849 newThreshold = WMI_RSSI_THRESHOLD1_ABOVE; |
| 1850 } else if ((rssi < sq_thresh->upper_threshold[2]) && |
| 1851 (rssi >= sq_thresh->upper_threshold[1])) |
| 1852 { |
| 1853 newThreshold = WMI_RSSI_THRESHOLD2_ABOVE; |
| 1854 } else if ((rssi < sq_thresh->upper_threshold[3]) && |
| 1855 (rssi >= sq_thresh->upper_threshold[2])) |
| 1856 { |
| 1857 newThreshold = WMI_RSSI_THRESHOLD3_ABOVE; |
| 1858 } else if ((rssi < sq_thresh->upper_threshold[4]) && |
| 1859 (rssi >= sq_thresh->upper_threshold[3])) |
| 1860 { |
| 1861 newThreshold = WMI_RSSI_THRESHOLD4_ABOVE; |
| 1862 } else if ((rssi < sq_thresh->upper_threshold[5]) && |
| 1863 (rssi >= sq_thresh->upper_threshold[4])) |
| 1864 { |
| 1865 newThreshold = WMI_RSSI_THRESHOLD5_ABOVE; |
| 1866 } else if (rssi >= sq_thresh->upper_threshold[5]) { |
| 1867 newThreshold = WMI_RSSI_THRESHOLD6_ABOVE; |
| 1868 } |
| 1869 } else { |
| 1870 /* Lower threshold breached */ |
| 1871 if (rssi > sq_thresh->lower_threshold[0]) { |
| 1872 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious lower RSSI threshold event: " |
| 1873 "%d %d\n", DBGARG, rssi, sq_thresh->lower_threshold[0])); |
| 1874 } else if ((rssi > sq_thresh->lower_threshold[1]) && |
| 1875 (rssi <= sq_thresh->lower_threshold[0])) |
| 1876 { |
| 1877 newThreshold = WMI_RSSI_THRESHOLD6_BELOW; |
| 1878 } else if ((rssi > sq_thresh->lower_threshold[2]) && |
| 1879 (rssi <= sq_thresh->lower_threshold[1])) |
| 1880 { |
| 1881 newThreshold = WMI_RSSI_THRESHOLD5_BELOW; |
| 1882 } else if ((rssi > sq_thresh->lower_threshold[3]) && |
| 1883 (rssi <= sq_thresh->lower_threshold[2])) |
| 1884 { |
| 1885 newThreshold = WMI_RSSI_THRESHOLD4_BELOW; |
| 1886 } else if ((rssi > sq_thresh->lower_threshold[4]) && |
| 1887 (rssi <= sq_thresh->lower_threshold[3])) |
| 1888 { |
| 1889 newThreshold = WMI_RSSI_THRESHOLD3_BELOW; |
| 1890 } else if ((rssi > sq_thresh->lower_threshold[5]) && |
| 1891 (rssi <= sq_thresh->lower_threshold[4])) |
| 1892 { |
| 1893 newThreshold = WMI_RSSI_THRESHOLD2_BELOW; |
| 1894 } else if (rssi <= sq_thresh->lower_threshold[5]) { |
| 1895 newThreshold = WMI_RSSI_THRESHOLD1_BELOW; |
| 1896 } |
| 1897 } |
| 1898 /* Calculate and install the next set of thresholds */ |
| 1899 lower_rssi_threshold = ar6000_get_lower_threshold(rssi, sq_thresh, |
| 1900 sq_thresh->lower_threshold_valid_count); |
| 1901 upper_rssi_threshold = ar6000_get_upper_threshold(rssi, sq_thresh, |
| 1902 sq_thresh->upper_threshold_valid_count); |
| 1903 /* Issue a wmi command to install the thresholds */ |
| 1904 cmd.thresholdAbove1_Val = upper_rssi_threshold; |
| 1905 cmd.thresholdBelow1_Val = lower_rssi_threshold; |
| 1906 cmd.weight = sq_thresh->weight; |
| 1907 cmd.pollTime = sq_thresh->polling_interval; |
| 1908 |
| 1909 rssi_event_value = rssi; |
| 1910 |
| 1911 if (wmi_send_rssi_threshold_params(wmip, &cmd) != A_OK) { |
| 1912 A_DPRINTF(DBG_WMI, (DBGFMT "Unable to configure the RSSI thresholds\n", |
| 1913 DBGARG)); |
| 1914 } |
| 1915 |
| 1916 A_WMI_RSSI_THRESHOLD_EVENT(wmip->wmi_devt, newThreshold, reply->rssi); |
| 1917 |
| 1918 return A_OK; |
| 1919 } |
| 1920 |
| 1921 |
| 1922 static A_STATUS |
| 1923 wmi_reportErrorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1924 { |
| 1925 WMI_TARGET_ERROR_REPORT_EVENT *reply; |
| 1926 |
| 1927 if (len < sizeof(*reply)) { |
| 1928 return A_EINVAL; |
| 1929 } |
| 1930 reply = (WMI_TARGET_ERROR_REPORT_EVENT *)datap; |
| 1931 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 1932 |
| 1933 A_WMI_REPORT_ERROR_EVENT(wmip->wmi_devt, (WMI_TARGET_ERROR_VAL) reply->error
Val); |
| 1934 |
| 1935 return A_OK; |
| 1936 } |
| 1937 |
| 1938 static A_STATUS |
| 1939 wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1940 { |
| 1941 WMI_CAC_EVENT *reply; |
| 1942 WMM_TSPEC_IE *tspec_ie; |
| 1943 |
| 1944 if (len < sizeof(*reply)) { |
| 1945 return A_EINVAL; |
| 1946 } |
| 1947 reply = (WMI_CAC_EVENT *)datap; |
| 1948 |
| 1949 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 1950 |
| 1951 if ((reply->cac_indication == CAC_INDICATION_ADMISSION_RESP) && |
| 1952 (reply->statusCode != TSPEC_STATUS_CODE_ADMISSION_ACCEPTED)) { |
| 1953 tspec_ie = (WMM_TSPEC_IE *) &(reply->tspecSuggestion); |
| 1954 |
| 1955 wmi_delete_pstream_cmd(wmip, reply->ac, |
| 1956 (tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK); |
| 1957 } |
| 1958 else if (reply->cac_indication == CAC_INDICATION_NO_RESP) { |
| 1959 A_UINT16 activeTsids; |
| 1960 A_UINT8 i; |
| 1961 |
| 1962 /* following assumes that there is only one outstanding ADDTS request |
| 1963 when this event is received */ |
| 1964 LOCK_WMI(wmip); |
| 1965 activeTsids = wmip->wmi_streamExistsForAC[reply->ac]; |
| 1966 UNLOCK_WMI(wmip); |
| 1967 |
| 1968 for (i = 0; i < sizeof(activeTsids) * 8; i++) { |
| 1969 if ((activeTsids >> i) & 1) { |
| 1970 break; |
| 1971 } |
| 1972 } |
| 1973 if (i < (sizeof(activeTsids) * 8)) { |
| 1974 wmi_delete_pstream_cmd(wmip, reply->ac, i); |
| 1975 } |
| 1976 } |
| 1977 |
| 1978 A_WMI_CAC_EVENT(wmip->wmi_devt, reply->ac, |
| 1979 reply->cac_indication, reply->statusCode, |
| 1980 reply->tspecSuggestion); |
| 1981 |
| 1982 return A_OK; |
| 1983 } |
| 1984 |
| 1985 static A_STATUS |
| 1986 wmi_channel_change_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 1987 { |
| 1988 WMI_CHANNEL_CHANGE_EVENT *reply; |
| 1989 |
| 1990 if (len < sizeof(*reply)) { |
| 1991 return A_EINVAL; |
| 1992 } |
| 1993 reply = (WMI_CHANNEL_CHANGE_EVENT *)datap; |
| 1994 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 1995 |
| 1996 A_WMI_CHANNEL_CHANGE_EVENT(wmip->wmi_devt, reply->oldChannel, |
| 1997 reply->newChannel); |
| 1998 |
| 1999 return A_OK; |
| 2000 } |
| 2001 |
| 2002 static A_STATUS |
| 2003 wmi_hbChallengeResp_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 2004 { |
| 2005 WMIX_HB_CHALLENGE_RESP_EVENT *reply; |
| 2006 |
| 2007 if (len < sizeof(*reply)) { |
| 2008 return A_EINVAL; |
| 2009 } |
| 2010 reply = (WMIX_HB_CHALLENGE_RESP_EVENT *)datap; |
| 2011 A_DPRINTF(DBG_WMI, (DBGFMT "wmi: challenge response event\n", DBGARG)); |
| 2012 |
| 2013 A_WMI_HBCHALLENGERESP_EVENT(wmip->wmi_devt, reply->cookie, reply->source); |
| 2014 |
| 2015 return A_OK; |
| 2016 } |
| 2017 |
| 2018 static A_STATUS |
| 2019 wmi_roam_tbl_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 2020 { |
| 2021 WMI_TARGET_ROAM_TBL *reply; |
| 2022 |
| 2023 if (len < sizeof(*reply)) { |
| 2024 return A_EINVAL; |
| 2025 } |
| 2026 reply = (WMI_TARGET_ROAM_TBL *)datap; |
| 2027 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 2028 |
| 2029 A_WMI_ROAM_TABLE_EVENT(wmip->wmi_devt, reply); |
| 2030 |
| 2031 return A_OK; |
| 2032 } |
| 2033 |
| 2034 static A_STATUS |
| 2035 wmi_roam_data_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 2036 { |
| 2037 WMI_TARGET_ROAM_DATA *reply; |
| 2038 |
| 2039 if (len < sizeof(*reply)) { |
| 2040 return A_EINVAL; |
| 2041 } |
| 2042 reply = (WMI_TARGET_ROAM_DATA *)datap; |
| 2043 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 2044 |
| 2045 A_WMI_ROAM_DATA_EVENT(wmip->wmi_devt, reply); |
| 2046 |
| 2047 return A_OK; |
| 2048 } |
| 2049 |
| 2050 static A_STATUS |
| 2051 wmi_txRetryErrEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 2052 { |
| 2053 if (len < sizeof(WMI_TX_RETRY_ERR_EVENT)) { |
| 2054 return A_EINVAL; |
| 2055 } |
| 2056 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 2057 |
| 2058 A_WMI_TX_RETRY_ERR_EVENT(wmip->wmi_devt); |
| 2059 |
| 2060 return A_OK; |
| 2061 } |
| 2062 |
| 2063 static A_STATUS |
| 2064 wmi_snrThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 2065 { |
| 2066 WMI_SNR_THRESHOLD_EVENT *reply; |
| 2067 SQ_THRESHOLD_PARAMS *sq_thresh = |
| 2068 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_SNR]; |
| 2069 WMI_SNR_THRESHOLD_VAL newThreshold; |
| 2070 WMI_SNR_THRESHOLD_PARAMS_CMD cmd; |
| 2071 A_UINT8 upper_snr_threshold, lower_snr_threshold; |
| 2072 A_INT16 snr; |
| 2073 |
| 2074 if (len < sizeof(*reply)) { |
| 2075 return A_EINVAL; |
| 2076 } |
| 2077 reply = (WMI_SNR_THRESHOLD_EVENT *)datap; |
| 2078 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 2079 |
| 2080 newThreshold = (WMI_SNR_THRESHOLD_VAL) reply->range; |
| 2081 snr = reply->snr; |
| 2082 /* |
| 2083 * Identify the threshold breached and communicate that to the app. After |
| 2084 * that install a new set of thresholds based on the signal quality |
| 2085 * reported by the target |
| 2086 */ |
| 2087 if (newThreshold) { |
| 2088 /* Upper threshold breached */ |
| 2089 if (snr < sq_thresh->upper_threshold[0]) { |
| 2090 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious upper SNR threshold event: " |
| 2091 "%d\n", DBGARG, snr)); |
| 2092 } else if ((snr < sq_thresh->upper_threshold[1]) && |
| 2093 (snr >= sq_thresh->upper_threshold[0])) |
| 2094 { |
| 2095 newThreshold = WMI_SNR_THRESHOLD1_ABOVE; |
| 2096 } else if ((snr < sq_thresh->upper_threshold[2]) && |
| 2097 (snr >= sq_thresh->upper_threshold[1])) |
| 2098 { |
| 2099 newThreshold = WMI_SNR_THRESHOLD2_ABOVE; |
| 2100 } else if ((snr < sq_thresh->upper_threshold[3]) && |
| 2101 (snr >= sq_thresh->upper_threshold[2])) |
| 2102 { |
| 2103 newThreshold = WMI_SNR_THRESHOLD3_ABOVE; |
| 2104 } else if (snr >= sq_thresh->upper_threshold[3]) { |
| 2105 newThreshold = WMI_SNR_THRESHOLD4_ABOVE; |
| 2106 } |
| 2107 } else { |
| 2108 /* Lower threshold breached */ |
| 2109 if (snr > sq_thresh->lower_threshold[0]) { |
| 2110 A_DPRINTF(DBG_WMI, (DBGFMT "Spurious lower SNR threshold event: " |
| 2111 "%d %d\n", DBGARG, snr, sq_thresh->lower_threshold[0])); |
| 2112 } else if ((snr > sq_thresh->lower_threshold[1]) && |
| 2113 (snr <= sq_thresh->lower_threshold[0])) |
| 2114 { |
| 2115 newThreshold = WMI_SNR_THRESHOLD4_BELOW; |
| 2116 } else if ((snr > sq_thresh->lower_threshold[2]) && |
| 2117 (snr <= sq_thresh->lower_threshold[1])) |
| 2118 { |
| 2119 newThreshold = WMI_SNR_THRESHOLD3_BELOW; |
| 2120 } else if ((snr > sq_thresh->lower_threshold[3]) && |
| 2121 (snr <= sq_thresh->lower_threshold[2])) |
| 2122 { |
| 2123 newThreshold = WMI_SNR_THRESHOLD2_BELOW; |
| 2124 } else if (snr <= sq_thresh->lower_threshold[3]) { |
| 2125 newThreshold = WMI_SNR_THRESHOLD1_BELOW; |
| 2126 } |
| 2127 } |
| 2128 |
| 2129 /* Calculate and install the next set of thresholds */ |
| 2130 lower_snr_threshold = ar6000_get_lower_threshold(snr, sq_thresh, |
| 2131 sq_thresh->lower_threshold_valid_count); |
| 2132 upper_snr_threshold = ar6000_get_upper_threshold(snr, sq_thresh, |
| 2133 sq_thresh->upper_threshold_valid_count); |
| 2134 |
| 2135 /* Issue a wmi command to install the thresholds */ |
| 2136 cmd.thresholdAbove1_Val = upper_snr_threshold; |
| 2137 cmd.thresholdBelow1_Val = lower_snr_threshold; |
| 2138 cmd.weight = sq_thresh->weight; |
| 2139 cmd.pollTime = sq_thresh->polling_interval; |
| 2140 |
| 2141 A_DPRINTF(DBG_WMI, (DBGFMT "snr: %d, threshold: %d, lower: %d, upper: %d\n" |
| 2142 ,DBGARG, snr, newThreshold, lower_snr_threshold, |
| 2143 upper_snr_threshold)); |
| 2144 |
| 2145 snr_event_value = snr; |
| 2146 |
| 2147 if (wmi_send_snr_threshold_params(wmip, &cmd) != A_OK) { |
| 2148 A_DPRINTF(DBG_WMI, (DBGFMT "Unable to configure the SNR thresholds\n", |
| 2149 DBGARG)); |
| 2150 } |
| 2151 A_WMI_SNR_THRESHOLD_EVENT_RX(wmip->wmi_devt, newThreshold, reply->snr); |
| 2152 |
| 2153 return A_OK; |
| 2154 } |
| 2155 |
| 2156 static A_STATUS |
| 2157 wmi_lqThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 2158 { |
| 2159 WMI_LQ_THRESHOLD_EVENT *reply; |
| 2160 |
| 2161 if (len < sizeof(*reply)) { |
| 2162 return A_EINVAL; |
| 2163 } |
| 2164 reply = (WMI_LQ_THRESHOLD_EVENT *)datap; |
| 2165 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 2166 |
| 2167 A_WMI_LQ_THRESHOLD_EVENT_RX(wmip->wmi_devt, |
| 2168 (WMI_LQ_THRESHOLD_VAL) reply->range, |
| 2169 reply->lq); |
| 2170 |
| 2171 return A_OK; |
| 2172 } |
| 2173 |
| 2174 static A_STATUS |
| 2175 wmi_aplistEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 2176 { |
| 2177 A_UINT16 ap_info_entry_size; |
| 2178 WMI_APLIST_EVENT *ev = (WMI_APLIST_EVENT *)datap; |
| 2179 WMI_AP_INFO_V1 *ap_info_v1; |
| 2180 A_UINT8 i; |
| 2181 |
| 2182 if (len < sizeof(WMI_APLIST_EVENT)) { |
| 2183 return A_EINVAL; |
| 2184 } |
| 2185 |
| 2186 if (ev->apListVer == APLIST_VER1) { |
| 2187 ap_info_entry_size = sizeof(WMI_AP_INFO_V1); |
| 2188 ap_info_v1 = (WMI_AP_INFO_V1 *)ev->apList; |
| 2189 } else { |
| 2190 return A_EINVAL; |
| 2191 } |
| 2192 |
| 2193 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Number of APs in APLIST Event is %d\n", ev-
>numAP)); |
| 2194 if (len < (int)(sizeof(WMI_APLIST_EVENT) + |
| 2195 (ev->numAP - 1) * ap_info_entry_size)) |
| 2196 { |
| 2197 return A_EINVAL; |
| 2198 } |
| 2199 |
| 2200 /* |
| 2201 * AP List Ver1 Contents |
| 2202 */ |
| 2203 for (i = 0; i < ev->numAP; i++) { |
| 2204 AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("AP#%d BSSID %2.2x %2.2x %2.2x %2.2x %2.
2x %2.2x "\ |
| 2205 "Channel %d\n", i, |
| 2206 ap_info_v1->bssid[0], ap_info_v1->bssid[1], |
| 2207 ap_info_v1->bssid[2], ap_info_v1->bssid[3], |
| 2208 ap_info_v1->bssid[4], ap_info_v1->bssid[5], |
| 2209 ap_info_v1->channel)); |
| 2210 ap_info_v1++; |
| 2211 } |
| 2212 return A_OK; |
| 2213 } |
| 2214 |
| 2215 static A_STATUS |
| 2216 wmi_dbglog_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 2217 { |
| 2218 A_UINT32 dropped; |
| 2219 |
| 2220 dropped = *((A_UINT32 *)datap); |
| 2221 datap += sizeof(dropped); |
| 2222 len -= sizeof(dropped); |
| 2223 A_WMI_DBGLOG_EVENT(wmip->wmi_devt, dropped, datap, len); |
| 2224 return A_OK; |
| 2225 } |
| 2226 |
| 2227 #ifdef CONFIG_HOST_GPIO_SUPPORT |
| 2228 static A_STATUS |
| 2229 wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 2230 { |
| 2231 WMIX_GPIO_INTR_EVENT *gpio_intr = (WMIX_GPIO_INTR_EVENT *)datap; |
| 2232 |
| 2233 A_DPRINTF(DBG_WMI, |
| 2234 (DBGFMT "Enter - intrmask=0x%x input=0x%x.\n", DBGARG, |
| 2235 gpio_intr->intr_mask, gpio_intr->input_values)); |
| 2236 |
| 2237 A_WMI_GPIO_INTR_RX(gpio_intr->intr_mask, gpio_intr->input_values); |
| 2238 |
| 2239 return A_OK; |
| 2240 } |
| 2241 |
| 2242 static A_STATUS |
| 2243 wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 2244 { |
| 2245 WMIX_GPIO_DATA_EVENT *gpio_data = (WMIX_GPIO_DATA_EVENT *)datap; |
| 2246 |
| 2247 A_DPRINTF(DBG_WMI, |
| 2248 (DBGFMT "Enter - reg=%d value=0x%x\n", DBGARG, |
| 2249 gpio_data->reg_id, gpio_data->value)); |
| 2250 |
| 2251 A_WMI_GPIO_DATA_RX(gpio_data->reg_id, gpio_data->value); |
| 2252 |
| 2253 return A_OK; |
| 2254 } |
| 2255 |
| 2256 static A_STATUS |
| 2257 wmi_gpio_ack_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 2258 { |
| 2259 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 2260 |
| 2261 A_WMI_GPIO_ACK_RX(); |
| 2262 |
| 2263 return A_OK; |
| 2264 } |
| 2265 #endif /* CONFIG_HOST_GPIO_SUPPORT */ |
| 2266 |
| 2267 /* |
| 2268 * Called to send a wmi command. Command specific data is already built |
| 2269 * on osbuf and current osbuf->data points to it. |
| 2270 */ |
| 2271 A_STATUS |
| 2272 wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId, |
| 2273 WMI_SYNC_FLAG syncflag) |
| 2274 { |
| 2275 #define IS_OPT_TX_CMD(cmdId) ((cmdId == WMI_OPT_TX_FRAME_CMDID)) |
| 2276 WMI_CMD_HDR *cHdr; |
| 2277 HTC_ENDPOINT_ID eid = wmip->wmi_endpoint_id; |
| 2278 |
| 2279 A_ASSERT(osbuf != NULL); |
| 2280 |
| 2281 if (syncflag >= END_WMIFLAG) { |
| 2282 return A_EINVAL; |
| 2283 } |
| 2284 |
| 2285 if ((syncflag == SYNC_BEFORE_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) { |
| 2286 /* |
| 2287 * We want to make sure all data currently queued is transmitted before |
| 2288 * the cmd execution. Establish a new sync point. |
| 2289 */ |
| 2290 wmi_sync_point(wmip); |
| 2291 } |
| 2292 |
| 2293 if (A_NETBUF_PUSH(osbuf, sizeof(WMI_CMD_HDR)) != A_OK) { |
| 2294 return A_NO_MEMORY; |
| 2295 } |
| 2296 |
| 2297 cHdr = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf); |
| 2298 cHdr->commandId = (A_UINT16) cmdId; |
| 2299 cHdr->info1 = 0; // added for virtual interface |
| 2300 |
| 2301 /* |
| 2302 * Only for OPT_TX_CMD, use BE endpoint. |
| 2303 */ |
| 2304 if (IS_OPT_TX_CMD(cmdId)) { |
| 2305 wmi_data_hdr_add(wmip, osbuf, OPT_MSGTYPE, FALSE, FALSE,0,NULL); |
| 2306 eid = A_WMI_Ac2EndpointID(wmip->wmi_devt, WMM_AC_BE); |
| 2307 } |
| 2308 A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid); |
| 2309 |
| 2310 if ((syncflag == SYNC_AFTER_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) { |
| 2311 /* |
| 2312 * We want to make sure all new data queued waits for the command to |
| 2313 * execute. Establish a new sync point. |
| 2314 */ |
| 2315 wmi_sync_point(wmip); |
| 2316 } |
| 2317 return (A_OK); |
| 2318 #undef IS_OPT_TX_CMD |
| 2319 } |
| 2320 |
| 2321 A_STATUS |
| 2322 wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId, |
| 2323 WMI_SYNC_FLAG syncflag) |
| 2324 { |
| 2325 WMIX_CMD_HDR *cHdr; |
| 2326 |
| 2327 if (A_NETBUF_PUSH(osbuf, sizeof(WMIX_CMD_HDR)) != A_OK) { |
| 2328 return A_NO_MEMORY; |
| 2329 } |
| 2330 |
| 2331 cHdr = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf); |
| 2332 cHdr->commandId = (A_UINT32) cmdId; |
| 2333 |
| 2334 return wmi_cmd_send(wmip, osbuf, WMI_EXTENSION_CMDID, syncflag); |
| 2335 } |
| 2336 |
| 2337 A_STATUS |
| 2338 wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType, |
| 2339 DOT11_AUTH_MODE dot11AuthMode, AUTH_MODE authMode, |
| 2340 CRYPTO_TYPE pairwiseCrypto, A_UINT8 pairwiseCryptoLen, |
| 2341 CRYPTO_TYPE groupCrypto, A_UINT8 groupCryptoLen, |
| 2342 int ssidLength, A_UCHAR *ssid, |
| 2343 A_UINT8 *bssid, A_UINT16 channel, A_UINT32 ctrl_flags) |
| 2344 { |
| 2345 void *osbuf; |
| 2346 WMI_CONNECT_CMD *cc; |
| 2347 struct ieee80211_node_table *nt; |
| 2348 |
| 2349 /* Do not allow a connect until a scan has been done. This will allow a host
initiated scan to take precedence over a connect */ |
| 2350 nt = &wmip->wmi_scan_table; |
| 2351 if (!(netType & ADHOC_NETWORK) && (nt->nt_node_first == NULL)) { |
| 2352 return A_EINVAL; |
| 2353 } |
| 2354 |
| 2355 if ((pairwiseCrypto == NONE_CRYPT) && (groupCrypto != NONE_CRYPT)) { |
| 2356 return A_EINVAL; |
| 2357 } |
| 2358 if ((pairwiseCrypto != NONE_CRYPT) && (groupCrypto == NONE_CRYPT)) { |
| 2359 return A_EINVAL; |
| 2360 } |
| 2361 |
| 2362 osbuf = A_NETBUF_ALLOC(sizeof(WMI_CONNECT_CMD)); |
| 2363 if (osbuf == NULL) { |
| 2364 return A_NO_MEMORY; |
| 2365 } |
| 2366 |
| 2367 A_NETBUF_PUT(osbuf, sizeof(WMI_CONNECT_CMD)); |
| 2368 |
| 2369 cc = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf)); |
| 2370 A_MEMZERO(cc, sizeof(*cc)); |
| 2371 |
| 2372 if (ssidLength) |
| 2373 { |
| 2374 A_MEMCPY(cc->ssid, ssid, ssidLength); |
| 2375 } |
| 2376 |
| 2377 cc->ssidLength = ssidLength; |
| 2378 cc->networkType = netType; |
| 2379 cc->dot11AuthMode = dot11AuthMode; |
| 2380 cc->authMode = authMode; |
| 2381 cc->pairwiseCryptoType = pairwiseCrypto; |
| 2382 cc->pairwiseCryptoLen = pairwiseCryptoLen; |
| 2383 cc->groupCryptoType = groupCrypto; |
| 2384 cc->groupCryptoLen = groupCryptoLen; |
| 2385 cc->channel = channel; |
| 2386 cc->ctrl_flags = ctrl_flags; |
| 2387 |
| 2388 if (bssid != NULL) { |
| 2389 A_MEMCPY(cc->bssid, bssid, ATH_MAC_LEN); |
| 2390 } |
| 2391 if (wmi_set_keepalive_cmd(wmip, wmip->wmi_keepaliveInterval) != A_OK) { |
| 2392 return(A_ERROR); |
| 2393 } |
| 2394 |
| 2395 wmip->wmi_pair_crypto_type = pairwiseCrypto; |
| 2396 wmip->wmi_grp_crypto_type = groupCrypto; |
| 2397 |
| 2398 return (wmi_cmd_send(wmip, osbuf, WMI_CONNECT_CMDID, NO_SYNC_WMIFLAG)); |
| 2399 } |
| 2400 |
| 2401 A_STATUS |
| 2402 wmi_reconnect_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT16 channel) |
| 2403 { |
| 2404 void *osbuf; |
| 2405 WMI_RECONNECT_CMD *cc; |
| 2406 |
| 2407 osbuf = A_NETBUF_ALLOC(sizeof(WMI_RECONNECT_CMD)); |
| 2408 if (osbuf == NULL) { |
| 2409 return A_NO_MEMORY; |
| 2410 } |
| 2411 |
| 2412 A_NETBUF_PUT(osbuf, sizeof(WMI_RECONNECT_CMD)); |
| 2413 |
| 2414 cc = (WMI_RECONNECT_CMD *)(A_NETBUF_DATA(osbuf)); |
| 2415 A_MEMZERO(cc, sizeof(*cc)); |
| 2416 |
| 2417 cc->channel = channel; |
| 2418 |
| 2419 if (bssid != NULL) { |
| 2420 A_MEMCPY(cc->bssid, bssid, ATH_MAC_LEN); |
| 2421 } |
| 2422 |
| 2423 return (wmi_cmd_send(wmip, osbuf, WMI_RECONNECT_CMDID, NO_SYNC_WMIFLAG)); |
| 2424 } |
| 2425 |
| 2426 A_STATUS |
| 2427 wmi_disconnect_cmd(struct wmi_t *wmip) |
| 2428 { |
| 2429 A_STATUS status; |
| 2430 |
| 2431 /* Bug fix for 24817(elevator bug) - the disconnect command does not |
| 2432 need to do a SYNC before.*/ |
| 2433 status = wmi_simple_cmd(wmip, WMI_DISCONNECT_CMDID); |
| 2434 |
| 2435 return status; |
| 2436 } |
| 2437 |
| 2438 A_STATUS |
| 2439 wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType, |
| 2440 A_BOOL forceFgScan, A_BOOL isLegacy, |
| 2441 A_UINT32 homeDwellTime, A_UINT32 forceScanInterval, |
| 2442 A_INT8 numChan, A_UINT16 *channelList) |
| 2443 { |
| 2444 void *osbuf; |
| 2445 WMI_START_SCAN_CMD *sc; |
| 2446 A_INT8 size; |
| 2447 |
| 2448 size = sizeof (*sc); |
| 2449 |
| 2450 if ((scanType != WMI_LONG_SCAN) && (scanType != WMI_SHORT_SCAN)) { |
| 2451 return A_EINVAL; |
| 2452 } |
| 2453 |
| 2454 if (numChan) { |
| 2455 if (numChan > WMI_MAX_CHANNELS) { |
| 2456 return A_EINVAL; |
| 2457 } |
| 2458 size += sizeof(A_UINT16) * (numChan - 1); |
| 2459 } |
| 2460 |
| 2461 osbuf = A_NETBUF_ALLOC(size); |
| 2462 if (osbuf == NULL) { |
| 2463 return A_NO_MEMORY; |
| 2464 } |
| 2465 |
| 2466 A_NETBUF_PUT(osbuf, size); |
| 2467 |
| 2468 sc = (WMI_START_SCAN_CMD *)(A_NETBUF_DATA(osbuf)); |
| 2469 sc->scanType = scanType; |
| 2470 sc->forceFgScan = forceFgScan; |
| 2471 sc->isLegacy = isLegacy; |
| 2472 sc->homeDwellTime = homeDwellTime; |
| 2473 sc->forceScanInterval = forceScanInterval; |
| 2474 sc->numChannels = numChan; |
| 2475 if (numChan) { |
| 2476 A_MEMCPY(sc->channelList, channelList, numChan * sizeof(A_UINT16)); |
| 2477 } |
| 2478 |
| 2479 return (wmi_cmd_send(wmip, osbuf, WMI_START_SCAN_CMDID, NO_SYNC_WMIFLAG)); |
| 2480 } |
| 2481 |
| 2482 A_STATUS |
| 2483 wmi_scanparams_cmd(struct wmi_t *wmip, A_UINT16 fg_start_sec, |
| 2484 A_UINT16 fg_end_sec, A_UINT16 bg_sec, |
| 2485 A_UINT16 minact_chdw_msec, A_UINT16 maxact_chdw_msec, |
| 2486 A_UINT16 pas_chdw_msec, |
| 2487 A_UINT8 shScanRatio, A_UINT8 scanCtrlFlags, |
| 2488 A_UINT32 max_dfsch_act_time, A_UINT16 maxact_scan_per_ssid) |
| 2489 { |
| 2490 void *osbuf; |
| 2491 WMI_SCAN_PARAMS_CMD *sc; |
| 2492 |
| 2493 osbuf = A_NETBUF_ALLOC(sizeof(*sc)); |
| 2494 if (osbuf == NULL) { |
| 2495 return A_NO_MEMORY; |
| 2496 } |
| 2497 |
| 2498 A_NETBUF_PUT(osbuf, sizeof(*sc)); |
| 2499 |
| 2500 sc = (WMI_SCAN_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); |
| 2501 A_MEMZERO(sc, sizeof(*sc)); |
| 2502 sc->fg_start_period = fg_start_sec; |
| 2503 sc->fg_end_period = fg_end_sec; |
| 2504 sc->bg_period = bg_sec; |
| 2505 sc->minact_chdwell_time = minact_chdw_msec; |
| 2506 sc->maxact_chdwell_time = maxact_chdw_msec; |
| 2507 sc->pas_chdwell_time = pas_chdw_msec; |
| 2508 sc->shortScanRatio = shScanRatio; |
| 2509 sc->scanCtrlFlags = scanCtrlFlags; |
| 2510 sc->max_dfsch_act_time = max_dfsch_act_time; |
| 2511 sc->maxact_scan_per_ssid = maxact_scan_per_ssid; |
| 2512 |
| 2513 return (wmi_cmd_send(wmip, osbuf, WMI_SET_SCAN_PARAMS_CMDID, |
| 2514 NO_SYNC_WMIFLAG)); |
| 2515 } |
| 2516 |
| 2517 A_STATUS |
| 2518 wmi_bssfilter_cmd(struct wmi_t *wmip, A_UINT8 filter, A_UINT32 ieMask) |
| 2519 { |
| 2520 void *osbuf; |
| 2521 WMI_BSS_FILTER_CMD *cmd; |
| 2522 |
| 2523 if (filter >= LAST_BSS_FILTER) { |
| 2524 return A_EINVAL; |
| 2525 } |
| 2526 |
| 2527 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 2528 if (osbuf == NULL) { |
| 2529 return A_NO_MEMORY; |
| 2530 } |
| 2531 |
| 2532 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 2533 |
| 2534 cmd = (WMI_BSS_FILTER_CMD *)(A_NETBUF_DATA(osbuf)); |
| 2535 A_MEMZERO(cmd, sizeof(*cmd)); |
| 2536 cmd->bssFilter = filter; |
| 2537 cmd->ieMask = ieMask; |
| 2538 |
| 2539 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BSS_FILTER_CMDID, |
| 2540 NO_SYNC_WMIFLAG)); |
| 2541 } |
| 2542 |
| 2543 A_STATUS |
| 2544 wmi_probedSsid_cmd(struct wmi_t *wmip, A_UINT8 index, A_UINT8 flag, |
| 2545 A_UINT8 ssidLength, A_UCHAR *ssid) |
| 2546 { |
| 2547 void *osbuf; |
| 2548 WMI_PROBED_SSID_CMD *cmd; |
| 2549 |
| 2550 if (index > MAX_PROBED_SSID_INDEX) { |
| 2551 return A_EINVAL; |
| 2552 } |
| 2553 if (ssidLength > sizeof(cmd->ssid)) { |
| 2554 return A_EINVAL; |
| 2555 } |
| 2556 if ((flag & (DISABLE_SSID_FLAG | ANY_SSID_FLAG)) && (ssidLength > 0)) { |
| 2557 return A_EINVAL; |
| 2558 } |
| 2559 if ((flag & SPECIFIC_SSID_FLAG) && !ssidLength) { |
| 2560 return A_EINVAL; |
| 2561 } |
| 2562 |
| 2563 if (flag & SPECIFIC_SSID_FLAG) { |
| 2564 is_probe_ssid = TRUE; |
| 2565 } |
| 2566 |
| 2567 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 2568 if (osbuf == NULL) { |
| 2569 return A_NO_MEMORY; |
| 2570 } |
| 2571 |
| 2572 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 2573 |
| 2574 cmd = (WMI_PROBED_SSID_CMD *)(A_NETBUF_DATA(osbuf)); |
| 2575 A_MEMZERO(cmd, sizeof(*cmd)); |
| 2576 cmd->entryIndex = index; |
| 2577 cmd->flag = flag; |
| 2578 cmd->ssidLength = ssidLength; |
| 2579 A_MEMCPY(cmd->ssid, ssid, ssidLength); |
| 2580 |
| 2581 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PROBED_SSID_CMDID, |
| 2582 NO_SYNC_WMIFLAG)); |
| 2583 } |
| 2584 |
| 2585 A_STATUS |
| 2586 wmi_listeninterval_cmd(struct wmi_t *wmip, A_UINT16 listenInterval, A_UINT16 lis
tenBeacons) |
| 2587 { |
| 2588 void *osbuf; |
| 2589 WMI_LISTEN_INT_CMD *cmd; |
| 2590 |
| 2591 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 2592 if (osbuf == NULL) { |
| 2593 return A_NO_MEMORY; |
| 2594 } |
| 2595 |
| 2596 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 2597 |
| 2598 cmd = (WMI_LISTEN_INT_CMD *)(A_NETBUF_DATA(osbuf)); |
| 2599 A_MEMZERO(cmd, sizeof(*cmd)); |
| 2600 cmd->listenInterval = listenInterval; |
| 2601 cmd->numBeacons = listenBeacons; |
| 2602 |
| 2603 return (wmi_cmd_send(wmip, osbuf, WMI_SET_LISTEN_INT_CMDID, |
| 2604 NO_SYNC_WMIFLAG)); |
| 2605 } |
| 2606 |
| 2607 A_STATUS |
| 2608 wmi_bmisstime_cmd(struct wmi_t *wmip, A_UINT16 bmissTime, A_UINT16 bmissBeacons) |
| 2609 { |
| 2610 void *osbuf; |
| 2611 WMI_BMISS_TIME_CMD *cmd; |
| 2612 |
| 2613 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 2614 if (osbuf == NULL) { |
| 2615 return A_NO_MEMORY; |
| 2616 } |
| 2617 |
| 2618 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 2619 |
| 2620 cmd = (WMI_BMISS_TIME_CMD *)(A_NETBUF_DATA(osbuf)); |
| 2621 A_MEMZERO(cmd, sizeof(*cmd)); |
| 2622 cmd->bmissTime = bmissTime; |
| 2623 cmd->numBeacons = bmissBeacons; |
| 2624 |
| 2625 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BMISS_TIME_CMDID, |
| 2626 NO_SYNC_WMIFLAG)); |
| 2627 } |
| 2628 |
| 2629 A_STATUS |
| 2630 wmi_associnfo_cmd(struct wmi_t *wmip, A_UINT8 ieType, |
| 2631 A_UINT8 ieLen, A_UINT8 *ieInfo) |
| 2632 { |
| 2633 void *osbuf; |
| 2634 WMI_SET_ASSOC_INFO_CMD *cmd; |
| 2635 A_UINT16 cmdLen; |
| 2636 |
| 2637 cmdLen = sizeof(*cmd) + ieLen - 1; |
| 2638 osbuf = A_NETBUF_ALLOC(cmdLen); |
| 2639 if (osbuf == NULL) { |
| 2640 return A_NO_MEMORY; |
| 2641 } |
| 2642 |
| 2643 A_NETBUF_PUT(osbuf, cmdLen); |
| 2644 |
| 2645 cmd = (WMI_SET_ASSOC_INFO_CMD *)(A_NETBUF_DATA(osbuf)); |
| 2646 A_MEMZERO(cmd, cmdLen); |
| 2647 cmd->ieType = ieType; |
| 2648 cmd->bufferSize = ieLen; |
| 2649 A_MEMCPY(cmd->assocInfo, ieInfo, ieLen); |
| 2650 |
| 2651 return (wmi_cmd_send(wmip, osbuf, WMI_SET_ASSOC_INFO_CMDID, |
| 2652 NO_SYNC_WMIFLAG)); |
| 2653 } |
| 2654 |
| 2655 A_STATUS |
| 2656 wmi_powermode_cmd(struct wmi_t *wmip, A_UINT8 powerMode) |
| 2657 { |
| 2658 void *osbuf; |
| 2659 WMI_POWER_MODE_CMD *cmd; |
| 2660 |
| 2661 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 2662 if (osbuf == NULL) { |
| 2663 return A_NO_MEMORY; |
| 2664 } |
| 2665 |
| 2666 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 2667 |
| 2668 cmd = (WMI_POWER_MODE_CMD *)(A_NETBUF_DATA(osbuf)); |
| 2669 A_MEMZERO(cmd, sizeof(*cmd)); |
| 2670 cmd->powerMode = powerMode; |
| 2671 wmip->wmi_powerMode = powerMode; |
| 2672 |
| 2673 return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_MODE_CMDID, |
| 2674 NO_SYNC_WMIFLAG)); |
| 2675 } |
| 2676 |
| 2677 A_STATUS |
| 2678 wmi_ibsspmcaps_cmd(struct wmi_t *wmip, A_UINT8 pmEnable, A_UINT8 ttl, |
| 2679 A_UINT16 atim_windows, A_UINT16 timeout_value) |
| 2680 { |
| 2681 void *osbuf; |
| 2682 WMI_IBSS_PM_CAPS_CMD *cmd; |
| 2683 |
| 2684 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 2685 if (osbuf == NULL) { |
| 2686 return A_NO_MEMORY; |
| 2687 } |
| 2688 |
| 2689 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 2690 |
| 2691 cmd = (WMI_IBSS_PM_CAPS_CMD *)(A_NETBUF_DATA(osbuf)); |
| 2692 A_MEMZERO(cmd, sizeof(*cmd)); |
| 2693 cmd->power_saving = pmEnable; |
| 2694 cmd->ttl = ttl; |
| 2695 cmd->atim_windows = atim_windows; |
| 2696 cmd->timeout_value = timeout_value; |
| 2697 |
| 2698 return (wmi_cmd_send(wmip, osbuf, WMI_SET_IBSS_PM_CAPS_CMDID, |
| 2699 NO_SYNC_WMIFLAG)); |
| 2700 } |
| 2701 |
| 2702 A_STATUS |
| 2703 wmi_apps_cmd(struct wmi_t *wmip, A_UINT8 psType, A_UINT32 idle_time, |
| 2704 A_UINT32 ps_period, A_UINT8 sleep_period) |
| 2705 { |
| 2706 void *osbuf; |
| 2707 WMI_AP_PS_CMD *cmd; |
| 2708 |
| 2709 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 2710 if (osbuf == NULL) { |
| 2711 return A_NO_MEMORY; |
| 2712 } |
| 2713 |
| 2714 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 2715 |
| 2716 cmd = (WMI_AP_PS_CMD *)(A_NETBUF_DATA(osbuf)); |
| 2717 A_MEMZERO(cmd, sizeof(*cmd)); |
| 2718 cmd->psType = psType; |
| 2719 cmd->idle_time = idle_time; |
| 2720 cmd->ps_period = ps_period; |
| 2721 cmd->sleep_period = sleep_period; |
| 2722 |
| 2723 return (wmi_cmd_send(wmip, osbuf, WMI_SET_AP_PS_CMDID, |
| 2724 NO_SYNC_WMIFLAG)); |
| 2725 } |
| 2726 |
| 2727 A_STATUS |
| 2728 wmi_pmparams_cmd(struct wmi_t *wmip, A_UINT16 idlePeriod, |
| 2729 A_UINT16 psPollNum, A_UINT16 dtimPolicy, |
| 2730 A_UINT16 tx_wakeup_policy, A_UINT16 num_tx_to_wakeup, |
| 2731 A_UINT16 ps_fail_event_policy) |
| 2732 { |
| 2733 void *osbuf; |
| 2734 WMI_POWER_PARAMS_CMD *pm; |
| 2735 |
| 2736 osbuf = A_NETBUF_ALLOC(sizeof(*pm)); |
| 2737 if (osbuf == NULL) { |
| 2738 return A_NO_MEMORY; |
| 2739 } |
| 2740 |
| 2741 A_NETBUF_PUT(osbuf, sizeof(*pm)); |
| 2742 |
| 2743 pm = (WMI_POWER_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); |
| 2744 A_MEMZERO(pm, sizeof(*pm)); |
| 2745 pm->idle_period = idlePeriod; |
| 2746 pm->pspoll_number = psPollNum; |
| 2747 pm->dtim_policy = dtimPolicy; |
| 2748 pm->tx_wakeup_policy = tx_wakeup_policy; |
| 2749 pm->num_tx_to_wakeup = num_tx_to_wakeup; |
| 2750 pm->ps_fail_event_policy = ps_fail_event_policy; |
| 2751 |
| 2752 return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_PARAMS_CMDID, |
| 2753 NO_SYNC_WMIFLAG)); |
| 2754 } |
| 2755 |
| 2756 A_STATUS |
| 2757 wmi_disctimeout_cmd(struct wmi_t *wmip, A_UINT8 timeout) |
| 2758 { |
| 2759 void *osbuf; |
| 2760 WMI_DISC_TIMEOUT_CMD *cmd; |
| 2761 |
| 2762 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 2763 if (osbuf == NULL) { |
| 2764 return A_NO_MEMORY; |
| 2765 } |
| 2766 |
| 2767 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 2768 |
| 2769 cmd = (WMI_DISC_TIMEOUT_CMD *)(A_NETBUF_DATA(osbuf)); |
| 2770 A_MEMZERO(cmd, sizeof(*cmd)); |
| 2771 cmd->disconnectTimeout = timeout; |
| 2772 |
| 2773 return (wmi_cmd_send(wmip, osbuf, WMI_SET_DISC_TIMEOUT_CMDID, |
| 2774 NO_SYNC_WMIFLAG)); |
| 2775 } |
| 2776 |
| 2777 A_STATUS |
| 2778 wmi_addKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex, CRYPTO_TYPE keyType, |
| 2779 A_UINT8 keyUsage, A_UINT8 keyLength, A_UINT8 *keyRSC, |
| 2780 A_UINT8 *keyMaterial, A_UINT8 key_op_ctrl, A_UINT8 *macAddr, |
| 2781 WMI_SYNC_FLAG sync_flag) |
| 2782 { |
| 2783 void *osbuf; |
| 2784 WMI_ADD_CIPHER_KEY_CMD *cmd; |
| 2785 |
| 2786 if ((keyIndex > WMI_MAX_KEY_INDEX) || (keyLength > WMI_MAX_KEY_LEN) || |
| 2787 (keyMaterial == NULL)) |
| 2788 { |
| 2789 return A_EINVAL; |
| 2790 } |
| 2791 |
| 2792 if ((WEP_CRYPT != keyType) && (NULL == keyRSC)) { |
| 2793 return A_EINVAL; |
| 2794 } |
| 2795 |
| 2796 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 2797 if (osbuf == NULL) { |
| 2798 return A_NO_MEMORY; |
| 2799 } |
| 2800 |
| 2801 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 2802 |
| 2803 cmd = (WMI_ADD_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf)); |
| 2804 A_MEMZERO(cmd, sizeof(*cmd)); |
| 2805 cmd->keyIndex = keyIndex; |
| 2806 cmd->keyType = keyType; |
| 2807 cmd->keyUsage = keyUsage; |
| 2808 cmd->keyLength = keyLength; |
| 2809 A_MEMCPY(cmd->key, keyMaterial, keyLength); |
| 2810 #ifdef WAPI_ENABLE |
| 2811 if (NULL != keyRSC && key_op_ctrl != KEY_OP_INIT_WAPIPN) { |
| 2812 #else |
| 2813 if (NULL != keyRSC) { |
| 2814 #endif // WAPI_ENABLE |
| 2815 A_MEMCPY(cmd->keyRSC, keyRSC, sizeof(cmd->keyRSC)); |
| 2816 } |
| 2817 cmd->key_op_ctrl = key_op_ctrl; |
| 2818 |
| 2819 if(macAddr) { |
| 2820 A_MEMCPY(cmd->key_macaddr,macAddr,IEEE80211_ADDR_LEN); |
| 2821 } |
| 2822 |
| 2823 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_CIPHER_KEY_CMDID, sync_flag)); |
| 2824 } |
| 2825 |
| 2826 A_STATUS |
| 2827 wmi_add_krk_cmd(struct wmi_t *wmip, A_UINT8 *krk) |
| 2828 { |
| 2829 void *osbuf; |
| 2830 WMI_ADD_KRK_CMD *cmd; |
| 2831 |
| 2832 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 2833 |
| 2834 if (osbuf == NULL) { |
| 2835 return A_NO_MEMORY; |
| 2836 } |
| 2837 |
| 2838 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 2839 |
| 2840 cmd = (WMI_ADD_KRK_CMD *)(A_NETBUF_DATA(osbuf)); |
| 2841 A_MEMZERO(cmd, sizeof(*cmd)); |
| 2842 A_MEMCPY(cmd->krk, krk, WMI_KRK_LEN); |
| 2843 |
| 2844 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_KRK_CMDID, NO_SYNC_WMIFLAG)); |
| 2845 } |
| 2846 |
| 2847 A_STATUS |
| 2848 wmi_delete_krk_cmd(struct wmi_t *wmip) |
| 2849 { |
| 2850 return wmi_simple_cmd(wmip, WMI_DELETE_KRK_CMDID); |
| 2851 } |
| 2852 |
| 2853 A_STATUS |
| 2854 wmi_deleteKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex) |
| 2855 { |
| 2856 void *osbuf; |
| 2857 WMI_DELETE_CIPHER_KEY_CMD *cmd; |
| 2858 |
| 2859 if (keyIndex > WMI_MAX_KEY_INDEX) { |
| 2860 return A_EINVAL; |
| 2861 } |
| 2862 |
| 2863 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 2864 if (osbuf == NULL) { |
| 2865 return A_NO_MEMORY; |
| 2866 } |
| 2867 |
| 2868 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 2869 |
| 2870 cmd = (WMI_DELETE_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf)); |
| 2871 A_MEMZERO(cmd, sizeof(*cmd)); |
| 2872 cmd->keyIndex = keyIndex; |
| 2873 |
| 2874 return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_CIPHER_KEY_CMDID, |
| 2875 NO_SYNC_WMIFLAG)); |
| 2876 } |
| 2877 |
| 2878 A_STATUS |
| 2879 wmi_setPmkid_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT8 *pmkId, |
| 2880 A_BOOL set) |
| 2881 { |
| 2882 void *osbuf; |
| 2883 WMI_SET_PMKID_CMD *cmd; |
| 2884 |
| 2885 if (bssid == NULL) { |
| 2886 return A_EINVAL; |
| 2887 } |
| 2888 |
| 2889 if ((set == TRUE) && (pmkId == NULL)) { |
| 2890 return A_EINVAL; |
| 2891 } |
| 2892 |
| 2893 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 2894 if (osbuf == NULL) { |
| 2895 return A_NO_MEMORY; |
| 2896 } |
| 2897 |
| 2898 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 2899 |
| 2900 cmd = (WMI_SET_PMKID_CMD *)(A_NETBUF_DATA(osbuf)); |
| 2901 A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid)); |
| 2902 if (set == TRUE) { |
| 2903 A_MEMCPY(cmd->pmkid, pmkId, sizeof(cmd->pmkid)); |
| 2904 cmd->enable = PMKID_ENABLE; |
| 2905 } else { |
| 2906 A_MEMZERO(cmd->pmkid, sizeof(cmd->pmkid)); |
| 2907 cmd->enable = PMKID_DISABLE; |
| 2908 } |
| 2909 |
| 2910 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_CMDID, NO_SYNC_WMIFLAG)); |
| 2911 } |
| 2912 |
| 2913 A_STATUS |
| 2914 wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, A_BOOL en) |
| 2915 { |
| 2916 void *osbuf; |
| 2917 WMI_SET_TKIP_COUNTERMEASURES_CMD *cmd; |
| 2918 |
| 2919 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 2920 if (osbuf == NULL) { |
| 2921 return A_NO_MEMORY; |
| 2922 } |
| 2923 |
| 2924 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 2925 |
| 2926 cmd = (WMI_SET_TKIP_COUNTERMEASURES_CMD *)(A_NETBUF_DATA(osbuf)); |
| 2927 cmd->cm_en = (en == TRUE)? WMI_TKIP_CM_ENABLE : WMI_TKIP_CM_DISABLE; |
| 2928 |
| 2929 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TKIP_COUNTERMEASURES_CMDID, |
| 2930 NO_SYNC_WMIFLAG)); |
| 2931 } |
| 2932 |
| 2933 A_STATUS |
| 2934 wmi_set_akmp_params_cmd(struct wmi_t *wmip, |
| 2935 WMI_SET_AKMP_PARAMS_CMD *akmpParams) |
| 2936 { |
| 2937 void *osbuf; |
| 2938 WMI_SET_AKMP_PARAMS_CMD *cmd; |
| 2939 |
| 2940 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 2941 if (osbuf == NULL) { |
| 2942 return A_NO_MEMORY; |
| 2943 } |
| 2944 |
| 2945 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 2946 cmd = (WMI_SET_AKMP_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); |
| 2947 cmd->akmpInfo = akmpParams->akmpInfo; |
| 2948 |
| 2949 return (wmi_cmd_send(wmip, osbuf, WMI_SET_AKMP_PARAMS_CMDID, |
| 2950 NO_SYNC_WMIFLAG)); |
| 2951 } |
| 2952 |
| 2953 A_STATUS |
| 2954 wmi_set_pmkid_list_cmd(struct wmi_t *wmip, |
| 2955 WMI_SET_PMKID_LIST_CMD *pmkInfo) |
| 2956 { |
| 2957 void *osbuf; |
| 2958 WMI_SET_PMKID_LIST_CMD *cmd; |
| 2959 A_UINT16 cmdLen; |
| 2960 A_UINT8 i; |
| 2961 |
| 2962 cmdLen = sizeof(pmkInfo->numPMKID) + |
| 2963 pmkInfo->numPMKID * sizeof(WMI_PMKID); |
| 2964 |
| 2965 osbuf = A_NETBUF_ALLOC(cmdLen); |
| 2966 |
| 2967 if (osbuf == NULL) { |
| 2968 return A_NO_MEMORY; |
| 2969 } |
| 2970 |
| 2971 A_NETBUF_PUT(osbuf, cmdLen); |
| 2972 cmd = (WMI_SET_PMKID_LIST_CMD *)(A_NETBUF_DATA(osbuf)); |
| 2973 cmd->numPMKID = pmkInfo->numPMKID; |
| 2974 |
| 2975 for (i = 0; i < cmd->numPMKID; i++) { |
| 2976 A_MEMCPY(&cmd->pmkidList[i], &pmkInfo->pmkidList[i], |
| 2977 WMI_PMKID_LEN); |
| 2978 } |
| 2979 |
| 2980 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_LIST_CMDID, |
| 2981 NO_SYNC_WMIFLAG)); |
| 2982 } |
| 2983 |
| 2984 A_STATUS |
| 2985 wmi_get_pmkid_list_cmd(struct wmi_t *wmip) |
| 2986 { |
| 2987 return wmi_simple_cmd(wmip, WMI_GET_PMKID_LIST_CMDID); |
| 2988 } |
| 2989 |
| 2990 A_STATUS |
| 2991 wmi_dataSync_send(struct wmi_t *wmip, void *osbuf, HTC_ENDPOINT_ID eid) |
| 2992 { |
| 2993 WMI_DATA_HDR *dtHdr; |
| 2994 |
| 2995 A_ASSERT( eid != wmip->wmi_endpoint_id); |
| 2996 A_ASSERT(osbuf != NULL); |
| 2997 |
| 2998 if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != A_OK) { |
| 2999 return A_NO_MEMORY; |
| 3000 } |
| 3001 |
| 3002 dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf); |
| 3003 dtHdr->info = |
| 3004 (SYNC_MSGTYPE & WMI_DATA_HDR_MSG_TYPE_MASK) << WMI_DATA_HDR_MSG_TYPE_SHIFT
; |
| 3005 |
| 3006 A_DPRINTF(DBG_WMI, (DBGFMT "Enter - eid %d\n", DBGARG, eid)); |
| 3007 |
| 3008 return (A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid)); |
| 3009 } |
| 3010 |
| 3011 typedef struct _WMI_DATA_SYNC_BUFS { |
| 3012 A_UINT8 trafficClass; |
| 3013 void *osbuf; |
| 3014 }WMI_DATA_SYNC_BUFS; |
| 3015 |
| 3016 static A_STATUS |
| 3017 wmi_sync_point(struct wmi_t *wmip) |
| 3018 { |
| 3019 void *cmd_osbuf; |
| 3020 WMI_SYNC_CMD *cmd; |
| 3021 WMI_DATA_SYNC_BUFS dataSyncBufs[WMM_NUM_AC]; |
| 3022 A_UINT8 i,numPriStreams=0; |
| 3023 A_STATUS status = A_OK; |
| 3024 |
| 3025 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 3026 |
| 3027 memset(dataSyncBufs,0,sizeof(dataSyncBufs)); |
| 3028 |
| 3029 /* lock out while we walk through the priority list and assemble our local a
rray */ |
| 3030 LOCK_WMI(wmip); |
| 3031 |
| 3032 for (i=0; i < WMM_NUM_AC ; i++) { |
| 3033 if (wmip->wmi_fatPipeExists & (1 << i)) { |
| 3034 numPriStreams++; |
| 3035 dataSyncBufs[numPriStreams-1].trafficClass = i; |
| 3036 } |
| 3037 } |
| 3038 |
| 3039 UNLOCK_WMI(wmip); |
| 3040 |
| 3041 /* dataSyncBufs is now filled with entries (starting at index 0) containing
valid streamIDs */ |
| 3042 |
| 3043 do { |
| 3044 /* |
| 3045 * We allocate all network buffers needed so we will be able to |
| 3046 * send all required frames. |
| 3047 */ |
| 3048 cmd_osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 3049 if (cmd_osbuf == NULL) { |
| 3050 status = A_NO_MEMORY; |
| 3051 break; |
| 3052 } |
| 3053 |
| 3054 A_NETBUF_PUT(cmd_osbuf, sizeof(*cmd)); |
| 3055 |
| 3056 cmd = (WMI_SYNC_CMD *)(A_NETBUF_DATA(cmd_osbuf)); |
| 3057 A_MEMZERO(cmd, sizeof(*cmd)); |
| 3058 |
| 3059 /* In the SYNC cmd sent on the control Ep, send a bitmap of the data |
| 3060 * eps on which the Data Sync will be sent |
| 3061 */ |
| 3062 cmd->dataSyncMap = wmip->wmi_fatPipeExists; |
| 3063 |
| 3064 for (i=0; i < numPriStreams ; i++) { |
| 3065 dataSyncBufs[i].osbuf = A_NETBUF_ALLOC(0); |
| 3066 if (dataSyncBufs[i].osbuf == NULL) { |
| 3067 status = A_NO_MEMORY; |
| 3068 break; |
| 3069 } |
| 3070 } //end for |
| 3071 |
| 3072 /* if Buffer allocation for any of the dataSync fails, then do not |
| 3073 * send the Synchronize cmd on the control ep |
| 3074 */ |
| 3075 if (A_FAILED(status)) { |
| 3076 break; |
| 3077 } |
| 3078 |
| 3079 /* |
| 3080 * Send sync cmd followed by sync data messages on all endpoints being |
| 3081 * used |
| 3082 */ |
| 3083 status = wmi_cmd_send(wmip, cmd_osbuf, WMI_SYNCHRONIZE_CMDID, |
| 3084 NO_SYNC_WMIFLAG); |
| 3085 |
| 3086 if (A_FAILED(status)) { |
| 3087 break; |
| 3088 } |
| 3089 /* cmd buffer sent, we no longer own it */ |
| 3090 cmd_osbuf = NULL; |
| 3091 |
| 3092 for(i=0; i < numPriStreams; i++) { |
| 3093 A_ASSERT(dataSyncBufs[i].osbuf != NULL); |
| 3094 status = wmi_dataSync_send(wmip, |
| 3095 dataSyncBufs[i].osbuf, |
| 3096 A_WMI_Ac2EndpointID(wmip->wmi_devt, |
| 3097 dataSyncBufs[i]. |
| 3098 trafficClass) |
| 3099 ); |
| 3100 |
| 3101 if (A_FAILED(status)) { |
| 3102 break; |
| 3103 } |
| 3104 /* we don't own this buffer anymore, NULL it out of the array so it |
| 3105 * won't get cleaned up */ |
| 3106 dataSyncBufs[i].osbuf = NULL; |
| 3107 } //end for |
| 3108 |
| 3109 } while(FALSE); |
| 3110 |
| 3111 /* free up any resources left over (possibly due to an error) */ |
| 3112 |
| 3113 if (cmd_osbuf != NULL) { |
| 3114 A_NETBUF_FREE(cmd_osbuf); |
| 3115 } |
| 3116 |
| 3117 for (i = 0; i < numPriStreams; i++) { |
| 3118 if (dataSyncBufs[i].osbuf != NULL) { |
| 3119 A_NETBUF_FREE(dataSyncBufs[i].osbuf); |
| 3120 } |
| 3121 } |
| 3122 |
| 3123 return (status); |
| 3124 } |
| 3125 |
| 3126 A_STATUS |
| 3127 wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *params) |
| 3128 { |
| 3129 void *osbuf; |
| 3130 WMI_CREATE_PSTREAM_CMD *cmd; |
| 3131 A_UINT8 fatPipeExistsForAC=0; |
| 3132 A_INT32 minimalPHY = 0; |
| 3133 A_INT32 nominalPHY = 0; |
| 3134 |
| 3135 /* Validate all the parameters. */ |
| 3136 if( !((params->userPriority < 8) && |
| 3137 (params->userPriority <= 0x7) && |
| 3138 (convert_userPriority_to_trafficClass(params->userPriority) == params->
trafficClass) && |
| 3139 (params->trafficDirection == UPLINK_TRAFFIC || |
| 3140 params->trafficDirection == DNLINK_TRAFFIC || |
| 3141 params->trafficDirection == BIDIR_TRAFFIC) && |
| 3142 (params->trafficType == TRAFFIC_TYPE_APERIODIC || |
| 3143 params->trafficType == TRAFFIC_TYPE_PERIODIC ) && |
| 3144 (params->voicePSCapability == DISABLE_FOR_THIS_AC || |
| 3145 params->voicePSCapability == ENABLE_FOR_THIS_AC || |
| 3146 params->voicePSCapability == ENABLE_FOR_ALL_AC) && |
| 3147 (params->tsid == WMI_IMPLICIT_PSTREAM || params->tsid <= WMI_MAX_THINST
REAM)) ) |
| 3148 { |
| 3149 return A_EINVAL; |
| 3150 } |
| 3151 |
| 3152 // |
| 3153 // check nominal PHY rate is >= minimalPHY, so that DUT |
| 3154 // can allow TSRS IE |
| 3155 // |
| 3156 |
| 3157 // get the physical rate |
| 3158 minimalPHY = ((params->minPhyRate / 1000)/1000); // unit of bps |
| 3159 |
| 3160 // check minimal phy < nominal phy rate |
| 3161 // |
| 3162 if (params->nominalPHY >= minimalPHY) |
| 3163 { |
| 3164 nominalPHY = (params->nominalPHY * 1000)/500; // unit of 500 kbps |
| 3165 A_DPRINTF(DBG_WMI, |
| 3166 (DBGFMT "TSRS IE Enabled::MinPhy %x->NominalPhy ===> %x\n", DB
GARG, |
| 3167 minimalPHY, nominalPHY)); |
| 3168 |
| 3169 params->nominalPHY = nominalPHY; |
| 3170 } |
| 3171 else |
| 3172 { |
| 3173 params->nominalPHY = 0; |
| 3174 } |
| 3175 |
| 3176 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 3177 if (osbuf == NULL) { |
| 3178 return A_NO_MEMORY; |
| 3179 } |
| 3180 |
| 3181 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 3182 |
| 3183 A_DPRINTF(DBG_WMI, |
| 3184 (DBGFMT "Sending create_pstream_cmd: ac=%d tsid:%d\n", DBGARG, |
| 3185 params->trafficClass, params->tsid)); |
| 3186 |
| 3187 cmd = (WMI_CREATE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf)); |
| 3188 A_MEMZERO(cmd, sizeof(*cmd)); |
| 3189 A_MEMCPY(cmd, params, sizeof(*cmd)); |
| 3190 |
| 3191 /* this is an implicitly created Fat pipe */ |
| 3192 if ((A_UINT32)params->tsid == (A_UINT32)WMI_IMPLICIT_PSTREAM) { |
| 3193 LOCK_WMI(wmip); |
| 3194 fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficCla
ss)); |
| 3195 wmip->wmi_fatPipeExists |= (1<<params->trafficClass); |
| 3196 UNLOCK_WMI(wmip); |
| 3197 } else { |
| 3198 /* this is an explicitly created thin stream within a fat pipe */ |
| 3199 LOCK_WMI(wmip); |
| 3200 fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficCla
ss)); |
| 3201 wmip->wmi_streamExistsForAC[params->trafficClass] |= (1<<params->tsid); |
| 3202 /* if a thinstream becomes active, the fat pipe automatically |
| 3203 * becomes active |
| 3204 */ |
| 3205 wmip->wmi_fatPipeExists |= (1<<params->trafficClass); |
| 3206 UNLOCK_WMI(wmip); |
| 3207 } |
| 3208 |
| 3209 /* Indicate activty change to driver layer only if this is the |
| 3210 * first TSID to get created in this AC explicitly or an implicit |
| 3211 * fat pipe is getting created. |
| 3212 */ |
| 3213 if (!fatPipeExistsForAC) { |
| 3214 A_WMI_STREAM_TX_ACTIVE(wmip->wmi_devt, params->trafficClass); |
| 3215 } |
| 3216 |
| 3217 /* mike: should be SYNC_BEFORE_WMIFLAG */ |
| 3218 return (wmi_cmd_send(wmip, osbuf, WMI_CREATE_PSTREAM_CMDID, |
| 3219 NO_SYNC_WMIFLAG)); |
| 3220 } |
| 3221 |
| 3222 A_STATUS |
| 3223 wmi_delete_pstream_cmd(struct wmi_t *wmip, A_UINT8 trafficClass, A_UINT8 tsid) |
| 3224 { |
| 3225 void *osbuf; |
| 3226 WMI_DELETE_PSTREAM_CMD *cmd; |
| 3227 A_STATUS status; |
| 3228 A_UINT16 activeTsids=0; |
| 3229 |
| 3230 /* validate the parameters */ |
| 3231 if (trafficClass > 3) { |
| 3232 A_DPRINTF(DBG_WMI, (DBGFMT "Invalid trafficClass: %d\n", DBGARG, traffic
Class)); |
| 3233 return A_EINVAL; |
| 3234 } |
| 3235 |
| 3236 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 3237 if (osbuf == NULL) { |
| 3238 return A_NO_MEMORY; |
| 3239 } |
| 3240 |
| 3241 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 3242 |
| 3243 cmd = (WMI_DELETE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf)); |
| 3244 A_MEMZERO(cmd, sizeof(*cmd)); |
| 3245 |
| 3246 cmd->trafficClass = trafficClass; |
| 3247 cmd->tsid = tsid; |
| 3248 |
| 3249 LOCK_WMI(wmip); |
| 3250 activeTsids = wmip->wmi_streamExistsForAC[trafficClass]; |
| 3251 UNLOCK_WMI(wmip); |
| 3252 |
| 3253 /* Check if the tsid was created & exists */ |
| 3254 if (!(activeTsids & (1<<tsid))) { |
| 3255 |
| 3256 A_DPRINTF(DBG_WMI, |
| 3257 (DBGFMT "TSID %d does'nt exist for trafficClass: %d\n", DBGARG, tsid, tr
afficClass)); |
| 3258 /* TODO: return a more appropriate err code */ |
| 3259 return A_ERROR; |
| 3260 } |
| 3261 |
| 3262 A_DPRINTF(DBG_WMI, |
| 3263 (DBGFMT "Sending delete_pstream_cmd: trafficClass: %d tsid=%d\n", DBGARG
, trafficClass, tsid)); |
| 3264 |
| 3265 status = (wmi_cmd_send(wmip, osbuf, WMI_DELETE_PSTREAM_CMDID, |
| 3266 SYNC_BEFORE_WMIFLAG)); |
| 3267 |
| 3268 LOCK_WMI(wmip); |
| 3269 wmip->wmi_streamExistsForAC[trafficClass] &= ~(1<<tsid); |
| 3270 activeTsids = wmip->wmi_streamExistsForAC[trafficClass]; |
| 3271 UNLOCK_WMI(wmip); |
| 3272 |
| 3273 |
| 3274 /* Indicate stream inactivity to driver layer only if all tsids |
| 3275 * within this AC are deleted. |
| 3276 */ |
| 3277 if(!activeTsids) { |
| 3278 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, trafficClass); |
| 3279 wmip->wmi_fatPipeExists &= ~(1<<trafficClass); |
| 3280 } |
| 3281 |
| 3282 return status; |
| 3283 } |
| 3284 |
| 3285 A_STATUS |
| 3286 wmi_set_framerate_cmd(struct wmi_t *wmip, A_UINT8 bEnable, A_UINT8 type, A_UINT8
subType, A_UINT16 rateMask) |
| 3287 { |
| 3288 void *osbuf; |
| 3289 WMI_FRAME_RATES_CMD *cmd; |
| 3290 A_UINT8 frameType; |
| 3291 |
| 3292 A_DPRINTF(DBG_WMI, |
| 3293 (DBGFMT " type %02X, subType %02X, rateMask %04x\n", DBGARG, type, subTy
pe, rateMask)); |
| 3294 |
| 3295 if((type != IEEE80211_FRAME_TYPE_MGT && type != IEEE80211_FRAME_TYPE_CTL) || |
| 3296 (subType > 15)){ |
| 3297 |
| 3298 return A_EINVAL; |
| 3299 } |
| 3300 |
| 3301 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 3302 if (osbuf == NULL) { |
| 3303 return A_NO_MEMORY; |
| 3304 } |
| 3305 |
| 3306 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 3307 |
| 3308 cmd = (WMI_FRAME_RATES_CMD *)(A_NETBUF_DATA(osbuf)); |
| 3309 A_MEMZERO(cmd, sizeof(*cmd)); |
| 3310 |
| 3311 frameType = (A_UINT8)((subType << 4) | type); |
| 3312 |
| 3313 cmd->bEnableMask = bEnable; |
| 3314 cmd->frameType = frameType; |
| 3315 cmd->frameRateMask = rateMask; |
| 3316 |
| 3317 return (wmi_cmd_send(wmip, osbuf, WMI_SET_FRAMERATES_CMDID, NO_SYNC_WMIFLAG)
); |
| 3318 } |
| 3319 |
| 3320 /* |
| 3321 * used to set the bit rate. rate is in Kbps. If rate == -1 |
| 3322 * then auto selection is used. |
| 3323 */ |
| 3324 A_STATUS |
| 3325 wmi_set_bitrate_cmd(struct wmi_t *wmip, A_INT32 dataRate, A_INT32 mgmtRate, A_IN
T32 ctlRate) |
| 3326 { |
| 3327 void *osbuf; |
| 3328 WMI_BIT_RATE_CMD *cmd; |
| 3329 A_INT8 drix, mrix, crix; |
| 3330 |
| 3331 if (dataRate != -1) { |
| 3332 drix = wmi_validate_bitrate(wmip, dataRate); |
| 3333 if(drix == A_EINVAL){ |
| 3334 return A_EINVAL; |
| 3335 } |
| 3336 } else { |
| 3337 drix = -1; |
| 3338 } |
| 3339 |
| 3340 if (mgmtRate != -1) { |
| 3341 mrix = wmi_validate_bitrate(wmip, mgmtRate); |
| 3342 if(mrix == A_EINVAL){ |
| 3343 return A_EINVAL; |
| 3344 } |
| 3345 } else { |
| 3346 mrix = -1; |
| 3347 } |
| 3348 if (ctlRate != -1) { |
| 3349 crix = wmi_validate_bitrate(wmip, ctlRate); |
| 3350 if(crix == A_EINVAL){ |
| 3351 return A_EINVAL; |
| 3352 } |
| 3353 } else { |
| 3354 crix = -1; |
| 3355 } |
| 3356 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 3357 if (osbuf == NULL) { |
| 3358 return A_NO_MEMORY; |
| 3359 } |
| 3360 |
| 3361 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 3362 |
| 3363 cmd = (WMI_BIT_RATE_CMD *)(A_NETBUF_DATA(osbuf)); |
| 3364 A_MEMZERO(cmd, sizeof(*cmd)); |
| 3365 |
| 3366 cmd->rateIndex = drix; |
| 3367 cmd->mgmtRateIndex = mrix; |
| 3368 cmd->ctlRateIndex = crix; |
| 3369 |
| 3370 |
| 3371 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BITRATE_CMDID, NO_SYNC_WMIFLAG)); |
| 3372 } |
| 3373 |
| 3374 A_STATUS |
| 3375 wmi_get_bitrate_cmd(struct wmi_t *wmip) |
| 3376 { |
| 3377 return wmi_simple_cmd(wmip, WMI_GET_BITRATE_CMDID); |
| 3378 } |
| 3379 |
| 3380 /* |
| 3381 * Returns TRUE iff the given rate index is legal in the current PHY mode. |
| 3382 */ |
| 3383 A_BOOL |
| 3384 wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_INT32 rateIndex) |
| 3385 { |
| 3386 WMI_PHY_MODE phyMode = (WMI_PHY_MODE) wmip->wmi_phyMode; |
| 3387 A_BOOL isValid = TRUE; |
| 3388 switch(phyMode) { |
| 3389 case WMI_11A_MODE: |
| 3390 if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_A_S
UPPORT_RATE_STOP)) { |
| 3391 isValid = FALSE; |
| 3392 } |
| 3393 break; |
| 3394 |
| 3395 case WMI_11B_MODE: |
| 3396 if ((rateIndex < MODE_B_SUPPORT_RATE_START) || (rateIndex > MODE_B_S
UPPORT_RATE_STOP)) { |
| 3397 isValid = FALSE; |
| 3398 } |
| 3399 break; |
| 3400 |
| 3401 case WMI_11GONLY_MODE: |
| 3402 if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE
_GONLY_SUPPORT_RATE_STOP)) { |
| 3403 isValid = FALSE; |
| 3404 } |
| 3405 break; |
| 3406 |
| 3407 case WMI_11G_MODE: |
| 3408 case WMI_11AG_MODE: |
| 3409 case WMI_DEFAULT_MODE: |
| 3410 case WMI_11GHT20_MODE: |
| 3411 if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_G_S
UPPORT_RATE_STOP)) { |
| 3412 isValid = FALSE; |
| 3413 } |
| 3414 break; |
| 3415 |
| 3416 default: |
| 3417 A_ASSERT(FALSE); |
| 3418 break; |
| 3419 } |
| 3420 |
| 3421 return isValid; |
| 3422 } |
| 3423 |
| 3424 A_INT8 |
| 3425 wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate) |
| 3426 { |
| 3427 A_INT8 i; |
| 3428 if (rate != -1) |
| 3429 { |
| 3430 for (i=0;;i++) |
| 3431 { |
| 3432 if (wmi_rateTable[(A_UINT32) i] == 0) { |
| 3433 return A_EINVAL; |
| 3434 } |
| 3435 if (wmi_rateTable[(A_UINT32) i] == rate) { |
| 3436 break; |
| 3437 } |
| 3438 } |
| 3439 } |
| 3440 else{ |
| 3441 i = -1; |
| 3442 } |
| 3443 |
| 3444 if(wmi_is_bitrate_index_valid(wmip, (A_INT32) i) != TRUE) { |
| 3445 return A_EINVAL; |
| 3446 } |
| 3447 |
| 3448 return i; |
| 3449 } |
| 3450 |
| 3451 A_STATUS |
| 3452 wmi_set_fixrates_cmd(struct wmi_t *wmip, A_UINT32 fixRatesMask) |
| 3453 { |
| 3454 void *osbuf; |
| 3455 WMI_FIX_RATES_CMD *cmd; |
| 3456 #if 0 |
| 3457 A_INT32 rateIndex; |
| 3458 /* This check does not work for AR6003 as the HT modes are enabled only when |
| 3459 * the STA is connected to a HT_BSS and is not based only on channel. It is |
| 3460 * safe to skip this check however because rate control will only use rates |
| 3461 * that are permitted by the valid rate mask and the fix rate mask. Meaning |
| 3462 * the fix rate mask is not sufficient by itself to cause an invalid rate |
| 3463 * to be used. */ |
| 3464 /* Make sure all rates in the mask are valid in the current PHY mode */ |
| 3465 for(rateIndex = 0; rateIndex < MAX_NUMBER_OF_SUPPORT_RATES; rateIndex++) { |
| 3466 if((1 << rateIndex) & (A_UINT32)fixRatesMask) { |
| 3467 if(wmi_is_bitrate_index_valid(wmip, rateIndex) != TRUE) { |
| 3468 A_DPRINTF(DBG_WMI, (DBGFMT "Set Fix Rates command failed: Given
rate is illegal in current PHY mode\n", DBGARG)); |
| 3469 return A_EINVAL; |
| 3470 } |
| 3471 } |
| 3472 } |
| 3473 #endif |
| 3474 |
| 3475 |
| 3476 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 3477 if (osbuf == NULL) { |
| 3478 return A_NO_MEMORY; |
| 3479 } |
| 3480 |
| 3481 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 3482 |
| 3483 cmd = (WMI_FIX_RATES_CMD *)(A_NETBUF_DATA(osbuf)); |
| 3484 A_MEMZERO(cmd, sizeof(*cmd)); |
| 3485 |
| 3486 cmd->fixRateMask = fixRatesMask; |
| 3487 |
| 3488 return (wmi_cmd_send(wmip, osbuf, WMI_SET_FIXRATES_CMDID, NO_SYNC_WMIFLAG)); |
| 3489 } |
| 3490 |
| 3491 A_STATUS |
| 3492 wmi_get_ratemask_cmd(struct wmi_t *wmip) |
| 3493 { |
| 3494 return wmi_simple_cmd(wmip, WMI_GET_FIXRATES_CMDID); |
| 3495 } |
| 3496 |
| 3497 A_STATUS |
| 3498 wmi_get_channelList_cmd(struct wmi_t *wmip) |
| 3499 { |
| 3500 return wmi_simple_cmd(wmip, WMI_GET_CHANNEL_LIST_CMDID); |
| 3501 } |
| 3502 |
| 3503 /* |
| 3504 * used to generate a wmi sey channel Parameters cmd. |
| 3505 * mode should always be specified and corresponds to the phy mode of the |
| 3506 * wlan. |
| 3507 * numChan should alway sbe specified. If zero indicates that all available |
| 3508 * channels should be used. |
| 3509 * channelList is an array of channel frequencies (in Mhz) which the radio |
| 3510 * should limit its operation to. It should be NULL if numChan == 0. Size of |
| 3511 * array should correspond to numChan entries. |
| 3512 */ |
| 3513 A_STATUS |
| 3514 wmi_set_channelParams_cmd(struct wmi_t *wmip, A_UINT8 scanParam, |
| 3515 WMI_PHY_MODE mode, A_INT8 numChan, |
| 3516 A_UINT16 *channelList) |
| 3517 { |
| 3518 void *osbuf; |
| 3519 WMI_CHANNEL_PARAMS_CMD *cmd; |
| 3520 A_INT8 size; |
| 3521 |
| 3522 size = sizeof (*cmd); |
| 3523 |
| 3524 if (numChan) { |
| 3525 if (numChan > WMI_MAX_CHANNELS) { |
| 3526 return A_EINVAL; |
| 3527 } |
| 3528 size += sizeof(A_UINT16) * (numChan - 1); |
| 3529 } |
| 3530 |
| 3531 osbuf = A_NETBUF_ALLOC(size); |
| 3532 if (osbuf == NULL) { |
| 3533 return A_NO_MEMORY; |
| 3534 } |
| 3535 |
| 3536 A_NETBUF_PUT(osbuf, size); |
| 3537 |
| 3538 cmd = (WMI_CHANNEL_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); |
| 3539 A_MEMZERO(cmd, size); |
| 3540 |
| 3541 wmip->wmi_phyMode = mode; |
| 3542 cmd->scanParam = scanParam; |
| 3543 cmd->phyMode = mode; |
| 3544 cmd->numChannels = numChan; |
| 3545 A_MEMCPY(cmd->channelList, channelList, numChan * sizeof(A_UINT16)); |
| 3546 |
| 3547 return (wmi_cmd_send(wmip, osbuf, WMI_SET_CHANNEL_PARAMS_CMDID, |
| 3548 NO_SYNC_WMIFLAG)); |
| 3549 } |
| 3550 |
| 3551 void |
| 3552 wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_
CMD *rssiCmd) |
| 3553 { |
| 3554 SQ_THRESHOLD_PARAMS *sq_thresh = |
| 3555 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI]; |
| 3556 /* |
| 3557 * Parse the command and store the threshold values here. The checks |
| 3558 * for valid values can be put here |
| 3559 */ |
| 3560 sq_thresh->weight = rssiCmd->weight; |
| 3561 sq_thresh->polling_interval = rssiCmd->pollTime; |
| 3562 |
| 3563 sq_thresh->upper_threshold[0] = rssiCmd->thresholdAbove1_Val - SIGNAL_QUALIT
Y_NOISE_FLOOR; |
| 3564 sq_thresh->upper_threshold[1] = rssiCmd->thresholdAbove2_Val - SIGNAL_QUALIT
Y_NOISE_FLOOR; |
| 3565 sq_thresh->upper_threshold[2] = rssiCmd->thresholdAbove3_Val - SIGNAL_QUALIT
Y_NOISE_FLOOR; |
| 3566 sq_thresh->upper_threshold[3] = rssiCmd->thresholdAbove4_Val - SIGNAL_QUALIT
Y_NOISE_FLOOR; |
| 3567 sq_thresh->upper_threshold[4] = rssiCmd->thresholdAbove5_Val - SIGNAL_QUALIT
Y_NOISE_FLOOR; |
| 3568 sq_thresh->upper_threshold[5] = rssiCmd->thresholdAbove6_Val - SIGNAL_QUALIT
Y_NOISE_FLOOR; |
| 3569 sq_thresh->upper_threshold_valid_count = 6; |
| 3570 |
| 3571 /* List sorted in descending order */ |
| 3572 sq_thresh->lower_threshold[0] = rssiCmd->thresholdBelow6_Val - SIGNAL_QUALIT
Y_NOISE_FLOOR; |
| 3573 sq_thresh->lower_threshold[1] = rssiCmd->thresholdBelow5_Val - SIGNAL_QUALIT
Y_NOISE_FLOOR; |
| 3574 sq_thresh->lower_threshold[2] = rssiCmd->thresholdBelow4_Val - SIGNAL_QUALIT
Y_NOISE_FLOOR; |
| 3575 sq_thresh->lower_threshold[3] = rssiCmd->thresholdBelow3_Val - SIGNAL_QUALIT
Y_NOISE_FLOOR; |
| 3576 sq_thresh->lower_threshold[4] = rssiCmd->thresholdBelow2_Val - SIGNAL_QUALIT
Y_NOISE_FLOOR; |
| 3577 sq_thresh->lower_threshold[5] = rssiCmd->thresholdBelow1_Val - SIGNAL_QUALIT
Y_NOISE_FLOOR; |
| 3578 sq_thresh->lower_threshold_valid_count = 6; |
| 3579 |
| 3580 if (!rssi_event_value) { |
| 3581 /* |
| 3582 * Configuring the thresholds to their extremes allows the host to get an |
| 3583 * event from the target which is used for the configuring the correct |
| 3584 * thresholds |
| 3585 */ |
| 3586 rssiCmd->thresholdAbove1_Val = sq_thresh->upper_threshold[0]; |
| 3587 rssiCmd->thresholdBelow1_Val = sq_thresh->lower_threshold[0]; |
| 3588 } else { |
| 3589 /* |
| 3590 * In case the user issues multiple times of rssi_threshold_setting, |
| 3591 * we should not use the extreames anymore, the target does not expect t
hat. |
| 3592 */ |
| 3593 rssiCmd->thresholdAbove1_Val = ar6000_get_upper_threshold(rssi_event_val
ue, sq_thresh, |
| 3594 sq_thresh->upper_threshold_valid_c
ount); |
| 3595 rssiCmd->thresholdBelow1_Val = ar6000_get_lower_threshold(rssi_event_val
ue, sq_thresh, |
| 3596 sq_thresh->lower_threshold_valid_c
ount); |
| 3597 } |
| 3598 } |
| 3599 |
| 3600 A_STATUS |
| 3601 wmi_set_rssi_threshold_params(struct wmi_t *wmip, |
| 3602 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd) |
| 3603 { |
| 3604 |
| 3605 /* Check these values are in ascending order */ |
| 3606 if( rssiCmd->thresholdAbove6_Val <= rssiCmd->thresholdAbove5_Val || |
| 3607 rssiCmd->thresholdAbove5_Val <= rssiCmd->thresholdAbove4_Val || |
| 3608 rssiCmd->thresholdAbove4_Val <= rssiCmd->thresholdAbove3_Val || |
| 3609 rssiCmd->thresholdAbove3_Val <= rssiCmd->thresholdAbove2_Val || |
| 3610 rssiCmd->thresholdAbove2_Val <= rssiCmd->thresholdAbove1_Val || |
| 3611 rssiCmd->thresholdBelow6_Val <= rssiCmd->thresholdBelow5_Val || |
| 3612 rssiCmd->thresholdBelow5_Val <= rssiCmd->thresholdBelow4_Val || |
| 3613 rssiCmd->thresholdBelow4_Val <= rssiCmd->thresholdBelow3_Val || |
| 3614 rssiCmd->thresholdBelow3_Val <= rssiCmd->thresholdBelow2_Val || |
| 3615 rssiCmd->thresholdBelow2_Val <= rssiCmd->thresholdBelow1_Val) |
| 3616 { |
| 3617 return A_EINVAL; |
| 3618 } |
| 3619 |
| 3620 wmi_cache_configure_rssithreshold(wmip, rssiCmd); |
| 3621 |
| 3622 return (wmi_send_rssi_threshold_params(wmip, rssiCmd)); |
| 3623 } |
| 3624 |
| 3625 A_STATUS |
| 3626 wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *ipCmd) |
| 3627 { |
| 3628 void *osbuf; |
| 3629 WMI_SET_IP_CMD *cmd; |
| 3630 |
| 3631 /* Multicast address are not valid */ |
| 3632 if((*((A_UINT8*)&ipCmd->ips[0]) >= 0xE0) || |
| 3633 (*((A_UINT8*)&ipCmd->ips[1]) >= 0xE0)) { |
| 3634 return A_EINVAL; |
| 3635 } |
| 3636 |
| 3637 osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_IP_CMD)); |
| 3638 if (osbuf == NULL) { |
| 3639 return A_NO_MEMORY; |
| 3640 } |
| 3641 |
| 3642 A_NETBUF_PUT(osbuf, sizeof(WMI_SET_IP_CMD)); |
| 3643 cmd = (WMI_SET_IP_CMD *)(A_NETBUF_DATA(osbuf)); |
| 3644 A_MEMCPY(cmd, ipCmd, sizeof(WMI_SET_IP_CMD)); |
| 3645 |
| 3646 return (wmi_cmd_send(wmip, osbuf, WMI_SET_IP_CMDID, |
| 3647 NO_SYNC_WMIFLAG)); |
| 3648 } |
| 3649 |
| 3650 A_STATUS |
| 3651 wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip, |
| 3652 WMI_SET_HOST_SLEEP_MODE_CMD *hostModeCmd) |
| 3653 { |
| 3654 void *osbuf; |
| 3655 A_INT8 size; |
| 3656 WMI_SET_HOST_SLEEP_MODE_CMD *cmd; |
| 3657 A_UINT16 activeTsids=0; |
| 3658 A_UINT8 streamExists=0; |
| 3659 A_UINT8 i; |
| 3660 |
| 3661 if( hostModeCmd->awake == hostModeCmd->asleep) { |
| 3662 return A_EINVAL; |
| 3663 } |
| 3664 |
| 3665 size = sizeof (*cmd); |
| 3666 |
| 3667 osbuf = A_NETBUF_ALLOC(size); |
| 3668 if (osbuf == NULL) { |
| 3669 return A_NO_MEMORY; |
| 3670 } |
| 3671 |
| 3672 A_NETBUF_PUT(osbuf, size); |
| 3673 |
| 3674 cmd = (WMI_SET_HOST_SLEEP_MODE_CMD *)(A_NETBUF_DATA(osbuf)); |
| 3675 A_MEMZERO(cmd, size); |
| 3676 A_MEMCPY(cmd, hostModeCmd, sizeof(WMI_SET_HOST_SLEEP_MODE_CMD)); |
| 3677 |
| 3678 if(hostModeCmd->asleep) { |
| 3679 /* |
| 3680 * Relinquish credits from all implicitly created pstreams since when we |
| 3681 * go to sleep. If user created explicit thinstreams exists with in a |
| 3682 * fatpipe leave them intact for the user to delete |
| 3683 */ |
| 3684 LOCK_WMI(wmip); |
| 3685 streamExists = wmip->wmi_fatPipeExists; |
| 3686 UNLOCK_WMI(wmip); |
| 3687 |
| 3688 for(i=0;i< WMM_NUM_AC;i++) { |
| 3689 if (streamExists & (1<<i)) { |
| 3690 LOCK_WMI(wmip); |
| 3691 activeTsids = wmip->wmi_streamExistsForAC[i]; |
| 3692 UNLOCK_WMI(wmip); |
| 3693 /* If there are no user created thin streams delete the fatpipe
*/ |
| 3694 if(!activeTsids) { |
| 3695 streamExists &= ~(1<<i); |
| 3696 /*Indicate inactivity to drv layer for this fatpipe(pstream)
*/ |
| 3697 A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt,i); |
| 3698 } |
| 3699 } |
| 3700 } |
| 3701 |
| 3702 /* Update the fatpipes that exists*/ |
| 3703 LOCK_WMI(wmip); |
| 3704 wmip->wmi_fatPipeExists = streamExists; |
| 3705 UNLOCK_WMI(wmip); |
| 3706 } |
| 3707 |
| 3708 return (wmi_cmd_send(wmip, osbuf, WMI_SET_HOST_SLEEP_MODE_CMDID, |
| 3709 NO_SYNC_WMIFLAG)); |
| 3710 } |
| 3711 |
| 3712 A_STATUS |
| 3713 wmi_set_wow_mode_cmd(struct wmi_t *wmip, |
| 3714 WMI_SET_WOW_MODE_CMD *wowModeCmd) |
| 3715 { |
| 3716 void *osbuf; |
| 3717 A_INT8 size; |
| 3718 WMI_SET_WOW_MODE_CMD *cmd; |
| 3719 |
| 3720 size = sizeof (*cmd); |
| 3721 |
| 3722 osbuf = A_NETBUF_ALLOC(size); |
| 3723 if (osbuf == NULL) { |
| 3724 return A_NO_MEMORY; |
| 3725 } |
| 3726 |
| 3727 A_NETBUF_PUT(osbuf, size); |
| 3728 |
| 3729 cmd = (WMI_SET_WOW_MODE_CMD *)(A_NETBUF_DATA(osbuf)); |
| 3730 A_MEMZERO(cmd, size); |
| 3731 A_MEMCPY(cmd, wowModeCmd, sizeof(WMI_SET_WOW_MODE_CMD)); |
| 3732 |
| 3733 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WOW_MODE_CMDID, |
| 3734 NO_SYNC_WMIFLAG)); |
| 3735 |
| 3736 } |
| 3737 |
| 3738 A_STATUS |
| 3739 wmi_get_wow_list_cmd(struct wmi_t *wmip, |
| 3740 WMI_GET_WOW_LIST_CMD *wowListCmd) |
| 3741 { |
| 3742 void *osbuf; |
| 3743 A_INT8 size; |
| 3744 WMI_GET_WOW_LIST_CMD *cmd; |
| 3745 |
| 3746 size = sizeof (*cmd); |
| 3747 |
| 3748 osbuf = A_NETBUF_ALLOC(size); |
| 3749 if (osbuf == NULL) { |
| 3750 return A_NO_MEMORY; |
| 3751 } |
| 3752 |
| 3753 A_NETBUF_PUT(osbuf, size); |
| 3754 |
| 3755 cmd = (WMI_GET_WOW_LIST_CMD *)(A_NETBUF_DATA(osbuf)); |
| 3756 A_MEMZERO(cmd, size); |
| 3757 A_MEMCPY(cmd, wowListCmd, sizeof(WMI_GET_WOW_LIST_CMD)); |
| 3758 |
| 3759 return (wmi_cmd_send(wmip, osbuf, WMI_GET_WOW_LIST_CMDID, |
| 3760 NO_SYNC_WMIFLAG)); |
| 3761 |
| 3762 } |
| 3763 |
| 3764 static A_STATUS |
| 3765 wmi_get_wow_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 3766 { |
| 3767 WMI_GET_WOW_LIST_REPLY *reply; |
| 3768 |
| 3769 if (len < sizeof(WMI_GET_WOW_LIST_REPLY)) { |
| 3770 return A_EINVAL; |
| 3771 } |
| 3772 reply = (WMI_GET_WOW_LIST_REPLY *)datap; |
| 3773 |
| 3774 A_WMI_WOW_LIST_EVENT(wmip->wmi_devt, reply->num_filters, |
| 3775 reply); |
| 3776 |
| 3777 return A_OK; |
| 3778 } |
| 3779 |
| 3780 A_STATUS wmi_add_wow_pattern_cmd(struct wmi_t *wmip, |
| 3781 WMI_ADD_WOW_PATTERN_CMD *addWowCmd, |
| 3782 A_UINT8* pattern, A_UINT8* mask, |
| 3783 A_UINT8 pattern_size) |
| 3784 { |
| 3785 void *osbuf; |
| 3786 A_INT8 size; |
| 3787 WMI_ADD_WOW_PATTERN_CMD *cmd; |
| 3788 A_UINT8 *filter_mask = NULL; |
| 3789 |
| 3790 size = sizeof (*cmd); |
| 3791 |
| 3792 size += ((2 * addWowCmd->filter_size)* sizeof(A_UINT8)); |
| 3793 osbuf = A_NETBUF_ALLOC(size); |
| 3794 if (osbuf == NULL) { |
| 3795 return A_NO_MEMORY; |
| 3796 } |
| 3797 |
| 3798 A_NETBUF_PUT(osbuf, size); |
| 3799 |
| 3800 cmd = (WMI_ADD_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf)); |
| 3801 cmd->filter_list_id = addWowCmd->filter_list_id; |
| 3802 cmd->filter_offset = addWowCmd->filter_offset; |
| 3803 cmd->filter_size = addWowCmd->filter_size; |
| 3804 |
| 3805 A_MEMCPY(cmd->filter, pattern, addWowCmd->filter_size); |
| 3806 |
| 3807 filter_mask = (A_UINT8*)(cmd->filter + cmd->filter_size); |
| 3808 A_MEMCPY(filter_mask, mask, addWowCmd->filter_size); |
| 3809 |
| 3810 |
| 3811 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_WOW_PATTERN_CMDID, |
| 3812 NO_SYNC_WMIFLAG)); |
| 3813 } |
| 3814 |
| 3815 A_STATUS |
| 3816 wmi_del_wow_pattern_cmd(struct wmi_t *wmip, |
| 3817 WMI_DEL_WOW_PATTERN_CMD *delWowCmd) |
| 3818 { |
| 3819 void *osbuf; |
| 3820 A_INT8 size; |
| 3821 WMI_DEL_WOW_PATTERN_CMD *cmd; |
| 3822 |
| 3823 size = sizeof (*cmd); |
| 3824 |
| 3825 osbuf = A_NETBUF_ALLOC(size); |
| 3826 if (osbuf == NULL) { |
| 3827 return A_NO_MEMORY; |
| 3828 } |
| 3829 |
| 3830 A_NETBUF_PUT(osbuf, size); |
| 3831 |
| 3832 cmd = (WMI_DEL_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf)); |
| 3833 A_MEMZERO(cmd, size); |
| 3834 A_MEMCPY(cmd, delWowCmd, sizeof(WMI_DEL_WOW_PATTERN_CMD)); |
| 3835 |
| 3836 return (wmi_cmd_send(wmip, osbuf, WMI_DEL_WOW_PATTERN_CMDID, |
| 3837 NO_SYNC_WMIFLAG)); |
| 3838 |
| 3839 } |
| 3840 |
| 3841 void |
| 3842 wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CM
D *snrCmd) |
| 3843 { |
| 3844 SQ_THRESHOLD_PARAMS *sq_thresh = |
| 3845 &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_SNR]; |
| 3846 /* |
| 3847 * Parse the command and store the threshold values here. The checks |
| 3848 * for valid values can be put here |
| 3849 */ |
| 3850 sq_thresh->weight = snrCmd->weight; |
| 3851 sq_thresh->polling_interval = snrCmd->pollTime; |
| 3852 |
| 3853 sq_thresh->upper_threshold[0] = snrCmd->thresholdAbove1_Val; |
| 3854 sq_thresh->upper_threshold[1] = snrCmd->thresholdAbove2_Val; |
| 3855 sq_thresh->upper_threshold[2] = snrCmd->thresholdAbove3_Val; |
| 3856 sq_thresh->upper_threshold[3] = snrCmd->thresholdAbove4_Val; |
| 3857 sq_thresh->upper_threshold_valid_count = 4; |
| 3858 |
| 3859 /* List sorted in descending order */ |
| 3860 sq_thresh->lower_threshold[0] = snrCmd->thresholdBelow4_Val; |
| 3861 sq_thresh->lower_threshold[1] = snrCmd->thresholdBelow3_Val; |
| 3862 sq_thresh->lower_threshold[2] = snrCmd->thresholdBelow2_Val; |
| 3863 sq_thresh->lower_threshold[3] = snrCmd->thresholdBelow1_Val; |
| 3864 sq_thresh->lower_threshold_valid_count = 4; |
| 3865 |
| 3866 if (!snr_event_value) { |
| 3867 /* |
| 3868 * Configuring the thresholds to their extremes allows the host to get an |
| 3869 * event from the target which is used for the configuring the correct |
| 3870 * thresholds |
| 3871 */ |
| 3872 snrCmd->thresholdAbove1_Val = (A_UINT8)sq_thresh->upper_threshold[0]; |
| 3873 snrCmd->thresholdBelow1_Val = (A_UINT8)sq_thresh->lower_threshold[0]; |
| 3874 } else { |
| 3875 /* |
| 3876 * In case the user issues multiple times of snr_threshold_setting, |
| 3877 * we should not use the extreames anymore, the target does not expect t
hat. |
| 3878 */ |
| 3879 snrCmd->thresholdAbove1_Val = ar6000_get_upper_threshold(snr_event_value
, sq_thresh, |
| 3880 sq_thresh->upper_threshold_valid_c
ount); |
| 3881 snrCmd->thresholdBelow1_Val = ar6000_get_lower_threshold(snr_event_value
, sq_thresh, |
| 3882 sq_thresh->lower_threshold_valid_c
ount); |
| 3883 } |
| 3884 |
| 3885 } |
| 3886 A_STATUS |
| 3887 wmi_set_snr_threshold_params(struct wmi_t *wmip, |
| 3888 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd) |
| 3889 { |
| 3890 if( snrCmd->thresholdAbove4_Val <= snrCmd->thresholdAbove3_Val || |
| 3891 snrCmd->thresholdAbove3_Val <= snrCmd->thresholdAbove2_Val || |
| 3892 snrCmd->thresholdAbove2_Val <= snrCmd->thresholdAbove1_Val || |
| 3893 snrCmd->thresholdBelow4_Val <= snrCmd->thresholdBelow3_Val || |
| 3894 snrCmd->thresholdBelow3_Val <= snrCmd->thresholdBelow2_Val || |
| 3895 snrCmd->thresholdBelow2_Val <= snrCmd->thresholdBelow1_Val) |
| 3896 { |
| 3897 return A_EINVAL; |
| 3898 } |
| 3899 wmi_cache_configure_snrthreshold(wmip, snrCmd); |
| 3900 return (wmi_send_snr_threshold_params(wmip, snrCmd)); |
| 3901 } |
| 3902 |
| 3903 A_STATUS |
| 3904 wmi_clr_rssi_snr(struct wmi_t *wmip) |
| 3905 { |
| 3906 void *osbuf; |
| 3907 |
| 3908 osbuf = A_NETBUF_ALLOC(sizeof(int)); |
| 3909 if (osbuf == NULL) { |
| 3910 return A_NO_MEMORY; |
| 3911 } |
| 3912 |
| 3913 return (wmi_cmd_send(wmip, osbuf, WMI_CLR_RSSI_SNR_CMDID, |
| 3914 NO_SYNC_WMIFLAG)); |
| 3915 } |
| 3916 |
| 3917 A_STATUS |
| 3918 wmi_set_lq_threshold_params(struct wmi_t *wmip, |
| 3919 WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd) |
| 3920 { |
| 3921 void *osbuf; |
| 3922 A_INT8 size; |
| 3923 WMI_LQ_THRESHOLD_PARAMS_CMD *cmd; |
| 3924 /* These values are in ascending order */ |
| 3925 if( lqCmd->thresholdAbove4_Val <= lqCmd->thresholdAbove3_Val || |
| 3926 lqCmd->thresholdAbove3_Val <= lqCmd->thresholdAbove2_Val || |
| 3927 lqCmd->thresholdAbove2_Val <= lqCmd->thresholdAbove1_Val || |
| 3928 lqCmd->thresholdBelow4_Val <= lqCmd->thresholdBelow3_Val || |
| 3929 lqCmd->thresholdBelow3_Val <= lqCmd->thresholdBelow2_Val || |
| 3930 lqCmd->thresholdBelow2_Val <= lqCmd->thresholdBelow1_Val ) { |
| 3931 |
| 3932 return A_EINVAL; |
| 3933 } |
| 3934 |
| 3935 size = sizeof (*cmd); |
| 3936 |
| 3937 osbuf = A_NETBUF_ALLOC(size); |
| 3938 if (osbuf == NULL) { |
| 3939 return A_NO_MEMORY; |
| 3940 } |
| 3941 |
| 3942 A_NETBUF_PUT(osbuf, size); |
| 3943 |
| 3944 cmd = (WMI_LQ_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); |
| 3945 A_MEMZERO(cmd, size); |
| 3946 A_MEMCPY(cmd, lqCmd, sizeof(WMI_LQ_THRESHOLD_PARAMS_CMD)); |
| 3947 |
| 3948 return (wmi_cmd_send(wmip, osbuf, WMI_LQ_THRESHOLD_PARAMS_CMDID, |
| 3949 NO_SYNC_WMIFLAG)); |
| 3950 } |
| 3951 |
| 3952 A_STATUS |
| 3953 wmi_set_error_report_bitmask(struct wmi_t *wmip, A_UINT32 mask) |
| 3954 { |
| 3955 void *osbuf; |
| 3956 A_INT8 size; |
| 3957 WMI_TARGET_ERROR_REPORT_BITMASK *cmd; |
| 3958 |
| 3959 size = sizeof (*cmd); |
| 3960 |
| 3961 osbuf = A_NETBUF_ALLOC(size); |
| 3962 if (osbuf == NULL) { |
| 3963 return A_NO_MEMORY; |
| 3964 } |
| 3965 |
| 3966 A_NETBUF_PUT(osbuf, size); |
| 3967 |
| 3968 cmd = (WMI_TARGET_ERROR_REPORT_BITMASK *)(A_NETBUF_DATA(osbuf)); |
| 3969 A_MEMZERO(cmd, size); |
| 3970 |
| 3971 cmd->bitmask = mask; |
| 3972 |
| 3973 return (wmi_cmd_send(wmip, osbuf, WMI_TARGET_ERROR_REPORT_BITMASK_CMDID, |
| 3974 NO_SYNC_WMIFLAG)); |
| 3975 } |
| 3976 |
| 3977 A_STATUS |
| 3978 wmi_get_challenge_resp_cmd(struct wmi_t *wmip, A_UINT32 cookie, A_UINT32 source) |
| 3979 { |
| 3980 void *osbuf; |
| 3981 WMIX_HB_CHALLENGE_RESP_CMD *cmd; |
| 3982 |
| 3983 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 3984 if (osbuf == NULL) { |
| 3985 return A_NO_MEMORY; |
| 3986 } |
| 3987 |
| 3988 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 3989 |
| 3990 cmd = (WMIX_HB_CHALLENGE_RESP_CMD *)(A_NETBUF_DATA(osbuf)); |
| 3991 cmd->cookie = cookie; |
| 3992 cmd->source = source; |
| 3993 |
| 3994 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_HB_CHALLENGE_RESP_CMDID, |
| 3995 NO_SYNC_WMIFLAG)); |
| 3996 } |
| 3997 |
| 3998 A_STATUS |
| 3999 wmi_config_debug_module_cmd(struct wmi_t *wmip, A_UINT16 mmask, |
| 4000 A_UINT16 tsr, A_BOOL rep, A_UINT16 size, |
| 4001 A_UINT32 valid) |
| 4002 { |
| 4003 void *osbuf; |
| 4004 WMIX_DBGLOG_CFG_MODULE_CMD *cmd; |
| 4005 |
| 4006 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4007 if (osbuf == NULL) { |
| 4008 return A_NO_MEMORY; |
| 4009 } |
| 4010 |
| 4011 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4012 |
| 4013 cmd = (WMIX_DBGLOG_CFG_MODULE_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4014 cmd->config.cfgmmask = mmask; |
| 4015 cmd->config.cfgtsr = tsr; |
| 4016 cmd->config.cfgrep = rep; |
| 4017 cmd->config.cfgsize = size; |
| 4018 cmd->config.cfgvalid = valid; |
| 4019 |
| 4020 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DBGLOG_CFG_MODULE_CMDID, |
| 4021 NO_SYNC_WMIFLAG)); |
| 4022 } |
| 4023 |
| 4024 A_STATUS |
| 4025 wmi_get_stats_cmd(struct wmi_t *wmip) |
| 4026 { |
| 4027 return wmi_simple_cmd(wmip, WMI_GET_STATISTICS_CMDID); |
| 4028 } |
| 4029 |
| 4030 A_STATUS |
| 4031 wmi_addBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex, A_UINT8 *bssid) |
| 4032 { |
| 4033 void *osbuf; |
| 4034 WMI_ADD_BAD_AP_CMD *cmd; |
| 4035 |
| 4036 if ((bssid == NULL) || (apIndex > WMI_MAX_BAD_AP_INDEX)) { |
| 4037 return A_EINVAL; |
| 4038 } |
| 4039 |
| 4040 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4041 if (osbuf == NULL) { |
| 4042 return A_NO_MEMORY; |
| 4043 } |
| 4044 |
| 4045 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4046 |
| 4047 cmd = (WMI_ADD_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4048 cmd->badApIndex = apIndex; |
| 4049 A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid)); |
| 4050 |
| 4051 return (wmi_cmd_send(wmip, osbuf, WMI_ADD_BAD_AP_CMDID, SYNC_BEFORE_WMIFLAG)
); |
| 4052 } |
| 4053 |
| 4054 A_STATUS |
| 4055 wmi_deleteBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex) |
| 4056 { |
| 4057 void *osbuf; |
| 4058 WMI_DELETE_BAD_AP_CMD *cmd; |
| 4059 |
| 4060 if (apIndex > WMI_MAX_BAD_AP_INDEX) { |
| 4061 return A_EINVAL; |
| 4062 } |
| 4063 |
| 4064 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4065 if (osbuf == NULL) { |
| 4066 return A_NO_MEMORY; |
| 4067 } |
| 4068 |
| 4069 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4070 |
| 4071 cmd = (WMI_DELETE_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4072 cmd->badApIndex = apIndex; |
| 4073 |
| 4074 return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_BAD_AP_CMDID, |
| 4075 NO_SYNC_WMIFLAG)); |
| 4076 } |
| 4077 |
| 4078 A_STATUS |
| 4079 wmi_abort_scan_cmd(struct wmi_t *wmip) |
| 4080 { |
| 4081 return wmi_simple_cmd(wmip, WMI_ABORT_SCAN_CMDID); |
| 4082 } |
| 4083 |
| 4084 A_STATUS |
| 4085 wmi_set_txPwr_cmd(struct wmi_t *wmip, A_UINT8 dbM) |
| 4086 { |
| 4087 void *osbuf; |
| 4088 WMI_SET_TX_PWR_CMD *cmd; |
| 4089 |
| 4090 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4091 if (osbuf == NULL) { |
| 4092 return A_NO_MEMORY; |
| 4093 } |
| 4094 |
| 4095 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4096 |
| 4097 cmd = (WMI_SET_TX_PWR_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4098 cmd->dbM = dbM; |
| 4099 |
| 4100 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_PWR_CMDID, NO_SYNC_WMIFLAG)); |
| 4101 } |
| 4102 |
| 4103 A_STATUS |
| 4104 wmi_get_txPwr_cmd(struct wmi_t *wmip) |
| 4105 { |
| 4106 return wmi_simple_cmd(wmip, WMI_GET_TX_PWR_CMDID); |
| 4107 } |
| 4108 |
| 4109 A_UINT16 |
| 4110 wmi_get_mapped_qos_queue(struct wmi_t *wmip, A_UINT8 trafficClass) |
| 4111 { |
| 4112 A_UINT16 activeTsids=0; |
| 4113 |
| 4114 LOCK_WMI(wmip); |
| 4115 activeTsids = wmip->wmi_streamExistsForAC[trafficClass]; |
| 4116 UNLOCK_WMI(wmip); |
| 4117 |
| 4118 return activeTsids; |
| 4119 } |
| 4120 |
| 4121 A_STATUS |
| 4122 wmi_get_roam_tbl_cmd(struct wmi_t *wmip) |
| 4123 { |
| 4124 return wmi_simple_cmd(wmip, WMI_GET_ROAM_TBL_CMDID); |
| 4125 } |
| 4126 |
| 4127 A_STATUS |
| 4128 wmi_get_roam_data_cmd(struct wmi_t *wmip, A_UINT8 roamDataType) |
| 4129 { |
| 4130 void *osbuf; |
| 4131 A_UINT32 size = sizeof(A_UINT8); |
| 4132 WMI_TARGET_ROAM_DATA *cmd; |
| 4133 |
| 4134 osbuf = A_NETBUF_ALLOC(size); /* no payload */ |
| 4135 if (osbuf == NULL) { |
| 4136 return A_NO_MEMORY; |
| 4137 } |
| 4138 |
| 4139 A_NETBUF_PUT(osbuf, size); |
| 4140 |
| 4141 cmd = (WMI_TARGET_ROAM_DATA *)(A_NETBUF_DATA(osbuf)); |
| 4142 cmd->roamDataType = roamDataType; |
| 4143 |
| 4144 return (wmi_cmd_send(wmip, osbuf, WMI_GET_ROAM_DATA_CMDID, |
| 4145 NO_SYNC_WMIFLAG)); |
| 4146 } |
| 4147 |
| 4148 A_STATUS |
| 4149 wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p, |
| 4150 A_UINT8 size) |
| 4151 { |
| 4152 void *osbuf; |
| 4153 WMI_SET_ROAM_CTRL_CMD *cmd; |
| 4154 |
| 4155 osbuf = A_NETBUF_ALLOC(size); |
| 4156 if (osbuf == NULL) { |
| 4157 return A_NO_MEMORY; |
| 4158 } |
| 4159 |
| 4160 A_NETBUF_PUT(osbuf, size); |
| 4161 |
| 4162 cmd = (WMI_SET_ROAM_CTRL_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4163 A_MEMZERO(cmd, size); |
| 4164 |
| 4165 A_MEMCPY(cmd, p, size); |
| 4166 |
| 4167 return (wmi_cmd_send(wmip, osbuf, WMI_SET_ROAM_CTRL_CMDID, |
| 4168 NO_SYNC_WMIFLAG)); |
| 4169 } |
| 4170 |
| 4171 A_STATUS |
| 4172 wmi_set_powersave_timers_cmd(struct wmi_t *wmip, |
| 4173 WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd, |
| 4174 A_UINT8 size) |
| 4175 { |
| 4176 void *osbuf; |
| 4177 WMI_POWERSAVE_TIMERS_POLICY_CMD *cmd; |
| 4178 |
| 4179 /* These timers can't be zero */ |
| 4180 if(!pCmd->psPollTimeout || !pCmd->triggerTimeout || |
| 4181 !(pCmd->apsdTimPolicy == IGNORE_TIM_ALL_QUEUES_APSD || |
| 4182 pCmd->apsdTimPolicy == PROCESS_TIM_ALL_QUEUES_APSD) || |
| 4183 !(pCmd->simulatedAPSDTimPolicy == IGNORE_TIM_SIMULATED_APSD || |
| 4184 pCmd->simulatedAPSDTimPolicy == PROCESS_TIM_SIMULATED_APSD)) |
| 4185 return A_EINVAL; |
| 4186 |
| 4187 osbuf = A_NETBUF_ALLOC(size); |
| 4188 if (osbuf == NULL) { |
| 4189 return A_NO_MEMORY; |
| 4190 } |
| 4191 |
| 4192 A_NETBUF_PUT(osbuf, size); |
| 4193 |
| 4194 cmd = (WMI_POWERSAVE_TIMERS_POLICY_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4195 A_MEMZERO(cmd, size); |
| 4196 |
| 4197 A_MEMCPY(cmd, pCmd, size); |
| 4198 |
| 4199 return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID, |
| 4200 NO_SYNC_WMIFLAG)); |
| 4201 } |
| 4202 |
| 4203 #ifdef CONFIG_HOST_GPIO_SUPPORT |
| 4204 /* Send a command to Target to change GPIO output pins. */ |
| 4205 A_STATUS |
| 4206 wmi_gpio_output_set(struct wmi_t *wmip, |
| 4207 A_UINT32 set_mask, |
| 4208 A_UINT32 clear_mask, |
| 4209 A_UINT32 enable_mask, |
| 4210 A_UINT32 disable_mask) |
| 4211 { |
| 4212 void *osbuf; |
| 4213 WMIX_GPIO_OUTPUT_SET_CMD *output_set; |
| 4214 int size; |
| 4215 |
| 4216 size = sizeof(*output_set); |
| 4217 |
| 4218 A_DPRINTF(DBG_WMI, |
| 4219 (DBGFMT "Enter - set=0x%x clear=0x%x enb=0x%x dis=0x%x\n", DBGARG, |
| 4220 set_mask, clear_mask, enable_mask, disable_mask)); |
| 4221 |
| 4222 osbuf = A_NETBUF_ALLOC(size); |
| 4223 if (osbuf == NULL) { |
| 4224 return A_NO_MEMORY; |
| 4225 } |
| 4226 A_NETBUF_PUT(osbuf, size); |
| 4227 output_set = (WMIX_GPIO_OUTPUT_SET_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4228 |
| 4229 output_set->set_mask = set_mask; |
| 4230 output_set->clear_mask = clear_mask; |
| 4231 output_set->enable_mask = enable_mask; |
| 4232 output_set->disable_mask = disable_mask; |
| 4233 |
| 4234 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_OUTPUT_SET_CMDID, |
| 4235 NO_SYNC_WMIFLAG)); |
| 4236 } |
| 4237 |
| 4238 /* Send a command to the Target requesting state of the GPIO input pins */ |
| 4239 A_STATUS |
| 4240 wmi_gpio_input_get(struct wmi_t *wmip) |
| 4241 { |
| 4242 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 4243 |
| 4244 return wmi_simple_cmd_xtnd(wmip, WMIX_GPIO_INPUT_GET_CMDID); |
| 4245 } |
| 4246 |
| 4247 /* Send a command to the Target that changes the value of a GPIO register. */ |
| 4248 A_STATUS |
| 4249 wmi_gpio_register_set(struct wmi_t *wmip, |
| 4250 A_UINT32 gpioreg_id, |
| 4251 A_UINT32 value) |
| 4252 { |
| 4253 void *osbuf; |
| 4254 WMIX_GPIO_REGISTER_SET_CMD *register_set; |
| 4255 int size; |
| 4256 |
| 4257 size = sizeof(*register_set); |
| 4258 |
| 4259 A_DPRINTF(DBG_WMI, |
| 4260 (DBGFMT "Enter - reg=%d value=0x%x\n", DBGARG, gpioreg_id, value)); |
| 4261 |
| 4262 osbuf = A_NETBUF_ALLOC(size); |
| 4263 if (osbuf == NULL) { |
| 4264 return A_NO_MEMORY; |
| 4265 } |
| 4266 A_NETBUF_PUT(osbuf, size); |
| 4267 register_set = (WMIX_GPIO_REGISTER_SET_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4268 |
| 4269 register_set->gpioreg_id = gpioreg_id; |
| 4270 register_set->value = value; |
| 4271 |
| 4272 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_REGISTER_SET_CMDID, |
| 4273 NO_SYNC_WMIFLAG)); |
| 4274 } |
| 4275 |
| 4276 /* Send a command to the Target to fetch the value of a GPIO register. */ |
| 4277 A_STATUS |
| 4278 wmi_gpio_register_get(struct wmi_t *wmip, |
| 4279 A_UINT32 gpioreg_id) |
| 4280 { |
| 4281 void *osbuf; |
| 4282 WMIX_GPIO_REGISTER_GET_CMD *register_get; |
| 4283 int size; |
| 4284 |
| 4285 size = sizeof(*register_get); |
| 4286 |
| 4287 A_DPRINTF(DBG_WMI, (DBGFMT "Enter - reg=%d\n", DBGARG, gpioreg_id)); |
| 4288 |
| 4289 osbuf = A_NETBUF_ALLOC(size); |
| 4290 if (osbuf == NULL) { |
| 4291 return A_NO_MEMORY; |
| 4292 } |
| 4293 A_NETBUF_PUT(osbuf, size); |
| 4294 register_get = (WMIX_GPIO_REGISTER_GET_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4295 |
| 4296 register_get->gpioreg_id = gpioreg_id; |
| 4297 |
| 4298 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_REGISTER_GET_CMDID, |
| 4299 NO_SYNC_WMIFLAG)); |
| 4300 } |
| 4301 |
| 4302 /* Send a command to the Target acknowledging some GPIO interrupts. */ |
| 4303 A_STATUS |
| 4304 wmi_gpio_intr_ack(struct wmi_t *wmip, |
| 4305 A_UINT32 ack_mask) |
| 4306 { |
| 4307 void *osbuf; |
| 4308 WMIX_GPIO_INTR_ACK_CMD *intr_ack; |
| 4309 int size; |
| 4310 |
| 4311 size = sizeof(*intr_ack); |
| 4312 |
| 4313 A_DPRINTF(DBG_WMI, (DBGFMT "Enter ack_mask=0x%x\n", DBGARG, ack_mask)); |
| 4314 |
| 4315 osbuf = A_NETBUF_ALLOC(size); |
| 4316 if (osbuf == NULL) { |
| 4317 return A_NO_MEMORY; |
| 4318 } |
| 4319 A_NETBUF_PUT(osbuf, size); |
| 4320 intr_ack = (WMIX_GPIO_INTR_ACK_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4321 |
| 4322 intr_ack->ack_mask = ack_mask; |
| 4323 |
| 4324 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_INTR_ACK_CMDID, |
| 4325 NO_SYNC_WMIFLAG)); |
| 4326 } |
| 4327 #endif /* CONFIG_HOST_GPIO_SUPPORT */ |
| 4328 |
| 4329 A_STATUS |
| 4330 wmi_set_access_params_cmd(struct wmi_t *wmip, A_UINT16 txop, A_UINT8 eCWmin, |
| 4331 A_UINT8 eCWmax, A_UINT8 aifsn) |
| 4332 { |
| 4333 void *osbuf; |
| 4334 WMI_SET_ACCESS_PARAMS_CMD *cmd; |
| 4335 |
| 4336 if ((eCWmin > WMI_MAX_CW_ACPARAM) || (eCWmax > WMI_MAX_CW_ACPARAM) || |
| 4337 (aifsn > WMI_MAX_AIFSN_ACPARAM)) |
| 4338 { |
| 4339 return A_EINVAL; |
| 4340 } |
| 4341 |
| 4342 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4343 if (osbuf == NULL) { |
| 4344 return A_NO_MEMORY; |
| 4345 } |
| 4346 |
| 4347 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4348 |
| 4349 cmd = (WMI_SET_ACCESS_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4350 cmd->txop = txop; |
| 4351 cmd->eCWmin = eCWmin; |
| 4352 cmd->eCWmax = eCWmax; |
| 4353 cmd->aifsn = aifsn; |
| 4354 |
| 4355 return (wmi_cmd_send(wmip, osbuf, WMI_SET_ACCESS_PARAMS_CMDID, |
| 4356 NO_SYNC_WMIFLAG)); |
| 4357 } |
| 4358 |
| 4359 A_STATUS |
| 4360 wmi_set_retry_limits_cmd(struct wmi_t *wmip, A_UINT8 frameType, |
| 4361 A_UINT8 trafficClass, A_UINT8 maxRetries, |
| 4362 A_UINT8 enableNotify) |
| 4363 { |
| 4364 void *osbuf; |
| 4365 WMI_SET_RETRY_LIMITS_CMD *cmd; |
| 4366 |
| 4367 if ((frameType != MGMT_FRAMETYPE) && (frameType != CONTROL_FRAMETYPE) && |
| 4368 (frameType != DATA_FRAMETYPE)) |
| 4369 { |
| 4370 return A_EINVAL; |
| 4371 } |
| 4372 |
| 4373 if (maxRetries > WMI_MAX_RETRIES) { |
| 4374 return A_EINVAL; |
| 4375 } |
| 4376 |
| 4377 if (frameType != DATA_FRAMETYPE) { |
| 4378 trafficClass = 0; |
| 4379 } |
| 4380 |
| 4381 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4382 if (osbuf == NULL) { |
| 4383 return A_NO_MEMORY; |
| 4384 } |
| 4385 |
| 4386 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4387 |
| 4388 cmd = (WMI_SET_RETRY_LIMITS_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4389 cmd->frameType = frameType; |
| 4390 cmd->trafficClass = trafficClass; |
| 4391 cmd->maxRetries = maxRetries; |
| 4392 cmd->enableNotify = enableNotify; |
| 4393 |
| 4394 return (wmi_cmd_send(wmip, osbuf, WMI_SET_RETRY_LIMITS_CMDID, |
| 4395 NO_SYNC_WMIFLAG)); |
| 4396 } |
| 4397 |
| 4398 void |
| 4399 wmi_get_current_bssid(struct wmi_t *wmip, A_UINT8 *bssid) |
| 4400 { |
| 4401 if (bssid != NULL) { |
| 4402 A_MEMCPY(bssid, wmip->wmi_bssid, ATH_MAC_LEN); |
| 4403 } |
| 4404 } |
| 4405 |
| 4406 A_STATUS |
| 4407 wmi_set_opt_mode_cmd(struct wmi_t *wmip, A_UINT8 optMode) |
| 4408 { |
| 4409 void *osbuf; |
| 4410 WMI_SET_OPT_MODE_CMD *cmd; |
| 4411 |
| 4412 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4413 if (osbuf == NULL) { |
| 4414 return A_NO_MEMORY; |
| 4415 } |
| 4416 |
| 4417 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4418 |
| 4419 cmd = (WMI_SET_OPT_MODE_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4420 A_MEMZERO(cmd, sizeof(*cmd)); |
| 4421 cmd->optMode = optMode; |
| 4422 |
| 4423 return (wmi_cmd_send(wmip, osbuf, WMI_SET_OPT_MODE_CMDID, |
| 4424 SYNC_BOTH_WMIFLAG)); |
| 4425 } |
| 4426 |
| 4427 A_STATUS |
| 4428 wmi_opt_tx_frame_cmd(struct wmi_t *wmip, |
| 4429 A_UINT8 frmType, |
| 4430 A_UINT8 *dstMacAddr, |
| 4431 A_UINT8 *bssid, |
| 4432 A_UINT16 optIEDataLen, |
| 4433 A_UINT8 *optIEData) |
| 4434 { |
| 4435 void *osbuf; |
| 4436 WMI_OPT_TX_FRAME_CMD *cmd; |
| 4437 osbuf = A_NETBUF_ALLOC(optIEDataLen + sizeof(*cmd)); |
| 4438 if (osbuf == NULL) { |
| 4439 return A_NO_MEMORY; |
| 4440 } |
| 4441 |
| 4442 A_NETBUF_PUT(osbuf, (optIEDataLen + sizeof(*cmd))); |
| 4443 |
| 4444 cmd = (WMI_OPT_TX_FRAME_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4445 A_MEMZERO(cmd, (optIEDataLen + sizeof(*cmd)-1)); |
| 4446 |
| 4447 cmd->frmType = frmType; |
| 4448 cmd->optIEDataLen = optIEDataLen; |
| 4449 //cmd->optIEData = (A_UINT8 *)((int)cmd + sizeof(*cmd)); |
| 4450 A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid)); |
| 4451 A_MEMCPY(cmd->dstAddr, dstMacAddr, sizeof(cmd->dstAddr)); |
| 4452 A_MEMCPY(&cmd->optIEData[0], optIEData, optIEDataLen); |
| 4453 |
| 4454 return (wmi_cmd_send(wmip, osbuf, WMI_OPT_TX_FRAME_CMDID, |
| 4455 NO_SYNC_WMIFLAG)); |
| 4456 } |
| 4457 |
| 4458 A_STATUS |
| 4459 wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, A_UINT16 intvl) |
| 4460 { |
| 4461 void *osbuf; |
| 4462 WMI_BEACON_INT_CMD *cmd; |
| 4463 |
| 4464 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4465 if (osbuf == NULL) { |
| 4466 return A_NO_MEMORY; |
| 4467 } |
| 4468 |
| 4469 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4470 |
| 4471 cmd = (WMI_BEACON_INT_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4472 A_MEMZERO(cmd, sizeof(*cmd)); |
| 4473 cmd->beaconInterval = intvl; |
| 4474 |
| 4475 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BEACON_INT_CMDID, |
| 4476 NO_SYNC_WMIFLAG)); |
| 4477 } |
| 4478 |
| 4479 |
| 4480 A_STATUS |
| 4481 wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, A_UINT16 voicePktSize) |
| 4482 { |
| 4483 void *osbuf; |
| 4484 WMI_SET_VOICE_PKT_SIZE_CMD *cmd; |
| 4485 |
| 4486 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4487 if (osbuf == NULL) { |
| 4488 return A_NO_MEMORY; |
| 4489 } |
| 4490 |
| 4491 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4492 |
| 4493 cmd = (WMI_SET_VOICE_PKT_SIZE_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4494 A_MEMZERO(cmd, sizeof(*cmd)); |
| 4495 cmd->voicePktSize = voicePktSize; |
| 4496 |
| 4497 return (wmi_cmd_send(wmip, osbuf, WMI_SET_VOICE_PKT_SIZE_CMDID, |
| 4498 NO_SYNC_WMIFLAG)); |
| 4499 } |
| 4500 |
| 4501 |
| 4502 A_STATUS |
| 4503 wmi_set_max_sp_len_cmd(struct wmi_t *wmip, A_UINT8 maxSPLen) |
| 4504 { |
| 4505 void *osbuf; |
| 4506 WMI_SET_MAX_SP_LEN_CMD *cmd; |
| 4507 |
| 4508 /* maxSPLen is a two-bit value. If user trys to set anything |
| 4509 * other than this, then its invalid |
| 4510 */ |
| 4511 if(maxSPLen & ~0x03) |
| 4512 return A_EINVAL; |
| 4513 |
| 4514 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4515 if (osbuf == NULL) { |
| 4516 return A_NO_MEMORY; |
| 4517 } |
| 4518 |
| 4519 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4520 |
| 4521 cmd = (WMI_SET_MAX_SP_LEN_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4522 A_MEMZERO(cmd, sizeof(*cmd)); |
| 4523 cmd->maxSPLen = maxSPLen; |
| 4524 |
| 4525 return (wmi_cmd_send(wmip, osbuf, WMI_SET_MAX_SP_LEN_CMDID, |
| 4526 NO_SYNC_WMIFLAG)); |
| 4527 } |
| 4528 |
| 4529 A_UINT8 |
| 4530 wmi_determine_userPriority( |
| 4531 A_UINT8 *pkt, |
| 4532 A_UINT32 layer2Pri) |
| 4533 { |
| 4534 A_UINT8 ipPri; |
| 4535 iphdr *ipHdr = (iphdr *)pkt; |
| 4536 |
| 4537 /* Determine IPTOS priority */ |
| 4538 /* |
| 4539 * IP Tos format : |
| 4540 * (Refer Pg 57 WMM-test-plan-v1.2) |
| 4541 * IP-TOS - 8bits |
| 4542 * : DSCP(6-bits) ECN(2-bits) |
| 4543 * : DSCP - P2 P1 P0 X X X |
| 4544 * where (P2 P1 P0) form 802.1D |
| 4545 */ |
| 4546 ipPri = ipHdr->ip_tos >> 5; |
| 4547 ipPri &= 0x7; |
| 4548 |
| 4549 if ((layer2Pri & 0x7) > ipPri) |
| 4550 return ((A_UINT8)layer2Pri & 0x7); |
| 4551 else |
| 4552 return ipPri; |
| 4553 } |
| 4554 |
| 4555 A_UINT8 |
| 4556 convert_userPriority_to_trafficClass(A_UINT8 userPriority) |
| 4557 { |
| 4558 return (up_to_ac[userPriority & 0x7]); |
| 4559 } |
| 4560 |
| 4561 A_UINT8 |
| 4562 wmi_get_power_mode_cmd(struct wmi_t *wmip) |
| 4563 { |
| 4564 return wmip->wmi_powerMode; |
| 4565 } |
| 4566 |
| 4567 A_STATUS |
| 4568 wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, A_BOOL tspecCompliance) |
| 4569 { |
| 4570 A_STATUS ret = A_OK; |
| 4571 |
| 4572 #define TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF (~0) |
| 4573 #define TSPEC_SERVICE_START_TIME_ATHEROS_DEF 0 |
| 4574 #define TSPEC_MAX_BURST_SIZE_ATHEROS_DEF 0 |
| 4575 #define TSPEC_DELAY_BOUND_ATHEROS_DEF 0 |
| 4576 #define TSPEC_MEDIUM_TIME_ATHEROS_DEF 0 |
| 4577 #define TSPEC_SBA_ATHEROS_DEF 0x2000 /* factor is 1 */ |
| 4578 |
| 4579 /* Verify TSPEC params for ATHEROS compliance */ |
| 4580 if(tspecCompliance == ATHEROS_COMPLIANCE) { |
| 4581 if ((pCmd->suspensionInt != TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF) || |
| 4582 (pCmd->serviceStartTime != TSPEC_SERVICE_START_TIME_ATHEROS_DEF) || |
| 4583 (pCmd->minDataRate != pCmd->meanDataRate) || |
| 4584 (pCmd->minDataRate != pCmd->peakDataRate) || |
| 4585 (pCmd->maxBurstSize != TSPEC_MAX_BURST_SIZE_ATHEROS_DEF) || |
| 4586 (pCmd->delayBound != TSPEC_DELAY_BOUND_ATHEROS_DEF) || |
| 4587 (pCmd->sba != TSPEC_SBA_ATHEROS_DEF) || |
| 4588 (pCmd->mediumTime != TSPEC_MEDIUM_TIME_ATHEROS_DEF)) { |
| 4589 |
| 4590 A_DPRINTF(DBG_WMI, (DBGFMT "Invalid TSPEC params\n", DBGARG)); |
| 4591 //A_PRINTF("%s: Invalid TSPEC params\n", __func__); |
| 4592 ret = A_EINVAL; |
| 4593 } |
| 4594 } |
| 4595 |
| 4596 return ret; |
| 4597 } |
| 4598 |
| 4599 #ifdef CONFIG_HOST_TCMD_SUPPORT |
| 4600 static A_STATUS |
| 4601 wmi_tcmd_test_report_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 4602 { |
| 4603 |
| 4604 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 4605 |
| 4606 A_WMI_TCMD_RX_REPORT_EVENT(wmip->wmi_devt, datap, len); |
| 4607 |
| 4608 return A_OK; |
| 4609 } |
| 4610 |
| 4611 #endif /* CONFIG_HOST_TCMD_SUPPORT*/ |
| 4612 |
| 4613 A_STATUS |
| 4614 wmi_set_authmode_cmd(struct wmi_t *wmip, A_UINT8 mode) |
| 4615 { |
| 4616 void *osbuf; |
| 4617 WMI_SET_AUTH_MODE_CMD *cmd; |
| 4618 |
| 4619 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4620 if (osbuf == NULL) { |
| 4621 return A_NO_MEMORY; |
| 4622 } |
| 4623 |
| 4624 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4625 |
| 4626 cmd = (WMI_SET_AUTH_MODE_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4627 A_MEMZERO(cmd, sizeof(*cmd)); |
| 4628 cmd->mode = mode; |
| 4629 |
| 4630 return (wmi_cmd_send(wmip, osbuf, WMI_SET_AUTH_MODE_CMDID, |
| 4631 NO_SYNC_WMIFLAG)); |
| 4632 } |
| 4633 |
| 4634 A_STATUS |
| 4635 wmi_set_reassocmode_cmd(struct wmi_t *wmip, A_UINT8 mode) |
| 4636 { |
| 4637 void *osbuf; |
| 4638 WMI_SET_REASSOC_MODE_CMD *cmd; |
| 4639 |
| 4640 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4641 if (osbuf == NULL) { |
| 4642 return A_NO_MEMORY; |
| 4643 } |
| 4644 |
| 4645 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4646 |
| 4647 cmd = (WMI_SET_REASSOC_MODE_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4648 A_MEMZERO(cmd, sizeof(*cmd)); |
| 4649 cmd->mode = mode; |
| 4650 |
| 4651 return (wmi_cmd_send(wmip, osbuf, WMI_SET_REASSOC_MODE_CMDID, |
| 4652 NO_SYNC_WMIFLAG)); |
| 4653 } |
| 4654 |
| 4655 A_STATUS |
| 4656 wmi_set_lpreamble_cmd(struct wmi_t *wmip, A_UINT8 status, A_UINT8 preamblePolicy
) |
| 4657 { |
| 4658 void *osbuf; |
| 4659 WMI_SET_LPREAMBLE_CMD *cmd; |
| 4660 |
| 4661 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4662 if (osbuf == NULL) { |
| 4663 return A_NO_MEMORY; |
| 4664 } |
| 4665 |
| 4666 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4667 |
| 4668 cmd = (WMI_SET_LPREAMBLE_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4669 A_MEMZERO(cmd, sizeof(*cmd)); |
| 4670 cmd->status = status; |
| 4671 cmd->preamblePolicy = preamblePolicy; |
| 4672 |
| 4673 return (wmi_cmd_send(wmip, osbuf, WMI_SET_LPREAMBLE_CMDID, |
| 4674 NO_SYNC_WMIFLAG)); |
| 4675 } |
| 4676 |
| 4677 A_STATUS |
| 4678 wmi_set_rts_cmd(struct wmi_t *wmip, A_UINT16 threshold) |
| 4679 { |
| 4680 void *osbuf; |
| 4681 WMI_SET_RTS_CMD *cmd; |
| 4682 |
| 4683 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4684 if (osbuf == NULL) { |
| 4685 return A_NO_MEMORY; |
| 4686 } |
| 4687 |
| 4688 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4689 |
| 4690 cmd = (WMI_SET_RTS_CMD*)(A_NETBUF_DATA(osbuf)); |
| 4691 A_MEMZERO(cmd, sizeof(*cmd)); |
| 4692 cmd->threshold = threshold; |
| 4693 |
| 4694 return (wmi_cmd_send(wmip, osbuf, WMI_SET_RTS_CMDID, |
| 4695 NO_SYNC_WMIFLAG)); |
| 4696 } |
| 4697 |
| 4698 A_STATUS |
| 4699 wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status) |
| 4700 { |
| 4701 void *osbuf; |
| 4702 WMI_SET_WMM_CMD *cmd; |
| 4703 |
| 4704 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4705 if (osbuf == NULL) { |
| 4706 return A_NO_MEMORY; |
| 4707 } |
| 4708 |
| 4709 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4710 |
| 4711 cmd = (WMI_SET_WMM_CMD*)(A_NETBUF_DATA(osbuf)); |
| 4712 A_MEMZERO(cmd, sizeof(*cmd)); |
| 4713 cmd->status = status; |
| 4714 |
| 4715 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_CMDID, |
| 4716 NO_SYNC_WMIFLAG)); |
| 4717 |
| 4718 } |
| 4719 |
| 4720 A_STATUS |
| 4721 wmi_set_qos_supp_cmd(struct wmi_t *wmip, A_UINT8 status) |
| 4722 { |
| 4723 void *osbuf; |
| 4724 WMI_SET_QOS_SUPP_CMD *cmd; |
| 4725 |
| 4726 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4727 if (osbuf == NULL) { |
| 4728 return A_NO_MEMORY; |
| 4729 } |
| 4730 |
| 4731 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4732 |
| 4733 cmd = (WMI_SET_QOS_SUPP_CMD*)(A_NETBUF_DATA(osbuf)); |
| 4734 A_MEMZERO(cmd, sizeof(*cmd)); |
| 4735 cmd->status = status; |
| 4736 return (wmi_cmd_send(wmip, osbuf, WMI_SET_QOS_SUPP_CMDID, |
| 4737 NO_SYNC_WMIFLAG)); |
| 4738 } |
| 4739 |
| 4740 |
| 4741 A_STATUS |
| 4742 wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG cfg) |
| 4743 { |
| 4744 void *osbuf; |
| 4745 WMI_SET_WMM_TXOP_CMD *cmd; |
| 4746 |
| 4747 if( !((cfg == WMI_TXOP_DISABLED) || (cfg == WMI_TXOP_ENABLED)) ) |
| 4748 return A_EINVAL; |
| 4749 |
| 4750 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4751 if (osbuf == NULL) { |
| 4752 return A_NO_MEMORY; |
| 4753 } |
| 4754 |
| 4755 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4756 |
| 4757 cmd = (WMI_SET_WMM_TXOP_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4758 A_MEMZERO(cmd, sizeof(*cmd)); |
| 4759 cmd->txopEnable = cfg; |
| 4760 |
| 4761 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_TXOP_CMDID, |
| 4762 NO_SYNC_WMIFLAG)); |
| 4763 |
| 4764 } |
| 4765 |
| 4766 A_STATUS |
| 4767 wmi_set_country(struct wmi_t *wmip, A_UCHAR *countryCode) |
| 4768 { |
| 4769 void *osbuf; |
| 4770 WMI_AP_SET_COUNTRY_CMD *cmd; |
| 4771 |
| 4772 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4773 if (osbuf == NULL) { |
| 4774 return A_NO_MEMORY; |
| 4775 } |
| 4776 |
| 4777 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4778 |
| 4779 cmd = (WMI_AP_SET_COUNTRY_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4780 A_MEMZERO(cmd, sizeof(*cmd)); |
| 4781 A_MEMCPY(cmd->countryCode,countryCode,3); |
| 4782 |
| 4783 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_COUNTRY_CMDID, |
| 4784 NO_SYNC_WMIFLAG)); |
| 4785 } |
| 4786 |
| 4787 #ifdef CONFIG_HOST_TCMD_SUPPORT |
| 4788 /* WMI layer doesn't need to know the data type of the test cmd. |
| 4789 This would be beneficial for customers like Qualcomm, who might |
| 4790 have different test command requirements from differnt manufacturers |
| 4791 */ |
| 4792 A_STATUS |
| 4793 wmi_test_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT32 len) |
| 4794 { |
| 4795 void *osbuf; |
| 4796 char *data; |
| 4797 |
| 4798 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 4799 |
| 4800 osbuf= A_NETBUF_ALLOC(len); |
| 4801 if(osbuf == NULL) |
| 4802 { |
| 4803 return A_NO_MEMORY; |
| 4804 } |
| 4805 A_NETBUF_PUT(osbuf, len); |
| 4806 data = A_NETBUF_DATA(osbuf); |
| 4807 A_MEMCPY(data, buf, len); |
| 4808 |
| 4809 return(wmi_cmd_send(wmip, osbuf, WMI_TEST_CMDID, |
| 4810 NO_SYNC_WMIFLAG)); |
| 4811 } |
| 4812 |
| 4813 #endif |
| 4814 |
| 4815 A_STATUS |
| 4816 wmi_set_bt_status_cmd(struct wmi_t *wmip, A_UINT8 streamType, A_UINT8 status) |
| 4817 { |
| 4818 void *osbuf; |
| 4819 WMI_SET_BT_STATUS_CMD *cmd; |
| 4820 |
| 4821 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Enter - streamType=%d, status=%d\n", strea
mType, status)); |
| 4822 |
| 4823 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4824 if (osbuf == NULL) { |
| 4825 return A_NO_MEMORY; |
| 4826 } |
| 4827 |
| 4828 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4829 |
| 4830 cmd = (WMI_SET_BT_STATUS_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4831 A_MEMZERO(cmd, sizeof(*cmd)); |
| 4832 cmd->streamType = streamType; |
| 4833 cmd->status = status; |
| 4834 |
| 4835 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_STATUS_CMDID, |
| 4836 NO_SYNC_WMIFLAG)); |
| 4837 } |
| 4838 |
| 4839 A_STATUS |
| 4840 wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd) |
| 4841 { |
| 4842 void *osbuf; |
| 4843 WMI_SET_BT_PARAMS_CMD* alloc_cmd; |
| 4844 |
| 4845 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("cmd params is %d\n", cmd->paramType)); |
| 4846 |
| 4847 if (cmd->paramType == BT_PARAM_SCO) { |
| 4848 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, |
| 4849 cmd->info.scoParams.dataResponseTimeout, |
| 4850 cmd->info.scoParams.stompScoRules, |
| 4851 cmd->info.scoParams.scoOptFlags, |
| 4852 cmd->info.scoParams.stompDutyCyleVal, |
| 4853 cmd->info.scoParams.stompDutyCyleMaxVal, |
| 4854 cmd->info.scoParams.psPollLatencyFraction, |
| 4855 cmd->info.scoParams.noSCOSlots, |
| 4856 cmd->info.scoParams.noIdleSlots, |
| 4857 cmd->info.scoParams.scoOptOffRssi, |
| 4858 cmd->info.scoParams.scoOptOnRssi, |
| 4859 cmd->info.scoParams.scoOptRtsCount)); |
| 4860 } |
| 4861 else if (cmd->paramType == BT_PARAM_A2DP) { |
| 4862 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("A2DP params %d %d %d %d %d %d %d %d\n",
cmd->info.a2dpParams.a2dpWlanUsageLimit, |
| 4863 cmd->info.a2dpParams.a2dpBurstCntMin, |
| 4864 cmd->info.a2dpParams.a2dpDataRespTimeout, |
| 4865 cmd->info.a2dpParams.a2dpOptFlags, |
| 4866 cmd->info.a2dpParams.isCoLocatedBtRoleMaster, |
| 4867 cmd->info.a2dpParams.a2dpOptOffRssi, |
| 4868 cmd->info.a2dpParams.a2dpOptOnRssi, |
| 4869 cmd->info.a2dpParams.a2dpOptRtsCount)); |
| 4870 } |
| 4871 else if (cmd->paramType == BT_PARAM_ANTENNA_CONFIG) { |
| 4872 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Ant config %d\n", cmd->info.antType)); |
| 4873 } |
| 4874 else if (cmd->paramType == BT_PARAM_COLOCATED_BT_DEVICE) { |
| 4875 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("co-located BT %d\n", cmd->info.coLocated
BtDev)); |
| 4876 } |
| 4877 else if (cmd->paramType == BT_PARAM_ACLCOEX) { |
| 4878 AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("ACL params %d %d %d\n", cmd->info.aclCoe
xParams.aclWlanMediumUsageTime, |
| 4879 cmd->info.aclCoexParams.aclBtMediumUsageTime, |
| 4880 cmd->info.aclCoexParams.aclDataRespTimeout)); |
| 4881 } |
| 4882 else if (cmd->paramType == BT_PARAM_11A_SEPARATE_ANT) { |
| 4883 A_DPRINTF(DBG_WMI, (DBGFMT "11A ant\n", DBGARG)); |
| 4884 } |
| 4885 |
| 4886 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4887 if (osbuf == NULL) { |
| 4888 return A_NO_MEMORY; |
| 4889 } |
| 4890 |
| 4891 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4892 |
| 4893 alloc_cmd = (WMI_SET_BT_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4894 A_MEMZERO(alloc_cmd, sizeof(*cmd)); |
| 4895 A_MEMCPY(alloc_cmd, cmd, sizeof(*cmd)); |
| 4896 |
| 4897 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_PARAMS_CMDID, |
| 4898 NO_SYNC_WMIFLAG)); |
| 4899 } |
| 4900 |
| 4901 A_STATUS |
| 4902 wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd) |
| 4903 { |
| 4904 void *osbuf; |
| 4905 WMI_SET_BTCOEX_FE_ANT_CMD *alloc_cmd; |
| 4906 |
| 4907 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4908 if (osbuf == NULL) { |
| 4909 return A_NO_MEMORY; |
| 4910 } |
| 4911 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4912 alloc_cmd = (WMI_SET_BTCOEX_FE_ANT_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4913 A_MEMZERO(alloc_cmd, sizeof(*cmd)); |
| 4914 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_FE_ANT_CMD)); |
| 4915 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_FE_ANT_CMDID, |
| 4916 NO_SYNC_WMIFLAG)); |
| 4917 |
| 4918 } |
| 4919 |
| 4920 |
| 4921 A_STATUS |
| 4922 wmi_set_btcoex_colocated_bt_dev_cmd(struct wmi_t *wmip, |
| 4923 WMI_SET_BTCOEX_COLOCATED_BT_DEV_
CMD * cmd) |
| 4924 { |
| 4925 void *osbuf; |
| 4926 WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD *alloc_cmd; |
| 4927 |
| 4928 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4929 if (osbuf == NULL) { |
| 4930 return A_NO_MEMORY; |
| 4931 } |
| 4932 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4933 alloc_cmd = (WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4934 A_MEMZERO(alloc_cmd, sizeof(*cmd)); |
| 4935 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD)); |
| 4936 A_PRINTF("colocated bt = %d\n", alloc_cmd->btcoexCoLocatedBTdev); |
| 4937 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID, |
| 4938 NO_SYNC_WMIFLAG)); |
| 4939 |
| 4940 } |
| 4941 |
| 4942 A_STATUS |
| 4943 wmi_set_btcoex_btinquiry_page_config_cmd(struct wmi_t *wmip, |
| 4944 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CO
NFIG_CMD* cmd) |
| 4945 { |
| 4946 void *osbuf; |
| 4947 WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *alloc_cmd; |
| 4948 |
| 4949 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4950 if (osbuf == NULL) { |
| 4951 return A_NO_MEMORY; |
| 4952 } |
| 4953 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4954 alloc_cmd = (WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *)(A_NETBUF_DATA(osbuf
)); |
| 4955 A_MEMZERO(alloc_cmd, sizeof(*cmd)); |
| 4956 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD))
; |
| 4957 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID
, |
| 4958 NO_SYNC_WMIFLAG)); |
| 4959 |
| 4960 } |
| 4961 |
| 4962 A_STATUS |
| 4963 wmi_set_btcoex_sco_config_cmd(struct wmi_t *wmip, |
| 4964 WMI_SET_BTCOEX_SCO_CONFIG_CMD *
cmd) |
| 4965 { |
| 4966 void *osbuf; |
| 4967 WMI_SET_BTCOEX_SCO_CONFIG_CMD *alloc_cmd; |
| 4968 |
| 4969 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4970 if (osbuf == NULL) { |
| 4971 return A_NO_MEMORY; |
| 4972 } |
| 4973 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4974 alloc_cmd = (WMI_SET_BTCOEX_SCO_CONFIG_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4975 A_MEMZERO(alloc_cmd, sizeof(*cmd)); |
| 4976 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_SCO_CONFIG_CMD)); |
| 4977 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_SCO_CONFIG_CMDID , |
| 4978 NO_SYNC_WMIFLAG)); |
| 4979 |
| 4980 } |
| 4981 |
| 4982 A_STATUS |
| 4983 wmi_set_btcoex_a2dp_config_cmd(struct wmi_t *wmip, |
| 4984 WMI_SET_BTCOEX_A2DP_CONFIG_CMD *
cmd) |
| 4985 { |
| 4986 void *osbuf; |
| 4987 WMI_SET_BTCOEX_A2DP_CONFIG_CMD *alloc_cmd; |
| 4988 |
| 4989 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 4990 if (osbuf == NULL) { |
| 4991 return A_NO_MEMORY; |
| 4992 } |
| 4993 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 4994 alloc_cmd = (WMI_SET_BTCOEX_A2DP_CONFIG_CMD *)(A_NETBUF_DATA(osbuf)); |
| 4995 A_MEMZERO(alloc_cmd, sizeof(*cmd)); |
| 4996 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_A2DP_CONFIG_CMD)); |
| 4997 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_A2DP_CONFIG_CMDID , |
| 4998 NO_SYNC_WMIFLAG)); |
| 4999 |
| 5000 } |
| 5001 |
| 5002 A_STATUS |
| 5003 wmi_set_btcoex_aclcoex_config_cmd(struct wmi_t *wmip, |
| 5004 WMI_SET_BTCOEX_ACLCOEX_CONFIG_CM
D * cmd) |
| 5005 { |
| 5006 void *osbuf; |
| 5007 WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD *alloc_cmd; |
| 5008 |
| 5009 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 5010 if (osbuf == NULL) { |
| 5011 return A_NO_MEMORY; |
| 5012 } |
| 5013 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 5014 alloc_cmd = (WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD *)(A_NETBUF_DATA(osbuf)); |
| 5015 A_MEMZERO(alloc_cmd, sizeof(*cmd)); |
| 5016 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD)); |
| 5017 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID , |
| 5018 NO_SYNC_WMIFLAG)); |
| 5019 |
| 5020 } |
| 5021 |
| 5022 A_STATUS |
| 5023 wmi_set_btcoex_debug_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_DEBUG_CMD * cmd) |
| 5024 { |
| 5025 void *osbuf; |
| 5026 WMI_SET_BTCOEX_DEBUG_CMD *alloc_cmd; |
| 5027 |
| 5028 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 5029 if (osbuf == NULL) { |
| 5030 return A_NO_MEMORY; |
| 5031 } |
| 5032 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 5033 alloc_cmd = (WMI_SET_BTCOEX_DEBUG_CMD *)(A_NETBUF_DATA(osbuf)); |
| 5034 A_MEMZERO(alloc_cmd, sizeof(*cmd)); |
| 5035 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_DEBUG_CMD)); |
| 5036 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_DEBUG_CMDID , |
| 5037 NO_SYNC_WMIFLAG)); |
| 5038 |
| 5039 } |
| 5040 |
| 5041 A_STATUS |
| 5042 wmi_set_btcoex_bt_operating_status_cmd(struct wmi_t * wmip, |
| 5043 WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *
cmd) |
| 5044 { |
| 5045 void *osbuf; |
| 5046 WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *alloc_cmd; |
| 5047 |
| 5048 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 5049 if (osbuf == NULL) { |
| 5050 return A_NO_MEMORY; |
| 5051 } |
| 5052 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 5053 alloc_cmd = (WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *)(A_NETBUF_DATA(osb
uf)); |
| 5054 A_MEMZERO(alloc_cmd, sizeof(*cmd)); |
| 5055 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD)); |
| 5056 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD
ID , |
| 5057 NO_SYNC_WMIFLAG
)); |
| 5058 |
| 5059 } |
| 5060 |
| 5061 A_STATUS |
| 5062 wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * cmd) |
| 5063 { |
| 5064 void *osbuf; |
| 5065 WMI_GET_BTCOEX_CONFIG_CMD *alloc_cmd; |
| 5066 |
| 5067 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 5068 if (osbuf == NULL) { |
| 5069 return A_NO_MEMORY; |
| 5070 } |
| 5071 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 5072 alloc_cmd = (WMI_GET_BTCOEX_CONFIG_CMD *)(A_NETBUF_DATA(osbuf)); |
| 5073 A_MEMZERO(alloc_cmd, sizeof(*cmd)); |
| 5074 A_MEMCPY(alloc_cmd,cmd,sizeof(WMI_GET_BTCOEX_CONFIG_CMD)); |
| 5075 return (wmi_cmd_send(wmip, osbuf, WMI_GET_BTCOEX_CONFIG_CMDID , |
| 5076 NO_SYNC_WMIFLAG)); |
| 5077 |
| 5078 } |
| 5079 |
| 5080 A_STATUS |
| 5081 wmi_get_btcoex_stats_cmd(struct wmi_t *wmip) |
| 5082 { |
| 5083 |
| 5084 return wmi_simple_cmd(wmip, WMI_GET_BTCOEX_STATS_CMDID); |
| 5085 |
| 5086 } |
| 5087 |
| 5088 A_STATUS |
| 5089 wmi_get_keepalive_configured(struct wmi_t *wmip) |
| 5090 { |
| 5091 void *osbuf; |
| 5092 WMI_GET_KEEPALIVE_CMD *cmd; |
| 5093 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 5094 if (osbuf == NULL) { |
| 5095 return A_NO_MEMORY; |
| 5096 } |
| 5097 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 5098 cmd = (WMI_GET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf)); |
| 5099 A_MEMZERO(cmd, sizeof(*cmd)); |
| 5100 return (wmi_cmd_send(wmip, osbuf, WMI_GET_KEEPALIVE_CMDID, |
| 5101 NO_SYNC_WMIFLAG)); |
| 5102 } |
| 5103 |
| 5104 A_UINT8 |
| 5105 wmi_get_keepalive_cmd(struct wmi_t *wmip) |
| 5106 { |
| 5107 return wmip->wmi_keepaliveInterval; |
| 5108 } |
| 5109 |
| 5110 A_STATUS |
| 5111 wmi_set_keepalive_cmd(struct wmi_t *wmip, A_UINT8 keepaliveInterval) |
| 5112 { |
| 5113 void *osbuf; |
| 5114 WMI_SET_KEEPALIVE_CMD *cmd; |
| 5115 |
| 5116 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 5117 if (osbuf == NULL) { |
| 5118 return A_NO_MEMORY; |
| 5119 } |
| 5120 |
| 5121 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 5122 |
| 5123 cmd = (WMI_SET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf)); |
| 5124 A_MEMZERO(cmd, sizeof(*cmd)); |
| 5125 cmd->keepaliveInterval = keepaliveInterval; |
| 5126 wmip->wmi_keepaliveInterval = keepaliveInterval; |
| 5127 |
| 5128 return (wmi_cmd_send(wmip, osbuf, WMI_SET_KEEPALIVE_CMDID, |
| 5129 NO_SYNC_WMIFLAG)); |
| 5130 } |
| 5131 |
| 5132 A_STATUS |
| 5133 wmi_set_params_cmd(struct wmi_t *wmip, A_UINT32 opcode, A_UINT32 length, A_CHAR*
buffer) |
| 5134 { |
| 5135 void *osbuf; |
| 5136 WMI_SET_PARAMS_CMD *cmd; |
| 5137 |
| 5138 osbuf = A_NETBUF_ALLOC(sizeof(*cmd) + length); |
| 5139 if (osbuf == NULL) { |
| 5140 return A_NO_MEMORY; |
| 5141 } |
| 5142 |
| 5143 A_NETBUF_PUT(osbuf, sizeof(*cmd) + length); |
| 5144 |
| 5145 cmd = (WMI_SET_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); |
| 5146 A_MEMZERO(cmd, sizeof(*cmd)); |
| 5147 cmd->opcode = opcode; |
| 5148 cmd->length = length; |
| 5149 A_MEMCPY(cmd->buffer, buffer, length); |
| 5150 |
| 5151 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PARAMS_CMDID, |
| 5152 NO_SYNC_WMIFLAG)); |
| 5153 } |
| 5154 |
| 5155 |
| 5156 A_STATUS |
| 5157 wmi_set_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8
dot3, A_UINT8 dot4) |
| 5158 { |
| 5159 void *osbuf; |
| 5160 WMI_SET_MCAST_FILTER_CMD *cmd; |
| 5161 |
| 5162 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 5163 if (osbuf == NULL) { |
| 5164 return A_NO_MEMORY; |
| 5165 } |
| 5166 |
| 5167 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 5168 |
| 5169 cmd = (WMI_SET_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf)); |
| 5170 cmd->multicast_mac[0] = 0x01; |
| 5171 cmd->multicast_mac[1] = 0x00; |
| 5172 cmd->multicast_mac[2] = 0x5e; |
| 5173 cmd->multicast_mac[3] = dot2&0x7F; |
| 5174 cmd->multicast_mac[4] = dot3; |
| 5175 cmd->multicast_mac[5] = dot4; |
| 5176 |
| 5177 return (wmi_cmd_send(wmip, osbuf, WMI_SET_MCAST_FILTER_CMDID, |
| 5178 NO_SYNC_WMIFLAG)); |
| 5179 } |
| 5180 |
| 5181 |
| 5182 A_STATUS |
| 5183 wmi_del_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 dot1, A_UINT8 dot2, A_UINT8
dot3, A_UINT8 dot4) |
| 5184 { |
| 5185 void *osbuf; |
| 5186 WMI_SET_MCAST_FILTER_CMD *cmd; |
| 5187 |
| 5188 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 5189 if (osbuf == NULL) { |
| 5190 return A_NO_MEMORY; |
| 5191 } |
| 5192 |
| 5193 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 5194 |
| 5195 cmd = (WMI_SET_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf)); |
| 5196 cmd->multicast_mac[0] = 0x01; |
| 5197 cmd->multicast_mac[1] = 0x00; |
| 5198 cmd->multicast_mac[2] = 0x5e; |
| 5199 cmd->multicast_mac[3] = dot2&0x7F; |
| 5200 cmd->multicast_mac[4] = dot3; |
| 5201 cmd->multicast_mac[5] = dot4; |
| 5202 |
| 5203 return (wmi_cmd_send(wmip, osbuf, WMI_DEL_MCAST_FILTER_CMDID, |
| 5204 NO_SYNC_WMIFLAG)); |
| 5205 } |
| 5206 |
| 5207 A_STATUS |
| 5208 wmi_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 enable) |
| 5209 { |
| 5210 void *osbuf; |
| 5211 WMI_MCAST_FILTER_CMD *cmd; |
| 5212 |
| 5213 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 5214 if (osbuf == NULL) { |
| 5215 return A_NO_MEMORY; |
| 5216 } |
| 5217 |
| 5218 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 5219 |
| 5220 cmd = (WMI_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf)); |
| 5221 cmd->enable = enable; |
| 5222 |
| 5223 return (wmi_cmd_send(wmip, osbuf, WMI_MCAST_FILTER_CMDID, |
| 5224 NO_SYNC_WMIFLAG)); |
| 5225 } |
| 5226 |
| 5227 A_STATUS |
| 5228 wmi_set_appie_cmd(struct wmi_t *wmip, A_UINT8 mgmtFrmType, A_UINT8 ieLen, |
| 5229 A_UINT8 *ieInfo) |
| 5230 { |
| 5231 void *osbuf; |
| 5232 WMI_SET_APPIE_CMD *cmd; |
| 5233 A_UINT16 cmdLen; |
| 5234 |
| 5235 cmdLen = sizeof(*cmd) + ieLen - 1; |
| 5236 osbuf = A_NETBUF_ALLOC(cmdLen); |
| 5237 if (osbuf == NULL) { |
| 5238 return A_NO_MEMORY; |
| 5239 } |
| 5240 |
| 5241 A_NETBUF_PUT(osbuf, cmdLen); |
| 5242 |
| 5243 cmd = (WMI_SET_APPIE_CMD *)(A_NETBUF_DATA(osbuf)); |
| 5244 A_MEMZERO(cmd, cmdLen); |
| 5245 |
| 5246 cmd->mgmtFrmType = mgmtFrmType; |
| 5247 cmd->ieLen = ieLen; |
| 5248 A_MEMCPY(cmd->ieInfo, ieInfo, ieLen); |
| 5249 |
| 5250 return (wmi_cmd_send(wmip, osbuf, WMI_SET_APPIE_CMDID, NO_SYNC_WMIFLAG)); |
| 5251 } |
| 5252 |
| 5253 A_STATUS |
| 5254 wmi_set_halparam_cmd(struct wmi_t *wmip, A_UINT8 *cmd, A_UINT16 dataLen) |
| 5255 { |
| 5256 void *osbuf; |
| 5257 A_UINT8 *data; |
| 5258 |
| 5259 osbuf = A_NETBUF_ALLOC(dataLen); |
| 5260 if (osbuf == NULL) { |
| 5261 return A_NO_MEMORY; |
| 5262 } |
| 5263 |
| 5264 A_NETBUF_PUT(osbuf, dataLen); |
| 5265 |
| 5266 data = A_NETBUF_DATA(osbuf); |
| 5267 |
| 5268 A_MEMCPY(data, cmd, dataLen); |
| 5269 |
| 5270 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WHALPARAM_CMDID, NO_SYNC_WMIFLAG))
; |
| 5271 } |
| 5272 |
| 5273 A_INT32 |
| 5274 wmi_get_rate(A_INT8 rateindex) |
| 5275 { |
| 5276 if (rateindex == RATE_AUTO) { |
| 5277 return 0; |
| 5278 } else { |
| 5279 return(wmi_rateTable[(A_UINT32) rateindex]); |
| 5280 } |
| 5281 } |
| 5282 |
| 5283 void |
| 5284 wmi_node_return (struct wmi_t *wmip, bss_t *bss) |
| 5285 { |
| 5286 if (NULL != bss) |
| 5287 { |
| 5288 wlan_node_return (&wmip->wmi_scan_table, bss); |
| 5289 } |
| 5290 } |
| 5291 |
| 5292 void |
| 5293 wmi_set_nodeage(struct wmi_t *wmip, A_UINT32 nodeAge) |
| 5294 { |
| 5295 wlan_set_nodeage(&wmip->wmi_scan_table,nodeAge); |
| 5296 } |
| 5297 |
| 5298 bss_t * |
| 5299 wmi_find_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid, |
| 5300 A_UINT32 ssidLength, A_BOOL bIsWPA2, A_BOOL bMatchSSID) |
| 5301 { |
| 5302 bss_t *node = NULL; |
| 5303 node = wlan_find_Ssidnode (&wmip->wmi_scan_table, pSsid, |
| 5304 ssidLength, bIsWPA2, bMatchSSID); |
| 5305 return node; |
| 5306 } |
| 5307 |
| 5308 |
| 5309 void |
| 5310 wmi_free_allnodes(struct wmi_t *wmip) |
| 5311 { |
| 5312 wlan_free_allnodes(&wmip->wmi_scan_table); |
| 5313 } |
| 5314 |
| 5315 bss_t * |
| 5316 wmi_find_node(struct wmi_t *wmip, const A_UINT8 *macaddr) |
| 5317 { |
| 5318 bss_t *ni=NULL; |
| 5319 ni=wlan_find_node(&wmip->wmi_scan_table,macaddr); |
| 5320 return ni; |
| 5321 } |
| 5322 |
| 5323 void |
| 5324 wmi_free_node(struct wmi_t *wmip, const A_UINT8 *macaddr) |
| 5325 { |
| 5326 bss_t *ni=NULL; |
| 5327 |
| 5328 ni=wlan_find_node(&wmip->wmi_scan_table,macaddr); |
| 5329 if (ni != NULL) { |
| 5330 wlan_node_reclaim(&wmip->wmi_scan_table, ni); |
| 5331 } |
| 5332 |
| 5333 return; |
| 5334 } |
| 5335 |
| 5336 A_STATUS |
| 5337 wmi_dset_open_reply(struct wmi_t *wmip, |
| 5338 A_UINT32 status, |
| 5339 A_UINT32 access_cookie, |
| 5340 A_UINT32 dset_size, |
| 5341 A_UINT32 dset_version, |
| 5342 A_UINT32 targ_handle, |
| 5343 A_UINT32 targ_reply_fn, |
| 5344 A_UINT32 targ_reply_arg) |
| 5345 { |
| 5346 void *osbuf; |
| 5347 WMIX_DSETOPEN_REPLY_CMD *open_reply; |
| 5348 |
| 5349 A_DPRINTF(DBG_WMI, (DBGFMT "Enter - wmip=0x%x\n", DBGARG, (int)wmip)); |
| 5350 |
| 5351 osbuf = A_NETBUF_ALLOC(sizeof(*open_reply)); |
| 5352 if (osbuf == NULL) { |
| 5353 return A_NO_MEMORY; |
| 5354 } |
| 5355 |
| 5356 A_NETBUF_PUT(osbuf, sizeof(*open_reply)); |
| 5357 open_reply = (WMIX_DSETOPEN_REPLY_CMD *)(A_NETBUF_DATA(osbuf)); |
| 5358 |
| 5359 open_reply->status = status; |
| 5360 open_reply->targ_dset_handle = targ_handle; |
| 5361 open_reply->targ_reply_fn = targ_reply_fn; |
| 5362 open_reply->targ_reply_arg = targ_reply_arg; |
| 5363 open_reply->access_cookie = access_cookie; |
| 5364 open_reply->size = dset_size; |
| 5365 open_reply->version = dset_version; |
| 5366 |
| 5367 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETOPEN_REPLY_CMDID, |
| 5368 NO_SYNC_WMIFLAG)); |
| 5369 } |
| 5370 |
| 5371 static A_STATUS |
| 5372 wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len) |
| 5373 { |
| 5374 WMI_PMKID_LIST_REPLY *reply; |
| 5375 A_UINT32 expected_len; |
| 5376 |
| 5377 if (len < sizeof(WMI_PMKID_LIST_REPLY)) { |
| 5378 return A_EINVAL; |
| 5379 } |
| 5380 reply = (WMI_PMKID_LIST_REPLY *)datap; |
| 5381 expected_len = sizeof(reply->numPMKID) + reply->numPMKID * WMI_PMKID_LEN; |
| 5382 |
| 5383 if (len < expected_len) { |
| 5384 return A_EINVAL; |
| 5385 } |
| 5386 |
| 5387 A_WMI_PMKID_LIST_EVENT(wmip->wmi_devt, reply->numPMKID, |
| 5388 reply->pmkidList, reply->bssidList[0]); |
| 5389 |
| 5390 return A_OK; |
| 5391 } |
| 5392 |
| 5393 |
| 5394 static A_STATUS |
| 5395 wmi_set_params_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len) |
| 5396 { |
| 5397 WMI_SET_PARAMS_REPLY *reply; |
| 5398 |
| 5399 if (len < sizeof(WMI_SET_PARAMS_REPLY)) { |
| 5400 return A_EINVAL; |
| 5401 } |
| 5402 reply = (WMI_SET_PARAMS_REPLY *)datap; |
| 5403 |
| 5404 if (A_OK == reply->status) |
| 5405 { |
| 5406 |
| 5407 } |
| 5408 else |
| 5409 { |
| 5410 |
| 5411 } |
| 5412 |
| 5413 return A_OK; |
| 5414 } |
| 5415 |
| 5416 |
| 5417 |
| 5418 #ifdef CONFIG_HOST_DSET_SUPPORT |
| 5419 A_STATUS |
| 5420 wmi_dset_data_reply(struct wmi_t *wmip, |
| 5421 A_UINT32 status, |
| 5422 A_UINT8 *user_buf, |
| 5423 A_UINT32 length, |
| 5424 A_UINT32 targ_buf, |
| 5425 A_UINT32 targ_reply_fn, |
| 5426 A_UINT32 targ_reply_arg) |
| 5427 { |
| 5428 void *osbuf; |
| 5429 WMIX_DSETDATA_REPLY_CMD *data_reply; |
| 5430 A_UINT32 size; |
| 5431 |
| 5432 size = sizeof(*data_reply) + length; |
| 5433 |
| 5434 if (size <= length) { |
| 5435 return A_ERROR; |
| 5436 } |
| 5437 |
| 5438 A_DPRINTF(DBG_WMI, |
| 5439 (DBGFMT "Enter - length=%d status=%d\n", DBGARG, length, status)); |
| 5440 |
| 5441 osbuf = A_NETBUF_ALLOC(size); |
| 5442 if (osbuf == NULL) { |
| 5443 return A_NO_MEMORY; |
| 5444 } |
| 5445 A_NETBUF_PUT(osbuf, size); |
| 5446 data_reply = (WMIX_DSETDATA_REPLY_CMD *)(A_NETBUF_DATA(osbuf)); |
| 5447 |
| 5448 data_reply->status = status; |
| 5449 data_reply->targ_buf = targ_buf; |
| 5450 data_reply->targ_reply_fn = targ_reply_fn; |
| 5451 data_reply->targ_reply_arg = targ_reply_arg; |
| 5452 data_reply->length = length; |
| 5453 |
| 5454 if (status == A_OK) { |
| 5455 if (a_copy_from_user(data_reply->buf, user_buf, length)) { |
| 5456 return A_ERROR; |
| 5457 } |
| 5458 } |
| 5459 |
| 5460 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETDATA_REPLY_CMDID, |
| 5461 NO_SYNC_WMIFLAG)); |
| 5462 } |
| 5463 #endif /* CONFIG_HOST_DSET_SUPPORT */ |
| 5464 |
| 5465 A_STATUS |
| 5466 wmi_set_wsc_status_cmd(struct wmi_t *wmip, A_UINT32 status) |
| 5467 { |
| 5468 void *osbuf; |
| 5469 char *cmd; |
| 5470 |
| 5471 wps_enable = status; |
| 5472 |
| 5473 osbuf = a_netbuf_alloc(sizeof(1)); |
| 5474 if (osbuf == NULL) { |
| 5475 return A_NO_MEMORY; |
| 5476 } |
| 5477 |
| 5478 a_netbuf_put(osbuf, sizeof(1)); |
| 5479 |
| 5480 cmd = (char *)(a_netbuf_to_data(osbuf)); |
| 5481 |
| 5482 A_MEMZERO(cmd, sizeof(*cmd)); |
| 5483 cmd[0] = (status?1:0); |
| 5484 return (wmi_cmd_send(wmip, osbuf, WMI_SET_WSC_STATUS_CMDID, |
| 5485 NO_SYNC_WMIFLAG)); |
| 5486 } |
| 5487 |
| 5488 #if defined(CONFIG_TARGET_PROFILE_SUPPORT) |
| 5489 A_STATUS |
| 5490 wmi_prof_cfg_cmd(struct wmi_t *wmip, |
| 5491 A_UINT32 period, |
| 5492 A_UINT32 nbins) |
| 5493 { |
| 5494 void *osbuf; |
| 5495 WMIX_PROF_CFG_CMD *cmd; |
| 5496 |
| 5497 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 5498 if (osbuf == NULL) { |
| 5499 return A_NO_MEMORY; |
| 5500 } |
| 5501 |
| 5502 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 5503 |
| 5504 cmd = (WMIX_PROF_CFG_CMD *)(A_NETBUF_DATA(osbuf)); |
| 5505 A_MEMZERO(cmd, sizeof(*cmd)); |
| 5506 cmd->period = period; |
| 5507 cmd->nbins = nbins; |
| 5508 |
| 5509 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_PROF_CFG_CMDID, NO_SYNC_WMIFLAG)
); |
| 5510 } |
| 5511 |
| 5512 A_STATUS |
| 5513 wmi_prof_addr_set_cmd(struct wmi_t *wmip, A_UINT32 addr) |
| 5514 { |
| 5515 void *osbuf; |
| 5516 WMIX_PROF_ADDR_SET_CMD *cmd; |
| 5517 |
| 5518 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 5519 if (osbuf == NULL) { |
| 5520 return A_NO_MEMORY; |
| 5521 } |
| 5522 |
| 5523 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 5524 |
| 5525 cmd = (WMIX_PROF_ADDR_SET_CMD *)(A_NETBUF_DATA(osbuf)); |
| 5526 A_MEMZERO(cmd, sizeof(*cmd)); |
| 5527 cmd->addr = addr; |
| 5528 |
| 5529 return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_PROF_ADDR_SET_CMDID, NO_SYNC_WMI
FLAG)); |
| 5530 } |
| 5531 |
| 5532 A_STATUS |
| 5533 wmi_prof_start_cmd(struct wmi_t *wmip) |
| 5534 { |
| 5535 return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_START_CMDID); |
| 5536 } |
| 5537 |
| 5538 A_STATUS |
| 5539 wmi_prof_stop_cmd(struct wmi_t *wmip) |
| 5540 { |
| 5541 return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_STOP_CMDID); |
| 5542 } |
| 5543 |
| 5544 A_STATUS |
| 5545 wmi_prof_count_get_cmd(struct wmi_t *wmip) |
| 5546 { |
| 5547 return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_COUNT_GET_CMDID); |
| 5548 } |
| 5549 |
| 5550 /* Called to handle WMIX_PROF_CONT_EVENTID */ |
| 5551 static A_STATUS |
| 5552 wmi_prof_count_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 5553 { |
| 5554 WMIX_PROF_COUNT_EVENT *prof_data = (WMIX_PROF_COUNT_EVENT *)datap; |
| 5555 |
| 5556 A_DPRINTF(DBG_WMI, |
| 5557 (DBGFMT "Enter - addr=0x%x count=%d\n", DBGARG, |
| 5558 prof_data->addr, prof_data->count)); |
| 5559 |
| 5560 A_WMI_PROF_COUNT_RX(prof_data->addr, prof_data->count); |
| 5561 |
| 5562 return A_OK; |
| 5563 } |
| 5564 #endif /* CONFIG_TARGET_PROFILE_SUPPORT */ |
| 5565 |
| 5566 #ifdef OS_ROAM_MANAGEMENT |
| 5567 |
| 5568 #define ETHERNET_MAC_ADDRESS_LENGTH 6 |
| 5569 |
| 5570 void |
| 5571 wmi_scan_indication (struct wmi_t *wmip) |
| 5572 { |
| 5573 struct ieee80211_node_table *nt; |
| 5574 A_UINT32 gen; |
| 5575 A_UINT32 size; |
| 5576 A_UINT32 bsssize; |
| 5577 bss_t *bss; |
| 5578 A_UINT32 numbss; |
| 5579 PNDIS_802_11_BSSID_SCAN_INFO psi; |
| 5580 PBYTE pie; |
| 5581 NDIS_802_11_FIXED_IEs *pFixed; |
| 5582 NDIS_802_11_VARIABLE_IEs *pVar; |
| 5583 A_UINT32 RateSize; |
| 5584 |
| 5585 struct ar6kScanIndication |
| 5586 { |
| 5587 NDIS_802_11_STATUS_INDICATION ind; |
| 5588 NDIS_802_11_BSSID_SCAN_INFO_LIST slist; |
| 5589 } *pAr6kScanIndEvent; |
| 5590 |
| 5591 nt = &wmip->wmi_scan_table; |
| 5592 |
| 5593 ++nt->nt_si_gen; |
| 5594 |
| 5595 |
| 5596 gen = nt->nt_si_gen; |
| 5597 |
| 5598 size = offsetof(struct ar6kScanIndication, slist) + |
| 5599 offsetof(NDIS_802_11_BSSID_SCAN_INFO_LIST, BssidScanInfo); |
| 5600 |
| 5601 numbss = 0; |
| 5602 |
| 5603 IEEE80211_NODE_LOCK(nt); |
| 5604 |
| 5605 //calc size |
| 5606 for (bss = nt->nt_node_first; bss; bss = bss->ni_list_next) { |
| 5607 if (bss->ni_si_gen != gen) { |
| 5608 bsssize = offsetof(NDIS_802_11_BSSID_SCAN_INFO, Bssid) + offsetof(ND
IS_WLAN_BSSID_EX, IEs); |
| 5609 bsssize = bsssize + sizeof(NDIS_802_11_FIXED_IEs); |
| 5610 |
| 5611 #ifdef SUPPORT_WPA2 |
| 5612 if (bss->ni_cie.ie_rsn) { |
| 5613 bsssize = bsssize + bss->ni_cie.ie_rsn[1] + 2; |
| 5614 } |
| 5615 #endif |
| 5616 if (bss->ni_cie.ie_wpa) { |
| 5617 bsssize = bsssize + bss->ni_cie.ie_wpa[1] + 2; |
| 5618 } |
| 5619 |
| 5620 // bsssize must be a multiple of 4 to maintain alignment. |
| 5621 bsssize = (bsssize + 3) & ~3; |
| 5622 |
| 5623 size += bsssize; |
| 5624 |
| 5625 numbss++; |
| 5626 } |
| 5627 } |
| 5628 |
| 5629 if (0 == numbss) |
| 5630 { |
| 5631 // RETAILMSG(1, (L"AR6K: scan indication: 0 bss\n")); |
| 5632 ar6000_scan_indication (wmip->wmi_devt, NULL, 0); |
| 5633 IEEE80211_NODE_UNLOCK (nt); |
| 5634 return; |
| 5635 } |
| 5636 |
| 5637 pAr6kScanIndEvent = A_MALLOC(size); |
| 5638 |
| 5639 if (NULL == pAr6kScanIndEvent) |
| 5640 { |
| 5641 IEEE80211_NODE_UNLOCK(nt); |
| 5642 return; |
| 5643 } |
| 5644 |
| 5645 A_MEMZERO(pAr6kScanIndEvent, size); |
| 5646 |
| 5647 //copy data |
| 5648 pAr6kScanIndEvent->ind.StatusType = Ndis802_11StatusType_BssidScanInfoList; |
| 5649 pAr6kScanIndEvent->slist.Version = 1; |
| 5650 pAr6kScanIndEvent->slist.NumItems = numbss; |
| 5651 |
| 5652 psi = &pAr6kScanIndEvent->slist.BssidScanInfo[0]; |
| 5653 |
| 5654 for (bss = nt->nt_node_first; bss; bss = bss->ni_list_next) { |
| 5655 if (bss->ni_si_gen != gen) { |
| 5656 |
| 5657 bss->ni_si_gen = gen; |
| 5658 |
| 5659 //Set scan time |
| 5660 psi->ScanTime = bss->ni_tstamp - WLAN_NODE_INACT_TIMEOUT_MSEC; |
| 5661 |
| 5662 // Copy data to bssid_ex |
| 5663 bsssize = offsetof(NDIS_WLAN_BSSID_EX, IEs); |
| 5664 bsssize = bsssize + sizeof(NDIS_802_11_FIXED_IEs); |
| 5665 |
| 5666 #ifdef SUPPORT_WPA2 |
| 5667 if (bss->ni_cie.ie_rsn) { |
| 5668 bsssize = bsssize + bss->ni_cie.ie_rsn[1] + 2; |
| 5669 } |
| 5670 #endif |
| 5671 if (bss->ni_cie.ie_wpa) { |
| 5672 bsssize = bsssize + bss->ni_cie.ie_wpa[1] + 2; |
| 5673 } |
| 5674 |
| 5675 // bsssize must be a multiple of 4 to maintain alignment. |
| 5676 bsssize = (bsssize + 3) & ~3; |
| 5677 |
| 5678 psi->Bssid.Length = bsssize; |
| 5679 |
| 5680 memcpy (psi->Bssid.MacAddress, bss->ni_macaddr, ETHERNET_MAC_ADDRESS
_LENGTH); |
| 5681 |
| 5682 |
| 5683 //if (((bss->ni_macaddr[3] == 0xCE) && (bss->ni_macaddr[4] == 0xF0) && (bss->ni_
macaddr[5] == 0xE7)) || |
| 5684 // ((bss->ni_macaddr[3] == 0x03) && (bss->ni_macaddr[4] == 0xE2) && (bss->ni_ma
caddr[5] == 0x70))) |
| 5685 // RETAILMSG (1, (L"%x\n",bss->ni_macaddr[5])); |
| 5686 |
| 5687 psi->Bssid.Ssid.SsidLength = 0; |
| 5688 pie = bss->ni_cie.ie_ssid; |
| 5689 |
| 5690 if (pie) { |
| 5691 // Format of SSID IE is: |
| 5692 // Type (1 octet) |
| 5693 // Length (1 octet) |
| 5694 // SSID (Length octets) |
| 5695 // |
| 5696 // Validation of the IE should have occurred within WMI. |
| 5697 // |
| 5698 if (pie[1] <= 32) { |
| 5699 psi->Bssid.Ssid.SsidLength = pie[1]; |
| 5700 memcpy(psi->Bssid.Ssid.Ssid, &pie[2], psi->Bssid.Ssid.SsidLe
ngth); |
| 5701 } |
| 5702 } |
| 5703 psi->Bssid.Privacy = (bss->ni_cie.ie_capInfo & 0x10) ? 1 : 0; |
| 5704 |
| 5705 //Post the RSSI value relative to the Standard Noise floor value. |
| 5706 psi->Bssid.Rssi = bss->ni_rssi; |
| 5707 |
| 5708 if (bss->ni_cie.ie_chan >= 2412 && bss->ni_cie.ie_chan <= 2484) { |
| 5709 |
| 5710 if (bss->ni_cie.ie_rates && bss->ni_cie.ie_xrates) { |
| 5711 psi->Bssid.NetworkTypeInUse = Ndis802_11OFDM24; |
| 5712 } |
| 5713 else { |
| 5714 psi->Bssid.NetworkTypeInUse = Ndis802_11DS; |
| 5715 } |
| 5716 } |
| 5717 else { |
| 5718 psi->Bssid.NetworkTypeInUse = Ndis802_11OFDM5; |
| 5719 } |
| 5720 |
| 5721 psi->Bssid.Configuration.Length = sizeof(psi->Bssid.Configuration); |
| 5722 psi->Bssid.Configuration.BeaconPeriod = bss->ni_cie.ie_beaconInt; //
Units are Kmicroseconds (1024 us) |
| 5723 psi->Bssid.Configuration.ATIMWindow = 0; |
| 5724 psi->Bssid.Configuration.DSConfig = bss->ni_cie.ie_chan * 1000; |
| 5725 psi->Bssid.InfrastructureMode = ((bss->ni_cie.ie_capInfo & 0x03) ==
0x01 ) ? Ndis802_11Infrastructure : Ndis802_11IBSS; |
| 5726 |
| 5727 RateSize = 0; |
| 5728 pie = bss->ni_cie.ie_rates; |
| 5729 if (pie) { |
| 5730 RateSize = (pie[1] < NDIS_802_11_LENGTH_RATES_EX) ? pie[1] : NDI
S_802_11_LENGTH_RATES_EX; |
| 5731 memcpy(psi->Bssid.SupportedRates, &pie[2], RateSize); |
| 5732 } |
| 5733 pie = bss->ni_cie.ie_xrates; |
| 5734 if (pie && RateSize < NDIS_802_11_LENGTH_RATES_EX) { |
| 5735 memcpy(psi->Bssid.SupportedRates + RateSize, &pie[2], |
| 5736 (pie[1] < (NDIS_802_11_LENGTH_RATES_EX - RateSize)) ? pie
[1] : (NDIS_802_11_LENGTH_RATES_EX - RateSize)); |
| 5737 } |
| 5738 |
| 5739 // Copy the fixed IEs |
| 5740 psi->Bssid.IELength = sizeof(NDIS_802_11_FIXED_IEs); |
| 5741 |
| 5742 pFixed = (NDIS_802_11_FIXED_IEs *)psi->Bssid.IEs; |
| 5743 memcpy(pFixed->Timestamp, bss->ni_cie.ie_tstamp, sizeof(pFixed->Time
stamp)); |
| 5744 pFixed->BeaconInterval = bss->ni_cie.ie_beaconInt; |
| 5745 pFixed->Capabilities = bss->ni_cie.ie_capInfo; |
| 5746 |
| 5747 // Copy selected variable IEs |
| 5748 |
| 5749 pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pFixed + sizeof(NDIS_802_
11_FIXED_IEs)); |
| 5750 |
| 5751 #ifdef SUPPORT_WPA2 |
| 5752 // Copy the WPAv2 IE |
| 5753 if (bss->ni_cie.ie_rsn) { |
| 5754 pie = bss->ni_cie.ie_rsn; |
| 5755 psi->Bssid.IELength += pie[1] + 2; |
| 5756 memcpy(pVar, pie, pie[1] + 2); |
| 5757 pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pVar + pie[1] + 2); |
| 5758 } |
| 5759 #endif |
| 5760 // Copy the WPAv1 IE |
| 5761 if (bss->ni_cie.ie_wpa) { |
| 5762 pie = bss->ni_cie.ie_wpa; |
| 5763 psi->Bssid.IELength += pie[1] + 2; |
| 5764 memcpy(pVar, pie, pie[1] + 2); |
| 5765 pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pVar + pie[1] + 2); |
| 5766 } |
| 5767 |
| 5768 // Advance buffer pointer |
| 5769 psi = (PNDIS_802_11_BSSID_SCAN_INFO)((BYTE*)psi + bsssize + FIELD_OF
FSET(NDIS_802_11_BSSID_SCAN_INFO, Bssid)); |
| 5770 } |
| 5771 } |
| 5772 |
| 5773 IEEE80211_NODE_UNLOCK(nt); |
| 5774 |
| 5775 // wmi_free_allnodes(wmip); |
| 5776 |
| 5777 // RETAILMSG(1, (L"AR6K: scan indication: %u bss\n", numbss)); |
| 5778 |
| 5779 ar6000_scan_indication (wmip->wmi_devt, pAr6kScanIndEvent, size); |
| 5780 |
| 5781 A_FREE(pAr6kScanIndEvent); |
| 5782 } |
| 5783 #endif |
| 5784 |
| 5785 A_UINT8 |
| 5786 ar6000_get_upper_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, |
| 5787 A_UINT32 size) |
| 5788 { |
| 5789 A_UINT32 index; |
| 5790 A_UINT8 threshold = (A_UINT8)sq_thresh->upper_threshold[size - 1]; |
| 5791 |
| 5792 /* The list is already in sorted order. Get the next lower value */ |
| 5793 for (index = 0; index < size; index ++) { |
| 5794 if (rssi < sq_thresh->upper_threshold[index]) { |
| 5795 threshold = (A_UINT8)sq_thresh->upper_threshold[index]; |
| 5796 break; |
| 5797 } |
| 5798 } |
| 5799 |
| 5800 return threshold; |
| 5801 } |
| 5802 |
| 5803 A_UINT8 |
| 5804 ar6000_get_lower_threshold(A_INT16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, |
| 5805 A_UINT32 size) |
| 5806 { |
| 5807 A_UINT32 index; |
| 5808 A_UINT8 threshold = (A_UINT8)sq_thresh->lower_threshold[size - 1]; |
| 5809 |
| 5810 /* The list is already in sorted order. Get the next lower value */ |
| 5811 for (index = 0; index < size; index ++) { |
| 5812 if (rssi > sq_thresh->lower_threshold[index]) { |
| 5813 threshold = (A_UINT8)sq_thresh->lower_threshold[index]; |
| 5814 break; |
| 5815 } |
| 5816 } |
| 5817 |
| 5818 return threshold; |
| 5819 } |
| 5820 static A_STATUS |
| 5821 wmi_send_rssi_threshold_params(struct wmi_t *wmip, |
| 5822 WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd) |
| 5823 { |
| 5824 void *osbuf; |
| 5825 A_INT8 size; |
| 5826 WMI_RSSI_THRESHOLD_PARAMS_CMD *cmd; |
| 5827 |
| 5828 size = sizeof (*cmd); |
| 5829 |
| 5830 osbuf = A_NETBUF_ALLOC(size); |
| 5831 if (osbuf == NULL) { |
| 5832 return A_NO_MEMORY; |
| 5833 } |
| 5834 |
| 5835 A_NETBUF_PUT(osbuf, size); |
| 5836 |
| 5837 cmd = (WMI_RSSI_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); |
| 5838 A_MEMZERO(cmd, size); |
| 5839 A_MEMCPY(cmd, rssiCmd, sizeof(WMI_RSSI_THRESHOLD_PARAMS_CMD)); |
| 5840 |
| 5841 return (wmi_cmd_send(wmip, osbuf, WMI_RSSI_THRESHOLD_PARAMS_CMDID, |
| 5842 NO_SYNC_WMIFLAG)); |
| 5843 } |
| 5844 static A_STATUS |
| 5845 wmi_send_snr_threshold_params(struct wmi_t *wmip, |
| 5846 WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd) |
| 5847 { |
| 5848 void *osbuf; |
| 5849 A_INT8 size; |
| 5850 WMI_SNR_THRESHOLD_PARAMS_CMD *cmd; |
| 5851 |
| 5852 size = sizeof (*cmd); |
| 5853 |
| 5854 osbuf = A_NETBUF_ALLOC(size); |
| 5855 if (osbuf == NULL) { |
| 5856 return A_NO_MEMORY; |
| 5857 } |
| 5858 |
| 5859 A_NETBUF_PUT(osbuf, size); |
| 5860 cmd = (WMI_SNR_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); |
| 5861 A_MEMZERO(cmd, size); |
| 5862 A_MEMCPY(cmd, snrCmd, sizeof(WMI_SNR_THRESHOLD_PARAMS_CMD)); |
| 5863 |
| 5864 return (wmi_cmd_send(wmip, osbuf, WMI_SNR_THRESHOLD_PARAMS_CMDID, |
| 5865 NO_SYNC_WMIFLAG)); |
| 5866 } |
| 5867 |
| 5868 A_STATUS |
| 5869 wmi_set_target_event_report_cmd(struct wmi_t *wmip, WMI_SET_TARGET_EVENT_REPORT_
CMD* cmd) |
| 5870 { |
| 5871 void *osbuf; |
| 5872 WMI_SET_TARGET_EVENT_REPORT_CMD* alloc_cmd; |
| 5873 |
| 5874 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 5875 if (osbuf == NULL) { |
| 5876 return A_NO_MEMORY; |
| 5877 } |
| 5878 |
| 5879 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 5880 |
| 5881 alloc_cmd = (WMI_SET_TARGET_EVENT_REPORT_CMD *)(A_NETBUF_DATA(osbuf)); |
| 5882 A_MEMZERO(alloc_cmd, sizeof(*cmd)); |
| 5883 A_MEMCPY(alloc_cmd, cmd, sizeof(*cmd)); |
| 5884 |
| 5885 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TARGET_EVENT_REPORT_CMDID, |
| 5886 NO_SYNC_WMIFLAG)); |
| 5887 } |
| 5888 |
| 5889 bss_t *wmi_rm_current_bss (struct wmi_t *wmip, A_UINT8 *id) |
| 5890 { |
| 5891 wmi_get_current_bssid (wmip, id); |
| 5892 return wlan_node_remove (&wmip->wmi_scan_table, id); |
| 5893 } |
| 5894 |
| 5895 A_STATUS wmi_add_current_bss (struct wmi_t *wmip, A_UINT8 *id, bss_t *bss) |
| 5896 { |
| 5897 wlan_setup_node (&wmip->wmi_scan_table, bss, id); |
| 5898 return A_OK; |
| 5899 } |
| 5900 |
| 5901 #ifdef ATH_AR6K_11N_SUPPORT |
| 5902 static A_STATUS |
| 5903 wmi_addba_req_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 5904 { |
| 5905 WMI_ADDBA_REQ_EVENT *cmd = (WMI_ADDBA_REQ_EVENT *)datap; |
| 5906 |
| 5907 A_WMI_AGGR_RECV_ADDBA_REQ_EVT(wmip->wmi_devt, cmd); |
| 5908 |
| 5909 return A_OK; |
| 5910 } |
| 5911 |
| 5912 |
| 5913 static A_STATUS |
| 5914 wmi_addba_resp_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 5915 { |
| 5916 WMI_ADDBA_RESP_EVENT *cmd = (WMI_ADDBA_RESP_EVENT *)datap; |
| 5917 |
| 5918 A_WMI_AGGR_RECV_ADDBA_RESP_EVT(wmip->wmi_devt, cmd); |
| 5919 |
| 5920 return A_OK; |
| 5921 } |
| 5922 |
| 5923 static A_STATUS |
| 5924 wmi_delba_req_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 5925 { |
| 5926 WMI_DELBA_EVENT *cmd = (WMI_DELBA_EVENT *)datap; |
| 5927 |
| 5928 A_WMI_AGGR_RECV_DELBA_REQ_EVT(wmip->wmi_devt, cmd); |
| 5929 |
| 5930 return A_OK; |
| 5931 } |
| 5932 |
| 5933 A_STATUS |
| 5934 wmi_btcoex_config_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 5935 { |
| 5936 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 5937 |
| 5938 A_WMI_BTCOEX_CONFIG_EVENT(wmip->wmi_devt, datap, len); |
| 5939 |
| 5940 return A_OK; |
| 5941 } |
| 5942 |
| 5943 |
| 5944 A_STATUS |
| 5945 wmi_btcoex_stats_event_rx(struct wmi_t * wmip,A_UINT8 * datap,int len) |
| 5946 { |
| 5947 A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); |
| 5948 |
| 5949 A_WMI_BTCOEX_STATS_EVENT(wmip->wmi_devt, datap, len); |
| 5950 |
| 5951 return A_OK; |
| 5952 |
| 5953 } |
| 5954 #endif |
| 5955 |
| 5956 static A_STATUS |
| 5957 wmi_hci_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 5958 { |
| 5959 WMI_HCI_EVENT *cmd = (WMI_HCI_EVENT *)datap; |
| 5960 A_WMI_HCI_EVENT_EVT(wmip->wmi_devt, cmd); |
| 5961 |
| 5962 return A_OK; |
| 5963 } |
| 5964 |
| 5965 //////////////////////////////////////////////////////////////////////////////// |
| 5966 //// //// |
| 5967 //// AP mode functions //// |
| 5968 //// //// |
| 5969 //////////////////////////////////////////////////////////////////////////////// |
| 5970 /* |
| 5971 * IOCTL: AR6000_XIOCTL_AP_COMMIT_CONFIG |
| 5972 * |
| 5973 * When AR6K in AP mode, This command will be called after |
| 5974 * changing ssid, channel etc. It will pass the profile to |
| 5975 * target with a flag which will indicate which parameter changed, |
| 5976 * also if this flag is 0, there was no change in parametes, so |
| 5977 * commit cmd will not be sent to target. Without calling this IOCTL |
| 5978 * the changes will not take effect. |
| 5979 */ |
| 5980 A_STATUS |
| 5981 wmi_ap_profile_commit(struct wmi_t *wmip, WMI_CONNECT_CMD *p) |
| 5982 { |
| 5983 void *osbuf; |
| 5984 WMI_CONNECT_CMD *cm; |
| 5985 |
| 5986 osbuf = A_NETBUF_ALLOC(sizeof(*cm)); |
| 5987 if (osbuf == NULL) { |
| 5988 return A_NO_MEMORY; |
| 5989 } |
| 5990 |
| 5991 A_NETBUF_PUT(osbuf, sizeof(*cm)); |
| 5992 cm = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf)); |
| 5993 A_MEMZERO(cm, sizeof(*cm)); |
| 5994 |
| 5995 A_MEMCPY(cm,p,sizeof(*cm)); |
| 5996 |
| 5997 return (wmi_cmd_send(wmip, osbuf, WMI_AP_CONFIG_COMMIT_CMDID, NO_SYNC_WMIFLA
G)); |
| 5998 } |
| 5999 |
| 6000 /* |
| 6001 * IOCTL: AR6000_XIOCTL_AP_HIDDEN_SSID |
| 6002 * |
| 6003 * This command will be used to enable/disable hidden ssid functioanlity of |
| 6004 * beacon. If it is enabled, ssid will be NULL in beacon. |
| 6005 */ |
| 6006 A_STATUS |
| 6007 wmi_ap_set_hidden_ssid(struct wmi_t *wmip, A_UINT8 hidden_ssid) |
| 6008 { |
| 6009 void *osbuf; |
| 6010 WMI_AP_HIDDEN_SSID_CMD *hs; |
| 6011 |
| 6012 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_HIDDEN_SSID_CMD)); |
| 6013 if (osbuf == NULL) { |
| 6014 return A_NO_MEMORY; |
| 6015 } |
| 6016 |
| 6017 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_HIDDEN_SSID_CMD)); |
| 6018 hs = (WMI_AP_HIDDEN_SSID_CMD *)(A_NETBUF_DATA(osbuf)); |
| 6019 A_MEMZERO(hs, sizeof(*hs)); |
| 6020 |
| 6021 hs->hidden_ssid = hidden_ssid; |
| 6022 |
| 6023 A_DPRINTF(DBG_WMI, (DBGFMT "AR6000_XIOCTL_AP_HIDDEN_SSID %d\n", DBGARG , hid
den_ssid)); |
| 6024 return (wmi_cmd_send(wmip, osbuf, WMI_AP_HIDDEN_SSID_CMDID, NO_SYNC_WMIFLAG)
); |
| 6025 } |
| 6026 |
| 6027 /* |
| 6028 * IOCTL: AR6000_XIOCTL_AP_SET_MAX_NUM_STA |
| 6029 * |
| 6030 * This command is used to limit max num of STA that can connect |
| 6031 * with this AP. This value should not exceed AP_MAX_NUM_STA (this |
| 6032 * is max num of STA supported by AP). Value was already validated |
| 6033 * in ioctl.c |
| 6034 */ |
| 6035 A_STATUS |
| 6036 wmi_ap_set_num_sta(struct wmi_t *wmip, A_UINT8 num_sta) |
| 6037 { |
| 6038 void *osbuf; |
| 6039 WMI_AP_SET_NUM_STA_CMD *ns; |
| 6040 |
| 6041 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_NUM_STA_CMD)); |
| 6042 if (osbuf == NULL) { |
| 6043 return A_NO_MEMORY; |
| 6044 } |
| 6045 |
| 6046 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_NUM_STA_CMD)); |
| 6047 ns = (WMI_AP_SET_NUM_STA_CMD *)(A_NETBUF_DATA(osbuf)); |
| 6048 A_MEMZERO(ns, sizeof(*ns)); |
| 6049 |
| 6050 ns->num_sta = num_sta; |
| 6051 |
| 6052 A_DPRINTF(DBG_WMI, (DBGFMT "AR6000_XIOCTL_AP_SET_MAX_NUM_STA %d\n", DBGARG ,
num_sta)); |
| 6053 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_NUM_STA_CMDID, NO_SYNC_WMIFLAG)
); |
| 6054 } |
| 6055 |
| 6056 /* |
| 6057 * IOCTL: AR6000_XIOCTL_AP_SET_ACL_MAC |
| 6058 * |
| 6059 * This command is used to send list of mac of STAs which will |
| 6060 * be allowed to connect with this AP. When this list is empty |
| 6061 * firware will allow all STAs till the count reaches AP_MAX_NUM_STA. |
| 6062 */ |
| 6063 A_STATUS |
| 6064 wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *acl) |
| 6065 { |
| 6066 void *osbuf; |
| 6067 WMI_AP_ACL_MAC_CMD *a; |
| 6068 |
| 6069 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_ACL_MAC_CMD)); |
| 6070 if (osbuf == NULL) { |
| 6071 return A_NO_MEMORY; |
| 6072 } |
| 6073 |
| 6074 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_ACL_MAC_CMD)); |
| 6075 a = (WMI_AP_ACL_MAC_CMD *)(A_NETBUF_DATA(osbuf)); |
| 6076 A_MEMZERO(a, sizeof(*a)); |
| 6077 A_MEMCPY(a,acl,sizeof(*acl)); |
| 6078 |
| 6079 return (wmi_cmd_send(wmip, osbuf, WMI_AP_ACL_MAC_LIST_CMDID, NO_SYNC_WMIFLAG
)); |
| 6080 } |
| 6081 |
| 6082 /* |
| 6083 * IOCTL: AR6000_XIOCTL_AP_SET_MLME |
| 6084 * |
| 6085 * This command is used to send list of mac of STAs which will |
| 6086 * be allowed to connect with this AP. When this list is empty |
| 6087 * firware will allow all STAs till the count reaches AP_MAX_NUM_STA. |
| 6088 */ |
| 6089 A_STATUS |
| 6090 wmi_ap_set_mlme(struct wmi_t *wmip, A_UINT8 cmd, A_UINT8 *mac, A_UINT16 reason) |
| 6091 { |
| 6092 void *osbuf; |
| 6093 WMI_AP_SET_MLME_CMD *mlme; |
| 6094 |
| 6095 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_MLME_CMD)); |
| 6096 if (osbuf == NULL) { |
| 6097 return A_NO_MEMORY; |
| 6098 } |
| 6099 |
| 6100 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_MLME_CMD)); |
| 6101 mlme = (WMI_AP_SET_MLME_CMD *)(A_NETBUF_DATA(osbuf)); |
| 6102 A_MEMZERO(mlme, sizeof(*mlme)); |
| 6103 |
| 6104 mlme->cmd = cmd; |
| 6105 A_MEMCPY(mlme->mac, mac, ATH_MAC_LEN); |
| 6106 mlme->reason = reason; |
| 6107 |
| 6108 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_MLME_CMDID, NO_SYNC_WMIFLAG)); |
| 6109 } |
| 6110 |
| 6111 static A_STATUS |
| 6112 wmi_pspoll_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len) |
| 6113 { |
| 6114 WMI_PSPOLL_EVENT *ev; |
| 6115 |
| 6116 if (len < sizeof(WMI_PSPOLL_EVENT)) { |
| 6117 return A_EINVAL; |
| 6118 } |
| 6119 ev = (WMI_PSPOLL_EVENT *)datap; |
| 6120 |
| 6121 A_WMI_PSPOLL_EVENT(wmip->wmi_devt, ev->aid); |
| 6122 return A_OK; |
| 6123 } |
| 6124 |
| 6125 static A_STATUS |
| 6126 wmi_dtimexpiry_event_rx(struct wmi_t *wmip, A_UINT8 *datap,int len) |
| 6127 { |
| 6128 A_WMI_DTIMEXPIRY_EVENT(wmip->wmi_devt); |
| 6129 return A_OK; |
| 6130 } |
| 6131 |
| 6132 #ifdef WAPI_ENABLE |
| 6133 static A_STATUS |
| 6134 wmi_wapi_rekey_event_rx(struct wmi_t *wmip, A_UINT8 *datap,int len) |
| 6135 { |
| 6136 A_UINT8 *ev; |
| 6137 |
| 6138 if (len < 7) { |
| 6139 return A_EINVAL; |
| 6140 } |
| 6141 ev = (A_UINT8 *)datap; |
| 6142 |
| 6143 A_WMI_WAPI_REKEY_EVENT(wmip->wmi_devt, *ev, &ev[1]); |
| 6144 return A_OK; |
| 6145 } |
| 6146 #endif |
| 6147 |
| 6148 A_STATUS |
| 6149 wmi_set_pvb_cmd(struct wmi_t *wmip, A_UINT16 aid, A_BOOL flag) |
| 6150 { |
| 6151 WMI_AP_SET_PVB_CMD *cmd; |
| 6152 void *osbuf = NULL; |
| 6153 |
| 6154 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_PVB_CMD)); |
| 6155 if (osbuf == NULL) { |
| 6156 return A_NO_MEMORY; |
| 6157 } |
| 6158 |
| 6159 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_PVB_CMD)); |
| 6160 cmd = (WMI_AP_SET_PVB_CMD *)(A_NETBUF_DATA(osbuf)); |
| 6161 A_MEMZERO(cmd, sizeof(*cmd)); |
| 6162 |
| 6163 cmd->aid = aid; |
| 6164 cmd->flag = flag; |
| 6165 |
| 6166 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_PVB_CMDID, NO_SYNC_WMIFLAG)); |
| 6167 } |
| 6168 |
| 6169 A_STATUS |
| 6170 wmi_ap_conn_inact_time(struct wmi_t *wmip, A_UINT32 period) |
| 6171 { |
| 6172 WMI_AP_CONN_INACT_CMD *cmd; |
| 6173 void *osbuf = NULL; |
| 6174 |
| 6175 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_CONN_INACT_CMD)); |
| 6176 if (osbuf == NULL) { |
| 6177 return A_NO_MEMORY; |
| 6178 } |
| 6179 |
| 6180 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_CONN_INACT_CMD)); |
| 6181 cmd = (WMI_AP_CONN_INACT_CMD *)(A_NETBUF_DATA(osbuf)); |
| 6182 A_MEMZERO(cmd, sizeof(*cmd)); |
| 6183 |
| 6184 cmd->period = period; |
| 6185 |
| 6186 return (wmi_cmd_send(wmip, osbuf, WMI_AP_CONN_INACT_CMDID, NO_SYNC_WMIFLAG))
; |
| 6187 } |
| 6188 |
| 6189 A_STATUS |
| 6190 wmi_ap_bgscan_time(struct wmi_t *wmip, A_UINT32 period, A_UINT32 dwell) |
| 6191 { |
| 6192 WMI_AP_PROT_SCAN_TIME_CMD *cmd; |
| 6193 void *osbuf = NULL; |
| 6194 |
| 6195 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_PROT_SCAN_TIME_CMD)); |
| 6196 if (osbuf == NULL) { |
| 6197 return A_NO_MEMORY; |
| 6198 } |
| 6199 |
| 6200 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_PROT_SCAN_TIME_CMD)); |
| 6201 cmd = (WMI_AP_PROT_SCAN_TIME_CMD *)(A_NETBUF_DATA(osbuf)); |
| 6202 A_MEMZERO(cmd, sizeof(*cmd)); |
| 6203 |
| 6204 cmd->period_min = period; |
| 6205 cmd->dwell_ms = dwell; |
| 6206 |
| 6207 return (wmi_cmd_send(wmip, osbuf, WMI_AP_PROT_SCAN_TIME_CMDID, NO_SYNC_WMIFL
AG)); |
| 6208 } |
| 6209 |
| 6210 A_STATUS |
| 6211 wmi_ap_set_dtim(struct wmi_t *wmip, A_UINT8 dtim) |
| 6212 { |
| 6213 WMI_AP_SET_DTIM_CMD *cmd; |
| 6214 void *osbuf = NULL; |
| 6215 |
| 6216 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_DTIM_CMD)); |
| 6217 if (osbuf == NULL) { |
| 6218 return A_NO_MEMORY; |
| 6219 } |
| 6220 |
| 6221 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_DTIM_CMD)); |
| 6222 cmd = (WMI_AP_SET_DTIM_CMD *)(A_NETBUF_DATA(osbuf)); |
| 6223 A_MEMZERO(cmd, sizeof(*cmd)); |
| 6224 |
| 6225 cmd->dtim = dtim; |
| 6226 |
| 6227 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_DTIM_CMDID, NO_SYNC_WMIFLAG)); |
| 6228 } |
| 6229 |
| 6230 /* |
| 6231 * IOCTL: AR6000_XIOCTL_AP_SET_ACL_POLICY |
| 6232 * |
| 6233 * This command is used to set ACL policay. While changing policy, if you |
| 6234 * want to retain the existing MAC addresses in the ACL list, policy should be |
| 6235 * OR with AP_ACL_RETAIN_LIST_MASK, else the existing list will be cleared. |
| 6236 * If there is no chage in policy, the list will be intact. |
| 6237 */ |
| 6238 A_STATUS |
| 6239 wmi_ap_set_acl_policy(struct wmi_t *wmip, A_UINT8 policy) |
| 6240 { |
| 6241 void *osbuf; |
| 6242 WMI_AP_ACL_POLICY_CMD *po; |
| 6243 |
| 6244 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_ACL_POLICY_CMD)); |
| 6245 if (osbuf == NULL) { |
| 6246 return A_NO_MEMORY; |
| 6247 } |
| 6248 |
| 6249 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_ACL_POLICY_CMD)); |
| 6250 po = (WMI_AP_ACL_POLICY_CMD *)(A_NETBUF_DATA(osbuf)); |
| 6251 A_MEMZERO(po, sizeof(*po)); |
| 6252 |
| 6253 po->policy = policy; |
| 6254 |
| 6255 return (wmi_cmd_send(wmip, osbuf, WMI_AP_ACL_POLICY_CMDID, NO_SYNC_WMIFLAG))
; |
| 6256 } |
| 6257 |
| 6258 A_STATUS |
| 6259 wmi_ap_set_rateset(struct wmi_t *wmip, A_UINT8 rateset) |
| 6260 { |
| 6261 void *osbuf; |
| 6262 WMI_AP_SET_11BG_RATESET_CMD *rs; |
| 6263 |
| 6264 osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_11BG_RATESET_CMD)); |
| 6265 if (osbuf == NULL) { |
| 6266 return A_NO_MEMORY; |
| 6267 } |
| 6268 |
| 6269 A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_11BG_RATESET_CMD)); |
| 6270 rs = (WMI_AP_SET_11BG_RATESET_CMD *)(A_NETBUF_DATA(osbuf)); |
| 6271 A_MEMZERO(rs, sizeof(*rs)); |
| 6272 |
| 6273 rs->rateset = rateset; |
| 6274 |
| 6275 return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_11BG_RATESET_CMDID, NO_SYNC_WMI
FLAG)); |
| 6276 } |
| 6277 |
| 6278 #ifdef ATH_AR6K_11N_SUPPORT |
| 6279 A_STATUS |
| 6280 wmi_set_ht_cap_cmd(struct wmi_t *wmip, A_UINT8 chan_width_40M_supported, |
| 6281 A_UINT8 short_GI_20MHz, A_UINT8 short_GI_40MHz, |
| 6282 A_UINT8 intolerance_40MHz, A_UINT8 max_ampdu_len_exp) |
| 6283 { |
| 6284 void *osbuf; |
| 6285 WMI_SET_HT_CAP_CMD *htCap; |
| 6286 |
| 6287 osbuf = A_NETBUF_ALLOC(sizeof(*htCap)); |
| 6288 if (osbuf == NULL) { |
| 6289 return A_NO_MEMORY; |
| 6290 } |
| 6291 |
| 6292 A_NETBUF_PUT(osbuf, sizeof(*htCap)); |
| 6293 |
| 6294 htCap = (WMI_SET_HT_CAP_CMD *)(A_NETBUF_DATA(osbuf)); |
| 6295 A_MEMZERO(htCap, sizeof(*htCap)); |
| 6296 htCap->chan_width_40M_supported = chan_width_40M_supported; |
| 6297 htCap->short_GI_20MHz = short_GI_20MHz; |
| 6298 htCap->short_GI_40MHz = short_GI_40MHz; |
| 6299 htCap->intolerance_40MHz = intolerance_40MHz; |
| 6300 htCap->max_ampdu_len_exp = max_ampdu_len_exp; |
| 6301 |
| 6302 return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_CAP_CMDID, |
| 6303 NO_SYNC_WMIFLAG)); |
| 6304 } |
| 6305 |
| 6306 A_STATUS |
| 6307 wmi_set_ht_op_cmd(struct wmi_t *wmip, A_UINT8 sta_chan_width) |
| 6308 { |
| 6309 void *osbuf; |
| 6310 WMI_SET_HT_OP_CMD *htInfo; |
| 6311 |
| 6312 osbuf = A_NETBUF_ALLOC(sizeof(*htInfo)); |
| 6313 if (osbuf == NULL) { |
| 6314 return A_NO_MEMORY; |
| 6315 } |
| 6316 |
| 6317 A_NETBUF_PUT(osbuf, sizeof(*htInfo)); |
| 6318 |
| 6319 htInfo = (WMI_SET_HT_OP_CMD *)(A_NETBUF_DATA(osbuf)); |
| 6320 A_MEMZERO(htInfo, sizeof(*htInfo)); |
| 6321 htInfo->sta_chan_width = sta_chan_width; |
| 6322 |
| 6323 return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_OP_CMDID, |
| 6324 NO_SYNC_WMIFLAG)); |
| 6325 } |
| 6326 #endif |
| 6327 |
| 6328 A_STATUS |
| 6329 wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, A_UINT32 *pMaskArray) |
| 6330 { |
| 6331 void *osbuf; |
| 6332 WMI_SET_TX_SELECT_RATES_CMD *pData; |
| 6333 |
| 6334 osbuf = A_NETBUF_ALLOC(sizeof(*pData)); |
| 6335 if (osbuf == NULL) { |
| 6336 return A_NO_MEMORY; |
| 6337 } |
| 6338 |
| 6339 A_NETBUF_PUT(osbuf, sizeof(*pData)); |
| 6340 |
| 6341 pData = (WMI_SET_TX_SELECT_RATES_CMD *)(A_NETBUF_DATA(osbuf)); |
| 6342 A_MEMCPY(pData, pMaskArray, sizeof(*pData)); |
| 6343 |
| 6344 return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_SELECT_RATES_CMDID, |
| 6345 NO_SYNC_WMIFLAG)); |
| 6346 } |
| 6347 |
| 6348 |
| 6349 A_STATUS |
| 6350 wmi_send_hci_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT16 sz) |
| 6351 { |
| 6352 void *osbuf; |
| 6353 WMI_HCI_CMD *cmd; |
| 6354 |
| 6355 osbuf = A_NETBUF_ALLOC(sizeof(*cmd) + sz); |
| 6356 if (osbuf == NULL) { |
| 6357 return A_NO_MEMORY; |
| 6358 } |
| 6359 |
| 6360 A_NETBUF_PUT(osbuf, sizeof(*cmd) + sz); |
| 6361 cmd = (WMI_HCI_CMD *)(A_NETBUF_DATA(osbuf)); |
| 6362 |
| 6363 cmd->cmd_buf_sz = sz; |
| 6364 A_MEMCPY(cmd->buf, buf, sz); |
| 6365 return (wmi_cmd_send(wmip, osbuf, WMI_HCI_CMD_CMDID, NO_SYNC_WMIFLAG)); |
| 6366 } |
| 6367 |
| 6368 #ifdef ATH_AR6K_11N_SUPPORT |
| 6369 A_STATUS |
| 6370 wmi_allow_aggr_cmd(struct wmi_t *wmip, A_UINT16 tx_tidmask, A_UINT16 rx_tidmask) |
| 6371 { |
| 6372 void *osbuf; |
| 6373 WMI_ALLOW_AGGR_CMD *cmd; |
| 6374 |
| 6375 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 6376 if (osbuf == NULL) { |
| 6377 return A_NO_MEMORY; |
| 6378 } |
| 6379 |
| 6380 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 6381 |
| 6382 cmd = (WMI_ALLOW_AGGR_CMD *)(A_NETBUF_DATA(osbuf)); |
| 6383 cmd->tx_allow_aggr = tx_tidmask; |
| 6384 cmd->rx_allow_aggr = rx_tidmask; |
| 6385 |
| 6386 return (wmi_cmd_send(wmip, osbuf, WMI_ALLOW_AGGR_CMDID, NO_SYNC_WMIFLAG)); |
| 6387 } |
| 6388 |
| 6389 A_STATUS |
| 6390 wmi_setup_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid) |
| 6391 { |
| 6392 void *osbuf; |
| 6393 WMI_ADDBA_REQ_CMD *cmd; |
| 6394 |
| 6395 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 6396 if (osbuf == NULL) { |
| 6397 return A_NO_MEMORY; |
| 6398 } |
| 6399 |
| 6400 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 6401 |
| 6402 cmd = (WMI_ADDBA_REQ_CMD *)(A_NETBUF_DATA(osbuf)); |
| 6403 cmd->tid = tid; |
| 6404 |
| 6405 return (wmi_cmd_send(wmip, osbuf, WMI_ADDBA_REQ_CMDID, NO_SYNC_WMIFLAG)); |
| 6406 } |
| 6407 |
| 6408 A_STATUS |
| 6409 wmi_delete_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid, A_BOOL uplink) |
| 6410 { |
| 6411 void *osbuf; |
| 6412 WMI_DELBA_REQ_CMD *cmd; |
| 6413 |
| 6414 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 6415 if (osbuf == NULL) { |
| 6416 return A_NO_MEMORY; |
| 6417 } |
| 6418 |
| 6419 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 6420 |
| 6421 cmd = (WMI_DELBA_REQ_CMD *)(A_NETBUF_DATA(osbuf)); |
| 6422 cmd->tid = tid; |
| 6423 cmd->is_sender_initiator = uplink; /* uplink =1 - uplink direction, 0=downl
ink direction */ |
| 6424 |
| 6425 /* Delete the local aggr state, on host */ |
| 6426 return (wmi_cmd_send(wmip, osbuf, WMI_DELBA_REQ_CMDID, NO_SYNC_WMIFLAG)); |
| 6427 } |
| 6428 #endif |
| 6429 |
| 6430 A_STATUS |
| 6431 wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, A_UINT8 rxMetaVersion, |
| 6432 A_BOOL rxDot11Hdr, A_BOOL defragOnHost) |
| 6433 { |
| 6434 void *osbuf; |
| 6435 WMI_RX_FRAME_FORMAT_CMD *cmd; |
| 6436 |
| 6437 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 6438 if (osbuf == NULL) { |
| 6439 return A_NO_MEMORY; |
| 6440 } |
| 6441 |
| 6442 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 6443 |
| 6444 cmd = (WMI_RX_FRAME_FORMAT_CMD *)(A_NETBUF_DATA(osbuf)); |
| 6445 cmd->dot11Hdr = (rxDot11Hdr==TRUE)? 1:0; |
| 6446 cmd->defragOnHost = (defragOnHost==TRUE)? 1:0; |
| 6447 cmd->metaVersion = rxMetaVersion; /* */ |
| 6448 |
| 6449 /* Delete the local aggr state, on host */ |
| 6450 return (wmi_cmd_send(wmip, osbuf, WMI_RX_FRAME_FORMAT_CMDID, NO_SYNC_WMIFLAG
)); |
| 6451 } |
| 6452 |
| 6453 |
| 6454 A_STATUS |
| 6455 wmi_set_thin_mode_cmd(struct wmi_t *wmip, A_BOOL bThinMode) |
| 6456 { |
| 6457 void *osbuf; |
| 6458 WMI_SET_THIN_MODE_CMD *cmd; |
| 6459 |
| 6460 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 6461 if (osbuf == NULL) { |
| 6462 return A_NO_MEMORY; |
| 6463 } |
| 6464 |
| 6465 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 6466 |
| 6467 cmd = (WMI_SET_THIN_MODE_CMD *)(A_NETBUF_DATA(osbuf)); |
| 6468 cmd->enable = (bThinMode==TRUE)? 1:0; |
| 6469 |
| 6470 /* Delete the local aggr state, on host */ |
| 6471 return (wmi_cmd_send(wmip, osbuf, WMI_SET_THIN_MODE_CMDID, NO_SYNC_WMIFLAG))
; |
| 6472 } |
| 6473 |
| 6474 |
| 6475 A_STATUS |
| 6476 wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE pre
cedence) |
| 6477 { |
| 6478 void *osbuf; |
| 6479 WMI_SET_BT_WLAN_CONN_PRECEDENCE *cmd; |
| 6480 |
| 6481 osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); |
| 6482 if (osbuf == NULL) { |
| 6483 return A_NO_MEMORY; |
| 6484 } |
| 6485 |
| 6486 A_NETBUF_PUT(osbuf, sizeof(*cmd)); |
| 6487 |
| 6488 cmd = (WMI_SET_BT_WLAN_CONN_PRECEDENCE *)(A_NETBUF_DATA(osbuf)); |
| 6489 A_MEMZERO(cmd, sizeof(*cmd)); |
| 6490 cmd->precedence = precedence; |
| 6491 |
| 6492 return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID, |
| 6493 NO_SYNC_WMIFLAG)); |
| 6494 } |
| 6495 |
| 6496 A_STATUS |
| 6497 wmi_set_pmk_cmd(struct wmi_t *wmip, A_UINT8 *pmk) |
| 6498 { |
| 6499 void *osbuf; |
| 6500 WMI_SET_PMK_CMD *p; |
| 6501 |
| 6502 osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_PMK_CMD)); |
| 6503 if (osbuf == NULL) { |
| 6504 return A_NO_MEMORY; |
| 6505 } |
| 6506 |
| 6507 A_NETBUF_PUT(osbuf, sizeof(WMI_SET_PMK_CMD)); |
| 6508 |
| 6509 p = (WMI_SET_PMK_CMD *)(A_NETBUF_DATA(osbuf)); |
| 6510 A_MEMZERO(p, sizeof(*p)); |
| 6511 |
| 6512 A_MEMCPY(p->pmk, pmk, WMI_PMK_LEN); |
| 6513 |
| 6514 return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMK_CMDID, NO_SYNC_WMIFLAG)); |
| 6515 } |
| 6516 |
OLD | NEW |