Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(253)

Side by Side Diff: chromeos/drivers/ath6kl/wmi/wmi.c

Issue 646055: Atheros AR600x driver + build glue (Closed)
Patch Set: Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chromeos/drivers/ath6kl/wmi/makefile ('k') | chromeos/drivers/ath6kl/wmi/wmi_host.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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
OLDNEW
« no previous file with comments | « chromeos/drivers/ath6kl/wmi/makefile ('k') | chromeos/drivers/ath6kl/wmi/wmi_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698