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