2 * Common code for wl command-line swiss-army-knife utility
4 * Copyright (C) 2010, Broadcom Corporation
7 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
8 * the contents of this file may not be disclosed to third parties, copied
9 * or duplicated in any form, in whole or in part, without the prior
10 * written permission of Broadcom Corporation.
12 * $Id: wlu.c,v 1.1104.2.99 2011-01-28 23:22:50 Exp $
17 #if defined(__NetBSD__)
21 /* Because IL_BIGENDIAN was removed there are few warnings that need
22 * to be fixed. Windows was not compiled earlier with IL_BIGENDIAN.
23 * Hence these warnings were not seen earlier.
24 * For now ignore the following warnings
28 #pragma warning(disable : 4244)
29 #pragma warning(disable : 4761)
33 #include <lib_types.h>
34 #include <lib_string.h>
35 #include <lib_printf.h>
36 #include <lib_malloc.h>
37 #include <cfe_error.h>
44 #endif /* defined(_CFE_) */
47 #include <proto/ethernet.h>
48 #include <proto/802.11.h>
49 #include <proto/802.1d.h>
50 #include <proto/802.11e.h>
51 #include <proto/wpa.h>
52 #include <proto/bcmip.h>
54 #include <proto/bt_amp_hci.h>
58 #include <bcmendian.h>
60 #include <bcmsrom_fmt.h>
61 #include <bcmsrom_tbl.h>
64 #if defined(WLPFN) && defined(linux)
65 #ifndef TARGETENV_android
69 #include <sys/types.h>
70 #include <sys/socket.h>
72 #include <sys/ioctl.h>
73 #include <netinet/in.h>
75 #include <linux/if_packet.h>
79 #include <wlc_extlog_idstr.h>
85 #if defined(__NetBSD__) || defined(linux) || defined(MACOSX) || defined(EFI)
86 #define stricmp strcasecmp
87 #define strnicmp strncasecmp
89 extern int stricmp(const char *s1
, const char *s2
);
90 extern int strnicmp(const char *s1
, const char *s2
, size_t len
);
91 #elif defined(UNDER_CE) || defined(_CRT_SECURE_NO_DEPRECATE)
92 #define stricmp _stricmp
93 #define strnicmp _strnicmp
97 #define isalnum(c) bcm_isalnum(c)
98 #define isalpha(c) bcm_isalpha(c)
99 #define iscntrl(c) bcm_iscntrl(c)
100 #define isdigit(c) bcm_isdigit(c)
101 #define isgraph(c) bcm_isgraph(c)
102 #define islower(c) bcm_islower(c)
103 #define isprint(c) bcm_isprint(c)
104 #define ispunct(c) bcm_ispunct(c)
105 #define isspace(c) bcm_isspace(c)
106 #define isupper(c) bcm_isupper(c)
107 #define isxdigit(c) bcm_isxdigit(c)
108 #define stricmp(s1, s2) lib_strcmpi((s1), (s2))
109 #define strtoul(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
110 #define tolower(c) (bcm_isupper((c)) ? ((c) + 'a' - 'A') : (c))
111 #define fprintf(stream, fmt, args...) xprintf(fmt, ##args)
112 #define fputs(s, stream) puts(s)
113 #define malloc(size) KMALLOC((size), 0)
114 #define free(ptr) KFREE(ptr)
115 #define strnicmp(s1, s2, len) strncmp((s1), (s2), (len))
116 #define strspn(s, accept) (0)
117 #define strtol(nptr, endptr, base) bcm_strtoul((nptr), (endptr), (base))
118 #elif defined(BWL_STRICMP)
119 #define stricmp bcmstricmp
120 #define strnicmp bcmstrnicmp
121 #endif /* __NetBSD__ */
124 /* For backwards compatibility, the absense of the define 'NO_FILESYSTEM_SUPPORT'
125 * implies that a filesystem is supported.
127 #if !defined(BWL_NO_FILESYSTEM_SUPPORT)
128 #define BWL_FILESYSTEM_SUPPORT
133 static cmd_func_t wl_print_deprecate
;
134 static cmd_func_t wl_void
, wl_rssi
, wl_rssi_event
, wl_phy_rssi_ant
, wl_gmode
;
135 static cmd_func_t wlu_dump
, wlu_srdump
, wlu_srwrite
, wlu_srvar
, wl_nvsource
;
136 static cmd_func_t wlu_ciswrite
, wlu_cisupdate
, wlu_cisdump
;
137 static cmd_func_t wl_rate_mrate
, wl_phy_rate
, wl_bss_max
;
138 static cmd_func_t wl_channel
, wl_chanspec
, wl_chanim_state
, wl_chanim_mode
;
139 static cmd_func_t wl_radio
, wl_version
, wl_list
, wl_band
, wl_bandlist
, wl_phylist
;
140 static cmd_func_t wl_join
, wl_tssi
, wl_txpwr
, wl_atten
, wl_evm
, wl_country
;
141 static cmd_func_t wl_out
, wl_txpwr1
, wl_country_ie_override
;
142 static cmd_func_t wl_maclist
, wl_get_pktcnt
, wl_upgrade
;
143 static cmd_func_t wl_maclist_1
;
144 static cmd_func_t wl_rateset
, wl_interfere
, wl_interfere_override
;
145 static cmd_func_t wl_radar_args
, wl_radar_thrs
, wl_dfs_status
;
146 static cmd_func_t wl_get_txpwr_limit
, wl_get_current_power
, wl_get_instant_power
;
147 static cmd_func_t wl_get_current_txppr
;
148 static cmd_func_t wl_var_get
, wl_var_getint
, wl_var_getinthex
, wl_var_getandprintstr
;
149 static cmd_func_t wl_var_setint
, wl_addwep
, wl_rmwep
;
150 static cmd_func_t wl_nvdump
, wl_nvget
, wl_nvset
, wl_sta_info
, wl_chan_info
;
151 static cmd_func_t wl_wme_ac_req
, wl_add_ie
, wl_del_ie
, wl_list_ie
;
152 static cmd_func_t wl_wme_apsd_sta
, wl_wme_dp
, wl_lifetime
;
153 static cmd_func_t wl_rand
, wl_otpw
, wl_counters
, wl_delta_stats
;
154 static cmd_func_t wl_assoc_info
, wl_wme_counters
, wl_devpath
;
155 static cmd_func_t wl_bitvec128
, wl_diag
, wl_var_void
;
156 static cmd_func_t wl_auto_channel_sel
;
157 static cmd_func_t wl_bsscfg_int
, wl_bsscfg_enable
;
158 static cmd_func_t wl_msglevel
, wl_plcphdr
, wl_reg
, wl_macreg
, wl_band_elm
;
159 static cmd_func_t wl_phymsglevel
;
160 static cmd_func_t wl_rateparam
, wl_wepstatus
, wl_status
, wl_spect
;
161 static cmd_func_t wl_sup_rateset
, wl_scan
, wl_send_csa
, wl_iscan
, wl_escan
;
163 static cmd_func_t wl_extdscan
;
165 static cmd_func_t wl_dump_chanlist
, wl_primary_key
, wl_measure_req
, wl_send_quiet
;
166 static cmd_func_t wl_dump_chanspecs
, wl_cur_mcsset
;
167 static cmd_func_t wl_wsec
, wl_keys
, wl_wsec_test
;
168 static cmd_func_t wl_channels_in_country
;
169 static cmd_func_t wl_wpa_auth
, wl_tsc
, wl_deauth_rc
, wl_ssid
, wl_bssid
, wl_smfstats
;
170 static cmd_func_t wl_wds_wpa_role_old
, wl_wds_wpa_role
, wl_set_pmk
;
171 static cmd_func_t wl_rm_request
, wl_rm_report
;
172 static cmd_func_t wl_join_pref
, wl_assoc_pref
;
173 static cmd_func_t wl_dump_networks
, wl_mac
, wl_revinfo
, wl_iov_mac
;
174 static cmd_func_t wl_cac
, wl_tslist
, wl_tspec
, wl_tslist_ea
, wl_tspec_ea
, wl_cac_delts_ea
;
175 static cmd_func_t wl_varstr
, wl_var_setintandprintstr
;
176 static cmd_func_t wl_rifs
;
177 static cmd_func_t wl_rifs_advert
;
178 static cmd_func_t wl_test_tssi
, wl_test_tssi_offs
, wl_phy_rssiant
, wl_rxiq
;
179 static cmd_func_t wl_obss_scan
, wl_obss_coex_action
;
180 static cmd_func_t wl_dump_lq
;
181 static cmd_func_t wl_monitor_lq
;
185 static cmd_func_t wl_pfn_set
;
186 static cmd_func_t wl_pfn_add
;
187 static cmd_func_t wl_pfn
;
189 static cmd_func_t wl_pfn_event_check
;
190 static cmd_func_t wl_escan_event_check
;
191 static cmd_func_t wl_escanresults
;
193 static cmd_func_t wl_event_filter
;
195 static cmd_func_t wl_wowl_pattern
, wl_wowl_wakeind
, wl_wowl_pkt
, wl_wowl_status
;
196 static cmd_func_t wl_reassoc
;
199 static cmd_func_t wl_pmkid_info
;
202 static cmd_func_t wl_rate_histo
;
203 static cmd_func_t wl_sample_collect
;
204 static cmd_func_t wlu_reg3args
;
206 static cmd_func_t wl_coma
;
207 static cmd_func_t wl_tpc_lm
;
208 static cmd_func_t wlu_reg2args
;
209 static cmd_func_t wme_tx_params
;
210 static cmd_func_t wme_maxbw_params
;
211 static cmd_func_t wl_ampdu_tid
, wl_ampdu_activate_test
;
212 static cmd_func_t wl_ampdu_retry_limit_tid
;
213 static cmd_func_t wl_ampdu_rr_retry_limit_tid
;
214 static cmd_func_t wl_ampdu_send_addba
;
215 static cmd_func_t wl_ampdu_send_delba
;
217 static cmd_func_t wl_dpt_deny
;
218 static cmd_func_t wl_dpt_endpoint
;
219 static cmd_func_t wl_dpt_pmk
;
220 static cmd_func_t wl_dpt_fname
;
221 static cmd_func_t wl_dpt_list
;
223 static cmd_func_t wl_HCI_cmd
;
224 static cmd_func_t wl_HCI_ACL_data
;
225 static cmd_func_t wl_get_btamp_log
;
227 static cmd_func_t wl_actframe
;
229 static cmd_func_t wl_gpioout
;
231 static cmd_func_t wl_nrate
, wl_antsel
, wl_txcore
;
232 static cmd_func_t wl_txcore_pwr_offset
;
233 static cmd_func_t wl_txfifo_sz
;
234 static cmd_func_t wl_pkteng
, wl_pkteng_stats
;
236 static cmd_func_t wl_offload_cmpnt
;
237 static cmd_func_t wl_hostip
, wl_arp_stats
, wl_toe_stats
;
239 static cmd_func_t wl_lpphy_papdepstbl
;
241 int wl_seq_batch_in_client(bool enable
);
242 cmd_func_t wl_seq_start
;
243 cmd_func_t wl_seq_stop
;
245 static cmd_func_t wl_phy_txiqcc
, wl_phy_txlocc
;
246 static cmd_func_t wl_phytable
, wl_phy_pavars
, wl_phy_pavars2
, wl_phy_povars
;
247 static cmd_func_t wl_phy_fem
, wl_phy_maxpower
, wl_antgain
, wl_phy_txpwrindex
;
248 static cmd_func_t wl_keep_alive
;
249 static cmd_func_t wl_srchmem
;
251 static cmd_func_t wl_pkt_filter_add
;
252 static cmd_func_t wl_pkt_filter_enable
;
253 static cmd_func_t wl_pkt_filter_list
;
254 static cmd_func_t wl_pkt_filter_stats
;
256 static cmd_func_t wl_ledbh
;
259 /* Function added to support RWL_WIFI Transport */
260 static cmd_func_t wl_wifiserver
;
263 static cmd_func_t wl_led_blink_sync
;
264 static cmd_func_t wl_cca_get_stats
;
265 static cmd_func_t wl_itfr_get_stats
;
266 static cmd_func_t wl_rrm_nbr_req
;
267 static cmd_func_t wl_wnm_bsstq
;
268 static cmd_func_t wl_chanim_acs_record
;
271 static cmd_func_t wl_p2p_state
;
272 static cmd_func_t wl_p2p_scan
;
273 static cmd_func_t wl_p2p_ifadd
;
274 static cmd_func_t wl_p2p_ifdel
;
275 static cmd_func_t wl_p2p_ifupd
;
276 static cmd_func_t wl_p2p_if
;
277 static cmd_func_t wl_p2p_ops
;
278 static cmd_func_t wl_p2p_noa
;
281 static cmd_func_t wl_rpmt
;
282 static cmd_func_t wl_spatial_policy
, wl_ratetbl_ppr
;
284 static cmd_func_t wl_ie
;
286 static void wl_txppr_print(txppr_t
*ppr
, int cck
, int mimo
);
287 static void wl_txpwr_array_print(uint8
*pwr
, int cck
, int mimo
);
288 static void wl_txpwr_range_print(uint8
*pwr
, int start
, int count
, const char* label
, int *newline
);
289 static void wl_txpwr_row_print(uint8
*pwr
, int start
, int count
);
290 static int wl_array_uniform(uint8
*pwr
, int start
, int count
);
291 static int wl_curpower_legacy(void *wl
);
292 static void wl_txpwr_array_print_legacy2(uint8
*pwr
, int cck
, int mimo
);
293 static void wl_txpwr_range_print_legacy2(uint8
*pwr
, int start
, int count
, const char* label
,
295 static int wl_curpower_legacy2(void *wl
, cmd_t
*cmd
);
297 static int wl_parse_rateset(void *wl
, wl_rateset_args_t
* rs
, char **argv
);
298 static void wl_print_mcsset(char *mcsset
);
300 static void dump_networks(char *buf
);
301 static void dump_bss_info(wl_bss_info_t
*bi
);
302 static void wl_dump_wpa_rsn_ies(uint8
* cp
, uint len
);
303 static void wl_rsn_ie_dump(bcm_tlv_t
*ie
);
305 int wlu_get(void *wl
, int cmd
, void *buf
, int len
);
306 int wlu_set(void *wl
, int cmd
, void *buf
, int len
);
308 static void clean_up_cmd_list(void);
309 static int add_one_batched_cmd(int cmd
, void *buf
, int len
);
310 static int _wl_dump_lq(void *wl
);
312 /* 802.11i/WPA RSN IE parsing utilities */
315 wpa_suite_mcast_t
*mcast
;
316 wpa_suite_ucast_t
*ucast
;
317 wpa_suite_auth_key_mgmt_t
*akm
;
321 static int wl_rsn_ie_parse_info(uint8
* buf
, uint len
, rsn_parse_info_t
*rsn
);
322 static uint
wl_rsn_ie_decode_cntrs(uint cntr_field
);
324 static int wl_parse_assoc_params(char **argv
, wl_assoc_params_t
*params
);
325 #define wl_parse_reassoc_params(argv, params) wl_parse_assoc_params(argv, \
326 (wl_assoc_params_t *)(params))
328 static int wl_parse_channel_list(char* list_str
, uint16
* channel_list
, int channel_num
);
329 static int wl_parse_chanspec_list(char* list_str
, chanspec_t
*chanspec_list
, int chanspec_num
);
332 static int wl_parse_extdchannel_list(char* list_str
,
333 chan_scandata_t
* channel_list
, int channel_num
);
336 static uint16
wl_qdbm_to_mw(uint8 qdbm
);
337 static uint8
wl_mw_to_qdbm(uint16 mw
);
339 static int wl_cfg_option(char **argv
, const char *fn_name
, int *bsscfg_idx
, int *consumed
);
340 static int get_oui_bytes(uchar
*oui_str
, uchar
*oui
);
341 static int get_ie_data(uchar
*data_str
, uchar
*ie_data
, int len
);
342 static void wl_printrate(int val
);
343 static int rate_string2int(char *s
);
344 static char *rate_int2string(char *buf
, int val
);
346 static int wl_get_scan(void *wl
, int opc
, char *buf
, uint buf_len
);
347 static int wl_get_iscan(void *wl
, char *buf
, uint buf_len
);
348 int wlu_var_getbuf(void *wl
, const char *iovar
, void *param
, int param_len
, void **bufptr
);
349 int wlu_var_getbuf_sm(void *wl
, const char *iovar
, void *param
, int param_len
, void **bufptr
);
350 int wlu_var_getbuf_med(void *wl
, const char *iovar
, void *param
, int param_len
, void **bufptr
);
351 int wlu_var_setbuf(void *wl
, const char *iovar
, void *param
, int param_len
);
353 static uint
wl_iovar_mkbuf(const char *name
, char *data
, uint datalen
, char *buf
, uint buflen
,
355 static int wlu_iovar_getbuf(void* wl
, const char *iovar
,
356 void *param
, int paramlen
, void *bufptr
, int buflen
);
357 static int wlu_iovar_setbuf(void* wl
, const char *iovar
,
358 void *param
, int paramlen
, void *bufptr
, int buflen
);
359 int wlu_iovar_get(void *wl
, const char *iovar
, void *outbuf
, int len
);
360 int wlu_iovar_set(void *wl
, const char *iovar
, void *param
, int paramlen
);
361 int wlu_iovar_getint(void *wl
, const char *iovar
, int *pval
);
362 int wlu_iovar_setint(void *wl
, const char *iovar
, int val
);
364 static int wl_bssiovar_mkbuf(const char *iovar
, int bssidx
, void *param
,
365 int paramlen
, void *bufptr
, int buflen
, int *perr
);
366 static int wl_bssiovar_setbuf(void* wl
, const char *iovar
, int bssidx
,
367 void *param
, int paramlen
, void *bufptr
, int buflen
);
368 static int wl_bssiovar_getbuf(void* wl
, const char *iovar
, int bssidx
,
369 void *param
, int paramlen
, void *bufptr
, int buflen
);
370 static int wl_bssiovar_set(void *wl
, const char *iovar
, int bssidx
, void *param
, int paramlen
);
371 static int wl_bssiovar_get(void *wl
, const char *iovar
, int bssidx
, void *outbuf
, int len
);
372 static int wl_bssiovar_setint(void *wl
, const char *iovar
, int bssidx
, int val
);
373 static int wl_bssiovar_getint(void *wl
, const char *iovar
, int bssidx
, int *pval
);
375 static int wl_vndr_ie(void *wl
, const char *command
, char **argv
);
376 static int hexstrtobitvec(const char *cp
, uchar
*bitvec
, int veclen
);
377 static void wl_join_pref_print_ie(bcm_tlv_t
*ie
);
378 static void wl_join_pref_print_akm(uint8
* suite
);
379 static void wl_join_pref_print_cipher_suite(uint8
* suite
);
380 static void wl_print_tspec(tspec_arg_t
*ts
);
381 static void wl_cac_addts_usage(void);
382 static void wl_cac_delts_usage(void);
384 static cmd_func_t wl_txmcsset
;
385 static cmd_func_t wl_rxmcsset
;
387 static int wl_mimo_stf(void *wl
, cmd_t
*cmd
, char **argv
);
390 static int wl_extlog(void *wl
, cmd_t
*cmd
, char **argv
);
391 static int wl_extlog_cfg(void *wl
, cmd_t
*cmd
, char **argv
);
394 static int wl_assertlog(void *wl
, cmd_t
*cmd
, char **argv
);
395 static char *ver2str(unsigned int vms
, unsigned int vls
);
396 static int wl_tsf(void *wl
, cmd_t
*cmd
, char **argv
);
397 static int wl_dngl_wd(void *wl
, cmd_t
*cmd
, char **argv
);
398 static int wl_mfp_config(void *wl
, cmd_t
*cmd
, char **argv
);
399 static int wl_mfp_sha256(void *wl
, cmd_t
*cmd
, char **argv
);
400 static int wl_mfp_sa_query(void *wl
, cmd_t
*cmd
, char **argv
);
401 static int wl_mfp_disassoc(void *wl
, cmd_t
*cmd
, char **argv
);
402 static int wl_mfp_deauth(void *wl
, cmd_t
*cmd
, char **argv
);
403 static int wl_mfp_assoc(void *wl
, cmd_t
*cmd
, char **argv
);
404 static int wl_mfp_auth(void *wl
, cmd_t
*cmd
, char **argv
);
405 static int wl_mfp_reassoc(void *wl
, cmd_t
*cmd
, char **argv
);
406 static int wl_scb_probe(void *wl
, cmd_t
*cmd
, char **argv
);
408 /* some OSes (FC4) have trouble allocating (kmalloc) 128KB worth of memory,
409 * hence keeping WL_DUMP_BUF_LEN below that
411 #if defined(BWL_SMALL_WLU_DUMP_BUF)
412 #define WL_DUMP_BUF_LEN (8 * 1024)
414 #define WL_DUMP_BUF_LEN (127 * 1024)
417 #define OUI_STR_SIZE 8 /* OUI string size */
418 #define MAX_OUI_SIZE 3 /* MAX OUI size */
419 #define MAX_BYTE_CHARS 2 /* MAX num chars */
420 #define MAX_DATA_COLS 16 /* MAX data cols */
421 #define DIV_QUO(num, div) ((num)/div) /* Return the quotient of division to avoid floats */
422 #define DIV_REM(num, div) (((num%div) * 100)/div) /* Return the remainder of division */
424 #define RADIO_CORE_SYN (0x0 << 12)
425 #define RADIO_CORE_TX0 (0x2 << 12)
426 #define RADIO_CORE_TX1 (0x3 << 12)
427 #define RADIO_CORE_RX0 (0x6 << 12)
428 #define RADIO_CORE_RX1 (0x7 << 12)
430 #define RADIO_CORE_CR0 (0x0 << 10)
431 #define RADIO_CORE_CR1 (0x1 << 10)
432 #define RADIO_CORE_CR2 (0x2 << 10)
433 #define RADIO_CORE_ALL (0x3 << 10)
435 #define WLC_MAXMCS 32
437 /* dword align allocation */
439 char bufdata
[WLC_IOCTL_MAXLEN
];
442 static char *buf
= (char*) &bufstruct_wlu
.bufdata
;
444 /* integer output format, default to signed integer */
445 static uint8 int_fmt
;
447 /* The below macros handle endian mis-matches between wl utility and wl driver. */
448 static bool g_swap
= FALSE
;
449 #define htod32(i) (g_swap?bcmswap32(i):(uint32)(i))
450 #define htod16(i) (g_swap?bcmswap16(i):(uint16)(i))
451 #define dtoh32(i) (g_swap?bcmswap32(i):(uint32)(i))
452 #define dtoh16(i) (g_swap?bcmswap16(i):(uint16)(i))
453 #define htodchanspec(i) (g_swap?htod16(i):i)
454 #define dtohchanspec(i) (g_swap?dtoh16(i):i)
455 #define htodenum(i) (g_swap?((sizeof(i) == 4) ? htod32(i) : ((sizeof(i) == 2) ? htod16(i) : i)):i)
456 #define dtohenum(i) (g_swap?((sizeof(i) == 4) ? dtoh32(i) : ((sizeof(i) == 2) ? htod16(i) : i)):i)
459 * Country names and abbreviations from ISO 3166
462 const char *name
; /* Long name */
463 const char *abbrev
; /* Abbreviation */
465 cntry_name_t cntry_names
[]; /* At end of this file */
477 #define WL_SCAN_PARAMS_SSID_MAX 10
478 #define SCAN_USAGE "" \
479 "\tDefault to an active scan across all channels for any SSID.\n" \
480 "\tOptional arg: SSIDs, list of [up to 10] SSIDs to scan (comma or space separated).\n" \
482 "\t-s S, --ssid=S\t\tSSIDs to scan\n" \
483 "\t-t ST, --scan_type=ST\t[active|passive|prohibit] scan type\n" \
484 "\t--bss_type=BT\t\t[bss/infra|ibss/adhoc] bss type to scan\n" \
485 "\t-b MAC, --bssid=MAC\tparticular BSSID MAC address to scan, xx:xx:xx:xx:xx:xx\n" \
486 "\t-n N, --nprobes=N\tnumber of probes per scanned channel\n" \
487 "\t-a N, --active=N\tdwell time per channel for active scanning\n" \
488 "\t-p N, --passive=N\tdwell time per channel for passive scanning\n" \
489 "\t-h N, --home=N\t\tdwell time for the home channel between channel scans\n" \
490 "\t-c L, --channels=L\tcomma or space separated list of channels to scan" \
492 /* command batching data structure */
493 typedef struct wl_seq_cmd_pkt
{
494 struct wl_seq_cmd_pkt
*next
;
495 wl_seq_cmd_ioctl_t cmd_header
;
496 char * data
; /* user buffer */
499 typedef struct wl_cmd_list
{
500 wl_seq_cmd_pkt_t
*head
;
501 wl_seq_cmd_pkt_t
*tail
;
504 static wl_cmd_list_t cmd_list
;
505 static int cmd_pkt_list_num
;
506 static bool cmd_batching_mode
;
507 /* the default behavior is batching in driver,
508 * to indicate client batching, users should specify --interactive and --clientbatch
510 static bool batch_in_client
;
512 /* If the new command needs to be part of 'wc.exe' tool used for WMM,
513 * be sure to modify wc_cmds[] array as well
515 * If you add a command, please update wlu_cmd.c cmd2cat to categorize the command.
518 { "ver", wl_version
, -1, -1,
519 "get version information" },
520 { "cmds", wl_list
, -1, -1,
521 "generate a short list of available commands"},
522 { "up", wl_void
, -1, WLC_UP
,
523 "reinitialize and mark adapter up (operational)" },
524 { "down", wl_void
, -1, WLC_DOWN
,
525 "reset and mark adapter down (disabled)" },
526 { "out", wl_out
, -1, WLC_OUT
,
527 "mark adapter down but do not reset hardware(disabled)\n"
528 "\tOn dualband cards, cards must be bandlocked before use."},
529 { "clk", wl_int
, WLC_GET_CLK
, WLC_SET_CLK
,
530 "set board clock state. return error for set_clk attempt if the driver is not down\n"
533 { "restart", wl_void
, -1, WLC_RESTART
,
534 "Restart driver. Driver must already be down."},
535 { "reboot", wl_void
, -1, WLC_REBOOT
,
537 { "radio", wl_radio
, WLC_GET_RADIO
, WLC_SET_RADIO
,
538 "Set the radio on or off.\n"
539 "\t\"on\" or \"off\"" },
540 { "dump", wlu_dump
, WLC_GET_VAR
, -1,
541 "Give suboption \"list\" to list various suboptions" },
542 { "srclear", wlu_srwrite
, -1, WLC_SET_SROM
,
543 "Clears first 'len' bytes of the srom, len in decimal or hex\n"
544 "\tUsage: srclear <len>" },
545 { "srdump", wlu_srdump
, WLC_GET_SROM
, -1,
546 "print contents of SPROM to stdout" },
547 { "srwrite", wlu_srwrite
, -1, WLC_SET_SROM
,
548 "Write the srom: srwrite byteoffset value" },
549 { "srcrc", wlu_srwrite
, WLC_GET_SROM
, -1,
550 "Get the CRC for input binary file" },
551 { "ciswrite", wlu_ciswrite
, -1, WLC_SET_VAR
,
552 "Write specified <file> to the SDIO CIS source (either SROM or OTP)"},
553 { "cisupdate", wlu_cisupdate
, -1, WLC_SET_VAR
,
554 "Write a hex byte stream to specified byte offset to the CIS source (either SROM or OTP)\n"
555 "--preview option allows you to review the update without committing it\n"
556 "\t<byte offset> <hex byte stream> [--preview]" },
557 { "cisdump", wlu_cisdump
, WLC_GET_VAR
, -1,
558 "Display the content of the SDIO CIS source\n"
559 "\t-b <file> -- also write raw bytes to <file>\n"
560 "\t<len> -- optional count of bytes to display (must be even)"},
561 { "cis_source", wl_varint
, WLC_GET_VAR
, -1,
562 "Display which source is used for the SDIO CIS"},
563 { "cisconvert", wlu_srvar
, -1, -1,
564 "Print CIS tuple for given name=value pair" },
565 { "rdvar", wlu_srvar
, WLC_GET_SROM
, -1,
566 "Read a named variable to the srom" },
567 { "wrvar", wlu_srvar
, WLC_GET_SROM
, WLC_SET_SROM
,
568 "Write a named variable to the srom" },
569 { "nvram_source", wl_nvsource
, WLC_GET_VAR
, -1,
570 "Display which source is used for nvram"},
571 { "nvram_dump", wl_nvdump
, WLC_NVRAM_DUMP
, -1,
572 "print nvram variables to stdout" },
573 { "nvset", wl_nvset
, -1, WLC_NVRAM_SET
,
574 "set an nvram variable\n"
575 "\tname=value (no spaces around \'=\')" },
576 { "nvget", wl_nvget
, WLC_NVRAM_GET
, -1,
577 "get the value of an nvram variable" },
578 { "nvram_get", wl_nvget
, WLC_NVRAM_GET
, -1,
579 "get the value of an nvram variable" },
580 { "revinfo", wl_revinfo
, WLC_GET_REVINFO
, -1,
581 "get hardware revision information" },
582 { "customvar1", wl_var_getinthex
, -1, -1,
583 "print the value of customvar1 in hex format" },
584 { "msglevel", wl_msglevel
, WLC_GET_VAR
, WLC_SET_VAR
,
585 "set driver console debugging message bitvector\n"
586 "\ttype \'wl msglevel ?\' for values" },
587 { "phymsglevel", wl_phymsglevel
, WLC_GET_VAR
, WLC_SET_VAR
,
588 "set phy debugging message bitvector\n"
589 "\ttype \'wl phymsglevel ?\' for values" },
590 { "PM", wl_int
, WLC_GET_PM
, WLC_SET_PM
,
591 "set driver power management mode:\n"
592 "\t0: CAM (constantly awake)\n"
593 "\t1: PS (power-save)\n"
594 "\t2: FAST PS mode" },
595 { "wake", wl_int
, WLC_GET_WAKE
, WLC_SET_WAKE
,
596 "set driver power-save mode sleep state:\n"
597 "\t0: core-managed\n"
599 { "promisc", wl_int
, WLC_GET_PROMISC
, WLC_SET_PROMISC
,
600 "set promiscuous mode ethernet address reception\n"
603 { "monitor", wl_int
, WLC_GET_MONITOR
, WLC_SET_MONITOR
,
606 "\t1 - enable active monitor mode (interface still operates)" },
607 { "frag", wl_print_deprecate
, -1, -1, "Deprecated. Use fragthresh." },
608 { "rts", wl_print_deprecate
, -1, -1, "Deprecated. Use rtsthresh." },
609 { "cwmin", wl_int
, WLC_GET_CWMIN
, WLC_SET_CWMIN
,
610 "Set the cwmin. (integer [1, 255])" },
611 { "cwmax", wl_int
, WLC_GET_CWMAX
, WLC_SET_CWMAX
,
612 "Set the cwmax. (integer [256, 2047])" },
613 { "srl", wl_int
, WLC_GET_SRL
, WLC_SET_SRL
,
614 "Set the short retry limit. (integer [1, 255])" },
615 { "lrl", wl_int
, WLC_GET_LRL
, WLC_SET_LRL
,
616 "Set the long retry limit. (integer [1, 255])" },
617 { "rate", wl_rate_mrate
, WLC_GET_RATE
, -1,
618 "force a fixed rate:\n"
619 "\tvalid values for 802.11a are (6, 9, 12, 18, 24, 36, 48, 54)\n"
620 "\tvalid values for 802.11b are (1, 2, 5.5, 11)\n"
621 "\tvalid values for 802.11g are (1, 2, 5.5, 6, 9, 11, 12, 18, 24, 36, 48, 54)\n"
622 "\t-1 (default) means automatically determine the best rate" },
623 { "mrate", wl_rate_mrate
, -1, -1, /* Deprecated. Use "bg_mrate" or "a_mrate" */
624 "force a fixed multicast rate:\n"
625 "\tvalid values for 802.11a are (6, 9, 12, 18, 24, 36, 48, 54)\n"
626 "\tvalid values for 802.11b are (1, 2, 5.5, 11)\n"
627 "\tvalid values for 802.11g are (1, 2, 5.5, 6, 9, 11, 12, 18, 24, 36, 48, 54)\n"
628 "\t-1 (default) means automatically determine the best rate" },
629 { "a_rate", wl_phy_rate
, WLC_GET_VAR
, WLC_SET_VAR
,
630 "force a fixed rate for the A PHY:\n"
631 "\tvalid values for 802.11a are (6, 9, 12, 18, 24, 36, 48, 54)\n"
632 "\t-1 (default) means automatically determine the best rate" },
633 { "a_mrate", wl_phy_rate
, WLC_GET_VAR
, WLC_SET_VAR
,
634 "force a fixed multicast rate for the A PHY:\n"
635 "\tvalid values for 802.11a are (6, 9, 12, 18, 24, 36, 48, 54)\n"
636 "\t-1 (default) means automatically determine the best rate" },
637 { "bg_rate", wl_phy_rate
, WLC_GET_VAR
, WLC_SET_VAR
,
638 "force a fixed rate for the B/G PHY:\n"
639 "\tvalid values for 802.11b are (1, 2, 5.5, 11)\n"
640 "\tvalid values for 802.11g are (1, 2, 5.5, 6, 9, 11, 12, 18, 24, 36, 48, 54)\n"
641 "\t-1 (default) means automatically determine the best rate" },
642 { "bg_mrate", wl_phy_rate
, WLC_GET_VAR
, WLC_SET_VAR
,
643 "force a fixed multicast rate for the B/G PHY:\n"
644 "\tvalid values for 802.11b are (1, 2, 5.5, 11)\n"
645 "\tvalid values for 802.11g are (1, 2, 5.5, 6, 9, 11, 12, 18, 24, 36, 48, 54)\n"
646 "\t-1 (default) means automatically determine the best rate" },
647 { "infra", wl_int
, WLC_GET_INFRA
, WLC_SET_INFRA
,
648 "Set Infrastructure mode: 0 (IBSS) or 1 (Infra BSS)" },
649 { "ap", wl_int
, WLC_GET_AP
, WLC_SET_AP
,
650 "Set AP mode: 0 (STA) or 1 (AP)" },
651 { "bssid", wl_bssid
, WLC_GET_BSSID
, -1,
652 "Get the BSSID value, error if STA and not associated"},
653 { "bssmax", wl_bss_max
, WLC_GET_VAR
, -1,
654 "get number of BSSes " },
655 { "channel", wl_channel
, WLC_GET_CHANNEL
, WLC_SET_CHANNEL
,
657 "\tvalid channels for 802.11b/g (2.4GHz band) are 1 through 14\n"
658 "\tvalid channels for 802.11a (5 GHz band) are:\n"
659 "\t\t36, 40, 44, 48, 52, 56, 60, 64,\n"
660 "\t\t100, 104, 108, 112, 116,120, 124, 128, 132, 136, 140,\n"
661 "\t\t149, 153, 157, 161,\n"
662 "\t\t184, 188, 192, 196, 200, 204, 208, 212, 216"},
663 { "cur_mcsset", wl_cur_mcsset
, WLC_GET_VAR
, -1,
664 "Get the current mcs set"
666 { "chanspecs", wl_dump_chanspecs
, WLC_GET_VAR
, -1,
667 "Get all the valid chanspecs (default: all within current locale):\n"
668 "\t-b band (5(a) or 2(b/g))\n"
669 "\t-w bandwidth, 10,20 or 40\n"
670 "\t[-c country_abbrev]"
672 { "chanspec", wl_chanspec
, WLC_GET_VAR
, WLC_SET_VAR
,
673 "Set <channel>[a,b][n][u,l]\n"
674 "\tchannel number (0-224)\n"
675 "\tband a=5G, b=2G, default to 2G if channel <= 14\n"
676 "\tbandwidth, n=10, none for 20 & 40\n"
677 "\tctl sideband, l=lower, u=upper\n"
678 "OR Set channel with legacy format:\n"
679 "\t-c channel number (0-224)\n"
680 "\t-b band (5(a) or 2(b/g))\n"
681 "\t-w bandwidth, 10,20 or 40\n"
682 "\t-s ctl sideband, -1=lower, 0=none, 1=upper"},
683 { "dfs_channel_forced", wl_chanspec
, WLC_GET_VAR
, WLC_SET_VAR
,
684 "Set <channel>[a,b][n][u,l]\n"
685 "\tchannel number (0-224)\n"
686 "\tband a=5G, b=2G, default to 2G if channel <= 14\n"
687 "\tbandwidth, n=10, non for 20 & 40\n"
688 "\tctl sideband, l=lower, u=upper"},
689 { "tssi", wl_tssi
, WLC_GET_TSSI
, -1,
690 "Get the tssi value from radio" },
691 { "txpwr", wl_txpwr
, -1, -1, /* Deprecated. Use "txpwr1" */
692 "Set tx power in milliwatts. Range [1, 84]." },
693 { "txpwr1", wl_txpwr1
, WLC_GET_VAR
, WLC_SET_VAR
,
694 "Set tx power in in various units. Choose one of (default: dbm): \n"
696 "\t-q quarter dbm units\n"
697 "\t-m milliwatt units\n"
698 "Can be combined with:\n"
699 "\t-o turn on override to disable regulatory and other limitations\n"
700 "Use wl txpwr -1 to restore defaults"},
701 { "txpathpwr", wl_int
, WLC_GET_TX_PATH_PWR
, WLC_SET_TX_PATH_PWR
,
702 "Turn the tx path power on or off on 2050 radios" },
703 { "txpwrlimit", wl_get_txpwr_limit
, WLC_CURRENT_PWR
, -1,
704 "Return current tx power limit" },
705 { "powerindex", wl_int
, WLC_GET_PWRIDX
, WLC_SET_PWRIDX
,
706 "Set the transmit power for A band(0-63).\n"
707 "\t-1 - default value" },
708 { "atten", wl_atten
, WLC_GET_ATTEN
, WLC_SET_ATTEN
,
709 "Set the transmit attenuation for B band. Args: bb radio txctl1.\n"
710 "\tauto to revert to automatic control\n"
711 "\tmanual to supspend automatic control" },
712 { "phyreg", wl_reg
, WLC_GET_PHYREG
, WLC_SET_PHYREG
,
713 "Get/Set a phy register:\n"
714 "\toffset [ value ] [ band ]" },
715 { "radioreg", wl_reg
, WLC_GET_RADIOREG
, WLC_SET_RADIOREG
,
716 "Get/Set a radio register:\n"
717 "\toffset [ value ] [ band/core ]\n"
719 "\tGet a radio register: wl radioreg [ offset ] [ cr0/cr1/cr2 ]\n"
720 "\tSet a radio register: wl radioreg [ offset ] [ value ] [ cr0/cr1/cr2/all ]\n"},
721 { "ucflags", wl_reg
, WLC_GET_UCFLAGS
, WLC_SET_UCFLAGS
,
722 "Get/Set ucode flags 1, 2, 3(16 bits each)\n"
723 "\toffset [ value ] [ band ]" },
724 { "shmem", wl_reg
, WLC_GET_SHMEM
, WLC_SET_SHMEM
,
725 "Get/Set a shared memory location:\n"
726 "\toffset [ value ] [band ]" },
727 { "macreg", wl_macreg
, WLC_R_REG
, WLC_W_REG
,
728 "Get/Set any mac registers(include IHR and SB):\n"
729 "\tmacreg offset size[2,4] [ value ] [ band ]" },
730 { "ucantdiv", wl_int
, WLC_GET_UCANTDIV
, WLC_SET_UCANTDIV
,
731 "Enable/disable ucode antenna diversity (1/0 or on/off)" },
732 { "gpioout", wl_gpioout
, -1, -1,
733 "Set any GPIO pins to any value. Use with caution as GPIOs would be "
734 "assigned to chipcommon\n"
735 "\tUsage: gpiomask gpioval"},
736 { "devpath", wl_devpath
, WLC_GET_VAR
, -1,
737 "print device path" },
739 { "jtagureg", wlu_reg2args
, WLC_GET_VAR
, WLC_SET_VAR
, "g/set JTAG user registers"},
740 { "coma", wl_coma
, -1, WLC_SET_VAR
, "Put the router in a catatonic state"},
741 { "pllreset", wl_var_void
, -1, WLC_SET_VAR
, "set the pll to reset value\n"
742 "\tUsage: wl pllreset"},
743 { "pcieserdesreg", wlu_reg3args
, WLC_GET_VAR
, WLC_SET_VAR
,
744 "g/set SERDES registers: dev offset [val]"},
745 { "ampdu_activate_test", wl_ampdu_activate_test
, -1, WLC_SET_VAR
,
747 /* nphy parameter setting is internal only for now */
748 { "ampdu_tid", wl_ampdu_tid
, WLC_GET_VAR
, WLC_SET_VAR
,
749 "enable/disable per-tid ampdu; usage: wl ampdu_tid <tid> [0/1]" },
750 { "ampdu_retry_limit_tid", wl_ampdu_retry_limit_tid
, WLC_GET_VAR
, WLC_SET_VAR
,
751 "Set per-tid ampdu retry limit; usage: wl ampdu_retry_limit_tid <tid> [0~31]" },
752 { "ampdu_rr_retry_limit_tid", wl_ampdu_rr_retry_limit_tid
, WLC_GET_VAR
, WLC_SET_VAR
,
753 "Set per-tid ampdu regular rate retry limit; usage: "
754 "wl ampdu_rr_retry_limit_tid <tid> [0~31]" },
755 { "ampdu_send_addba", wl_ampdu_send_addba
, WLC_GET_VAR
, WLC_SET_VAR
,
756 "send addba to specified ea-tid; usage: wl ampdu_send_addba <tid> <ea>" },
757 { "ampdu_send_delba", wl_ampdu_send_delba
, WLC_GET_VAR
, WLC_SET_VAR
,
758 "send delba to specified ea-tid; usage: wl ampdu_send_delba <tid> <ea>" },
759 { "ampdu_clear_dump", wl_var_void
, -1, WLC_SET_VAR
,
760 "clear ampdu counters"},
761 { "dpt_deny", wl_dpt_deny
, WLC_GET_VAR
, WLC_SET_VAR
,
762 "adds/removes ea to dpt deny list\n"
763 "\tusage: wl dpt_deny <add,remove> <ea>" },
764 { "dpt_endpoint", wl_dpt_endpoint
, WLC_GET_VAR
, WLC_SET_VAR
,
765 "creates/updates/deletes dpt endpoint for ea\n"
766 "\tusage: wl dpt_endpoint <create, update, delete> <ea>" },
767 { "dpt_pmk", wl_dpt_pmk
, -1, WLC_SET_VAR
,
768 "sets DPT pre-shared key" },
769 { "dpt_fname", wl_dpt_fname
, WLC_GET_VAR
, WLC_SET_VAR
,
770 "sets/gets DPT friendly name" },
771 { "dpt_list", wl_dpt_list
, WLC_GET_VAR
, -1,
772 "gets status of all dpt peers" },
774 { "HCI_cmd", wl_HCI_cmd
, WLC_GET_VAR
, WLC_SET_VAR
,
775 "carries HCI commands to the driver\n"
776 "\tusage: wl HCI_cmd <command> <args>" },
777 { "HCI_ACL_data", wl_HCI_ACL_data
, WLC_GET_VAR
, WLC_SET_VAR
,
778 "carries HCI ACL data packet to the driver\n"
779 "\tusage: wl HCI_ACL_data <logical link handle> <data>" },
780 { "btamp_statelog", wl_get_btamp_log
, WLC_GET_VAR
, WLC_SET_VAR
,
781 "Return state transistion log of BTAMP\n" },
783 { "actframe", wl_actframe
, -1, WLC_SET_VAR
,
784 "Send a Vendor specific Action frame to a channel\n"
785 "\tusage: wl actframe <Dest Mac Addr> <data> channel dwell-time <BSSID>" },
786 { "antdiv", wl_int
, WLC_GET_ANTDIV
, WLC_SET_ANTDIV
,
787 "Set antenna diversity for rx\n"
788 "\t0 - force use of antenna 0\n"
789 "\t1 - force use of antenna 1\n"
790 "\t3 - automatic selection of antenna diversity" },
791 { "txant", wl_int
, WLC_GET_TXANT
, WLC_SET_TXANT
,
792 "Set the transmit antenna\n"
793 "\t0 - force use of antenna 0\n"
794 "\t1 - force use of antenna 1\n"
795 "\t3 - use the RX antenna selection that was in force during\n"
796 "\t the most recently received good PLCP header" },
797 { "plcphdr", wl_plcphdr
, WLC_GET_PLCPHDR
, WLC_SET_PLCPHDR
,
798 "Set the plcp header.\n"
799 "\t\"long\" or \"auto\" or \"debug\"" },
800 { "phytype", wl_int
, WLC_GET_PHYTYPE
, -1,
802 { "rateparam", wl_rateparam
, -1, WLC_SET_RATE_PARAMS
,
803 "set driver rate selection tunables\n"
804 "\targ 1: tunable id\n"
805 "\targ 2: tunable value" },
806 { "wepstatus", wl_wepstatus
, -1, -1, /* Deprecated. Use "wsec" */
807 "Set or Get WEP status\n"
808 "\twepstatus [on|off]" },
809 { "primary_key", wl_primary_key
, WLC_GET_KEY_PRIMARY
, WLC_SET_KEY_PRIMARY
,
810 "Set or get index of primary key" },
811 { "addwep", wl_addwep
, -1, WLC_SET_KEY
,
812 "Set an encryption key. The key must be 5, 13 or 16 bytes long, or\n"
813 "\t10, 26, 32, or 64 hex digits long. The encryption algorithm is\n"
814 "\tautomatically selected based on the key size. keytype is accepted\n"
815 "\tonly when key length is 16 bytes/32 hex digits and specifies\n"
816 "\twhether AES-OCB or AES-CCM encryption is used. Default is ccm.\n"
817 "\tWAPI is selected if key len is 32 and arguments contain wapi.\n"
818 "\taddwep <keyindex> <keydata> [ocb | ccm | wapi] [notx] [xx:xx:xx:xx:xx:xx]" },
819 { "rmwep", wl_rmwep
, -1, WLC_SET_KEY
,
820 "Remove the encryption key at the specified key index." },
821 { "keys", wl_keys
, WLC_GET_KEY
, -1,
822 "Prints a list of the current WEP keys" },
823 { "tsc", wl_tsc
, WLC_GET_KEY_SEQ
, -1,
824 "Print Tx Sequence Couter for key at specified key index." },
825 { "wsec_test", wl_wsec_test
, -1, WLC_SET_WSEC_TEST
,
826 "Generate wsec errors\n"
827 "\twsec_test <test_type> <keyindex|xx:xx:xx:xx:xx:xx>\n"
828 "\ttype \'wl wsec_test ?\' for test_types" },
829 { "tkip_countermeasures", wl_int
, -1, WLC_TKIP_COUNTERMEASURES
,
830 "Enable or disable TKIP countermeasures (TKIP-enabled AP only)\n"
833 { "wsec_restrict", wl_bsscfg_int
, WLC_GET_WEP_RESTRICT
, WLC_SET_WEP_RESTRICT
,
834 "Drop unencrypted packets if WSEC is enabled\n"
837 { "eap", wl_int
, WLC_GET_EAP_RESTRICT
, WLC_SET_EAP_RESTRICT
,
838 "restrict traffic to 802.1X packets until 802.1X authorization succeeds\n"
841 { "cur_etheraddr", wl_iov_mac
, -1, -1,
842 "Get/set the current hw address" },
843 { "perm_etheraddr", wl_iov_mac
, -1, -1,
844 "Get the permanent address from NVRAM" },
845 { "authorize", wl_mac
, -1, WLC_SCB_AUTHORIZE
,
846 "restrict traffic to 802.1X packets until 802.1X authorization succeeds" },
847 { "deauthorize", wl_mac
, -1, WLC_SCB_DEAUTHORIZE
,
848 "do not restrict traffic to 802.1X packets until 802.1X authorization succeeds" },
849 { "deauthenticate", wl_deauth_rc
, -1, WLC_SCB_DEAUTHENTICATE_FOR_REASON
,
850 "deauthenticate a STA from the AP with optional reason code (AP ONLY)" },
851 { "wsec", wl_wsec
, WLC_GET_WSEC
, WLC_SET_WSEC
,
852 "wireless security bit vector\n"
853 "\t1 - WEP enabled\n"
854 "\t2 - TKIP enabled\n"
855 "\t4 - AES enabled\n"
856 "\t8 - WSEC in software\n"
857 "\t0x80 - FIPS enabled\n"
858 "\t0x100 - WAPI enabled" },
859 { "auth", wl_bsscfg_int
, WLC_GET_AUTH
, WLC_SET_AUTH
,
860 "set/get 802.11 authentication type. 0 = OpenSystem, 1= SharedKey, 2=Open/Shared" },
861 { "wpa_auth", wl_wpa_auth
, WLC_GET_WPA_AUTH
, WLC_SET_WPA_AUTH
,
862 "Bitvector of WPA authorization modes:\n"
864 "\t2 WPA-802.1X/WPA-Professional\n"
865 "\t4 WPA-PSK/WPA-Personal\n"
866 "\t64 WPA2-802.1X/WPA2-Professional\n"
867 "\t128 WPA2-PSK/WPA2-Personal\n"
870 { "wpa_cap", wl_bsscfg_int
, WLC_GET_VAR
, WLC_SET_VAR
,
871 "set/get 802.11i RSN capabilities" },
872 { "set_pmk", wl_set_pmk
, -1, WLC_SET_WSEC_PMK
,
873 "Set passphrase for PMK in driver-resident supplicant." },
874 { "scan", wl_scan
, -1, WLC_SCAN
,
875 "Initiate a scan.\n" SCAN_USAGE
877 { "iscan_s", wl_iscan
, -1, WLC_SET_VAR
,
878 "Initiate an incremental scan.\n" SCAN_USAGE
880 { "iscan_c", wl_iscan
, -1, WLC_SET_VAR
,
881 "Continue an incremental scan.\n" SCAN_USAGE
883 { "scancache_clear", wl_var_void
, -1, WLC_SET_VAR
,
884 "clear the scan cache"},
885 { "escan", wl_escan
, -1, WLC_SET_VAR
,
886 "Start an escan.\n" SCAN_USAGE
888 { "escanabort", wl_escan
, -1, WLC_SET_VAR
,
889 "Abort an escan.\n" SCAN_USAGE
892 { "extdscan", wl_extdscan
, -1, WLC_SET_VAR
,
893 "Initiate an extended scan.\n"
894 "\tDefault to an active scan across all channels for any SSID.\n"
895 "\tOptional args: list of SSIDs to scan.\n"
897 "\t-s S1 S2 S3, --ssid=S1 S2 S3\t\tSSIDs to scan, comma or space separated\n"
898 "\t-x x, --split_scan=ST\t[split_scan] scan type\n"
899 "\t-t ST, --scan_type=ST\t[background:0/forcedbackground:1/foreground:2] scan type\n"
900 "\t-n N, --nprobes=N\tnumber of probes per scanned channel, per SSID\n"
901 "\t-c L, --channels=L\tcomma or space separated list of channels to scan"},
903 { "passive", wl_int
, WLC_GET_PASSIVE_SCAN
, WLC_SET_PASSIVE_SCAN
,
904 "Puts scan engine into passive mode" },
905 { "regulatory", wl_int
, WLC_GET_REGULATORY
, WLC_SET_REGULATORY
,
906 "Get/Set regulatory domain mode (802.11d). Driver must be down." },
907 { "spect", wl_spect
, WLC_GET_SPECT_MANAGMENT
, WLC_SET_SPECT_MANAGMENT
,
908 "Get/Set 802.11h Spectrum Management mode.\n"
910 "\t1 - Loose interpretation of 11h spec - may join non-11h APs\n"
911 "\t2 - Strict interpretation of 11h spec - may not join non-11h APs\n"
912 "\t3 - Disable 11h and enable 11d\n"
913 "\t4 - Loose interpretation of 11h+d spec - may join non-11h APs"
915 {"scanabort", wl_var_void
, -1, WLC_SET_VAR
,
917 { "scanresults", wl_dump_networks
, WLC_SCAN_RESULTS
, -1,
918 "Return results from last scan." },
919 { "iscanresults", wl_dump_networks
, WLC_GET_VAR
, -1,
920 "Return results from last iscan. Specify a buflen (max 8188)\n"
921 "\tto artificially limit the size of the results buffer.\n"
922 "\tiscanresults [buflen]"},
923 { "assoc", wl_status
, -1, -1,
924 "Print information about current network association.\n"
925 "\t(also known as \"status\")" },
926 { "status", wl_status
, -1, -1,
927 "Print information about current network association.\n"
928 "\t(also known as \"assoc\")" },
929 { "disassoc", wl_void
, -1, WLC_DISASSOC
,
930 "Disassociate from the current BSS/IBSS." },
931 { "chanlist", wl_print_deprecate
, WLC_GET_VALID_CHANNELS
, -1,
932 "Deprecated. Use channels." },
933 { "channels", wl_dump_chanlist
, WLC_GET_VALID_CHANNELS
, -1,
934 "Return valid channels for the current settings." },
935 { "channels_in_country", wl_channels_in_country
, WLC_GET_CHANNELS_IN_COUNTRY
, -1,
936 "Return valid channels for the country specified.\n"
937 "\tArg 1 is the country abbreviation\n"
938 "\tArg 2 is the band(a or b)"},
939 { "curpower", wl_get_current_power
, WLC_CURRENT_PWR
, -1,
940 "Return current tx power settings.\n"
941 "\t-q (quiet): estimated power only." },
942 { "curppr", wl_get_current_txppr
, WLC_GET_VAR
, -1,
943 "Return current tx power per rate offset.\n"},
944 { "txinstpwr", wl_get_instant_power
, WLC_GET_VAR
, -1,
945 "Return tx power based on instant TSSI "},
946 { "scansuppress", wl_int
, WLC_GET_SCANSUPPRESS
, WLC_SET_SCANSUPPRESS
,
947 "Suppress all scans for testing.\n"
948 "\t0 - allow scans\n"
949 "\t1 - suppress scans" },
950 { "evm", wl_evm
, -1, WLC_EVM
,
951 "Start an EVM test on the given channel, or stop EVM test.\n"
952 "\tArg 1 is channel number 1-14, or \"off\" or 0 to stop the test.\n"
953 "\tArg 2 is optional rate (1, 2, 5.5 or 11)"},
954 { "rateset", wl_rateset
, WLC_GET_RATESET
, WLC_SET_RATESET
,
955 "Returns or sets the supported and basic rateset, (b) indicates basic\n"
956 "\tWith no args, returns the rateset. Args are\n"
957 "\trateset \"default\" | \"all\" | <arbitrary rateset> -m <arbitrary mcsset>\n"
958 "\t\tdefault - driver defaults\n"
959 "\t\tall - all rates are basic rates\n"
960 "\t\tarbitrary rateset - list of rates\n"
961 "\t\tarbitrary mcsset - list of mcs rates octets, each bit representing\n"
962 "\t\t\t\tcorresponding mcs\n"
963 "\tList of rates are in Mbps and each rate is optionally followed\n"
964 "\tby \"(b)\" or \"b\" for a Basic rate. Example: 1(b) 2b 5.5 11\n"
965 "\tAt least one rate must be Basic for a legal rateset."},
966 { "roam_trigger", wl_band_elm
, WLC_GET_ROAM_TRIGGER
, WLC_SET_ROAM_TRIGGER
,
967 "Get or Set the roam trigger RSSI threshold:\n"
968 "\tGet: roam_trigger [a|b]\n"
969 "\tSet: roam_trigger <integer> [a|b|all]\n"
970 "\tinteger - 0: default\n"
971 "\t 1: optimize bandwidth\n"
972 "\t 2: optimize distance\n"
973 "\t [-1, -99]: dBm trigger value"},
974 { "roam_delta", wl_band_elm
, WLC_GET_ROAM_DELTA
, WLC_SET_ROAM_DELTA
,
975 "Set the roam candidate qualification delta. roam_delta [integer [, a/b]]" },
976 { "roam_scan_period", wl_int
, WLC_GET_ROAM_SCAN_PERIOD
, WLC_SET_ROAM_SCAN_PERIOD
,
977 "Set the roam candidate qualification delta. (integer)" },
978 { "suprates", wl_sup_rateset
, WLC_GET_SUP_RATESET_OVERRIDE
, WLC_SET_SUP_RATESET_OVERRIDE
,
979 "Returns or sets the 11g override for the supported rateset\n"
980 "\tWith no args, returns the rateset. Args are a list of rates,\n"
981 "\tor 0 or -1 to specify an empty rateset to clear the override.\n"
982 "\tList of rates are in Mbps, example: 1 2 5.5 11"},
983 { "scan_channel_time", wl_int
, WLC_GET_SCAN_CHANNEL_TIME
, WLC_SET_SCAN_CHANNEL_TIME
,
984 "Get/Set scan channel time"},
985 { "scan_unassoc_time", wl_int
, WLC_GET_SCAN_UNASSOC_TIME
, WLC_SET_SCAN_UNASSOC_TIME
,
986 "Get/Set unassociated scan channel dwell time"},
987 { "scan_home_time", wl_int
, WLC_GET_SCAN_HOME_TIME
, WLC_SET_SCAN_HOME_TIME
,
988 "Get/Set scan home channel dwell time"},
989 { "scan_passive_time", wl_int
, WLC_GET_SCAN_PASSIVE_TIME
, WLC_SET_SCAN_PASSIVE_TIME
,
990 "Get/Set passive scan channel dwell time"},
991 { "scan_nprobes", wl_int
, WLC_GET_SCAN_NPROBES
, WLC_SET_SCAN_NPROBES
,
992 "Get/Set scan parameter for number of probes to use per channel scanned"},
993 { "prb_resp_timeout", wl_int
, WLC_GET_PRB_RESP_TIMEOUT
, WLC_SET_PRB_RESP_TIMEOUT
,
994 "Get/Set probe response timeout"},
995 { "channel_qa", wl_int
, WLC_GET_CHANNEL_QA
, -1,
996 "Get last channel quality measurment"},
997 { "channel_qa_start", wl_void
, -1, WLC_START_CHANNEL_QA
,
998 "Start a channel quality measurment"},
999 { "country", wl_country
, WLC_GET_COUNTRY
, WLC_SET_COUNTRY
,
1000 "Select Country Code for driver operational region\n"
1001 "\tFor simple country setting: wl country <country>\n"
1002 "\tWhere <country> is either a long name or country code from ISO 3166; "
1003 "for example \"Germany\" or \"DE\"\n"
1004 "\n\tFor a specific built-in country definition: "
1005 "wl country <built-in> [<advertised-country>]\n"
1006 "\tWhere <built-in> is a country country code followed by '/' and "
1007 "regulatory revision number.\n"
1008 "\tFor example, \"US/3\".\n"
1009 "\tAnd where <advertised-country> is either a long name or country code from ISO 3166.\n"
1010 "\tIf <advertised-country> is omitted, it will be the same as the built-in country code.\n"
1011 "\n\tUse 'wl country list [band(a or b)]' for the list of supported countries"},
1012 { "country_ie_override", wl_country_ie_override
, WLC_GET_VAR
, WLC_SET_VAR
,
1013 "To set/get country ie"},
1014 { "autocountry_default", wl_varstr
, WLC_GET_VAR
, WLC_SET_VAR
,
1015 "Select Country Code for use with Auto Contry Discovery"},
1016 { "join", wl_join
, -1, -1,
1017 "Join a specified network SSID.\n"
1018 "\tUsage: join <ssid> [key <0-3>:xxxxx] [imode bss|ibss] "
1019 "[amode open|shared|openshared|wpa|wpapsk|wpa2|wpa2psk|wpanone] [options]\n"
1021 "\t-b MAC, --bssid=MAC \tBSSID (xx:xx:xx:xx:xx:xx) to scan and join\n"
1022 "\t-c CL, --chanspecs=CL \tchanspecs (comma or space separated list)"},
1023 { "ssid", wl_ssid
, WLC_GET_SSID
, WLC_SET_SSID
,
1024 "Set or get a configuration's SSID.\n"
1025 "\twl ssid [-C num]|[--cfg=num] [<ssid>]\n"
1026 "\tIf the configuration index 'num' is not given, configuraion #0 is assumed and\n"
1027 "\tsetting will initiate an assoication attempt if in infrastructure mode,\n"
1028 "\tor join/creation of an IBSS if in IBSS mode,\n"
1029 "\tor creation of a BSS if in AP mode."},
1030 { "mac", wl_maclist
, WLC_GET_MACLIST
, WLC_SET_MACLIST
,
1031 "Set or get the list of source MAC address matches.\n"
1032 "\twl mac xx:xx:xx:xx:xx:xx [xx:xx:xx:xx:xx:xx ...]\n"
1033 "\tTo Clear the list: wl mac none" },
1034 { "macmode", wl_int
, WLC_GET_MACMODE
, WLC_SET_MACMODE
,
1035 "Set the mode of the MAC list.\n"
1036 "\t0 - Disable MAC address matching.\n"
1037 "\t1 - Deny association to stations on the MAC list.\n"
1038 "\t2 - Allow association to stations on the MAC list."},
1039 { "wds", wl_maclist
, WLC_GET_WDSLIST
, WLC_SET_WDSLIST
,
1040 "Set or get the list of WDS member MAC addresses.\n"
1041 "\tSet using a space separated list of MAC addresses.\n"
1042 "\twl wds xx:xx:xx:xx:xx:xx [xx:xx:xx:xx:xx:xx ...]" },
1043 { "lazywds", wl_int
, WLC_GET_LAZYWDS
, WLC_SET_LAZYWDS
,
1044 "Set or get \"lazy\" WDS mode (dynamically grant WDS membership to anyone)."},
1045 { "noise", wl_int
, WLC_GET_PHY_NOISE
, -1,
1046 "Get noise (moving average) right after tx in dBm" },
1047 { "fqacurcy", wl_int
, -1, WLC_FREQ_ACCURACY
,
1048 "Manufacturing test: set frequency accuracy mode.\n"
1049 "\tfreqacuracy syntax is: fqacurcy <channel>\n"
1050 "\tArg is channel number 1-14, or 0 to stop the test." },
1051 { "crsuprs", wl_int
, -1, WLC_CARRIER_SUPPRESS
,
1052 "Manufacturing test: set carrier suppression mode.\n"
1053 "\tcarriersuprs syntax is: crsuprs <channel>\n"
1054 "\tArg is channel number 1-14, or 0 to stop the test." },
1055 { "longtrain", wl_int
, -1, WLC_LONGTRAIN
,
1056 "Manufacturing test: set longtraining mode.\n"
1057 "\tlongtrain syntax is: longtrain <channel>\n"
1058 "\tArg is A band channel number or 0 to stop the test." },
1059 { "band", wl_band
, WLC_GET_BAND
, WLC_SET_BAND
,
1060 "Returns or sets the current band\n"
1061 "\tauto - auto switch between available bands (default)\n"
1062 "\ta - force use of 802.11a band\n"
1063 "\tb - force use of 802.11b band" },
1064 { "bands", wl_bandlist
, WLC_GET_BANDLIST
, -1,
1065 "Return the list of available 802.11 bands" },
1066 { "phylist", wl_phylist
, WLC_GET_PHYLIST
, -1,
1067 "Return the list of available phytypes" },
1068 { "shortslot", wl_int
, WLC_GET_SHORTSLOT
, -1,
1069 "Get current 11g Short Slot Timing mode. (0=long, 1=short)" },
1070 { "shortslot_override", wl_int
, WLC_GET_SHORTSLOT_OVERRIDE
, WLC_SET_SHORTSLOT_OVERRIDE
,
1071 "Get/Set 11g Short Slot Timing mode override. (-1=auto, 0=long, 1=short)" },
1072 { "shortslot_restrict", wl_int
, WLC_GET_SHORTSLOT_RESTRICT
, WLC_SET_SHORTSLOT_RESTRICT
,
1073 "Get/Set AP Restriction on associations for 11g Short Slot Timing capable STAs.\n"
1074 "\t0 - Do not restrict association based on ShortSlot capability\n"
1075 "\t1 - Restrict association to STAs with ShortSlot capability" },
1076 { "ignore_bcns", wl_int
, WLC_GET_IGNORE_BCNS
, WLC_SET_IGNORE_BCNS
,
1077 "AP only (G mode): Check for beacons without NONERP element"
1078 "(0=Examine beacons, 1=Ignore beacons)" },
1079 { "pktcnt", wl_get_pktcnt
, WLC_GET_PKTCNTS
, -1,
1080 "Get the summary of good and bad packets." },
1081 { "upgrade", wl_upgrade
, -1, WLC_UPGRADE
,
1082 "Upgrade the firmware on an embedded device" },
1083 { "gmode", wl_gmode
, WLC_GET_GMODE
, WLC_SET_GMODE
,
1084 "Set the 54g Mode (LegacyB|Auto||GOnly|BDeferred|Performance|LRS)" },
1085 { "gmode_protection", wl_int
, WLC_GET_GMODE_PROTECTION
, -1,
1086 "Get G protection mode. (0=disabled, 1=enabled)" },
1087 { "gmode_protection_control", wl_int
, WLC_GET_PROTECTION_CONTROL
,
1088 WLC_SET_PROTECTION_CONTROL
,
1089 "Get/Set 11g protection mode control alg."
1090 "(0=always off, 1=monitor local association, 2=monitor overlapping BSS)" },
1091 { "gmode_protection_override", wl_int
, WLC_GET_GMODE_PROTECTION_OVERRIDE
,
1092 WLC_SET_GMODE_PROTECTION_OVERRIDE
,
1093 "Get/Set 11g protection mode override. (-1=auto, 0=disable, 1=enable)" },
1094 { "protection_control", wl_int
, WLC_GET_PROTECTION_CONTROL
,
1095 WLC_SET_PROTECTION_CONTROL
,
1096 "Get/Set protection mode control alg."
1097 "(0=always off, 1=monitor local association, 2=monitor overlapping BSS)" },
1098 { "legacy_erp", wl_int
, WLC_GET_LEGACY_ERP
, WLC_SET_LEGACY_ERP
,
1099 "Get/Set 11g legacy ERP inclusion (0=disable, 1=enable)" },
1100 { "scb_timeout", wl_int
, WLC_GET_SCB_TIMEOUT
, WLC_SET_SCB_TIMEOUT
,
1101 "AP only: inactivity timeout value for authenticated stas" },
1102 { "assoclist", wl_maclist
, WLC_GET_ASSOCLIST
, -1,
1103 "AP only: Get the list of associated MAC addresses."},
1104 { "isup", wl_int
, WLC_GET_UP
, -1,
1105 "Get driver operational state (0=down, 1=up)"},
1106 { "rssi", wl_rssi
, WLC_GET_RSSI
, -1,
1107 "Get the current RSSI val, for an AP you must specify the mac addr of the STA" },
1108 { "rssi_event", wl_rssi_event
, WLC_GET_VAR
, WLC_SET_VAR
,
1109 "Set parameters associated with RSSI event notification\n"
1110 "\tusage: wl rssi_event <rate_limit> <rssi_levels>\n"
1111 "\trate_limit: Number of events posted to application will be limited"
1112 " to 1 per this rate limit. Set to 0 to disable rate limit.\n"
1113 "\trssi_levels: Variable number of RSSI levels (maximum 8) "
1114 " in increasing order (e.g. -85 -70 -60). An event will be posted"
1115 " each time the RSSI of received beacons/packets crosses a level."},
1116 { "fasttimer", wl_print_deprecate
, -1, -1,
1117 "Deprecated. Use fast_timer."},
1118 { "slowtimer", wl_print_deprecate
, -1, -1,
1119 "Deprecated. Use slow_timer."},
1120 { "glacialtimer", wl_print_deprecate
, -1, -1,
1121 "Deprecated. Use glacial_timer."},
1122 { "radar", wl_int
, WLC_GET_RADAR
, WLC_SET_RADAR
,
1123 "Enable/Disable radar"},
1124 { "radarargs", wl_radar_args
, WLC_GET_VAR
, WLC_SET_VAR
,
1125 "Get/Set Radar parameters in \n"
1126 "\torder as version, npulses, ncontig, min_pw, max_pw, thresh0,\n"
1127 "\tthresh1, blank, fmdemodcfg, npulses_lp, min_pw_lp, max_pw_lp,\n"
1128 "\tmin_fm_lp, max_span_lp, min_deltat, max_deltat,\n"
1129 "\tautocorr, st_level_time, t2_min, fra_pulse_err, npulses_fra,\n"
1130 "\tnpulses_stg2, npulses_stg3, percal_mask, quant, \n"
1131 "\tmin_burst_intv_lp, max_burst_intv_lp, nskip_rst_lp, max_pw_tol, feature_mask"},
1132 { "radarargs40", wl_radar_args
, WLC_GET_VAR
, WLC_SET_VAR
,
1133 "Get/Set Radar parameters for 40Mhz channel in \n"
1134 "\torder as version, npulses, ncontig, min_pw, max_pw, thresh0,\n"
1135 "\tthresh1, blank, fmdemodcfg, npulses_lp, min_pw_lp, max_pw_lp,\n"
1136 "\tmin_fm_lp, max_span_lp, min_deltat, max_deltat,\n"
1137 "\tautocorr, st_level_time, t2_min, fra_pulse_err, npulses_fra,\n"
1138 "\tnpulses_stg2, npulses_stg3, percal_mask, quant, \n"
1139 "\tmin_burst_intv_lp, max_burst_intv_lp, nskip_rst_lp, max_pw_tol, feature_mask"},
1140 { "radarthrs", wl_radar_thrs
, -1, WLC_SET_VAR
,
1141 "Set Radar threshold for both 20 & 40MHz BW:\n"
1142 "\torder as thresh0_20_lo, thresh1_20_lo, thresh0_40_lo, thresh1_40_lo\n"
1143 "\tthresh0_20_hi, thresh1_20_hi, thresh0_40_hi, thresh1_40_hi"},
1144 { "dfs_status", wl_dfs_status
, WLC_GET_VAR
, -1,
1146 { "interference", wl_interfere
, WLC_GET_INTERFERENCE_MODE
, WLC_SET_INTERFERENCE_MODE
,
1147 "Get/Set interference mitigation mode. Choices are:\n"
1150 "\t2 = wlan manual\n"
1151 "\t3 = wlan automatic\n"
1152 "\t4 = wlan automatic with noise reduction"},
1153 { "interference_override", wl_interfere_override
,
1154 WLC_GET_INTERFERENCE_OVERRIDE_MODE
,
1155 WLC_SET_INTERFERENCE_OVERRIDE_MODE
,
1156 "Get/Set interference mitigation override. Choices are:\n"
1157 "\t0 = no interference mitigation\n"
1159 "\t2 = wlan manual\n"
1160 "\t3 = wlan automatic\n"
1161 "\t4 = wlan automatic with noise reduction\n"
1162 "\t-1 = remove override, override disabled"},
1163 { "frameburst", wl_int
, WLC_GET_FAKEFRAG
, WLC_SET_FAKEFRAG
,
1164 "Disable/Enable frameburst mode" },
1165 { "pwr_percent", wl_int
, WLC_GET_PWROUT_PERCENTAGE
, WLC_SET_PWROUT_PERCENTAGE
,
1166 "Get/Set power output percentage"},
1167 { "toe", wl_varint
, WLC_GET_VAR
, WLC_SET_VAR
,
1168 "Enable/Disable tcpip offload feature"},
1169 { "toe_ol", wl_offload_cmpnt
, WLC_GET_VAR
, WLC_SET_VAR
,
1170 "Get/Set tcpip offload components"},
1171 { "toe_stats", wl_toe_stats
, WLC_GET_VAR
, -1,
1172 "Display checksum offload statistics"},
1173 { "toe_stats_clear", wl_var_void
, -1, WLC_SET_VAR
,
1174 "Clear checksum offload statistics"},
1175 { "arpoe", wl_varint
, WLC_GET_VAR
, WLC_SET_VAR
,
1176 "Enable/Disable arp agent offload feature"},
1177 { "arp_ol", wl_offload_cmpnt
, WLC_GET_VAR
, WLC_SET_VAR
,
1178 "Get/Set arp offload components"},
1179 { "arp_peerage", wl_varint
, WLC_GET_VAR
, WLC_SET_VAR
,
1180 "Get/Set age of the arp entry in minutes"},
1181 { "arp_table_clear", wl_var_void
, -1, WLC_SET_VAR
,
1183 { "arp_hostip", wl_hostip
, WLC_GET_VAR
, WLC_SET_VAR
,
1184 "Add a host-ip address or display them"},
1185 { "arp_hostip_clear", wl_var_void
, -1, WLC_SET_VAR
,
1186 "Clear all host-ip addresses"},
1187 { "arp_stats", wl_arp_stats
, WLC_GET_VAR
, -1,
1188 "Display ARP offload statistics"},
1189 { "arp_stats_clear", wl_var_void
, -1, WLC_SET_VAR
,
1190 "Clear ARP offload statistics"},
1191 { "wet", wl_int
, WLC_GET_WET
, WLC_SET_WET
,
1192 "Get/Set wireless ethernet bridging mode"},
1193 { "bi", wl_int
, WLC_GET_BCNPRD
, WLC_SET_BCNPRD
,
1194 "Get/Set the beacon period (bi=beacon interval)"},
1195 { "dtim", wl_int
, WLC_GET_DTIMPRD
, WLC_SET_DTIMPRD
,
1197 { "wds_remote_mac", wl_mac
, WLC_WDS_GET_REMOTE_HWADDR
, -1,
1198 "Get WDS link remote endpoint's MAC address"},
1199 { "wds_wpa_role_old", wl_wds_wpa_role_old
, WLC_WDS_GET_WPA_SUP
, -1,
1200 "Get WDS link local endpoint's WPA role (old)"},
1201 { "wds_wpa_role", wl_wds_wpa_role
, WLC_GET_VAR
, WLC_SET_VAR
,
1202 "Get/Set WDS link local endpoint's WPA role"},
1203 { "authe_sta_list", wl_maclist_1
, WLC_GET_VAR
, -1,
1204 "Get authenticated sta mac address list"},
1205 { "autho_sta_list", wl_maclist_1
, WLC_GET_VAR
, -1,
1206 "Get authorized sta mac address list"},
1207 { "measure_req", wl_measure_req
, -1, WLC_MEASURE_REQUEST
,
1208 "Send an 802.11h measurement request.\n"
1209 "\tUsage: wl measure_req <type> <target MAC addr>\n"
1210 "\tMeasurement types are: TPC, Basic, CCA, RPI\n"
1211 "\tTarget MAC addr format is xx:xx:xx:xx:xx:xx"},
1212 { "quiet", wl_send_quiet
, -1, WLC_SEND_QUIET
,
1213 "Send an 802.11h quiet command.\n"
1214 "\tUsage: wl quiet <TBTTs until start>, <duration (in TUs)>, <offset (in TUs)>"},
1215 { "csa", wl_send_csa
, -1, WLC_SET_VAR
,
1216 "Send an 802.11h channel switch anouncement with chanspec:\n"
1217 "\t<mode> <count> <channel>[a,b][n][u,l]\n"
1220 "\tchannel number (0-224)\n"
1221 "\tband a=5G, b=2G\n"
1222 "\tbandwidth n=10, non for 20 & 40\n"
1223 "\tctl sideband, l=lower, u=upper, default no ctl sideband"},
1224 { "constraint", wl_int
, -1, WLC_SEND_PWR_CONSTRAINT
,
1225 "Send an 802.11h Power Constraint IE\n"
1226 "\tUsage: wl constraint 1-255 db"},
1227 { "rm_req", wl_rm_request
, -1, WLC_SET_VAR
,
1228 "Request a radio measurement of type basic, cca, or rpi\n"
1229 "\tspecify a series of measurement types each followed by options.\n"
1230 "\texample: wl rm_req cca -c 1 -d 50 cca -c 6 cca -c 11\n"
1232 "\t-t n numeric token id for measurement set or measurement\n"
1234 "\t-d n duration in TUs (1024 us)\n"
1235 "\t-p parallel flag, measurement starts at the same time as previous\n"
1237 "\tEach measurement specified uses the same channel and duration as the\n"
1238 "\tprevious unless a new channel or duration is specified."},
1239 { "rm_rep", wl_rm_report
, WLC_GET_VAR
, -1,
1240 "Get current radio measurement report"},
1241 { "join_pref", wl_join_pref
, WLC_GET_VAR
, WLC_SET_VAR
,
1242 "Set/Get join target preferences."},
1243 { "assoc_pref", wl_assoc_pref
, WLC_GET_ASSOC_PREFER
, WLC_SET_ASSOC_PREFER
,
1244 "Set/Get association preference.\n"
1245 "Usage: wl assoc_pref [auto|a|b|g]"},
1246 { "wme", wl_varint
, WLC_GET_VAR
, WLC_SET_VAR
,
1247 "Set WME (Wireless Multimedia Extensions) mode (0=off, 1=on, -1=auto)"},
1248 { "wme_ac", wl_wme_ac_req
, WLC_GET_VAR
, WLC_SET_VAR
,
1249 "wl wme_ac ap|sta [be|bk|vi|vo [ecwmax|ecwmin|txop|aifsn|acm <value>] ...]"},
1250 { "wme_apsd", wl_varint
, WLC_GET_VAR
, WLC_SET_VAR
,
1251 "Set APSD (Automatic Power Save Delivery) mode on AP (0=off, 1=on)" },
1252 { "wme_apsd_sta", wl_wme_apsd_sta
, WLC_GET_VAR
, WLC_SET_VAR
,
1253 "Set APSD parameters on STA. Driver must be down.\n"
1254 "Usage: wl wme_apsd_sta <max_sp_len> <be> <bk> <vi> <vo>\n"
1255 " <max_sp_len>: number of frames per USP: 0 (all), 2, 4, or 6\n"
1256 " <xx>: value 0 to disable, 1 to enable U-APSD per AC" },
1257 { "wme_dp", wl_wme_dp
, WLC_GET_VAR
, WLC_SET_VAR
,
1258 "Set AC queue discard policy.\n"
1259 "Usage: wl wme_dp <be> <bk> <vi> <vo>\n"
1260 " <xx>: value 0 for newest-first, 1 for oldest-first" },
1261 { "wme_counters", wl_wme_counters
, WLC_GET_VAR
, -1,
1262 "print WMM stats" },
1263 { "wme_clear_counters", wl_var_void
, -1, WLC_SET_VAR
,
1264 "clear WMM counters"},
1265 { "wme_tx_params", wme_tx_params
, -1, -1,
1266 "wl wme_tx_params [be|bk|vi|vo [short|sfb|long|lfb|max_rate <value>] ...]"},
1267 { "wme_maxbw_params", wme_maxbw_params
, WLC_GET_VAR
, WLC_SET_VAR
,
1268 "wl wme_maxbw_params [be|bk|vi|vo <value> ....]"},
1269 { "lifetime", wl_lifetime
, WLC_GET_VAR
, WLC_SET_VAR
,
1270 "Set Lifetime parameter (milliseconds) for each ac.\n"
1271 "wl lifetime be|bk|vi|vo [<value>]"},
1272 { "reinit", wl_void
, -1, WLC_INIT
,
1273 "Reinitialize device"},
1274 { "sta_info", wl_sta_info
, WLC_GET_VAR
, -1,
1275 "wl sta_info <xx:xx:xx:xx:xx:xx>"},
1276 { "cap", wl_var_getandprintstr
, WLC_GET_VAR
, -1, "driver capabilities"},
1277 { "malloc_dump", wl_print_deprecate
, -1, -1, "Deprecated. Folded under 'wl dump malloc"},
1278 { "chan_info", wl_chan_info
, WLC_GET_VAR
, -1, "channel info"},
1279 { "add_ie", wl_add_ie
, -1, WLC_SET_VAR
,
1280 "Add a vendor proprietary IE to 802.11 management packets\n"
1281 "Usage: wl add_ie <pktflag> length OUI hexdata\n"
1282 "<pktflag>: Bit 0 - Beacons\n"
1283 " Bit 1 - Probe Rsp\n"
1284 " Bit 2 - Assoc/Reassoc Rsp\n"
1285 " Bit 3 - Auth Rsp\n"
1286 " Bit 4 - Probe Req\n"
1287 " Bit 5 - Assoc/Reassoc Req\n"
1288 "Example: wl add_ie 3 10 00:90:4C 0101050c121a03\n"
1289 " to add this IE to beacons and probe responses" },
1290 { "del_ie", wl_del_ie
, -1, WLC_SET_VAR
,
1291 "Delete a vendor proprietary IE from 802.11 management packets\n"
1292 "Usage: wl del_ie <pktflag> length OUI hexdata\n"
1293 "<pktflag>: Bit 0 - Beacons\n"
1294 " Bit 1 - Probe Rsp\n"
1295 " Bit 2 - Assoc/Reassoc Rsp\n"
1296 " Bit 3 - Auth Rsp\n"
1297 " Bit 4 - Probe Req\n"
1298 " Bit 5 - Assoc/Reassoc Req\n"
1299 "Example: wl del_ie 3 10 00:90:4C 0101050c121a03" },
1300 { "list_ie", wl_list_ie
, WLC_GET_VAR
, -1,
1301 "Dump the list of vendor proprietary IEs" },
1302 { "rand", wl_rand
, WLC_GET_VAR
, -1,
1303 "Get a 2-byte Random Number from the MAC's PRNG\n"
1305 { "otpw", wl_otpw
, -1, WLC_OTPW
,
1306 "Write an srom image to on-chip otp\n"
1307 "Usage: wl otpw file"},
1308 { "nvotpw", wl_otpw
, -1, WLC_NVOTPW
,
1309 "Write nvram to on-chip otp\n"
1310 "Usage: wl nvotpw file"},
1311 { "bcmerrorstr", wl_var_getandprintstr
, WLC_GET_VAR
, -1, "errorstring"},
1312 { "freqtrack", wl_varint
, WLC_GET_VAR
, WLC_SET_VAR
,
1313 "Set Frequency Tracking Mode (0=Auto, 1=On, 2=OFF)"},
1314 { "eventing", wl_bitvec128
, WLC_GET_VAR
, WLC_SET_VAR
,
1315 "set/get 128-bit hex filter bitmask for MAC event reporting up to application layer"},
1316 { "event_msgs", wl_bitvec128
, WLC_GET_VAR
, WLC_SET_VAR
,
1317 "set/get 128-bit hex filter bitmask for MAC event reporting via packet indications"},
1318 { "counters", wl_counters
, WLC_GET_VAR
, -1,
1319 "Return driver counter values" },
1320 { "delta_stats_interval", wl_varint
, WLC_GET_VAR
, WLC_SET_VAR
,
1321 "set/get the delta statistics interval in seconds (0 to disable)"},
1322 { "delta_stats", wl_delta_stats
, WLC_GET_VAR
, -1,
1323 "get the delta statistics for the last interval" },
1324 { "assoc_info", wl_assoc_info
, WLC_GET_VAR
, -1,
1325 "Returns the assoc req and resp information [STA only]" },
1326 { "autochannel", wl_auto_channel_sel
, WLC_GET_CHANNEL_SEL
, WLC_START_CHANNEL_SEL
,
1327 "auto channel selection: \n"
1328 "\t1 to issue a channel scanning;\n"
1329 "\t2 to set chanspec based on the channel scan result;\n"
1330 "\twithout argument to only show the chanspec selected; \n"
1331 "\tssid must set to null before this process, RF must be up"},
1332 { "csscantimer", wl_int
, WLC_GET_CS_SCAN_TIMER
, WLC_SET_CS_SCAN_TIMER
,
1333 "auto channel scan timer in minutes (0 to disable)" },
1334 { "closed", wl_int
, WLC_GET_CLOSED
, WLC_SET_CLOSED
,
1335 "hides the network from active scans, 0 or 1.\n"
1336 "\t0 is open, 1 is hide" },
1337 { "pmkid_info", wl_pmkid_info
, WLC_GET_VAR
, WLC_SET_VAR
,
1338 "Returns the pmkid table" },
1339 { "abminrate", wl_phy_rate
, WLC_GET_VAR
, WLC_SET_VAR
,
1340 "get/set afterburner minimum rate threshold" },
1341 { "bss", wl_bsscfg_enable
, WLC_GET_VAR
, WLC_SET_VAR
,
1342 "set/get BSS enabled status: up/down"},
1343 { "closednet", wl_bsscfg_int
, WLC_GET_VAR
, WLC_SET_VAR
,
1344 "set/get BSS closed network attribute"},
1345 { "ap_isolate", wl_bsscfg_int
, WLC_GET_VAR
, WLC_SET_VAR
,
1346 "set/get AP isolation"},
1347 { "eap_restrict", wl_bsscfg_int
, WLC_GET_VAR
, WLC_SET_VAR
,
1348 "set/get EAP restriction"},
1349 { "diag", wl_diag
, WLC_GET_VAR
, -1,
1350 "diag testindex(1-interrupt, 2-loopback, 3-memory, 4-led);"
1351 " precede by 'wl down' and follow by 'wl up'" },
1352 { "reset_d11cnts", wl_var_void
, -1, WLC_SET_VAR
,
1353 "reset 802.11 MIB counters"},
1354 { "staname", wl_varstr
, WLC_GET_VAR
, WLC_SET_VAR
,
1355 "get/set station name: \n"
1356 "\tMaximum name length is 15 bytes"},
1357 { "apname", wl_varstr
, WLC_GET_VAR
, -1,
1359 { "otpdump", wl_var_setintandprintstr
, WLC_GET_VAR
, -1,
1361 { "otpstat", wl_var_setintandprintstr
, WLC_GET_VAR
, -1,
1363 { "nrate", wl_nrate
, WLC_GET_VAR
, WLC_SET_VAR
,
1364 "-r legacy rate (CCK, OFDM)"
1366 "-s stf mode (0=SISO,1=CDD,2=STBC(not supported),3=SDM)"
1367 "-w Override mcs only to support STA's with/without STBC capability"},
1368 { "mimo_txbw", wl_varint
, WLC_GET_VAR
, WLC_SET_VAR
,
1369 "get/set mimo txbw (2=20Mhz(lower), 3=20Mhz upper, 4=40Mhz, 5=40Mhz dup<mcs32 only)"},
1370 { "cac_addts", wl_cac
, -1, WLC_SET_VAR
,
1371 "add TSPEC, error if STA is not associated or WME is not enabled\n"
1372 "\targ: TSPEC parameter input list"},
1373 { "cac_delts", wl_cac
, -1, WLC_SET_VAR
,
1374 "delete TSPEC, error if STA is not associated or WME is not enabled\n"
1375 "\targ: TSINFO for the target tspec"},
1376 { "cac_delts_ea", wl_cac_delts_ea
, -1, WLC_SET_VAR
,
1377 "delete TSPEC, error if STA is not associated or WME is not enabled\n"
1378 "\targ1: Desired TSINFO for the target tspec\n"
1379 "\targ2: Desired MAC address"},
1380 { "cac_tslist", wl_tslist
, WLC_GET_VAR
, -1,
1381 "Get the list of TSINFO in driver\n"
1382 "\teg. 'wl cac_tslist' get a list of TSINFO"},
1383 { "cac_tslist_ea", wl_tslist_ea
, WLC_GET_VAR
, -1,
1384 "Get the list of TSINFO for given STA in driver\n"
1385 "\teg. 'wl cac_tslist_ea ea' get a list of TSINFO"},
1386 { "cac_tspec", wl_tspec
, WLC_GET_VAR
, -1,
1387 "Get specific TSPEC with matching TSINFO\n"
1388 "\teg. 'wl cac_tspec 0xaa 0xbb 0xcc' where 0xaa 0xbb & 0xcc are TSINFO octets"},
1389 { "cac_tspec_ea", wl_tspec_ea
, WLC_GET_VAR
, -1,
1390 "Get specific TSPEC for given STA with matching TSINFO\n"
1391 "\teg. 'wl cac_tspec 0xaa 0xbb 0xcc xx:xx:xx:xx:xx:xx'\n"
1392 "\t where 0xaa 0xbb & 0xcc are TSINFO octets and xx is mac address"},
1395 { "phy_txpwrindex", wl_phy_txpwrindex
, WLC_GET_VAR
, WLC_SET_VAR
,
1396 "usage: (set) phy_txpwrindex core0_idx core1_idx core2_idx core3_idx"
1397 " (get) phy_txpwrindex, return format: core0_idx core1_idx core2_idx core3_idx"
1398 "Set/Get txpwrindex"
1400 { "phy_test_tssi", wl_test_tssi
, WLC_GET_VAR
, -1,
1401 "wl phy_test_tssi val"},
1402 { "phy_test_tssi_offs", wl_test_tssi_offs
, WLC_GET_VAR
, -1,
1403 "wl phy_test_tssi_offs val"},
1404 { "phy_rssiant", wl_phy_rssiant
, WLC_GET_VAR
, -1,
1405 "wl phy_rssiant antindex(0-3)"},
1406 { "phy_rssi_ant", wl_phy_rssi_ant
, WLC_GET_VAR
, WLC_SET_VAR
,
1407 "Get RSSI per antenna (only gives RSSI of current antenna for SISO PHY)"},
1408 { "lpphy_papdepstbl", wl_lpphy_papdepstbl
, -1, WLC_GET_VAR
,
1409 "print papd eps table; Usage: wl lpphy_papdepstbl"
1411 { "rifs", wl_rifs
, WLC_GET_VAR
, WLC_SET_VAR
,
1412 "set/get the rifs status; usage: wl rifs <1/0> (On/Off)"
1414 { "rifs_advert", wl_rifs_advert
, WLC_GET_VAR
, WLC_SET_VAR
,
1415 "set/get the rifs mode advertisement status; usage: wl rifs_advert <-1/0> (Auto/Off)"
1417 { "phy_rxiqest", wl_rxiq
, WLC_GET_VAR
, -1,
1418 "Get phy RX IQ noise in dBm:\n"
1419 "\t-s # of samples (2^n)\n"
1420 "\t-a antenna select, 0,1 or 3\n"
1421 "\t-r resolution select, 0 (coarse) or 1 (fine)\n"
1422 "\t-f lpf hpc override select, 0 (hpc unchanged) or 1 (overridden to lowest value)\n"
1423 "\t-g gain-correction select, 0 (disable) or 1 (enable)"
1425 { "phy_txiqcc", wl_phy_txiqcc
, WLC_GET_VAR
, WLC_SET_VAR
,
1426 "usage: phy_txiqcc [a b]\n"
1427 "Set/get the iqcc a, b values"
1429 { "phy_txlocc", wl_phy_txlocc
, WLC_GET_VAR
, WLC_SET_VAR
,
1430 "usage: phy_txlocc [di dq ei eq fi fq]\n"
1431 "Set/get locc di dq ei eq fi fq values"
1433 { "phytable", wl_phytable
, WLC_GET_VAR
, WLC_SET_VAR
,
1434 "usage: wl phytable table_id offset width_of_table_element [table_element]\n"
1435 "Set/get table element of a table with the given ID at the given offset\n"
1436 "Note that table width supplied should be 8 or 16 or 32\n"
1437 "table ID, table offset can not be negative"
1439 { "pavars", wl_phy_pavars
, WLC_GET_VAR
, WLC_SET_VAR
,
1440 "Set/get temp PA parameters\n"
1442 " wl pavars pa2gw0a0=0x1 pa2gw1a0=0x2 pa2gw2a0=0x3 ... \n"
1445 " override the PA parameters after driver attach(srom read), before diver up\n"
1446 " These override values will be propogated to HW when driver goes up\n"
1447 " PA parameters in one band range (2g, 5gl, 5g, 5gh) must all present if\n"
1448 " one of them is specified in the command, otherwise it will be filled with 0"
1450 { "pavars2", wl_phy_pavars2
, WLC_GET_VAR
, WLC_SET_VAR
,
1451 "Set/get temp PA parameters. Extended cmd of pavars\n"
1453 " wl pavars2 pa2gw0a0=0x1 pa2gw1a0=0x2 pa2gw2a0=0x3 ... \n"
1456 " override the PA parameters after driver attach(srom read), before diver up\n"
1457 " These override values will be propogated to HW when driver goes up\n"
1458 " PA parameters in one band range (2g, 5gl, 5g, 5gh) must all present if\n"
1459 " one of them is specified in the command, otherwise it will be filled with 0"
1461 { "povars", wl_phy_povars
, WLC_GET_VAR
, WLC_SET_VAR
,
1462 "Set/get temp power offset\n"
1464 " wl povars cck2gpo=0x1 ofdm2gpo=0x2 mcs2gpo=0x3 ... \n"
1467 " override the power offset after driver attach(srom read), before diver up\n"
1468 " These override values will be propogated to HW when driver goes up\n"
1469 " power offsets in one band range (2g, 5gl, 5g, 5gh) must all present if\n"
1470 " one of them is specified in the command, otherwise it will be filled with 0"
1471 " cck(2g only), ofdm, and mcs(0-7) for NPHY are supported "
1473 { "fem", wl_phy_fem
, WLC_GET_VAR
, WLC_SET_VAR
,
1474 "Set temp fem2g/5g value\n"
1475 "usage: wl fem (tssipos2g=0x1 extpagain2g=0x2 pdetrange2g=0x1 triso2g=0x1 antswctl2g=0)\n"
1476 " (tssipos5g=0x1 extpagain5g=0x2 pdetrange5g=0x1 triso5g=0x1 antswctl5g=0)"
1478 { "antgain", wl_antgain
, WLC_GET_VAR
, WLC_SET_VAR
,
1479 "Set temp ag0/1 value\n"
1480 "usage: wl antgain ag0=0x1 ag1=0x2"
1482 { "maxpower", wl_phy_maxpower
, WLC_GET_VAR
, WLC_SET_VAR
,
1483 "Set temp maxp2g(5g)a0(a1) value\n"
1484 "usage: wl maxpower maxp2ga0=0x1 maxp2ga1=0x2 maxp5ga0=0xff maxp5ga1=0xff\n"
1485 " maxp5gla0=0x3 maxp5gla1=0x4 maxp5gha0=0x5 maxp5gha1=0x6"
1488 { "phy_antsel", wl_antsel
, WLC_GET_VAR
, -1,
1489 "get/set antenna configuration \n"
1490 "\tset: -1(AUTO), 0xAB(fixed antenna selection)\n"
1491 "\t\twhere A and B is the antenna numbers used for RF chain 1 and 0 respectively\n"
1492 "\tquery: <utx>[AUTO] <urx>[AUTO] <dtx>[AUTO] <drx>[AUTO]\n"
1493 "\t\twhere utx = TX unicast antenna configuration\n"
1494 "\t\t\turx = RX unicast antenna configuration\n"
1495 "\t\t\tdtx = TX default (non-unicast) antenna configuration\n"
1496 "\t\t\tdrx = RX default (non-unicast) antenna configuration\n"
1498 { "txcore", wl_txcore
, WLC_GET_VAR
, WLC_SET_VAR
,
1499 "Usage: wl txcore -k <CCK core mask> -o <OFDM core mask> -s <1..4> -c <core bitmap>\n"
1500 "\t-k CCK core mask\n"
1501 "\t-o OFDM core mask\n"
1502 "\t-s # of space-time-streams\n"
1503 "\t-c active core (bitmask) to be used when transmitting frames\n"
1505 { "txcore_override", wl_txcore
, WLC_GET_VAR
, -1,
1506 "Usage: wl txcore_override\n"
1507 "\tget the user override of txcore\n"
1509 { "txchain_pwr_offset", wl_txcore_pwr_offset
, WLC_GET_VAR
, WLC_SET_VAR
,
1510 "Usage: wl txchain_pwr_offset [qdBm offsets]\n"
1511 "\tGet/Set the current offsets for each core in qdBm (quarter dBm)\n"
1513 { "sample_collect", wl_sample_collect
, WLC_PHY_SAMPLE_COLLECT
, -1,
1514 "Optional parameters HTPHY/(NPHY with NREV >= 7) are:\n"
1515 "\t-f File name to dump the sample buffer (default \"sample_collect.dat\")\n"
1516 "\t-t Trigger condition (default now)\n"
1517 "\t\t now, good_fcs, bad_fcs, bad_plcp, crs, crs_glitch, crs_deassert\n"
1518 "\t-b PreTrigger duration in us (default 10)\n"
1519 "\t-a PostTrigger duration in us (default 10) \n"
1520 "\t-m Sample collect mode (default 1) \n"
1521 "\t\t HTPHY: 0=adc, 1..3=adc+rssi, 4=gpio\n"
1522 "\t\t NPHY: 1=Dual-Core adc[9:2], 2=Core0 adc[9:0], 3=Core1 adc[9:0], gpio=gpio\n"
1523 "\t-g GPIO mux select (default 0)\n"
1524 "\t\t use only for gpio mode\n"
1525 "\t-d Downsample enable (default 0)\n"
1526 "\t\t use only for HTPHY\n"
1527 "\t-e BeDeaf enable (default 0)\n"
1528 "\t-i Timeout in units of 10us (default 1000)\n"
1529 "Optional parameters (NPHY with NREV < 7) are:\n"
1530 "\t-f File name to dump the sample buffer (binary format, default \"sample_collect.dat\")\n"
1531 "\t-u Sample collect duration in us (default 60)\n"
1532 "\t-c Cores to do sample collect, only if BW=40MHz (default both)\n"
1533 "For (NREV < 7), the NPHY buffer returned has the format:\n"
1534 "\tIn 20MHz [(uint16)num_bytes, <I(core0), Q(core0), I(core1), Q(core1)>]\n"
1535 "\tIn 40MHz [(uint16)num_bytes(core0), <I(core0), Q(core0)>,\n"
1536 "\t\t(uint16)num_bytes(core1), <I(core1), Q(core1)>]"},
1537 { "txfifo_sz", wl_txfifo_sz
, WLC_GET_VAR
, WLC_SET_VAR
,
1538 "set/get the txfifo size; usage: wl txfifo_sz <fifonum> <size_in_bytes>" },
1540 { "pfnset", wl_pfn_set
, -1, -1,
1541 "Configures preferred network off load parameter\n"
1542 "\tpfnset syntax is: pfnset [scanfrq xxxxx(30 sec)] [netimeout xxxx(60 sec)]"
1543 "[rssi_delta xxxx(30 dBm)] [sort (listorder)|rssi] [bkgscan (0)|1] [autoswitch (0)|1]"
1544 "[immediate 0|(1)] [autoconnect (0)|1]"},
1545 { "pfnadd", wl_pfn_add
, -1, -1,
1546 "Adding preferred network to monitor and connect\n"
1547 "\tpfnadd syntax is: pfnadd <SSID> [key xxxxx] [imode (bss)|ibss]"
1548 "[amode (open)|shared] [wpa_auth (wpadisabled)|wpapsk|wpa2psk|wpanone]"
1549 "[wsec WEP|TKIP|AES|TKIPAES]"},
1550 { "pfn", wl_pfn
, -1, -1,
1551 "Enable/disable preferred network off load monitoring\n"
1552 "\tpfn syntax is: pfn 0|1"},
1553 { "pfnclear", wl_var_void
, -1, WLC_SET_VAR
,
1554 "Clear the preferred network list\n"
1555 "\tpfn syntax is: pfnclear"},
1557 { "pfneventchk", wl_pfn_event_check
, -1, -1,
1558 "Listen and prints the preferred network off load event from dongle\n"
1559 "\tpfneventchk syntax is: pfneventchk [(eth1)ifname]"},
1560 { "escan_event_check", wl_escan_event_check
, -1, -1,
1561 "Listen and prints the escan events from the dongle\n"
1562 "\tescan_event_check syntax is: escan_event_check ifname flag\n"
1563 "\tflag 1 = sync_id info, 2 = bss info, 4 = state + bss info [default], "
1564 "8 = TLV check for IEs"},
1565 { "escanresults", wl_escanresults
, -1, WLC_SET_VAR
,
1566 "Start escan and display results.\n" SCAN_USAGE
1569 { "event_filter", wl_event_filter
, -1, -1,
1570 "Set/get event filter\n"
1571 "\tevent_filter syntax is: event_filter [value]"},
1573 {"rate_histo", wl_rate_histo
, -1, WLC_GET_VAR
,
1574 "Get rate hostrogram"
1576 { "pkteng_start", wl_pkteng
, -1, WLC_SET_VAR
,
1577 "start packet engine tx usage: wl pkteng_start <xx:xx:xx:xx:xx:xx>"
1578 " <tx|txwithack> [(async)|sync] [ipg] [len] [nframes] [src]\n"
1579 "\tstart packet engine rx usage: wl pkteng_start <xx:xx:xx:xx:xx:xx>"
1580 " <rx|rxwithack> [(async)|sync] [rxframes] [rxtimeout]\n"
1581 "\tsync: synchronous mode\n"
1582 "\tipg: inter packet gap in us\n"
1583 "\tlen: packet length\n"
1584 "\tnframes: number of frames; 0 indicates continuous tx test\n"
1585 "\tsrc: source mac address\n"
1586 "\trxframes: number of receive frames (sync mode only)\n"
1587 "\trxtimeout: maximum timout in msec (sync mode only)"},
1588 { "pkteng_stop", wl_pkteng
, -1, WLC_SET_VAR
,
1589 "stop packet engine; usage: wl pkteng_stop <tx|rx>"},
1590 { "pkteng_stats", wl_pkteng_stats
, -1, WLC_GET_VAR
,
1591 "packet engine stats; usage: wl pkteng_stats"},
1592 { "wowl", wl_varint
, WLC_GET_VAR
, WLC_SET_VAR
,
1593 "Enable/disable WOWL events\n"
1594 " 0 - Clear all events\n"
1595 "Bit 0 - Wakeup on Magic Packet\n"
1596 "Bit 1 - Wakeup on NetPattern (use 'wl wowl_pattern' to configure pattern)\n"
1597 "Bit 2 - Wakeup on loss-of-link due to Disassociation/Deauth\n"
1598 "Bit 3 - Wakeup on retrograde tsf\n"
1599 "Bit 4 - Wakeup on loss of beacon (use 'wl wowl_bcn_loss' to configure time)"},
1600 { "wowl_bcn_loss", wl_varint
, WLC_GET_VAR
, WLC_SET_VAR
,
1601 "Set #of seconds of beacon loss for wakeup event"},
1602 { "wowl_pattern", wl_wowl_pattern
, -1, -1,
1603 "usage: wowl_pattern [ [clr | [[ add | del ] offset mask value ]]]\n"
1604 "No options -- lists existing pattern list\n"
1605 "add -- Adds the pattern to the list\n"
1606 "del -- Removes a pattern from the list\n"
1607 "clr -- Clear current list\n"
1608 "offset -- Starting offset for the pattern\n"
1609 "mask -- Mask to be used for pattern. Bit i of mask => byte i of the pattern\n"
1610 "value -- Value of the pattern"
1612 { "wowl_wakeind", wl_wowl_wakeind
, WLC_GET_VAR
, WLC_SET_VAR
,
1613 "usage: wowl_wakeind [clear]\n"
1614 "Shows last system wakeup event indications from PCI and D11 cores\n"
1615 "clear - Clear the indications"
1617 { "wowl_status", wl_wowl_status
, WLC_GET_VAR
, -1,
1618 "usage: wowl_status [clear]\n"
1619 "Shows last system wakeup setting"
1621 {"wowl_pkt", wl_wowl_pkt
, -1, -1,
1622 "Send a wakeup frame to wakup a sleeping STA in WAKE mode\n"
1623 "Usage: wl wowl_pkt <len> <dst ea | bcast | ucast <STA ea>>"
1624 "[ magic [<STA ea>] | net <offset> <pattern>]\n"
1625 "e.g. To send bcast magic frame -- "
1626 "wl wowl_pkt 102 bcast magic 00:90:4c:AA:BB:CC\n"
1627 " To send ucast magic frame -- "
1628 "wl wowl_pkt 102 ucast 00:90:4c:aa:bb:cc magic\n"
1629 " To send a frame with L2 unicast - "
1630 "wl wowl_pkt 102 00:90:4c:aa:bb:cc net 0 0x00904caabbcc\n"
1631 " NOTE: offset for netpattern frame starts from \"Dest EA\" of ethernet frame."
1632 "So dest ea will be used only when offset is >= 6"},
1633 { "wme_apsd_trigger", wl_varint
, WLC_GET_VAR
, WLC_SET_VAR
,
1634 "Set Periodic APSD Trigger Frame Timer timeout in ms (0=off)"},
1635 { "wme_autotrigger", wl_varint
, WLC_GET_VAR
, WLC_SET_VAR
,
1636 "Enable/Disable sending of APSD Trigger frame when all ac are delivery enabled"},
1637 { "reassoc", wl_reassoc
, -1, WLC_REASSOC
,
1638 "Initiate a (re)association request.\n"
1639 "\tUsage: wl reassoc <bssid> [options]\n"
1641 "\t-c CL, --chanspecs=CL \tchanspecs (comma or space separated list)"},
1642 { "send_nulldata", wl_iov_mac
, -1, -1,
1643 "Sed a null frame to the specified hw address" },
1644 { "btc_params", wlu_reg2args
, WLC_GET_VAR
, WLC_SET_VAR
, "g/set BT Coex parameters"},
1645 { "btc_flags", wlu_reg2args
, WLC_GET_VAR
, WLC_SET_VAR
, "g/set BT Coex flags"},
1646 { "obss_scan_params", wl_obss_scan
, WLC_GET_VAR
, WLC_SET_VAR
,
1647 "set/get Overlapping BSS scan parameters\n"
1648 "Usage: wl obss_scan a b c d e ...; where\n"
1649 "\ta-Passive Dwell, {5-1000TU}, default = 100\n"
1650 "\tb-Active Dwell, {10-1000TU}, default = 20\n"
1651 "\tc-Width Trigger Scan Interval, {10-900sec}, default = 300\n"
1652 "\td-Passive Total per Channel, {200-10000TU}, default = 200\n"
1653 "\te-Active Total per Channel, {20-1000TU}, default = 20\n"
1654 "\tf-Channel Transition Delay Factor, {5-100}, default = 5\n"
1655 "\tg-Activity Threshold, {0-100%}, default = 25"},
1656 {"keep_alive", wl_keep_alive
, -1, -1,
1657 "Send specified \"keep-alive\" packet periodically.\n"
1658 "\tUsage: wl keep_alive <period> <packet>\n"
1659 "\t\tperiod: Re-transmission period in milli-seconds. 0 to disable packet transmits.\n"
1660 "\t\tpacket: Hex packet contents to transmit. The packet contents should include "
1661 "the entire ethernet packet (ethernet header, IP header, UDP header, and UDP "
1662 "payload) specified in network byte order.\n"
1663 "\n\te.g. Send keep alive packet every 30 seconds:\n"
1664 "\twl keep_alive 30000 0x0014a54b164f000f66f45b7e08004500001e000040004011c"
1665 "52a0a8830700a88302513c413c4000a00000a0d" },
1666 { "srchmem", wl_srchmem
, WLC_GET_VAR
, WLC_SET_VAR
,
1667 "g/set ucode srch engine memory"},
1668 { "pkt_filter_add", wl_pkt_filter_add
, -1, -1,
1669 "Install a packet filter.\n"
1670 "\tUsage: wl pkt_filter_add <id> <polarity> <type> <offset> <bitmask> <pattern>\n"
1671 "\tid: Integer. User specified id.\n"
1672 "\ttype: 0 (Pattern matching filter).\n"
1673 "\toffset: Integer. Offset within received packets to start matching.\n"
1674 "\tpolarity: Set to 1 to negate match result. 0 is default.\n"
1675 "\tbitmask: Hex bitmask that indicates which bits of 'pattern' to match. Must be same\n"
1676 "\t\tsize as 'pattern'. Bit 0 of bitmask corresponds to bit 0 of pattern, etc.\n"
1677 "\t\tIf bit N of bitmask is 0, then do *not* match bit N of the pattern with\n"
1678 "\t\tthe received payload. If bit N of bitmask is 1, then perform match.\n"
1679 "\tpattern: Hex pattern to match." },
1680 { "pkt_filter_clear_stats", wl_varint
, -1, WLC_SET_VAR
,
1681 "Clear packet filter statistic counter values.\n"
1682 "\tUsage: wl pkt_filter_clear_stats <id>" },
1683 { "pkt_filter_enable", wl_pkt_filter_enable
, -1, -1,
1684 "Enable/disable a packet filter.\n"
1685 "\tUsage: wl pkt_filter_enable <id> <0|1>"},
1686 { "pkt_filter_list", wl_pkt_filter_list
, -1, -1,
1687 "List installed packet filters.\n"
1688 "\tUsage: wl pkt_filter_list [val]\n"
1689 "\tval: 0 (disabled filters) 1 (enabled filters)"},
1690 { "pkt_filter_mode", wl_varint
, WLC_GET_VAR
, WLC_SET_VAR
,
1691 "Set packet filter match action.\n"
1692 "\tUsage: wl pkt_filter_mode <value>\n"
1693 "\tvalue: 1 - Forward packet on match, discard on non-match (default).\n"
1694 "\t 0 - Discard packet on match, forward on non-match." },
1695 { "pkt_filter_delete", wl_varint
, -1, WLC_SET_VAR
,
1696 "Uninstall a packet filter.\n"
1697 "\tUsage: wl pkt_filter_delete <id>"},
1698 { "pkt_filter_stats", wl_pkt_filter_stats
, -1, -1,
1699 "Retrieve packet filter statistic counter values.\n"
1700 "\tUsage: wl pkt_filter_stats <id>"},
1701 { "seq_start", wl_seq_start
, -1, WLC_SET_VAR
,
1702 "Initiates command batching sequence. Subsequent IOCTLs will be queued until\n"
1703 "seq_stop is received."},
1704 { "seq_stop", wl_seq_stop
, -1, WLC_SET_VAR
,
1705 "Defines the end of command batching sequence. Queued IOCTLs will be executed."},
1706 { "seq_delay", wl_varint
, -1, WLC_SET_VAR
,
1707 "Driver should spin for the indicated amount of time.\n"
1708 "It is only valid within the context of batched commands."},
1709 { "seq_error_index", wl_varint
, WLC_GET_VAR
, -1,
1710 "Used to retrieve the index (starting at 1) of the command that failed within a batch"},
1711 { "bmac_reboot", wl_var_void
, -1, WLC_SET_VAR
,
1714 { "findserver", wl_wifiserver
, -1, -1,
1715 "Used to find the remote server with proper mac address given by the user,this "
1716 "cmd is specific to wifi protocol."},
1718 { "txmcsset", wl_txmcsset
, WLC_GET_VAR
, -1, "get Transmit MCS rateset for 11N device"},
1719 { "rxmcsset", wl_rxmcsset
, WLC_GET_VAR
, -1, "get Receive MCS rateset for 11N device"},
1720 { "mimo_ss_stf", wl_mimo_stf
, WLC_GET_VAR
, WLC_SET_VAR
,
1721 "get/set SS STF mode.\n"
1722 "\tUsage: wl mimo_ss_stf <value> <-b a | b>\n"
1723 "\tvalue: 0 - SISO; 1 - CDD\n"
1724 "\t-b(band): a - 5G; b - 2.4G"},
1726 { "extlog", wl_extlog
, WLC_GET_VAR
, -1,
1727 "get external logs\n"
1728 "\tUsage: wl extlog <from_last> <number>\n"
1729 "\from_last: 1 - from the last log record; 0 - whole log recrods"
1730 "\tnumber: number of log records to get, MAX is 32."},
1731 { "extlog_clr", wl_var_void
, -1, WLC_SET_VAR
, "clear external log records"},
1732 { "extlog_cfg", wl_extlog_cfg
, WLC_GET_VAR
, WLC_SET_VAR
,
1733 "get/set external log configuration"},
1735 { "assertlog", wl_assertlog
, WLC_GET_VAR
, -1,
1736 "get external assert logs\n"
1737 "\tUsage: wl assertlog"},
1738 { "assert_type", wl_varint
, WLC_GET_VAR
, WLC_SET_VAR
,
1739 "set/get the asset_bypass flag; usage: wl assert_type <1/0> (On/Off)"
1741 { "ledbh", wl_ledbh
, WLC_GET_VAR
, WLC_SET_VAR
,
1742 "set/get led behavior\n"
1743 "\tUsage: wl ledbh [0-3] [0-15]"},
1744 { "obss_coex_action", wl_obss_coex_action
, -1, WLC_SET_VAR
,
1745 "send OBSS 20/40 Coexistence Mangement Action Frame\n"
1746 "\tUsage: wl obss_coex_action -i <1/0> -w <1/0> -c <channel list>\n"
1747 "\t -i: 40MHz intolerate bit; -w: 20MHz width Req bit;\n"
1748 "\t -c: channel list, 1 - 14\n"
1749 "\t At least one option must be provided"
1751 {"chanim_state", wl_chanim_state
, WLC_GET_VAR
, -1,
1752 "get channel interference state\n"
1753 "\tUsage: wl chanim_state channel\n"
1754 "\tValid channels: 1 - 14\n"
1755 "\treturns: 0 - Acceptable; 1 - Severe"
1757 {"chanim_mode", wl_chanim_mode
, WLC_GET_VAR
, WLC_SET_VAR
,
1758 "get/set channel interference measure (chanim) mode\n"
1759 "\tUsage: wl chanim_mode <value>\n"
1760 "\tvalue: 0 - disabled; 1 - detection only; 2 - detection and avoidance"
1762 { "ledbh", wl_ledbh
, WLC_GET_VAR
, WLC_SET_VAR
, "set/get led behavior\n"
1763 "\tUsage: wl ledbh [0-3] [0-15]"},
1764 { "led_blink_sync", wl_led_blink_sync
, WLC_GET_VAR
, WLC_SET_VAR
, "set/get led_blink_sync\n"
1765 "\tUsage: wl led_blink_sync [0-3] [0/1]"},
1767 {"cca_get_stats", wl_cca_get_stats
, WLC_GET_VAR
, -1,
1768 "Usage: wl cca_stats [-c channel] [-s num seconds][-a]\n"
1769 "\t -c channel: Optional. specify channel. 0 = All channels. Default = current channel \n"
1770 "\t -s num_seconds: Optional. Default = 10, Max = 60\n"
1771 "\t -i: list individual measurements in addition to the averages\n"
1772 "\t -curband: Only recommend channels on current band"
1774 { "itfr_get_stats", wl_itfr_get_stats
, WLC_GET_VAR
, -1,
1775 "get interference source information"
1777 { "itfr_enab", wl_varint
, WLC_GET_VAR
, WLC_SET_VAR
,
1778 "get/set STA interference detection mode(STA only)\n"
1780 "\t 1 - enable maual detection\n"
1781 "\t 2 - enable auto detection"
1783 { "itfr_detect", wl_var_void
, -1, WLC_SET_VAR
,
1784 "issue an interference detection request"
1786 { "smfstats", wl_smfstats
, WLC_GET_VAR
, WLC_SET_VAR
,
1787 "get/clear selected management frame (smf) stats"
1788 "\twl smfstats [-C num]|[--cfg=num] [auth]|[assoc]|[reassoc]|[clear]\n"
1789 "\tclear - to clear the stats" },
1791 { "dongleset", wl_varint
, WLC_GET_VAR
, WLC_SET_VAR
,
1792 "Enable uart driver"
1795 { "manfinfo", wl_var_getandprintstr
, WLC_GET_VAR
, -1,
1796 "show chip package info in OTP"},
1797 { "rrm_nbr_req", wl_rrm_nbr_req
, -1, WLC_SET_VAR
,
1798 "send 11k neighbor report measurement request\n"
1799 "\tUsage: wl rrm_nbr_req [ssid]"},
1800 { "wnm_bsstq", wl_wnm_bsstq
, -1, WLC_SET_VAR
,
1801 "send 11v BSS transition management query\n"
1802 "\tUsage: wl wnm_bsstq [ssid]"},
1804 { "p2p_ssid", wl_ssid
, -1, WLC_SET_VAR
,
1805 "set WiFi P2P wildcard ssid.\n"
1806 "\tUsage: wl p2p_ssid <ssid>"
1808 { "p2p_state", wl_p2p_state
, -1, WLC_SET_VAR
,
1809 "set WiFi P2P discovery state.\n"
1810 "\tUsage: wl p2p_state <state> [<chanspec> <dwell time>]"
1812 { "p2p_scan", wl_p2p_scan
, -1, WLC_SET_VAR
,
1813 "initiate WiFi P2P scan.\n"
1814 "\tUsage: wl p2p_scan S|E <scan parms>\n"
1817 { "p2p_ifadd", wl_p2p_ifadd
, -1, WLC_SET_VAR
,
1818 "add WiFi P2P interface\n"
1819 "\tUsage: wl p2p_ifadd <MAC-address> go|client|dyngo [chanspec]\n"
1820 "MAC-address: xx:xx:xx:xx:xx:xx"
1822 { "p2p_ifdel", wl_p2p_ifdel
, -1, WLC_SET_VAR
,
1823 "delete WiFi P2P interface\n"
1824 "\tUsage: wl p2p_ifdel <MAC-address>\n"
1825 "MAC-address: xx:xx:xx:xx:xx:xx"
1827 { "p2p_ifupd", wl_p2p_ifupd
, -1, WLC_SET_VAR
,
1828 "update an interface to WiFi P2P interface\n"
1829 "\tUsage: wl p2p_ifupd <MAC-address> go|client\n"
1830 "MAC-address: xx:xx:xx:xx:xx:xx"
1832 { "p2p_if", wl_p2p_if
, WLC_GET_VAR
, -1,
1833 "query WiFi P2P interface bsscfg index\n"
1834 "\tUsage: wl p2p_if <MAC-address>\n"
1835 "MAC-address: xx:xx:xx:xx:xx:xx"
1837 { "p2p_noa", wl_p2p_noa
, WLC_GET_VAR
, WLC_SET_VAR
,
1838 "set/get WiFi P2P NoA schedule\n"
1839 "\tUsage: wl p2p_noa <type> <type-specific-params>\n"
1840 "\t\ttype 0: Scheduled Absence (on GO): <type> <action> <action-specific-params>\n"
1841 "\t\t\taction -1: Cancel the schedule: <type> <action>\n"
1842 "\t\t\taction 0,1,2: <type> <action> <option> <option-specific-params>\n"
1843 "\t\t\t\taction 0: Do nothing during absence periods\n"
1844 "\t\t\t\taction 1: Sleep during absence periods\n"
1845 "\t\t\t\toption 0: <start:tsf> <interval> <duration> <count> ...\n"
1846 "\t\t\t\toption 1 [<start-percentage>] <duration-percentage>\n"
1847 "\t\t\t\toption 2 <start:tsf-offset> <interval> <duration> <count>\n"
1848 "\t\ttype 1: Requested Absence (on GO): "
1849 "\t\t\taction -1: Cancel the schedule: <type> <action>\n"
1850 "\t\t\taction 2: <type> <action> <option> <option-specific-params>\n"
1851 "\t\t\t\taction 2: Turn off GO beacons and probe responses during absence period\n"
1852 "\t\t\t\toption 2 <start:tsf-offset> <interval> <duration> <count>\n"
1854 { "p2p_ops", wl_p2p_ops
, WLC_GET_VAR
, WLC_SET_VAR
,
1855 "set/get WiFi P2P OppPS and CTWindow\n"
1856 "\tUsage: wl p2p_ops <ops> [<ctw>]\n"
1858 "\t\t\t0: Disable OppPS\n"
1859 "\t\t\t1: Enable OppPS\n"
1861 "\t\t\t10 and up to beacon interval\n"
1863 { "p2p_da_override", wl_iov_mac
, WLC_GET_VAR
, WLC_SET_VAR
,
1864 "Get/Set WiFi P2P device interface addr\n"
1865 "\tUsage: wl p2p_da_override <MAC-address>\n"
1866 "MAC-address: xx:xx:xx:xx:xx:xx\n"
1867 "(When MAC-address is set to 00:00:00:00:00:00, default da restored)"
1870 { "pm_dur", wl_varint
, WLC_GET_VAR
, WLC_SET_VAR
,
1871 "Retrieve accumulated PM duration information (GET) or clear accumulator (SET)\n"
1872 "\tUsage: wl pm_dur <any-number-to-clear>"
1874 { "mpc_dur", wl_varint
, WLC_GET_VAR
, WLC_SET_VAR
,
1875 "Retrieve accumulated MPC duration information in ms (GET) or clear accumulator (SET)\n"
1876 "\tUsage: wl mpc_dur <any-number-to-clear>"},
1877 {"chanim_acs_record", wl_chanim_acs_record
, WLC_GET_VAR
, -1,
1878 "get the auto channel scan record. \n"
1879 "\t Usage: wl acs_record"
1881 { "dngl_wd", wl_dngl_wd
, WLC_GET_VAR
, WLC_SET_VAR
,
1882 "enable or disable dongle watchdog timer\n"
1883 "\tUsage: wl dngl_wd <on/off>(to turn on\\off) <exptime in sec>"},
1884 { "tsf", wl_tsf
, WLC_GET_VAR
, WLC_SET_VAR
,
1885 "set/get tsf register\n"
1886 "\tUsage: wl tsf [<high> <low>]"},
1887 { "tpc_mode", wl_varint
, WLC_GET_VAR
, WLC_SET_VAR
,
1888 "Enable/disable AP TPC.\n"
1889 "Usage: wl tpc_mode <mode> \n"
1890 "\t0 - disable, 1 - BSS power control, 2 - AP power control, 3 - Both (1) and (2)\n"},
1891 { "tpc_period", wl_varint
, WLC_GET_VAR
, WLC_SET_VAR
,
1892 "Set AP TPC periodicity in secs.\n"
1893 "Usage: wl tpc_period <secs> \n"},
1894 { "tpc_lm", wl_tpc_lm
, WLC_GET_VAR
, -1,
1895 "Get current link margins.\n"},
1896 { "mfp_config", wl_mfp_config
, -1, WLC_SET_VAR
,
1897 "Config PMF capability\n"
1898 "\tusage: wl mfp 0/disable, 1/capable, 2/requred" },
1899 { "mfp_sha256", wl_mfp_sha256
, -1, WLC_SET_VAR
,
1900 "Config SHA256 capability\n"
1901 "\tusage: wl sha256 0/disable, 1/enable" },
1902 { "mfp_sa_query", wl_mfp_sa_query
, -1, WLC_SET_VAR
,
1903 "Send a sa query req/resp to a peer\n"
1904 "\tusage: wl mfp_sa_query flag action id" },
1905 { "mfp_disassoc", wl_mfp_disassoc
, WLC_GET_VAR
, WLC_SET_VAR
,
1906 "send bogus disassoc\n"
1907 "Usage: wl mfp_disassoc\n"},
1908 { "mfp_deauth", wl_mfp_deauth
, WLC_GET_VAR
, WLC_SET_VAR
,
1909 "send bogus deauth\n"
1910 "\tUsage: wl mfp_dedauth\n"},
1911 { "mfp_assoc", wl_mfp_assoc
, WLC_GET_VAR
, WLC_SET_VAR
,
1913 "Usage: wl mfp_assoc\n"},
1914 { "mfp_auth", wl_mfp_auth
, WLC_GET_VAR
, WLC_SET_VAR
,
1916 "\tUsage: wl mfp_auth\n"},
1917 { "mfp_reassoc", wl_mfp_reassoc
, WLC_GET_VAR
, WLC_SET_VAR
,
1919 "Usage: wl mfp_reassoc\n"},
1920 { "monitor_lq", wl_monitor_lq
, WLC_GET_VAR
, WLC_SET_VAR
,
1921 "Start/Stop monitoring link quality metrics - RSSI and SNR\n"
1922 "\tUsage: wl monitor_lq <0: turn off / 1: turn on\n"},
1923 { "monitor_lq_status", wl_dump_lq
, WLC_GET_VAR
, -1 /* Set not reqd */,
1924 "Returns averaged link quality metrics - RSSI and SNR values"},
1925 {"scb_probe", wl_scb_probe
, WLC_GET_VAR
, WLC_SET_VAR
,
1926 "Set probing parameters for inactive clients.\n"
1927 "\t<timout in seconds> <activity_time in seconds> <max number of probes>"},
1928 { "rpmt", wl_rpmt
, -1, WLC_SET_VAR
, "rpmt <pm1-to> <pm0-to>\n"},
1929 { "spatial_policy", wl_spatial_policy
, WLC_GET_VAR
, WLC_SET_VAR
,
1930 "set/get spatial_policy\n"
1931 "\tUsage: wl spatial_policy <-1: auto / 0: turn off / 1: turn on>\n"
1932 "\t to control individual band/sub-band use\n"
1933 "\t wl spatial_policy a b c d e\n"
1934 "\t where a is 2.4G band setting\n"
1935 "\t where b is 5G lower band setting\n"
1936 "\t where c is 5G middle band setting\n"
1937 "\t where d is 5G high band setting\n"
1938 "\t where e is 5G upper band setting\n"},
1939 { "ratetbl_ppr", wl_ratetbl_ppr
, WLC_GET_VAR
, WLC_SET_VAR
,
1940 "Usage: For get: wl ratetbl_ppr\n"
1941 "\t For set: wl ratetbl_ppr <rate> <ppr>\n" },
1942 { "ie", wl_ie
, WLC_GET_VAR
, WLC_SET_VAR
,
1944 "Usage for set: wl ie type length hexdata\n"
1945 "Example: wl ie 107 9 02020800904c09215c\n"
1946 " to set IW IE with length 9\n"
1947 "Usage for get: wl ie type\n"
1948 "Example: wl ie 107\n"
1949 " to get current IW IE" },
1950 { NULL
, NULL
, 0, 0, NULL
}
1953 cmd_t wl_varcmd
= {"var", wl_varint
, -1, -1, "unrecognized name, type -h for help"};
1954 const char *wlu_av0
;
1957 /* Include any commands for wc tool used for WMM
1958 * These need to be only the command names from port_cmds and wl_cmds array
1960 static const char *wc_cmds
[] = {
1961 "ver", "cmds", "up", "down",
1962 "gmode", "listen", "wme", "wme_ac", "wme_apsd",
1963 "wme_apsd_sta", "wme_dp"
1966 static const char **wc_cmds
= NULL
;
1967 #endif /* WC_TOOL */
1969 /* initialize stuff needed before processing the command */
1973 int_fmt
= INT_FMT_DEC
;
1980 /* Init global variables at run-time, not as part of the declaration.
1981 * This is required to support init/de-init of the driver. Initialization
1982 * of globals as part of the declaration results in non-deterministic
1983 * behaviour since the value of the globals may be different on the
1984 * first time that the driver is initialized vs subsequent initializations.
1986 int_fmt
= INT_FMT_DEC
;
1987 batch_in_client
= FALSE
;
1988 cmd_pkt_list_num
= 0;
1989 cmd_batching_mode
= FALSE
;
1992 /* parse/validate the command line arguments */
1994 * pargv is updated upon return if the first argument is an option.
1995 * It remains intact otherwise.
1998 wl_option(char ***pargv
, char **pifname
, int *phelp
)
2000 char *ifname
= NULL
;
2002 int status
= CMD_OPT
;
2003 char **argv
= *pargv
;
2006 /* select different adapter */
2007 if (!strcmp(*argv
, "-a") || !strcmp(*argv
, "-i")) {
2008 char *opt
= *argv
++;
2012 "error: expected interface name after option %s\n", opt
);
2018 /* integer output format */
2019 else if (!strcmp(*argv
, "-d"))
2020 int_fmt
= INT_FMT_DEC
;
2021 else if (!strcmp(*argv
, "-u"))
2022 int_fmt
= INT_FMT_UINT
;
2023 else if (!strcmp(*argv
, "-x"))
2024 int_fmt
= INT_FMT_HEX
;
2027 else if (!strcmp(*argv
, "-h") || !strcmp(*argv
, "--help"))
2030 else if (!strcmp(*argv
, "--clientbatch")) {
2031 wl_seq_batch_in_client(TRUE
);
2033 /* To handle endian mis-matches between wl utility and wl driver */
2034 else if (!strcmp(*argv
, "--es")) {
2037 /* start of non wl options */
2043 /* consume the argument */
2056 wl_cmd_usage(FILE *fid
, cmd_t
*cmd
)
2058 if (strlen(cmd
->name
) >= 8)
2059 fprintf(fid
, "%s\n\t%s\n\n", cmd
->name
, cmd
->help
);
2061 fprintf(fid
, "%s\t%s\n\n", cmd
->name
, cmd
->help
);
2065 wl_print_deprecate(void *wl
, cmd_t
*cmd
, char **argv
)
2067 UNUSED_PARAMETER(wl
);
2068 UNUSED_PARAMETER(argv
);
2070 wl_cmd_usage(stderr
, cmd
); /* warning string is in command table */
2074 /* Dump out short list of commands */
2076 wl_list(void *wl
, cmd_t
*garb
, char **argv
)
2081 int letter
, col
, row
, pad
;
2083 UNUSED_PARAMETER(wl
);
2084 UNUSED_PARAMETER(garb
);
2085 UNUSED_PARAMETER(argv
);
2087 for (cmd
= wl_cmds
, nrows
= 0; cmd
->name
; cmd
++)
2088 /* Check for wc_cmd */
2089 if (wc_cmd_check(cmd
->name
))
2095 len
= nrows
* 80 + 2;
2096 list_buf
= malloc(len
);
2097 if (list_buf
== NULL
) {
2098 fprintf(stderr
, "Failed to allocate buffer of %d bytes\n", len
);
2101 for (i
= 0; i
< len
; i
++)
2105 for (letter
= 'a'; letter
< 'z'; letter
++) {
2106 for (cmd
= wl_cmds
; cmd
->name
; cmd
++) {
2107 /* Check for wc_cmd */
2108 if (!wc_cmd_check(cmd
->name
))
2110 if (cmd
->name
[0] == letter
|| cmd
->name
[0] == letter
- 0x20) {
2111 strcat(list_buf
+row
*80, cmd
->name
);
2112 pad
= 18 * (col
+ 1) - strlen(list_buf
+row
*80);
2116 strcat(list_buf
+row
*80, " ");
2124 for (row
= 0; row
< nrows
; row
++)
2125 printf("%s\n", list_buf
+row
*80);
2134 wl_cmds_usage(FILE *fid
, cmd_t
*port_cmds
)
2139 /* print usage of port commands */
2140 for (port_cmd
= port_cmds
; port_cmd
&& port_cmd
->name
; port_cmd
++)
2141 /* Check for wc_cmd */
2142 if (wc_cmd_check(port_cmd
->name
))
2143 wl_cmd_usage(fid
, port_cmd
);
2145 /* print usage of common commands without port counterparts */
2146 for (cmd
= wl_cmds
; cmd
->name
; cmd
++) {
2147 /* search if port counterpart exists */
2148 for (port_cmd
= port_cmds
; port_cmd
&& port_cmd
->name
; port_cmd
++)
2149 if (!strcmp(port_cmd
->name
, cmd
->name
))
2151 /* Also, check for this being a wc_cmd */
2152 if ((!port_cmd
|| !port_cmd
->name
) && (wc_cmd_check(cmd
->name
)))
2153 wl_cmd_usage(fid
, cmd
);
2158 wl_usage(FILE *fid
, cmd_t
*port_cmds
)
2160 fprintf(fid
, "Usage: %s [-a|i <adapter>] [-h] [-d|u|x] <command> [arguments]\n", wlu_av0
);
2163 fprintf(fid
, " -h this message and command descriptions\n");
2164 fprintf(fid
, " -h [cmd] command description for cmd\n");
2165 fprintf(fid
, " -a, -i adapter name or number\n");
2166 fprintf(fid
, " -d output format signed integer\n");
2167 fprintf(fid
, " -u output format unsigned integer\n");
2168 fprintf(fid
, " -x output format hexdecimal\n");
2171 wl_cmds_usage(fid
, port_cmds
);
2180 if ((ret
= wlu_get(wl
, WLC_GET_MAGIC
, &val
, sizeof(int)) < 0))
2183 /* Detect if IOCTL swapping is necessary */
2184 if (val
== (int)bcmswap32(WLC_IOCTL_MAGIC
))
2186 val
= bcmswap32(val
);
2189 if (val
!= WLC_IOCTL_MAGIC
)
2191 if ((ret
= wlu_get(wl
, WLC_GET_VERSION
, &val
, sizeof(int)) < 0))
2194 if (val
> WLC_IOCTL_VERSION
) {
2195 fprintf(stderr
, "Version mismatch, please upgrade\n");
2202 wl_printint(int val
)
2206 printf("%u\n", val
);
2209 printf("0x%x\n", val
);
2213 printf("%d\n", val
);
2219 /* Common routine to check for an option arg specifying the configuration index.
2220 * Takes the syntax -C num, --cfg=num, --config=num, or --configuration=num
2221 * Returns -1 if there is a command line parsing error.
2222 * Returns 0 if no error, and sets *consumed to the number of argv strings
2223 * used. Sets *bsscfg_idx to the index to use. Will set *bsscfg_idx to zero if there
2224 * was no config arg.
2227 wl_cfg_option(char **argv
, const char *fn_name
, int *bsscfg_idx
, int *consumed
)
2235 miniopt_init(&mo
, fn_name
, NULL
, FALSE
);
2237 /* process the first option */
2238 opt_err
= miniopt(&mo
, argv
);
2240 /* check for no args or end of options */
2244 /* check for no options, just a positional arg encountered */
2248 /* check for error parsing options */
2252 /* check for -C, --cfg=X, --config=X, --configuration=X */
2253 if (mo
.opt
== 'C' ||
2254 !strcmp(mo
.key
, "cfg") ||
2255 !strcmp(mo
.key
, "config") ||
2256 !strcmp(mo
.key
, "configuration")) {
2259 "%s: could not parse \"%s\" as an integer for the configuartion index\n",
2260 fn_name
, mo
.valstr
);
2263 *bsscfg_idx
= mo
.val
;
2264 *consumed
= mo
.consumed
;
2271 wl_void(void *wl
, cmd_t
*cmd
, char **argv
)
2273 UNUSED_PARAMETER(argv
);
2277 return wlu_set(wl
, cmd
->set
, NULL
, 0);
2281 wl_int(void *wl
, cmd_t
*cmd
, char **argv
)
2285 char *endptr
= NULL
;
2290 if ((ret
= wlu_get(wl
, cmd
->get
, &val
, sizeof(int))) < 0)
2298 if (!stricmp(*argv
, "on"))
2300 else if (!stricmp(*argv
, "off"))
2303 val
= strtol(*argv
, &endptr
, 0);
2304 if (*endptr
!= '\0') {
2305 /* not all the value string was parsed by strtol */
2311 ret
= wlu_set(wl
, cmd
->set
, &val
, sizeof(int));
2318 wl_bsscfg_int(void *wl
, cmd_t
*cmd
, char **argv
)
2320 char *endptr
= NULL
;
2329 /* parse a bsscfg_idx option if present */
2330 if ((ret
= wl_cfg_option(argv
, val_name
, &bsscfg_idx
, &consumed
)) != 0)
2333 /* handle a bsscfg int with a legacy ioctl */
2334 if (consumed
== 0 && cmd
->set
!= WLC_SET_VAR
) {
2335 /* back up to the orig command and run as an ioctl int */
2337 return wl_int(wl
, cmd
, argv
);
2348 ret
= wlu_iovar_getint(wl
, val_name
, &val
);
2350 ret
= wl_bssiovar_getint(wl
, val_name
, bsscfg_idx
, &val
);
2361 if (!stricmp(*argv
, "on"))
2363 else if (!stricmp(*argv
, "off"))
2366 val
= strtol(*argv
, &endptr
, 0);
2367 if (*endptr
!= '\0') {
2368 /* not all the value string was parsed by strtol */
2374 ret
= wlu_iovar_setint(wl
, val_name
, val
);
2376 ret
= wl_bssiovar_setint(wl
, val_name
, bsscfg_idx
, val
);
2383 wl_bsscfg_enable(void *wl
, cmd_t
*cmd
, char **argv
)
2386 const char *val_name
= "bss";
2392 UNUSED_PARAMETER(cmd
);
2394 /* skip the command name */
2397 /* parse a bsscfg_idx option if present */
2398 if ((ret
= wl_cfg_option(argv
, val_name
, &bsscfg_idx
, &consumed
)) != 0)
2402 if (consumed
== 0) { /* Use the -i parameter if that was present */
2407 bsscfg_idx
= htod32(bsscfg_idx
);
2408 ret
= wlu_iovar_getbuf(wl
, val_name
, &bsscfg_idx
, sizeof(bsscfg_idx
),
2409 buf
, WLC_IOCTL_MAXLEN
);
2424 if (!stricmp(*argv
, "ap"))
2426 else if (!stricmp(*argv
, "sta"))
2428 else if (!stricmp(*argv
, "up"))
2430 else if (!stricmp(*argv
, "down"))
2432 else if (!stricmp(*argv
, "del"))
2435 val
= strtol(*argv
, &endptr
, 0);
2436 if (*endptr
!= '\0') {
2437 /* not all the value string was parsed by strtol */
2441 bss_setbuf
.cfg
= htod32(bsscfg_idx
);
2442 bss_setbuf
.val
= htod32(val
);
2444 return wlu_iovar_set(wl
, val_name
, &bss_setbuf
, sizeof(bss_setbuf
));
2448 /* Get/Set the gmode config */
2450 wl_gmode(void *wl
, cmd_t
*cmd
, char **argv
)
2452 char *endptr
= NULL
;
2456 const char *gconfig
;
2458 /* Get the current G mode */
2459 if ((ret
= wlu_get(wl
, cmd
->get
, &val
, sizeof(val
))))
2464 case GMODE_LEGACY_B
:
2465 gconfig
= "54g Legacy B";
2468 gconfig
= "54g Auto";
2471 gconfig
= "54g Only";
2473 case GMODE_PERFORMANCE
:
2474 gconfig
= "54g Performance";
2477 gconfig
= "54g LRS";
2480 gconfig
= "unknown";
2484 printf("%s (%d)\n", gconfig
, val
);
2487 /* Set the new G mode */
2489 if (!strnicmp(*argv
, "legacy", 6))
2490 val
= GMODE_LEGACY_B
;
2491 else if (!strnicmp(*argv
, "auto", 4))
2493 else if (!strnicmp(*argv
, "gonly", 5))
2495 else if (!strnicmp(*argv
, "perf", 4))
2496 val
= GMODE_PERFORMANCE
;
2497 else if (!strnicmp(*argv
, "lrs", 3))
2500 val
= strtol(*argv
, &endptr
, 0);
2501 if (*endptr
!= '\0') {
2502 /* not all the value string was parsed by strtol */
2507 /* Set the gmode configration */
2509 if ((ret
= wlu_set(wl
, cmd
->set
, &val
, sizeof(val
))))
2520 wl_reg(void *wl
, cmd_t
*cmd
, char **argv
)
2528 char *endptr
= NULL
;
2532 /* eat command name */
2536 for (argc
= 0; argv
[argc
]; argc
++)
2539 /* required arg: reg offset */
2543 reg
= strtol(argv
[0], &endptr
, 0);
2545 if (*endptr
!= '\0')
2549 x
.band
= WLC_BAND_AUTO
;
2552 /* Second arg: value or band or "radio core" */
2554 if (!stricmp(argv
[1], "a"))
2555 x
.band
= WLC_BAND_5G
;
2556 else if (!stricmp(argv
[1], "b"))
2557 x
.band
= WLC_BAND_2G
;
2559 /* For NPHY Rev >= 3, the 2nd argument can be
2562 if (strcmp(cmd
->name
, "radioreg") == 0) {
2563 if (strcmp(argv
[1], "syn") == 0) {
2564 reg
|= RADIO_CORE_SYN
;
2566 } else if (strcmp(argv
[1], "tx0") == 0) {
2567 reg
|= RADIO_CORE_TX0
;
2569 } else if (strcmp(argv
[1], "tx1") == 0) {
2570 reg
|= RADIO_CORE_TX1
;
2572 } else if (strcmp(argv
[1], "rx0") == 0) {
2573 reg
|= RADIO_CORE_RX0
;
2575 } else if (strcmp(argv
[1], "rx1") == 0) {
2576 reg
|= RADIO_CORE_RX1
;
2580 /* For HTPHY, the 2nd argument can be
2583 if (strcmp(cmd
->name
, "radioreg") == 0) {
2584 if (strcmp(argv
[1], "cr0") == 0) {
2585 reg
|= RADIO_CORE_CR0
;
2587 } else if (strcmp(argv
[1], "cr1") == 0) {
2588 reg
|= RADIO_CORE_CR1
;
2590 } else if (strcmp(argv
[1], "cr2") == 0) {
2591 reg
|= RADIO_CORE_CR2
;
2595 /* If the second argument is a value */
2597 x
.val
= strtol(argv
[1], &endptr
, 0);
2598 if (*endptr
!= '\0')
2604 /* Third arg: band OR "radio core" */
2606 if (!stricmp(argv
[2], "a"))
2607 x
.band
= WLC_BAND_5G
;
2608 else if (!stricmp(argv
[2], "b"))
2609 x
.band
= WLC_BAND_2G
;
2611 /* For NPHY Rev >= 3, the 3rd argument can be
2615 if (strcmp(cmd
->name
, "radioreg") == 0) {
2616 if (strcmp(argv
[2], "syn") == 0) {
2617 reg
|= RADIO_CORE_SYN
;
2619 } else if (strcmp(argv
[2], "tx0") == 0) {
2620 reg
|= RADIO_CORE_TX0
;
2622 } else if (strcmp(argv
[2], "tx1") == 0) {
2623 reg
|= RADIO_CORE_TX1
;
2625 } else if (strcmp(argv
[2], "rx0") == 0) {
2626 reg
|= RADIO_CORE_RX0
;
2628 } else if (strcmp(argv
[2], "rx1") == 0) {
2629 reg
|= RADIO_CORE_RX1
;
2633 /* For HTPHY, the 3rd argument can be
2636 if (strcmp(cmd
->name
, "radioreg") == 0) {
2637 if (strcmp(argv
[2], "cr0") == 0) {
2638 reg
|= RADIO_CORE_CR0
;
2640 } else if (strcmp(argv
[2], "cr1") == 0) {
2641 reg
|= RADIO_CORE_CR1
;
2643 } else if (strcmp(argv
[2], "cr2") == 0) {
2644 reg
|= RADIO_CORE_CR2
;
2646 } else if (strcmp(argv
[2], "all") == 0) {
2647 reg
|= RADIO_CORE_ALL
;
2658 x
.val
= (x
.val
<< 16) | (reg
& 0xffff);
2660 /* issue the get or set ioctl */
2661 if ((argc
== 1) || ((argc
== 2) && ((x
.band
!= WLC_BAND_AUTO
) || core_cmd
))) {
2662 x
.band
= htod32(x
.band
);
2663 x
.val
= htod32(x
.val
);
2664 if ((ret
= wlu_get(wl
, cmd
->get
, &x
, sizeof(x
))) < 0)
2666 printf("0x%04x\n", (uint16
)(dtoh32(x
.val
)));
2668 x
.band
= htod32(x
.band
);
2669 x
.val
= htod32(x
.val
);
2670 ret
= wlu_set(wl
, cmd
->set
, &x
, sizeof(x
));
2677 wl_gpioout(void *wl
, cmd_t
*cmd
, char **argv
)
2681 char *endptr
= NULL
;
2685 UNUSED_PARAMETER(cmd
);
2689 /* eat command name */
2693 for (argc
= 0; argv
[argc
]; argc
++)
2696 /* Get and print the values */
2702 if (wlu_iovar_get(wl
, "gpioout", buf
, sizeof(uint32
) *3))
2704 gpio_cntrl
= dtoh32(((uint32
*)buf
)[0]);
2705 gpio_out
= dtoh32(((uint32
*)buf
)[1]);
2706 gpio_outen
= dtoh32(((uint32
*)buf
)[2]);
2708 printf("gpiocontrol 0x%x gpioout 0x%x gpioouten 0x%x\n", gpio_cntrl
,
2709 gpio_out
, gpio_outen
);
2714 /* required arg: mask value */
2718 mask
= strtoul(argv
[0], &endptr
, 0);
2719 if (*endptr
!= '\0')
2722 val
= strtoul(argv
[1], &endptr
, 0);
2723 if (*endptr
!= '\0')
2726 if ((~mask
& val
) != 0)
2729 int_ptr
= (uint32
*)buf
;
2730 mask
= htod32(mask
);
2731 memcpy(int_ptr
, (const void *)&mask
, sizeof(mask
));
2734 memcpy(int_ptr
, (const void *)&val
, sizeof(val
));
2736 return wlu_iovar_set(wl
, "gpioout", buf
, sizeof(uint32
) *2);
2740 wl_macreg(void *wl
, cmd_t
*cmd
, char **argv
)
2746 char *endptr
= NULL
;
2752 /* eat command name */
2756 for (argc
= 0; argv
[argc
]; argc
++)
2759 /* required arg: reg offset */
2763 reg
= strtol(argv
[0], &endptr
, 0);
2764 if (*endptr
!= '\0')
2767 /* required arg: reg size */
2771 size
= strtol(argv
[1], &endptr
, 0);
2772 if (*endptr
!= '\0')
2775 rwt
.band
= WLC_BAND_AUTO
;
2777 /* Third arg: new value or band */
2779 if (!stricmp(argv
[2], "a"))
2780 rwt
.band
= WLC_BAND_5G
;
2781 else if (!stricmp(argv
[2], "b"))
2782 rwt
.band
= WLC_BAND_2G
;
2784 val
= strtoul(argv
[2], &endptr
, 0);
2785 if (*endptr
!= '\0')
2791 /* Fourth arg: band */
2793 if (!stricmp(argv
[3], "a"))
2794 rwt
.band
= WLC_BAND_5G
;
2795 else if (!stricmp(argv
[3], "b"))
2796 rwt
.band
= WLC_BAND_2G
;
2801 if ((argc
== 2) || ((argc
== 3) && (rwt
.band
!= WLC_BAND_AUTO
))) {
2802 rwt
.band
= htod32(rwt
.band
);
2803 rwt
.byteoff
= htod32(reg
);
2804 rwt
.size
= htod32(size
);
2805 if ((ret
= wlu_get(wl
, cmd
->get
, &rwt
, sizeof(rw_reg_t
))) < 0)
2807 printf("0x%04x\n", dtoh32(rwt
.val
));
2810 rwt
.band
= htod32(rwt
.band
);
2811 rwt
.byteoff
= htod32(reg
);
2812 rwt
.size
= htod32(size
);
2813 rwt
.val
= htod32(val
);
2814 ret
= wlu_set(wl
, cmd
->set
, &rwt
, sizeof(rw_reg_t
));
2821 * get or get a band specific variable
2822 * the band can be a/b/all or omitted. "all"(set only)
2823 * means all supported bands. blank means current band
2826 wl_band_elm(void *wl
, cmd_t
*cmd
, char **argv
)
2833 char *endptr
= NULL
;
2836 /* eat command name */
2840 for (argc
= 0; argv
[argc
]; argc
++)
2844 x
.band
= WLC_BAND_AUTO
;
2846 /* First arg: value or band */
2848 if (!stricmp(argv
[0], "a"))
2849 x
.band
= WLC_BAND_5G
;
2850 else if (!stricmp(argv
[0], "b"))
2851 x
.band
= WLC_BAND_2G
;
2852 else if (!stricmp(argv
[0], "all"))
2853 x
.band
= WLC_BAND_ALL
;
2855 x
.val
= strtol(argv
[0], &endptr
, 0);
2856 if (*endptr
!= '\0')
2861 /* Second arg: band */
2863 if (!stricmp(argv
[1], "a"))
2864 x
.band
= WLC_BAND_5G
;
2865 else if (!stricmp(argv
[1], "b"))
2866 x
.band
= WLC_BAND_2G
;
2867 else if (!stricmp(argv
[1], "all"))
2868 x
.band
= WLC_BAND_ALL
;
2873 /* issue the get or set ioctl */
2874 if ((argc
== 0) || ((argc
== 1) && (x
.band
!= WLC_BAND_AUTO
))) {
2875 if (x
.band
== WLC_BAND_ALL
) {
2876 printf("band option \"all\" is for set only, not get\n");
2880 x
.band
= htod32(x
.band
);
2881 if ((ret
= wlu_get(wl
, cmd
->get
, &x
, sizeof(x
))) < 0)
2884 printf("%s is 0x%04x(%d)\n", cmd
->name
, (uint16
)(dtoh32(x
.val
)), dtoh32(x
.val
));
2886 x
.band
= htod32(x
.band
);
2887 x
.val
= htod32(x
.val
);
2888 ret
= wlu_set(wl
, cmd
->set
, &x
, sizeof(x
));
2894 /* Command may or may not take a MAC address */
2896 wl_rssi(void *wl
, cmd_t
*cmd
, char **argv
)
2903 if ((ret
= wlu_get(wl
, cmd
->get
, &rssi
, sizeof(rssi
))) < 0)
2905 printf("%d\n", dtoh32(rssi
));
2908 if (!wl_ether_atoe(*argv
, &scb_val
.ea
))
2910 if ((ret
= wlu_get(wl
, cmd
->get
, &scb_val
, sizeof(scb_val
))) < 0)
2912 printf("%d\n", dtoh32(scb_val
.val
));
2918 wl_rssi_event(void *wl
, cmd_t
*cmd
, char **argv
)
2925 wl_rssi_event_t rssi
;
2928 if ((ret
= wlu_var_getbuf(wl
, cmd
->name
, NULL
, 0, &ptr
)) < 0)
2931 memcpy(&rssi
, ptr
, sizeof(rssi
));
2932 rssi
.rate_limit_msec
= dtoh32(rssi
.rate_limit_msec
);
2934 printf("%d", rssi
.rate_limit_msec
);
2935 for (i
= 0; i
< rssi
.num_rssi_levels
; i
++) {
2936 printf(" %d", rssi
.rssi_levels
[i
]);
2941 wl_rssi_event_t rssi
;
2943 memset(&rssi
, 0, sizeof(wl_rssi_event_t
));
2944 rssi
.rate_limit_msec
= atoi(*argv
);
2946 while (*++argv
&& rssi
.num_rssi_levels
< MAX_RSSI_LEVELS
) {
2947 rssi
.rssi_levels
[rssi
.num_rssi_levels
++] = atoi(*argv
);
2948 if (rssi
.num_rssi_levels
> 1) {
2949 if (rssi
.rssi_levels
[rssi
.num_rssi_levels
- 1] <=
2950 rssi
.rssi_levels
[rssi
.num_rssi_levels
- 2]) {
2951 /* rssi levels must be in increasing order */
2958 /* too many parameters */
2962 rssi
.rate_limit_msec
= htod32(rssi
.rate_limit_msec
);
2963 ret
= wlu_var_setbuf(wl
, cmd
->name
, &rssi
, sizeof(rssi
));
2969 wl_phy_rssi_ant(void *wl
, cmd_t
*cmd
, char **argv
)
2973 wl_rssi_ant_t
*rssi_ant_p
;
2979 if ((ret
= wlu_var_getbuf(wl
, cmd
->name
, NULL
, 0, &ptr
)) < 0)
2982 rssi_ant_p
= (wl_rssi_ant_t
*)ptr
;
2983 rssi_ant_p
->version
= dtoh32(rssi_ant_p
->version
);
2984 rssi_ant_p
->count
= dtoh32(rssi_ant_p
->count
);
2986 if (rssi_ant_p
->count
== 0) {
2987 printf("not supported on this chip\n");
2989 for (i
= 0; i
< rssi_ant_p
->count
; i
++)
2990 printf("rssi[%d] %d ", i
, rssi_ant_p
->rssi_ant
[i
]);
2999 /* Commands that take a MAC address */
3001 wl_mac(void *wl
, cmd_t
*cmd
, char **argv
)
3004 struct ether_addr ea
;
3007 if ((ret
= wlu_get(wl
, cmd
->get
, &ea
, ETHER_ADDR_LEN
)) < 0)
3009 printf("%s\n", wl_ether_etoa(&ea
));
3012 if (!wl_ether_atoe(*argv
, &ea
))
3014 return wlu_set(wl
, cmd
->set
, &ea
, ETHER_ADDR_LEN
);
3018 /* IO variables that take a MAC address */
3020 wl_iov_mac(void *wl
, cmd_t
*cmd
, char **argv
)
3023 struct ether_addr ea
= {{0, 0, 0, 0, 0, 0}};
3025 if (argv
[1]) { /* set */
3026 if (!wl_ether_atoe(argv
[1], &ea
)) {
3027 printf(" ERROR: no valid ether addr provided\n");
3030 if ((ret
= wlu_iovar_set(wl
, cmd
->name
, &ea
, ETHER_ADDR_LEN
)) < 0) {
3031 printf("Error setting variable %s\n", argv
[0]);
3036 if ((ret
= wlu_iovar_get(wl
, cmd
->name
, &ea
, ETHER_ADDR_LEN
)) < 0) {
3037 printf("Error getting variable %s\n", argv
[0]);
3040 printf("%s %s\n", argv
[0], wl_ether_etoa(&ea
));
3047 wlu_dump(void *wl
, cmd_t
*cmd
, char **argv
)
3056 dump_buf
= malloc(WL_DUMP_BUF_LEN
);
3057 if (dump_buf
== NULL
) {
3058 fprintf(stderr
, "Failed to allocate dump buffer of %d bytes\n", WL_DUMP_BUF_LEN
);
3061 memset(dump_buf
, 0, WL_DUMP_BUF_LEN
);
3063 /* skip the command name */
3066 /* If no args given, get the subset of 'wl dump all'
3067 * Otherwise, if args are given, they are the dump section names.
3069 if (*argv
== NULL
) {
3070 /* query for the 'dump' without any argument */
3071 ret
= wlu_iovar_getbuf(wl
, "dump", NULL
, 0, dump_buf
, WL_DUMP_BUF_LEN
);
3073 /* if the query is successful, continue on and print the result. */
3075 /* if the query fails, check for a legacy driver that does not support
3076 * the "dump" iovar, and instead issue a WLC_DUMP ioctl.
3079 wlu_iovar_getint(wl
, "bcmerror", &bcmerr
);
3080 if (bcmerr
== BCME_UNSUPPORTED
) {
3081 ret
= wlu_get(wl
, WLC_DUMP
, dump_buf
, WL_DUMP_BUF_LEN
);
3083 fprintf(stderr
, "dump: error on query of WLC_DUMP\n");
3087 fprintf(stderr
, "dump: error on query of dump list\n");
3092 /* create the dump section name list */
3094 /* add space delimiter if this is not the first section name */
3095 if (dump_buf
[0] != '\0')
3096 strcat(dump_buf
, " ");
3098 strcat(dump_buf
, *argv
);
3103 /* This is a "space" added at end of last argument */
3104 strcat(dump_buf
, " ");
3106 ret
= wlu_iovar_getbuf(wl
, "dump", dump_buf
, strlen(dump_buf
),
3107 dump_buf
, WL_DUMP_BUF_LEN
);
3111 fputs(dump_buf
, stdout
);
3121 wlu_srdump(void *wl
, cmd_t
*cmd
, char **argv
)
3123 int ret
, i
, nw
, nb
= 0;
3124 uint16
*words
= (uint16
*)&buf
[8];
3128 /* srom has been expanded a few times, at the moment sromrev4/8 are the largest */
3131 /* allow reading a larger (or any other-size one) if specified */
3132 if (*++argv
!= NULL
) {
3133 nb
= (int)strtol(*argv
, NULL
, 0);
3135 printf("Byte count %d is odd\n", nb
);
3141 srt
= (srom_rw_t
*)buf
;
3142 srt
->byteoff
= htod32(0);
3143 srt
->nbytes
= htod32(2 * nw
);
3147 if ((ret
= wlu_get(wl
, cmd
->get
, buf
, WLC_IOCTL_MAXLEN
)) < 0)
3149 if ((words
[SROM4_SIGN
] != SROM4_SIGNATURE
) &&
3150 (words
[SROM8_SIGN
] != SROM4_SIGNATURE
))
3151 nw
= nb
? nw
: SROM_WORDS
;
3152 for (i
= 0; i
< nw
; i
++) {
3154 printf("\n srom[%03d]: ", i
);
3155 printf("0x%04x ", words
[i
]);
3163 wlu_srwrite(void *wl
, cmd_t
*cmd
, char **argv
)
3165 #if !defined(BWL_FILESYSTEM_SUPPORT)
3166 UNUSED_PARAMETER(wl
); UNUSED_PARAMETER(cmd
); UNUSED_PARAMETER(argv
);
3168 #elif defined(_CFE_)
3169 UNUSED_PARAMETER(wl
); UNUSED_PARAMETER(cmd
); UNUSED_PARAMETER(argv
);
3170 return CFE_ERR_UNSUPPORTED
;
3175 int ret
= 0, erase
, srcrc
;
3177 srom_rw_t
*srt
= (srom_rw_t
*)buf
;
3179 erase
= !strcmp(*argv
, "srclear");
3180 srcrc
= !strcmp(*argv
, "srcrc");
3182 /* We need at least one arg */
3191 len
= strtoul(arg
, &endptr
, 0);
3192 if (*endptr
!= '\0') {
3193 fprintf(stderr
, "error parsing value \"%s\" as an integer for byte count\n",
3197 srt
->byteoff
= 0x55aa;
3198 } else if (!*argv
) { /* srwrite or srcrc */
3199 /* Only one arg, it better be a file name */
3200 if (!(fp
= fopen(arg
, "rb"))) {
3201 fprintf(stderr
, "%s: No such file or directory\n", arg
);
3205 len
= fread(srt
->buf
, 1, SROM_MAX
+ 1, fp
);
3206 if ((ret
= ferror(fp
))) {
3207 printf("\nerror %d reading %s\n", ret
, arg
);
3213 printf("\nFile %s is too large\n", arg
);
3218 if (len
== SROM4_WORDS
* 2) {
3219 if ((srt
->buf
[SROM4_SIGN
] != SROM4_SIGNATURE
) &&
3220 (srt
->buf
[SROM8_SIGN
] != SROM4_SIGNATURE
)) {
3221 printf("\nFile %s is %d bytes but lacks a REV4/ signature\n",
3222 arg
, SROM4_WORDS
* 2);
3226 } else if ((len
!= SROM_WORDS
* 2) && (len
!= SROM_MAX
)) {
3227 printf("\nFile %s is %d bytes, not %d or %d or %d bytes\n", arg
, len
,
3228 SROM_WORDS
* 2, SROM4_WORDS
* 2, SROM_MAX
);
3236 printf("srcrc only takes one arg\n");
3241 /* More than 1 arg, first is offset, rest are data. */
3242 srt
->byteoff
= strtoul(arg
, &endptr
, 0);
3243 if (*endptr
!= '\0')
3247 while ((arg
= *argv
++) != NULL
) {
3248 srt
->buf
[i
++] = (uint16
)strtoul(arg
, &endptr
, 0);
3249 if (*endptr
!= '\0') {
3251 printf("\n%s is not an integer\n", arg
);
3257 if (srt
->byteoff
& 1) {
3258 printf("Byte offset (%d) is odd or negative\n", srt
->byteoff
);
3264 if ((srt
->byteoff
+ len
) > SROM_MAX
) {
3265 printf("Data extends past %d bytes\n", SROM_MAX
);
3273 srt
->byteoff
= 0x55ab; /* Hack for srcrc */
3274 ret
= wlu_get(wl
, cmd
->get
, buf
, len
+ 8);
3275 printf("0x%x\n", (uint8
)buf
[0]);
3277 printf("Writing srom. ioctl %d, iolen %d, sroff %d, len %d\n",
3278 cmd
->set
, len
+ 8, srt
->byteoff
, srt
->nbytes
);
3280 ret
= wlu_set(wl
, cmd
->set
, buf
, len
+ 8);
3288 #endif /* BWL_FILESYSTEM_SUPPORT */
3292 wlu_ciswrite(void *wl
, cmd_t
*cmd
, char **argv
)
3294 #if !defined(BWL_FILESYSTEM_SUPPORT)
3295 UNUSED_PARAMETER(wl
); UNUSED_PARAMETER(cmd
); UNUSED_PARAMETER(argv
);
3297 #elif defined(_CFE_)
3298 UNUSED_PARAMETER(wl
); UNUSED_PARAMETER(cmd
); UNUSED_PARAMETER(argv
);
3299 return CFE_ERR_UNSUPPORTED
;
3307 char *cisp
, *cisdata
;
3309 UNUSED_PARAMETER(cmd
);
3311 /* We need extacly one arg */
3312 if (!*++argv
|| argv
[1])
3315 /* initialize buffer with iovar */
3317 memset(buf
, 0, WLC_IOCTL_MAXLEN
);
3318 strcpy(bufp
, "ciswrite");
3319 bufp
+= strlen("ciswrite") + 1;
3321 cisdata
= cisp
+ sizeof(cish
);
3323 cish
.source
= htod32(0);
3325 /* grab the filename arg */
3327 if (!(fp
= fopen(arg
, "rb"))) {
3328 fprintf(stderr
, "%s: No such file or directory\n", arg
);
3332 len
= fread(cisdata
, 1, SROM_MAX
+ 1, fp
);
3333 if ((ret
= ferror(fp
))) {
3334 printf("\nerror %d reading %s\n", ret
, arg
);
3340 printf("\nFile %s is too large\n", arg
);
3345 /* fill in offset and length */
3346 cish
.byteoff
= htod32(0);
3347 cish
.nbytes
= htod32(len
);
3348 memcpy(cisp
, (char*)&cish
, sizeof(cish
));
3350 printf("len %d sizeof(cish) %d total %d\n", len
, (int)sizeof(cish
),
3351 (int)(len
+ sizeof(cish
)));
3352 ret
= wl_set(wl
, WLC_SET_VAR
, buf
, (cisp
- buf
) + sizeof(cish
) + len
);
3354 fprintf(stderr
, "ciswrite failed: %d\n", ret
);
3362 #endif /* BWL_FILESYSTEM_SUPPORT */
3366 wlu_cisupdate(void *wl
, cmd_t
*cmd
, char **argv
)
3369 return CFE_ERR_UNSUPPORTED
;
3371 char *bufp
, *endptr
;
3379 char bytes
[SROM_MAX
];
3384 UNUSED_PARAMETER(cmd
);
3386 /* validate arg count */
3387 if (!*++argv
|| !argv
[1])
3390 if (argv
[2] && !strcmp(argv
[2], "--preview"))
3393 /* grab byte offset */
3394 off
= (uint32
)strtol(argv
[0], &endptr
, 0);
3395 if (*endptr
!= '\0')
3400 updatelen
= strlen(bufp
);
3401 if (updatelen
% 2) {
3402 fprintf(stderr
, "cisupdate hex string must contain an even number of digits\n");
3407 /* convert and store hex byte values */
3408 for (i
= 0; i
< updatelen
; i
++) {
3410 hexstr
[1] = *(bufp
+ 1);
3411 if (!isxdigit((int)hexstr
[0]) || !isxdigit((int)hexstr
[1])) {
3412 fprintf(stderr
, "cisupdate invalid hex digit(s) in %s\n", argv
[1]);
3416 bytes
[i
] = (char) strtol(hexstr
, NULL
, 16);
3420 /* Prepare the read info */
3425 /* set up the buffer and do the get (+9 allows space for "ciswrite" string later) */
3426 memset(buf
+ 9, 0, WLC_IOCTL_MAXLEN
);
3427 strcpy(buf
+ 9, "cisdump");
3428 bufp
= buf
+ strlen("cisdump") + 1 + 9;
3429 memcpy(bufp
, (char*)&cish
, sizeof(cish
));
3430 bufp
+= sizeof(cish
);
3431 ret
= wl_get(wl
, WLC_GET_VAR
, buf
+ 9, (bufp
- (buf
+ 9)) + SROM_MAX
);
3433 fprintf(stderr
, "cisupdate failed to read cis: %d\n", ret
);
3437 /* pull off the cis_rw_t */
3439 memcpy((char*)&cish
, bufp
, sizeof(cish
));
3440 len
= dtoh32(cish
.nbytes
);
3442 if ((off
+ updatelen
) > len
) {
3443 fprintf(stderr
, "cisupdate offset %d plus update len %d exceeds CIS len %d\n",
3444 off
, updatelen
, len
);
3448 /* move past to the data */
3449 bufp
+= sizeof(cish
);
3451 /* update the bytes */
3452 if (cish
.source
== WLC_CIS_SROM
) {
3453 for (i
= 0; i
< updatelen
; ++i
)
3454 bufp
[off
+ i
] = bytes
[i
] & 0xff;
3456 for (i
= 0; i
< updatelen
; ++i
) {
3457 if (~bytes
[i
] & bufp
[off
+ i
]) {
3458 fprintf(stderr
, "cisupdate: OTP update incompatible:"
3459 " update[%d](0x%02x)->cis[%d](0x%02x)\n",
3460 i
, bytes
[i
], off
+ i
, bufp
[off
+ i
]);
3463 bufp
[off
+ i
] |= bytes
[i
];
3467 /* initialize buffer with iovar */
3469 strcpy(bufp
, "ciswrite");
3470 bufp
+= strlen("ciswrite") + 1;
3473 /* fill in cis_rw_t fields */
3476 cish
.nbytes
= htod32(len
);
3477 memcpy(cisp
, (char*)&cish
, sizeof(cish
));
3479 /* write the data back to the device */
3480 printf("offset %d data %s cislen %d\n", off
, argv
[1], len
);
3482 bufp
+= sizeof(cish
);
3483 for (i
= 0; i
< len
; i
++) {
3485 printf("\nByte %3d: ", i
);
3486 printf("0x%02x ", (uint8
)bufp
[i
]);
3490 ret
= wl_set(wl
, WLC_SET_VAR
, buf
, (cisp
- buf
) + sizeof(cish
) + len
);
3492 fprintf(stderr
, "cisupdate cis write failed: %d\n", ret
);
3502 wlu_cisdump(void *wl
, cmd_t
*cmd
, char **argv
)
3510 UNUSED_PARAMETER(cmd
);
3512 /* Grab and move past optional output file argument */
3513 if ((argv
[1] != NULL
) && (strcmp(argv
[1], "-b") == 0)) {
3518 /* check for a length argument */
3519 if (*++argv
!= NULL
) {
3520 nbytes
= (int)strtol(*argv
, NULL
, 0);
3522 printf("Invalid byte count %d, must be even\n", nbytes
);
3526 if (nbytes
> SROM_MAX
) {
3527 printf("Count %d too large\n", nbytes
);
3533 /* Prepare the read info */
3536 cish
.nbytes
= htod32(nbytes
);
3538 /* set up the buffer and do the get */
3539 memset(buf
, 0, WLC_IOCTL_MAXLEN
);
3540 strcpy(buf
, "cisdump");
3541 bufp
= buf
+ strlen("cisdump") + 1;
3542 memcpy(bufp
, (char*)&cish
, sizeof(cish
));
3543 bufp
+= sizeof(cish
);
3544 ret
= wl_get(wl
, WLC_GET_VAR
, buf
, (bufp
- buf
) + (nbytes
? nbytes
: SROM_MAX
));
3546 fprintf(stderr
, "Failed cisdump request: %d\n", ret
);
3550 /* pull off the cis_rw_t */
3552 memcpy((char*)&cish
, bufp
, sizeof(cish
));
3553 cish
.source
= dtoh32(cish
.source
);
3554 cish
.byteoff
= dtoh32(cish
.byteoff
);
3555 cish
.nbytes
= dtoh32(cish
.nbytes
);
3557 /* move past to the data */
3558 bufp
+= sizeof(cish
);
3560 printf("Source: %d (%s)", cish
.source
,
3561 (cish
.source
== WLC_CIS_DEFAULT
) ? "Built-in default" :
3562 (cish
.source
== WLC_CIS_SROM
) ? "External SPROM" :
3563 (cish
.source
== WLC_CIS_OTP
) ? "Internal OTP" : "Unknown?");
3565 printf("\nMaximum length: %d bytes", cish
.nbytes
);
3566 for (i
= 0; i
< (int)cish
.nbytes
; i
++) {
3568 printf("\nByte %3d: ", i
);
3569 printf("0x%02x ", (uint8
)bufp
[i
]);
3573 #if defined(BWL_FILESYSTEM_SUPPORT)
3575 if (fname
!= NULL
) {
3579 nbytes
= cish
.nbytes
;
3581 fp
= fopen(fname
, "wb");
3583 ret
= fwrite(bufp
, 1, nbytes
, fp
);
3584 if (ret
!= (int)nbytes
) {
3585 fprintf(stderr
, "Error writing %d bytes to file, rc %d!\n",
3589 printf("Wrote %d bytes to %s\n", ret
, fname
);
3594 fprintf(stderr
, "Problem opening file %s\n", fname
);
3598 #endif /* !(CFE|HNDRTE|IOPOS) -- has stdio filesystem */
3599 #endif /* BWL_FILESYSTEM_SUPPORT */
3605 #if defined(linux) || defined(MACOSX) || defined(_CFE_) || defined(__NetBSD__)
3606 /* linux, MacOS, NetBSD: ffs is in the standard C library */
3607 /* CFE, HNDRTE & IOPOS: Not needed, the code below is ifdef out */
3615 for (j
= 0; j
< 32; j
++)
3620 #endif /* linux, MACOSX, CFE, HNDRTE, IOPOS, NetBSD */
3624 /* VX wants prototypes even for static functions. */
3625 static char* find_pattern(char **argv
, const char *pattern
, uint
*val
);
3626 static int newtuple(char *b
, int *cnt
, uint8 tag
, const cis_tuple_t
*srv
);
3627 static int parsecis(char *b
, char **argv
);
3628 static const sromvar_t
*srvlookup(const sromvar_t
*tab
, char *name
, int nlen
, int sromrev
);
3630 /* Find an entry in argv[][] in this form
3631 * name=value, could be pattern=(0x)1234 or pattern=ABC
3633 * If *val is NULL, return the pointer to value.
3634 * If *val is not NULL, fill the value into val, return the pointer to name if found,
3635 * return NULL if no match found.
3638 find_pattern(char **argv
, const char *pattern
, uint
*val
)
3640 char *ret
= NULL
, *name
= NULL
, **pargv
= argv
;
3642 /* clear val first */
3645 while ((name
= *pargv
++)) {
3646 if ((ret
= strstr(name
, pattern
))) {
3647 char *p
= ret
, *q
= NULL
;
3649 /* Extracting the content */
3650 p
+= strlen(pattern
);
3652 /* var name could have same prefix */
3657 if (!val
) return (ret
+strlen(pattern
)+1);
3659 *val
= strtoul(p
, &q
, strncmp(p
, "0x", 2) ? 10 : 16);
3661 printf("Bad value: %s\n", ret
);
3672 newtuple(char *b
, int *cnt
, uint8 tag
, const cis_tuple_t
*srv
)
3674 memset(b
, 0, srv
->len
+ 2);
3677 b
[1] = (char)srv
->len
;
3678 b
[2] = (char)srv
->tag
;
3686 parsecis(char *b
, char **argv
)
3688 const cis_tuple_t
*srv
= cis_hnbuvars
;
3689 char *cpar
= NULL
, *p
= NULL
;
3690 char par
[256]; /* holds longest srv->params */
3691 char delimit
[2] = " \0";
3694 /* Walk through all the tuples, create append buffer */
3695 while (srv
->tag
!= 0xFF) {
3698 /* Special cases (Raw Data / macaddr / ccode / fem) */
3699 if (srv
->tag
== OTP_RAW
|| srv
->tag
== OTP_RAW1
) {
3700 if ((p
= find_pattern(argv
, "RAW", &val
))) {
3701 p
+= (strlen("RAW") + 1); /* RAW= */
3703 b
[cnt
++] = (unsigned char) strtoul(p
, &p
, 16);
3708 } else if (srv
->tag
== OTP_VERS_1
) {
3709 uint l1
= 1, l2
= 1;
3712 if ((p
= find_pattern(argv
, "manf", NULL
)))
3715 if ((p2
= find_pattern(argv
, "productname", NULL
)))
3718 if ((p
!= NULL
) | (p2
!= NULL
)) {
3719 b
[cnt
++] = CISTPL_VERS_1
;
3720 b
[cnt
++] = 2 + l1
+ l2
;
3725 /* Replace '_' by space */
3726 while ((q
= strchr(q
, '_')))
3728 memcpy(&b
[cnt
], p
, l1
);
3735 /* Replace '_' by space */
3736 while ((q
= strchr(q
, '_')))
3738 memcpy(&b
[cnt
], p2
, l2
);
3743 } else if (srv
->tag
== OTP_MANFID
) {
3745 uint manfid
= 0, prodid
= 0;
3747 if ((p
= find_pattern(argv
, "manfid", &manfid
)))
3750 if ((p
= find_pattern(argv
, "prodid", &prodid
)))
3754 b
[cnt
++] = CISTPL_MANFID
;
3755 b
[cnt
++] = srv
->len
;
3756 b
[cnt
++] = (uint8
)(manfid
& 0xff);
3757 b
[cnt
++] = (uint8
)((manfid
>> 8) & 0xff);
3758 b
[cnt
++] = (uint8
)(prodid
& 0xff);
3759 b
[cnt
++] = (uint8
)((prodid
>> 8) & 0xff);
3761 } else if (srv
->tag
== HNBU_MACADDR
) {
3762 if ((p
= find_pattern(argv
, "macaddr", NULL
))) {
3763 newtuple(&b
[cnt
], &cnt
, CISTPL_BRCM_HNBU
, srv
);
3764 if (!wl_ether_atoe(p
, (struct ether_addr
*)&b
[cnt
]))
3765 printf("Argument does not look like a MAC "
3766 "address: %s\n", p
);
3767 cnt
+= sizeof(struct ether_addr
);
3769 } else if (srv
->tag
== HNBU_CCODE
) {
3771 char tmp
[3] = "\0\0\0";
3773 if ((p
= find_pattern(argv
, "ccode", NULL
))) {
3778 if ((p
= find_pattern(argv
, "cctl", &val
))) {
3780 tmp
[2] = (uint8
)val
;
3783 newtuple(&b
[cnt
], &cnt
, CISTPL_BRCM_HNBU
, srv
);
3784 memcpy(&b
[cnt
], tmp
, 3);
3785 cnt
+= 3; /* contents filled already */
3787 } else if (srv
->tag
== HNBU_RSSISMBXA2G
) {
3789 char tmp
[2] = "\0\0";
3791 if ((p
= find_pattern(argv
, "rssismf2g", &val
))) {
3793 tmp
[0] |= val
& 0xf;
3795 if ((p
= find_pattern(argv
, "rssismc2g", &val
))) {
3797 tmp
[0] |= (val
& 0xf) << 4;
3799 if ((p
= find_pattern(argv
, "rssisav2g", &val
))) {
3801 tmp
[1] |= val
& 0x7;
3803 if ((p
= find_pattern(argv
, "bxa2g", &val
))) {
3805 tmp
[1] |= (val
& 0x3) << 3;
3808 newtuple(&b
[cnt
], &cnt
, CISTPL_BRCM_HNBU
, srv
);
3809 memcpy(&b
[cnt
], tmp
, 2);
3810 cnt
+= 2; /* contents filled already */
3812 } else if (srv
->tag
== HNBU_RSSISMBXA5G
) {
3814 char tmp
[2] = "\0\0";
3816 if ((p
= find_pattern(argv
, "rssismf5g", &val
))) {
3818 tmp
[0] |= val
& 0xf;
3820 if ((p
= find_pattern(argv
, "rssismc5g", &val
))) {
3822 tmp
[0] |= (val
& 0xf) << 4;
3824 if ((p
= find_pattern(argv
, "rssisav5g", &val
))) {
3826 tmp
[1] |= val
& 0x7;
3828 if ((p
= find_pattern(argv
, "bxa5g", &val
))) {
3830 tmp
[1] |= (val
& 0x3) << 3;
3833 newtuple(&b
[cnt
], &cnt
, CISTPL_BRCM_HNBU
, srv
);
3834 memcpy(&b
[cnt
], tmp
, 2);
3835 cnt
+= 2; /* contents filled already */
3837 } else if (srv
->tag
== HNBU_FEM
) {
3839 uint16 tmp2g
= 0, tmp5g
= 0;
3841 if ((p
= find_pattern(argv
, "antswctl2g", &val
))) {
3843 tmp2g
|= ((val
<< SROM8_FEM_ANTSWLUT_SHIFT
) &
3844 SROM8_FEM_ANTSWLUT_MASK
);
3846 if ((p
= find_pattern(argv
, "triso2g", &val
))) {
3848 tmp2g
|= ((val
<< SROM8_FEM_TR_ISO_SHIFT
) &
3849 SROM8_FEM_TR_ISO_MASK
);
3851 if ((p
= find_pattern(argv
, "pdetrange2g", &val
))) {
3853 tmp2g
|= ((val
<< SROM8_FEM_PDET_RANGE_SHIFT
) &
3854 SROM8_FEM_PDET_RANGE_MASK
);
3856 if ((p
= find_pattern(argv
, "extpagain2g", &val
))) {
3858 tmp2g
|= ((val
<< SROM8_FEM_EXTPA_GAIN_SHIFT
) &
3859 SROM8_FEM_EXTPA_GAIN_MASK
);
3861 if ((p
= find_pattern(argv
, "tssipos2g", &val
))) {
3863 tmp2g
|= ((val
<< SROM8_FEM_TSSIPOS_SHIFT
) &
3864 SROM8_FEM_TSSIPOS_MASK
);
3866 if ((p
= find_pattern(argv
, "antswctl5g", &val
))) {
3868 tmp5g
|= ((val
<< SROM8_FEM_ANTSWLUT_SHIFT
) &
3869 SROM8_FEM_ANTSWLUT_MASK
);
3871 if ((p
= find_pattern(argv
, "triso5g", &val
))) {
3873 tmp5g
|= ((val
<< SROM8_FEM_TR_ISO_SHIFT
) &
3874 SROM8_FEM_TR_ISO_MASK
);
3876 if ((p
= find_pattern(argv
, "pdetrange5g", &val
))) {
3878 tmp5g
|= ((val
<< SROM8_FEM_PDET_RANGE_SHIFT
) &
3879 SROM8_FEM_PDET_RANGE_MASK
);
3881 if ((p
= find_pattern(argv
, "extpagain5g", &val
))) {
3883 tmp5g
|= ((val
<< SROM8_FEM_EXTPA_GAIN_SHIFT
) &
3884 SROM8_FEM_EXTPA_GAIN_MASK
);
3886 if ((p
= find_pattern(argv
, "tssipos5g", &val
))) {
3888 tmp5g
|= ((val
<< SROM8_FEM_TSSIPOS_SHIFT
) &
3889 SROM8_FEM_TSSIPOS_MASK
);
3893 newtuple(&b
[cnt
], &cnt
, CISTPL_BRCM_HNBU
, srv
);
3894 b
[cnt
++] = (uint8
)(tmp2g
& 0xff);
3895 b
[cnt
++] = (uint8
)((tmp2g
>> 8) & 0xff);
3896 b
[cnt
++] = (uint8
)(tmp5g
& 0xff);
3897 b
[cnt
++] = (uint8
)((tmp5g
>> 8) & 0xff);
3899 } else if (srv
->tag
== HNBU_UUID
) {
3901 char *uuidstr
= NULL
;
3902 char nibble
[3] = {0, 0, 0};
3904 if ((uuidstr
= find_pattern(argv
, "uuid", NULL
)) != NULL
) {
3906 /* uuid format 12345678-1234-5678-1234-567812345678 */
3908 if (strlen(uuidstr
) == 36) {
3909 newtuple(&b
[cnt
], &cnt
, CISTPL_BRCM_HNBU
, srv
);
3910 while (*uuidstr
!= '\0') {
3911 if (*uuidstr
== '-') {
3915 nibble
[0] = *uuidstr
++;
3916 nibble
[1] = *uuidstr
++;
3917 b
[cnt
++] = (strtoul(nibble
, NULL
, 16) & 0xFF);
3922 } else { /* All other tuples */
3923 int found
= FALSE
, varlen
= 0;
3924 char *cur
= &b
[cnt
];
3927 /* Walk through each parameters in one tuple */
3928 strcpy(par
, srv
->params
);
3930 cpar
= strtok (par
, delimit
); /* current param */
3934 /* Fill the CIS tuple to b but don't commit cnt yet */
3936 newtuple(cur
, NULL
, CISTPL_BRCM_HNBU
, srv
);
3941 /* the first byte of each parameter indicates its length */
3942 varlen
= (*cpar
++) - '0';
3943 /* Find the parameter in the input argument list */
3944 if ((p
= find_pattern(argv
, cpar
, &val
)))
3947 *cur
++ = (uint8
)(val
& 0xff);
3949 *cur
++ = (uint8
)((val
>> 8) & 0xff);
3951 *cur
++ = (uint8
)((val
>> 16) & 0xff);
3952 *cur
++ = (uint8
)((val
>> 24) & 0xff);
3955 /* move to the next parameter string */
3956 cpar
= strtok(NULL
, delimit
);
3959 /* commit the tuple if its valid */
3961 cnt
+= (cur
- &b
[cnt
]);
3967 printf("buffer size %d bytes:\n", cnt
);
3968 for (i
= 0; i
< cnt
; i
++) {
3969 printf("0x%.02x ", b
[i
] & 0xff);
3970 if (i
%8 == 7) printf("\n");
3977 static const sromvar_t
*
3978 srvlookup(const sromvar_t
*tab
, char *name
, int nlen
, int sromrev
)
3981 const sromvar_t
*srv
= tab
;
3983 srrmask
= 1 << sromrev
;
3986 if ((strncmp(name
, srv
->name
, nlen
) == 0) &&
3987 ((srrmask
& srv
->revmask
) != 0))
3989 while (srv
->flags
& SRFL_MORE
)
3999 wl_nvsource(void *wl
, cmd_t
*cmd
, char **argv
)
4003 if ((err
= wl_var_get(wl
, cmd
, argv
)))
4006 val
= dtoh32(*(int32
*)buf
);
4016 printf("Unrecognized source %d\n", val
);
4024 wlu_srvar(void *wl
, cmd_t
*cmd
, char **argv
)
4027 return CFE_ERR_UNSUPPORTED
;
4029 int ret
, nw
, nlen
, ro
, co
, wr
, sromrev
, shift
= 0;
4032 char *name
, *p
, *newval
;
4033 const sromvar_t
*srv
;
4034 uint16 w
, *words
= (uint16
*)&buf
[8];
4036 struct ether_addr ea
;
4038 ro
= !strcmp(*argv
, "rdvar");
4039 wr
= !strcmp(*argv
, "wrvar");
4040 co
= !strcmp(*argv
, "cisconvert");
4045 /* Check the cis source */
4046 memset(buf
, 0, WLC_IOCTL_MAXLEN
);
4047 strcpy(buf
, "cis_source");
4048 ret
= wl_get(wl
, WLC_GET_VAR
, buf
, strlen(buf
)+1);
4050 ; /* printf("Error %x: cannot get cis_source\n", ret); */
4053 if (buf
[0] == WLC_CIS_OTP
)
4056 /* Do the same thing as nvget */
4057 wl_nvget(wl
, cmd
, argv
);
4061 if ((otp
&& wr
) || co
) {
4063 /* leave an empty srom_rw_t at the front for backward
4066 if (!(cnt
= parsecis(buf
, argv
))) {
4067 printf("Nothing to write!\n");
4072 /* Pass the append buffer to driver */
4073 ret
= wlu_iovar_set(wl
, "cisvar", buf
, cnt
);
4077 /* First read the srom and find out the sromrev */
4078 srt
= (srom_rw_t
*)buf
;
4079 srt
->byteoff
= htod32(0);
4080 srt
->nbytes
= htod32(2 * SROM4_WORDS
);
4084 if ((ret
= wlu_get(wl
, cmd
->get
, buf
, WLC_IOCTL_MAXLEN
)) < 0)
4086 if ((words
[SROM4_SIGN
] != SROM4_SIGNATURE
) &&
4087 (words
[SROM8_SIGN
] != SROM4_SIGNATURE
))
4091 sromrev
= words
[nw
] & 0xff;
4092 if ((sromrev
< 2) || (sromrev
> SROM_MAXREV
)) {
4097 while ((name
= *argv
++) != NULL
) {
4100 newval
= strchr(name
, '=');
4103 nlen
= strlen(name
);
4104 if ((nlen
== 0) || (nlen
> 16)) {
4105 printf("Bad variable name: %s\n", name
);
4109 srv
= srvlookup(pci_sromvars
, name
, nlen
+ 1, sromrev
);
4110 if (srv
->name
== NULL
) {
4113 srv
= srvlookup(perpath_pci_sromvars
, name
, nlen
- 1, sromrev
);
4114 path
= name
[nlen
- 1] - '0';
4115 if ((srv
->name
== NULL
) || (path
< 0) || (path
>= MAX_PATH_SROM
)) {
4116 printf("Variable %s does not exist in sromrev %d\n",
4123 } else if (path
== 1) {
4125 } else if (path
== 2) {
4127 } else if (path
== 3) {
4131 off
= (path
== 0) ? SROM4_PATH0
: SROM4_PATH1
;
4136 /* This code is cheating a bit: it knows that SRFL_ETHADDR means three
4137 * whole words, and SRFL_MORE means 2 whole words (i.e. the masks for
4138 * them are all 0xffff).
4140 if (srv
->flags
& SRFL_ETHADDR
) {
4142 ea
.octet
[0] = w
>> 8;
4143 ea
.octet
[1] = w
& 0xff;
4145 ea
.octet
[2] = w
>> 8;
4146 ea
.octet
[3] = w
& 0xff;
4148 ea
.octet
[4] = w
>> 8;
4149 ea
.octet
[5] = w
& 0xff;
4150 } else if (srv
->flags
& SRFL_MORE
) {
4152 val32
|= words
[srv
[1].off
] << 16;
4154 shift
= ffs(srv
->mask
) - 1;
4155 val32
= (words
[off
] & srv
->mask
) >> shift
;
4159 if (srv
->flags
& SRFL_ETHADDR
)
4160 printf("%s=%s\n", name
, wl_ether_etoa(&ea
));
4161 else if (srv
->flags
& SRFL_PRHEX
)
4162 printf("%s=0x%x\n", name
, val32
);
4163 else if (srv
->flags
& SRFL_PRSIGN
)
4164 printf("%s=%d\n", name
, val32
);
4166 printf("%s=%u\n", name
, val32
);
4169 } else if (wr
&& ((srv
->flags
& (SRFL_MORE
|SRFL_ETHADDR
)) == 0)) {
4170 shift
= ffs(srv
->mask
) - 1;
4173 /* Make the change in the image we read */
4175 printf("wrvar missing value to write for variable %s\n", name
);
4182 /* Cheating again as above */
4183 if (srv
->flags
& SRFL_ETHADDR
) {
4184 if (!wl_ether_atoe(newval
, &ea
)) {
4185 printf("Argument does not look like a MAC address: %s\n", newval
);
4188 words
[off
] = (ea
.octet
[0] << 8) | ea
.octet
[1];
4189 words
[off
+ 1] = (ea
.octet
[2] << 8) | ea
.octet
[3];
4190 words
[off
+ 2] = (ea
.octet
[4] << 8) | ea
.octet
[5];
4193 val32
= strtoul(newval
, &p
, 0);
4195 printf("Bad value: %s for variable %s\n", newval
, name
);
4198 if (srv
->flags
& SRFL_MORE
) {
4199 words
[off
] = val32
& 0xffff;
4200 words
[off
+ 1] = val32
>> 16;
4203 words
[off
] = (((val32
<< shift
) & srv
->mask
) |
4204 (words
[off
] & ~srv
->mask
));
4210 /* Now write all the changes */
4213 srt
->nbytes
= htod32(2 * nw
);
4214 ret
= wlu_set(wl
, cmd
->set
, buf
, (2 * nw
) + 8);
4216 printf("Error %d writing the srom\n", ret
);
4223 /* All 32bits are used. Please populate wl_msgs2[] with further entries */
4224 static dbg_msg_t wl_msgs
[] = {
4225 {WL_ERROR_VAL
, "error"},
4226 {WL_ERROR_VAL
, "err"},
4227 {WL_TRACE_VAL
, "trace"},
4228 {WL_PRHDRS_VAL
, "prhdrs"},
4229 {WL_PRPKT_VAL
, "prpkt"},
4230 {WL_INFORM_VAL
, "inform"},
4231 {WL_INFORM_VAL
, "info"},
4232 {WL_INFORM_VAL
, "inf"},
4233 {WL_TMP_VAL
, "tmp"},
4234 {WL_OID_VAL
, "oid"},
4235 {WL_RATE_VAL
, "rate"},
4236 {WL_ASSOC_VAL
, "assoc"},
4237 {WL_ASSOC_VAL
, "as"},
4238 {WL_PRUSR_VAL
, "prusr"},
4240 {WL_TXPWR_VAL
, "txpwr"},
4241 {WL_TXPWR_VAL
, "pwr"},
4242 {WL_PORT_VAL
, "port"},
4243 {WL_DUAL_VAL
, "dual"},
4244 {WL_WSEC_VAL
, "wsec"},
4245 {WL_WSEC_DUMP_VAL
, "wsec_dump"},
4246 {WL_LOG_VAL
, "log"},
4247 {WL_NRSSI_VAL
, "nrssi"},
4248 {WL_LOFT_VAL
, "loft"},
4249 {WL_REGULATORY_VAL
, "regulatory"},
4250 {WL_RADAR_VAL
, "radar"},
4251 {WL_MPC_VAL
, "mpc"},
4252 {WL_APSTA_VAL
, "apsta"},
4253 {WL_DFS_VAL
, "dfs"},
4255 {WL_MBSS_VAL
, "mbss"},
4256 {WL_CAC_VAL
, "cac"},
4257 {WL_AMSDU_VAL
, "amsdu"},
4258 {WL_AMPDU_VAL
, "ampdu"},
4259 {WL_FFPLD_VAL
, "ffpld"},
4263 /* msglevels which use wl_msg_level2 should go here */
4264 static dbg_msg_t wl_msgs2
[] = {
4265 {WL_DPT_VAL
, "dpt"},
4266 {WL_SCAN_VAL
, "scan"},
4267 {WL_WOWL_VAL
, "wowl"},
4268 {WL_COEX_VAL
, "coex"},
4269 {WL_RTDC_VAL
, "rtdc"},
4270 {WL_PROTO_VAL
, "proto"},
4272 {WL_BTA_VAL
, "bta"},
4274 {WL_CHANINT_VAL
, "chanim"},
4275 {WL_THERMAL_VAL
, "thermal"},
4277 {WL_P2P_VAL
, "p2p"},
4279 {WL_ITFR_VAL
, "itfr"},
4281 {WL_MCHAN_VAL
, "mchan"},
4287 wl_msglevel(void *wl
, cmd_t
*cmd
, char **argv
)
4290 uint hval
= 0, len
, val
= 0, found
, last_val
= 0, msglevel
= 0, msglevel2_add
= 0;
4291 uint msglevel2_del
= 0, msglevel_add
= 0, msglevel_del
= 0, supported
= 1;
4292 char *endptr
= NULL
;
4293 dbg_msg_t
*dbg_msg
= wl_msgs
, *dbg_msg2
= wl_msgs2
;
4295 struct wl_msglevel2 msglevel64
, *reply
;
4296 const char *cmdname
= "msglevel";
4298 UNUSED_PARAMETER(cmd
);
4300 /* but preseve older IOCTL call for older drivers */
4301 if ((ret
= wlu_var_getbuf_sm(wl
, cmdname
, &msglevel64
, sizeof(msglevel64
), &ptr
) < 0)) {
4302 if ((ret
= wlu_get(wl
, WLC_GET_MSGLEVEL
, &msglevel
, sizeof(int))) < 0)
4305 msglevel
= dtoh32(msglevel
);
4307 printf("0x%x ", msglevel
);
4308 for (i
= 0; (val
= dbg_msg
[i
].value
); i
++) {
4309 if ((msglevel
& val
) && (val
!= last_val
))
4310 printf(" %s", dbg_msg
[i
].string
);
4318 if (*s
== '+' || *s
== '-')
4321 msglevel_del
= ~0; /* make the whole list absolute */
4322 val
= strtoul(s
, &endptr
, 0);
4323 if (val
== 0xFFFFFFFF) {
4325 "Bits >32 are not supported on this driver version\n");
4328 /* not an integer if not all the string was parsed by strtoul */
4329 if (*endptr
!= '\0') {
4330 for (i
= 0; (val
= dbg_msg
[i
].value
); i
++)
4331 if (stricmp(dbg_msg
[i
].string
, s
) == 0)
4337 msglevel_del
|= val
;
4339 msglevel_add
|= val
;
4342 msglevel
&= ~msglevel_del
;
4343 msglevel
|= msglevel_add
;
4344 msglevel
= htod32(msglevel
);
4345 return (wlu_set(wl
, WLC_SET_MSGLEVEL
, &msglevel
, sizeof(int)));
4346 } else { /* 64bit message level */
4347 reply
= (struct wl_msglevel2
*)ptr
;
4348 reply
->low
= dtoh32(reply
->low
);
4349 reply
->high
= dtoh32(reply
->high
);
4351 if (reply
->high
!= 0)
4352 printf("0x%x%08x", reply
->high
, reply
->low
);
4354 printf("0x%x ", reply
->low
);
4355 for (i
= 0; (val
= dbg_msg2
[i
].value
); i
++) {
4356 if (((reply
->high
& val
)) && (val
!= last_val
))
4357 printf(" %s", dbg_msg2
[i
].string
);
4361 for (i
= 0; (val
= dbg_msg
[i
].value
); i
++) {
4362 if (((reply
->low
& val
)) && (val
!= last_val
))
4363 printf(" %s", dbg_msg
[i
].string
);
4373 if (*s
== '+' || *s
== '-')
4376 msglevel_del
= ~0; /* make the whole list absolute */
4379 val
= strtoul(s
, &endptr
, 0);
4380 if (val
== 0xFFFFFFFF){ /* Assume >32 bit hex passed in */
4381 if (!(*s
== '0' && *(s
+1) == 'x')) {
4383 "Msg bits >32 take only numerical input in hex\n");
4388 hval
= strtoul(strncpy(t
, s
, len
-8), &endptr
, 0);
4392 val
= strtoul(s
, &endptr
, 0);
4393 if (hval
== 0xFFFFFFFF) {
4394 fprintf(stderr
, "Invalid entry for msglevel\n");
4400 if (*endptr
!= '\0') {
4401 for (i
= 0; (val
= dbg_msg
[i
].value
); i
++) {
4402 if (stricmp(dbg_msg
[i
].string
, s
) == 0) {
4408 for (i
= 0; (hval
= dbg_msg2
[i
].value
); i
++)
4409 if (stricmp(dbg_msg2
[i
].string
, s
) == 0)
4415 if (**argv
== '-') {
4416 msglevel_del
|= val
;
4418 msglevel2_del
|= hval
;
4421 msglevel_add
|= val
;
4423 msglevel2_add
|= hval
;
4427 reply
->low
&= ~msglevel_del
;
4428 reply
->high
&= ~msglevel2_del
;
4429 reply
->low
|= msglevel_add
;
4430 reply
->high
|= msglevel2_add
;
4431 reply
->low
= htod32(reply
->low
);
4432 reply
->high
= htod32(reply
->high
);
4433 msglevel64
.low
= reply
->low
;
4434 msglevel64
.high
= reply
->high
;
4435 return (wlu_var_setbuf(wl
, cmdname
, &msglevel64
, sizeof(msglevel64
)));
4439 fprintf(stderr
, "msg values may be a list of numbers or names from the following set.\n");
4440 fprintf(stderr
, "Use a + or - prefix to make an incremental change.");
4442 for (i
= 0; (val
= dbg_msg
[i
].value
); i
++) {
4443 if (val
!= last_val
)
4444 fprintf(stderr
, "\n0x%04x %s", val
, dbg_msg
[i
].string
);
4446 fprintf(stderr
, ", %s", dbg_msg
[i
].string
);
4450 for (i
= 0; (val
= dbg_msg2
[i
].value
); i
++) {
4451 if (val
!= last_val
)
4452 fprintf(stderr
, "\n0x%x00000000 %s", val
, dbg_msg2
[i
].string
);
4454 fprintf(stderr
, ", %s", dbg_msg2
[i
].string
);
4458 fprintf(stderr
, "\n");
4462 /* make sure the PHY msg level here are in sync with wlc_phy_int.h */
4463 #define WL_PHYHAL_ERROR 0x0001
4464 #define WL_PHYHAL_TRACE 0x0002
4465 #define WL_PHYHAL_INFORM 0x0004
4466 #define WL_PHYHAL_TMP 0x0008
4467 #define WL_PHYHAL_TXPWR 0x0010
4468 #define WL_PHYHAL_CAL 0x0020
4469 #define WL_PHYHAL_ACI 0x0040
4470 #define WL_PHYHAL_RADAR 0x0080
4471 #define WL_PHYHAL_THERMAL 0x0100
4473 static phy_msg_t wl_phy_msgs
[] = {
4474 {WL_PHYHAL_ERROR
, "error"},
4475 {WL_PHYHAL_ERROR
, "err"},
4476 {WL_PHYHAL_TRACE
, "trace"},
4477 {WL_PHYHAL_INFORM
, "inform"},
4478 {WL_PHYHAL_TMP
, "tmp"},
4479 {WL_PHYHAL_TXPWR
, "txpwr"},
4480 {WL_PHYHAL_CAL
, "cal"},
4481 {WL_PHYHAL_RADAR
, "radar"},
4482 {WL_PHYHAL_THERMAL
, "thermal"},
4487 wl_phymsglevel(void *wl
, cmd_t
*cmd
, char **argv
)
4490 uint val
= 0, last_val
= 0;
4491 uint phymsglevel
= 0, phymsglevel_add
= 0, phymsglevel_del
= 0;
4493 phy_msg_t
*phy_msg
= wl_phy_msgs
;
4494 const char *cmdname
= "phymsglevel";
4496 UNUSED_PARAMETER(cmd
);
4497 if ((ret
= wlu_iovar_getint(wl
, cmdname
, (int *)&phymsglevel
) < 0)) {
4500 phymsglevel
= dtoh32(phymsglevel
);
4502 printf("0x%x ", phymsglevel
);
4503 for (i
= 0; (val
= phy_msg
[i
].value
); i
++) {
4504 if ((phymsglevel
& val
) && (val
!= last_val
))
4505 printf(" %s", phy_msg
[i
].string
);
4513 if (*s
== '+' || *s
== '-')
4516 phymsglevel_del
= ~0; /* make the whole list absolute */
4517 val
= strtoul(s
, &endptr
, 0);
4518 if (val
== 0xFFFFFFFF) {
4520 "Bits >32 are not supported on this driver version\n");
4523 /* not an integer if not all the string was parsed by strtoul */
4524 if (*endptr
!= '\0') {
4525 for (i
= 0; (val
= phy_msg
[i
].value
); i
++)
4526 if (stricmp(phy_msg
[i
].string
, s
) == 0)
4532 phymsglevel_del
|= val
;
4534 phymsglevel_add
|= val
;
4537 phymsglevel
&= ~phymsglevel_del
;
4538 phymsglevel
|= phymsglevel_add
;
4539 phymsglevel
= htod32(phymsglevel
);
4540 return (wlu_iovar_setint(wl
, cmdname
, (int)phymsglevel
));
4543 fprintf(stderr
, "msg values may be a list of numbers or names from the following set.\n");
4544 fprintf(stderr
, "Use a + or - prefix to make an incremental change.");
4545 for (i
= 0; (val
= phy_msg
[i
].value
); i
++) {
4546 if (val
!= last_val
)
4547 fprintf(stderr
, "\n0x%04x %s", val
, phy_msg
[i
].string
);
4549 fprintf(stderr
, ", %s", phy_msg
[i
].string
);
4555 /* take rate arg in units of 500Kbits/s and print it in units of Mbit/s */
4557 wl_printrate(int val
)
4561 printf("%s\n", rate_int2string(rate_buf
, val
));
4564 /* convert rate string in Mbit/s format, like "11", "5.5", to internal 500 Kbit/s units */
4566 rate_string2int(char *s
)
4568 if (!stricmp(s
, "-1"))
4570 if (!stricmp(s
, "5.5"))
4572 return (atoi(s
) * 2);
4575 /* convert rate internal 500 Kbits/s units to string in Mbits/s format, like "11", "5.5" */
4577 rate_int2string(char *rate_buf
, int val
)
4579 if ((val
== -1) || (val
== 0))
4580 sprintf(rate_buf
, "auto");
4581 else if (val
> 1000) /* this indicates that units are kbps */
4582 sprintf(rate_buf
, "%d Kbps", val
);
4584 sprintf(rate_buf
, "%d%s Mbps", (val
/ 2), (val
& 1) ? ".5" : "");
4588 /* handles both "rate" and "mrate", which makes the flow a bit complex */
4590 wl_rate_mrate(void *wl
, cmd_t
*cmd
, char **argv
)
4596 char aname
[sizeof("a_mrate") + 1];
4597 char bgname
[sizeof("bg_mrate") + 1];
4600 sprintf(aname
, "a_%s", *argv
);
4601 sprintf(bgname
, "bg_%s", *argv
);
4604 if ((error
= wlu_get(wl
, WLC_GET_BAND
, &band
, sizeof(uint
))) < 0)
4606 band
= dtoh32(band
);
4608 if ((error
= wlu_get(wl
, WLC_GET_BANDLIST
, list
, sizeof(list
))) < 0)
4610 list
[0] = dtoh32(list
[0]);
4611 list
[1] = dtoh32(list
[1]);
4612 list
[2] = dtoh32(list
[2]);
4616 else if (list
[0] > 2)
4619 if ((!strcmp(*argv
, "rate"))) {
4622 /* it is "rate" get. handle it here */
4623 /* WLC_GET_RATE processing */
4624 if ((error
= wlu_get(wl
, cmd
->get
, &val
, sizeof(int))) < 0)
4632 --argv
; /* move it back for later processing */
4636 case WLC_BAND_AUTO
:
4639 else if (list
[1] == WLC_BAND_5G
)
4640 name
= (char *)aname
;
4641 else if (list
[1] == WLC_BAND_2G
)
4642 name
= (char *)bgname
;
4649 name
= (char *)aname
;
4653 name
= (char *)bgname
;
4662 /* it is "mrate" get */
4663 if ((error
= wlu_iovar_getint(wl
, name
, &val
) < 0))
4673 val
= rate_string2int(*argv
);
4674 return wlu_iovar_setint(wl
, name
, val
);
4679 wl_wepstatus(void *wl
, cmd_t
*cmd
, char **argv
)
4682 const char *name
= "wsec";
4685 UNUSED_PARAMETER(cmd
);
4688 if ((error
= wlu_iovar_getint(wl
, name
, &val
) < 0))
4691 printf("%d\n", val
);
4695 if ((error
= wlu_iovar_getint(wl
, name
, &wsec
) < 0))
4699 wsec
|= WEP_ENABLED
;
4701 wsec
&= ~WEP_ENABLED
;
4703 return wlu_iovar_setint(wl
, name
, wsec
);
4708 wl_bss_max(void *wl
, cmd_t
*cmd
, char **argv
)
4713 UNUSED_PARAMETER(argv
);
4715 /* Get the CAP variable; search for mbss4 or mbss16 */
4717 if ((error
= wlu_get(wl
, cmd
->get
, buf
, WLC_IOCTL_SMLEN
)) < 0)
4719 if (strstr(buf
, "mbss16")) val
= 16;
4720 else if (strstr(buf
, "mbss4")) val
= 4;
4722 printf("%d\n", val
);
4727 wl_phy_rate(void *wl
, cmd_t
*cmd
, char **argv
)
4735 strcpy(buf
, cmd
->name
);
4736 if ((error
= wlu_get(wl
, cmd
->get
, buf
, WLC_IOCTL_SMLEN
)) < 0)
4738 val
= dtoh32(*pval
);
4742 val
= htod32(rate_string2int(*argv
));
4744 /* construct an iovar */
4745 strcpy(buf
, cmd
->name
);
4746 p
= &buf
[strlen(buf
) + 1];
4747 memcpy(p
, &val
, sizeof(uint
));
4750 return (wlu_set(wl
, cmd
->set
, &buf
[0], (p
- buf
)));
4755 wl_nrate(void *wl
, cmd_t
*cmd
, char **argv
)
4758 const char* fn_name
= "wl_nrate", *rspec_auto
= "auto";
4759 bool mcs_set
= FALSE
, legacy_set
= FALSE
, stf_set
= FALSE
;
4760 bool mcs_only
= FALSE
;
4766 /* toss the command name */
4772 if ((err
= wlu_iovar_getint(wl
, "nrate", (int*)&val
)) < 0)
4778 stf
= (uint
)((val
& NRATE_STF_MASK
) >> NRATE_STF_SHIFT
);
4779 nrate
= (val
& NRATE_RATE_MASK
);
4780 if (val
& NRATE_OVERRIDE
) {
4781 if (val
& NRATE_OVERRIDE_MCS_ONLY
)
4782 rspec_auto
= "fixed mcs only";
4784 rspec_auto
= "fixed";
4787 if (val
& NRATE_MCS_INUSE
)
4788 printf("mcs index %d stf mode %d %s\n",
4789 nrate
, stf
, rspec_auto
);
4791 printf("legacy rate %d%s Mbps stf mode %d %s\n",
4792 nrate
/2, (nrate
% 2)?".5":"", stf
, rspec_auto
);
4797 miniopt_init(&to
, fn_name
, "w", FALSE
);
4798 while ((opt_err
= miniopt(&to
, argv
)) != -1) {
4803 argv
+= to
.consumed
;
4805 if (to
.opt
== 'r') {
4807 /* special case check for "-r 5.5" */
4808 if (!strcmp(to
.valstr
, "5.5")) {
4812 "%s: could not parse \"%s\" as a rate value\n",
4813 fn_name
, to
.valstr
);
4820 fprintf(stderr
, "%s: cannot use -r and -m\n", fn_name
);
4824 nrate
|= to
.val
& NRATE_RATE_MASK
;
4827 if (to
.opt
== 'm') {
4830 "%s: could not parse \"%s\" as an int for mcs\n",
4831 fn_name
, to
.valstr
);
4836 fprintf(stderr
, "%s: cannot use -r and -m\n", fn_name
);
4841 nrate
|= to
.val
& NRATE_RATE_MASK
;
4842 nrate
|= NRATE_MCS_INUSE
;
4844 if (to
.opt
== 's') {
4847 "%s: could not parse \"%s\" as an int for stf mode\n",
4848 fn_name
, to
.valstr
);
4852 nrate
|= (to
.val
<< NRATE_STF_SHIFT
) & NRATE_STF_MASK
;
4855 if (to
.opt
== 'w') {
4856 nrate
|= NRATE_OVERRIDE_MCS_ONLY
;
4861 if ((mcs_only
&& !mcs_set
) || (mcs_only
&& (stf_set
|| legacy_set
))) {
4862 fprintf(stderr
, "%s: can use -w only with -m\n", fn_name
);
4870 stf
= NRATE_STF_SISO
; /* SISO */
4872 if ((nrate
& NRATE_RATE_MASK
) <= HIGHEST_SINGLE_STREAM_MCS
||
4873 (nrate
& NRATE_RATE_MASK
) == 32)
4874 stf
= NRATE_STF_SISO
; /* SISO */
4876 stf
= NRATE_STF_SDM
; /* SDM */
4878 nrate
|= (stf
<< NRATE_STF_SHIFT
) & NRATE_STF_MASK
;
4881 if (legacy_set
|| mcs_set
) {
4882 err
= wlu_iovar_setint(wl
, "nrate", (int)nrate
);
4884 fprintf(stderr
, "%s: you need to set a legacy or mcs rate\n", fn_name
);
4893 wl_assoc_info(void *wl
, cmd_t
*cmd
, char **argv
)
4895 uint i
, req_ies_len
= 0, resp_ies_len
= 0;
4896 wl_assoc_info_t assoc_info
;
4900 UNUSED_PARAMETER(argv
);
4902 /* get the generic association information */
4903 strcpy(buf
, cmd
->name
);
4904 if ((ret
= wlu_get(wl
, cmd
->get
, buf
, WLC_IOCTL_SMLEN
)) < 0)
4907 memcpy(&assoc_info
, buf
, sizeof(wl_assoc_info_t
));
4908 assoc_info
.req_len
= htod32(assoc_info
.req_len
);
4909 assoc_info
.resp_len
= htod32(assoc_info
.resp_len
);
4910 assoc_info
.flags
= htod32(assoc_info
.flags
);
4912 printf("Assoc req:\n");
4913 printf("\tlen 0x%x\n", assoc_info
.req_len
);
4914 if (assoc_info
.req_len
) {
4915 printf("\tcapab 0x%x\n", ltoh16(assoc_info
.req
.capability
));
4916 printf("\tlisten 0x%x\n", ltoh16(assoc_info
.req
.listen
));
4917 req_ies_len
= assoc_info
.req_len
- sizeof(struct dot11_assoc_req
);
4918 if (assoc_info
.flags
& WLC_ASSOC_REQ_IS_REASSOC
) {
4919 printf("\treassoc bssid %s\n",
4920 wl_ether_etoa(&assoc_info
.reassoc_bssid
));
4921 req_ies_len
-= ETHER_ADDR_LEN
;
4925 /* get the association req IE's if there are any */
4927 strcpy(buf
, "assoc_req_ies");
4928 if ((ret
= wlu_get(wl
, cmd
->get
, buf
, WLC_IOCTL_SMLEN
)) < 0)
4931 printf("assoc req IEs:\n\t");
4932 for (i
= 1, pbuf
= (uint8
*)buf
; i
<= req_ies_len
; i
++) {
4933 printf("0x%02x ", *pbuf
++);
4939 printf("\nAssoc resp:\n");
4940 printf("\tlen 0x%x\n", assoc_info
.resp_len
);
4941 if (assoc_info
.resp_len
) {
4942 printf("\tcapab 0x%x\n", ltoh16(assoc_info
.resp
.capability
));
4943 printf("\tstatus 0x%x\n", ltoh16(assoc_info
.resp
.status
));
4944 printf("\taid 0x%x\n", ltoh16(assoc_info
.resp
.aid
));
4945 resp_ies_len
= assoc_info
.resp_len
- sizeof(struct dot11_assoc_resp
);
4948 /* get the association resp IE's if there are any */
4950 strcpy(buf
, "assoc_resp_ies");
4951 if ((ret
= wlu_get(wl
, cmd
->get
, buf
, WLC_IOCTL_SMLEN
)) < 0)
4954 printf("assoc resp IEs:\n\t");
4955 for (i
= 1, pbuf
= (uint8
*)buf
; i
<= resp_ies_len
; i
++) {
4956 printf(" 0x%02x ", *pbuf
++);
4968 wl_pmkid_info(void *wl
, cmd_t
*cmd
, char**argv
)
4971 pmkid_list_t
*pmkid_info
;
4974 strcpy(buf
, cmd
->name
);
4975 if ((ret
= wlu_get(wl
, cmd
->get
, buf
, WLC_IOCTL_SMLEN
)) < 0)
4978 pmkid_info
= (pmkid_list_t
*)buf
;
4979 pmkid_info
->npmkid
= dtoh32(pmkid_info
->npmkid
);
4980 printf("\npmkid entries : %d\n", pmkid_info
->npmkid
);
4982 for (i
= 0; i
< (int)pmkid_info
->npmkid
; i
++) {
4983 printf("\tPMKID[%d]: %s =",
4984 i
, wl_ether_etoa(&pmkid_info
->pmkid
[i
].BSSID
));
4985 for (j
= 0; j
< WPA2_PMKID_LEN
; j
++)
4986 printf("%02x ", pmkid_info
->pmkid
[i
].PMKID
[j
]);
4991 #ifdef test_pmkid_info
4992 char eaddr
[6] = {0x0, 0x0, 0x1, 0x2, 0x3, 0x5};
4993 char eaddr1
[6] = {0xa, 0xb, 0xc, 0xd, 0xe, 0xf};
4994 char id
[WPA2_PMKID_LEN
], id1
[WPA2_PMKID_LEN
];
4995 int i
, len
= (sizeof(uint32
) + 2*(sizeof(pmkid_t
)));
4997 /* check that the set uses to "test" cmd */
4998 if (strcmp(*argv
, "test")) {
4999 printf("\t wl pmkid_info only supports `test` a test specific set\n");
5002 if ((pmkid_info
= (pmkid_list_t
*)malloc(len
)) == NULL
) {
5003 printf("\tfailed to allocate buffer\n");
5007 printf("\toverwriting pmkid table with test pattern\n");
5008 for (i
= 0; i
< (int)sizeof(id
); i
++) {
5013 /* "test" - creates two PMKID entries and sets the table to that */
5014 pmkid_info
->npmkid
= htod32(2);
5015 memcpy(&pmkid_info
->pmkid
[0].BSSID
.octet
[0], &eaddr
[0], ETHER_ADDR_LEN
);
5016 memcpy(&pmkid_info
->pmkid
[0].PMKID
[0], &id
[0], WPA2_PMKID_LEN
);
5017 memcpy(&pmkid_info
->pmkid
[1].BSSID
.octet
[0], &eaddr1
[0], ETHER_ADDR_LEN
);
5018 memcpy(&pmkid_info
->pmkid
[1].PMKID
[0], &id1
[0], WPA2_PMKID_LEN
);
5020 ret
= wlu_var_setbuf(wl
, cmd
->name
, pmkid_info
, len
);
5026 printf("\tset cmd ignored\n");
5027 #endif /* test_pmkid_info */
5034 wl_rateset(void *wl
, cmd_t
*cmd
, char **argv
)
5036 wl_rateset_args_t rs
, defrs
;
5040 UNUSED_PARAMETER(cmd
);
5046 if (*argv
== NULL
) {
5047 /* get current rateset */
5048 if ((error
= wlu_iovar_get(wl
, "cur_rateset", &rs
, sizeof(rs
))) < 0)
5051 dump_rateset(rs
.rates
, dtoh32(rs
.count
));
5053 wl_print_mcsset((char *)rs
.mcs
);
5055 /* get default rateset and mcsset */
5056 if ((error
= wlu_iovar_get(wl
, "rateset", &defrs
,
5057 sizeof(wl_rateset_args_t
))) < 0)
5059 defrs
.count
= dtoh32(defrs
.count
);
5061 if (!stricmp(*argv
, "all")) {
5062 for (i
= 0; i
< defrs
.count
; i
++)
5063 defrs
.rates
[i
] |= 0x80;
5064 defrs
.count
= htod32(defrs
.count
);
5065 error
= wlu_iovar_set(wl
, "rateset", &defrs
,
5066 sizeof(wl_rateset_args_t
));
5068 else if (!stricmp(*argv
, "default")) {
5069 defrs
.count
= htod32(defrs
.count
);
5070 error
= wlu_iovar_set(wl
, "rateset", &defrs
,
5071 sizeof(wl_rateset_args_t
));
5073 else { /* arbitrary list */
5074 wl_parse_rateset(wl
, &defrs
, argv
);
5075 /* check for common error of no basic rates */
5076 for (i
= 0; i
< defrs
.count
; i
++) {
5077 if (defrs
.rates
[i
] & 0x80)
5080 if (i
< defrs
.count
) {
5081 defrs
.count
= htod32(defrs
.count
);
5082 error
= wlu_iovar_set(wl
, "rateset", &defrs
,
5083 sizeof(wl_rateset_args_t
));
5087 "Bad Args: at least one rate must be marked Basic\n");
5097 wl_sup_rateset(void *wl
, cmd_t
*cmd
, char **argv
)
5099 wl_rateset_args_t rs
;
5105 memset((char*)&rs
, 0, sizeof(wl_rateset_args_t
));
5109 if (*argv
== NULL
) {
5111 if ((error
= wlu_get(wl
, cmd
->get
, &rs
, sizeof(wl_rateset_t
))) < 0)
5114 dump_rateset(rs
.rates
, dtoh32(rs
.count
));
5117 if (!stricmp(*argv
, "-1") || !stricmp(*argv
, "0")) {
5118 /* set an empty rateset */
5119 error
= wlu_set(wl
, cmd
->set
, &rs
, sizeof(wl_rateset_t
));
5121 else { /* set the specified rateset */
5122 wl_parse_rateset(wl
, &rs
, argv
);
5123 /* check for common error of including a basic rate */
5125 for (i
= 0; i
< rs
.count
; i
++) {
5126 if (rs
.rates
[i
] & 0x80) {
5127 rs
.rates
[i
] &= 0x7F;
5133 "Warning: Basic rate attribute ignored for \"%s\" command\n",
5136 rs
.count
= htod32(rs
.count
);
5137 error
= wlu_set(wl
, cmd
->set
, &rs
, sizeof(wl_rateset_t
));
5145 wl_parse_rateset(void *wl
, wl_rateset_args_t
* rs
, char **argv
)
5152 bool mcs_args
= FALSE
;
5153 wl_rateset_args_t cur_rs
;
5155 memset(rs
, 0, sizeof(*rs
));
5157 while ((arg
= *argv
++) != NULL
) {
5159 if (!stricmp(arg
, "-m")) {
5164 if (rs
->count
>= WL_NUMRATES
) {
5166 "parsing \"%s\", too many rates specified, max is %d rates\n",
5172 /* convert the rate number to a 500kbps rate by multiplying by 2 */
5173 r
= (int)(strtoul(arg
, &endp
, 0) * 2);
5175 fprintf(stderr
, "unable to convert the rate parameter \"%s\"\n", arg
);
5180 /* parse a .5 specially */
5181 if (!strncmp(endp
, ".5", 2)) {
5186 /* strip trailing space */
5187 while (isspace((int)endp
[0]))
5190 /* check for a basic rate specifier */
5191 if (!stricmp(endp
, "b") || !stricmp(endp
, "(b)")) {
5193 } else if (endp
[0] != '\0') {
5195 "unable to convert trailing characters"
5196 " \"%s\" in the rate parameter \"%s\"\n",
5202 /* no legacy rates specified */
5203 if ((rs
->count
== 0) && (r
== 0)) {
5204 fprintf(stderr
, "empty legacy rateset not supported\n");
5209 rs
->rates
[rs
->count
++] = r
;
5216 /* if legacy rates are specified and not the mcs rates then
5217 * it implies that the user is trying to change only the
5218 * legacy rates. to avoid clearing the mcsset first get
5219 * the current mcsset and use it to set along with the new
5222 error
= wlu_iovar_get(wl
, "cur_rateset", &cur_rs
, sizeof(cur_rs
));
5224 memcpy(rs
->mcs
, cur_rs
.mcs
, MCSSET_LEN
);
5229 /* no legacy rates are specified in the command. so get the current
5230 * legacy rateset and use it to set along with new mcsset.
5232 if (rs
->count
== 0) {
5233 error
= wlu_iovar_get(wl
, "cur_rateset", &cur_rs
, sizeof(cur_rs
));
5235 rs
->count
= cur_rs
.count
;
5236 memcpy(&rs
->rates
, &cur_rs
.rates
, rs
->count
);
5241 /* Parse mcs rateset values */
5242 while ((arg
= *argv
++) != NULL
) {
5243 if (i
>= MCSSET_LEN
) {
5244 fprintf(stderr
, "parsing \"%s\", too many mcs rates "
5245 "specified, max is %d rates\n", arg
, MCSSET_LEN
);
5250 m
= (int)strtoul(arg
, &endp
, 16);
5253 fprintf(stderr
, "unable to convert the mcs parameter \"%s\"\n", arg
);
5258 /* strip trailing space */
5259 while (isspace((int)endp
[0]))
5262 /* clear the mcs rates */
5264 memset(rs
->mcs
, 0, MCSSET_LEN
);
5268 /* copy the mcs rates bitmap octets */
5276 wl_channel(void *wl
, cmd_t
*cmd
, char **argv
)
5282 memset(&ci
, 0, sizeof(ci
));
5283 if ((ret
= wlu_get(wl
, cmd
->get
, &ci
, sizeof(channel_info_t
))) < 0)
5285 ci
.hw_channel
= dtoh32(ci
.hw_channel
);
5286 ci
.scan_channel
= dtoh32(ci
.scan_channel
);
5287 ci
.target_channel
= dtoh32(ci
.target_channel
);
5288 if (ci
.scan_channel
) {
5289 printf("Scan in progress.\n");
5290 printf("current scan channel\t%d\n", ci
.scan_channel
);
5292 printf("No scan in progress.\n");
5294 printf("current mac channel\t%d\n", ci
.hw_channel
);
5295 printf("target channel\t%d\n", ci
.target_channel
);
5298 ci
.target_channel
= htod32(atoi(*argv
));
5299 ret
= wlu_set(wl
, cmd
->set
, &ci
.target_channel
, sizeof(int));
5305 wl_chanspec(void *wl
, cmd_t
*cmd
, char **argv
)
5308 const char* fn_name
= "wl_chanspec";
5309 bool band_set
= FALSE
, ch_set
= FALSE
, bw_set
= FALSE
, ctl_sb_set
= FALSE
;
5312 chanspec_t chanspec
= 0;
5314 /* toss the command name */
5320 if ((err
= wlu_iovar_getint(wl
, cmd
->name
, (int*)&val
)) < 0)
5323 wf_chspec_ntoa((chanspec_t
)val
, buf
);
5324 printf("%s (0x%x)\n", buf
, val
);
5329 if ((chanspec
= wf_chspec_aton(*argv
))) {
5330 err
= wlu_iovar_setint(wl
, cmd
->name
, (int)chanspec
);
5332 miniopt_init(&to
, fn_name
, NULL
, FALSE
);
5333 while ((opt_err
= miniopt(&to
, argv
)) != -1) {
5338 argv
+= to
.consumed
;
5340 if (to
.opt
== 'c') {
5343 "%s: could not parse \"%s\" as an int for"
5344 " the channel\n", fn_name
, to
.valstr
);
5349 fprintf(stderr
, "%s: invalid channel %d\n",
5357 if (to
.opt
== 'b') {
5360 "%s: could not parse \"%s\" as an int for band\n",
5361 fn_name
, to
.valstr
);
5365 if ((to
.val
!= 5) && (to
.val
!= 2)) {
5367 "%s: invalid band %d\n",
5373 chanspec
|= WL_CHANSPEC_BAND_5G
;
5375 chanspec
|= WL_CHANSPEC_BAND_2G
;
5378 if (to
.opt
== 'w') {
5381 "%s: could not parse \"%s\" as an int for"
5382 " bandwidth\n", fn_name
, to
.valstr
);
5386 if ((to
.val
!= 20) && (to
.val
!= 40)) {
5388 "%s: invalid bandwidth %d\n",
5394 chanspec
|= WL_CHANSPEC_BW_20
;
5396 chanspec
|= WL_CHANSPEC_BW_40
;
5399 if (to
.opt
== 's') {
5402 "%s: could not parse \"%s\" as an int for"
5403 " ctl sideband\n", fn_name
, to
.valstr
);
5407 if ((to
.val
!= 1) && (to
.val
!= 0) && (to
.val
!= -1)) {
5409 "%s: invalid ctl sideband %d\n",
5415 chanspec
|= WL_CHANSPEC_CTL_SB_LOWER
;
5416 else if (to
.val
== 1)
5417 chanspec
|= WL_CHANSPEC_CTL_SB_UPPER
;
5419 chanspec
|= WL_CHANSPEC_CTL_SB_NONE
;
5424 /* set ctl sb to 20 if not set and 20mhz is selected */
5425 if (!ctl_sb_set
&& CHSPEC_IS20(chanspec
)) {
5426 chanspec
|= WL_CHANSPEC_CTL_SB_NONE
;
5430 if (ch_set
&& band_set
&& bw_set
&& ctl_sb_set
) {
5431 err
= wlu_iovar_setint(wl
, cmd
->name
, (int)chanspec
);
5434 fprintf(stderr
, "%s: you need to set a channel,"
5435 " '-c <ch>'\n", fn_name
);
5437 fprintf(stderr
, "%s: you need to set a band,"
5438 " '-b <5|2>'\n", fn_name
);
5440 fprintf(stderr
, "%s: you need to set a bandwidth,"
5441 " '-w <20|40>'\n", fn_name
);
5443 fprintf(stderr
, "%s: you need to set a ctl sideband,"
5444 " '-s <-1|0|1>'\n", fn_name
);
5450 printf("Chanspec set to 0x%x\n", chanspec
);
5457 wl_chanim_state(void *wl
, cmd_t
*cmd
, char **argv
)
5465 /* find the arg count */
5472 chanspec
= wf_chspec_aton(*argv
);
5474 ret
= wlu_iovar_getbuf(wl
, cmd
->name
, &chanspec
, sizeof(chanspec
),
5475 buf
, WLC_IOCTL_SMLEN
);
5481 printf("%d\n", val
);
5486 wl_chanim_mode(void *wl
, cmd_t
*cmd
, char **argv
)
5496 if ((ret
= wlu_iovar_getint(wl
, cmd
->name
, &mode
)) < 0)
5500 case CHANIM_DISABLE
:
5501 printf("CHANIM mode: disabled.\n");
5504 printf("CHANIM mode: detect only.\n");
5507 printf("CHANIM mode: detect + act.\n");
5512 mode
= CHANIM_DETECT
;
5513 val
= strtol(*argv
, &endptr
, 0);
5514 if (*endptr
!= '\0')
5519 mode
= CHANIM_DISABLE
;
5522 mode
= CHANIM_DETECT
;
5531 mode
= htod32(mode
);
5532 return wlu_iovar_setint(wl
, cmd
->name
, mode
);
5537 wl_ether_atoe(const char *a
, struct ether_addr
*n
)
5542 memset(n
, 0, ETHER_ADDR_LEN
);
5544 n
->octet
[i
++] = (uint8
)strtoul(a
, &c
, 16);
5545 if (!*c
++ || i
== ETHER_ADDR_LEN
)
5549 return (i
== ETHER_ADDR_LEN
);
5553 wl_ether_etoa(const struct ether_addr
*n
)
5555 static char etoa_buf
[ETHER_ADDR_LEN
* 3];
5559 for (i
= 0; i
< ETHER_ADDR_LEN
; i
++) {
5562 c
+= sprintf(c
, "%02X", n
->octet
[i
] & 0xff);
5568 wl_atoip(const char *a
, struct ipv4_addr
*n
)
5574 n
->addr
[i
++] = (uint8
)strtoul(a
, &c
, 0);
5575 if (*c
++ != '.' || i
== IPV4_ADDR_LEN
)
5579 return (i
== IPV4_ADDR_LEN
);
5583 wl_iptoa(const struct ipv4_addr
*n
)
5585 static char iptoa_buf
[IPV4_ADDR_LEN
* 4];
5587 sprintf(iptoa_buf
, "%u.%u.%u.%u",
5588 n
->addr
[0], n
->addr
[1], n
->addr
[2], n
->addr
[3]);
5594 wl_format_ssid(char* ssid_buf
, uint8
* ssid
, int ssid_len
)
5599 if (ssid_len
> 32) ssid_len
= 32;
5601 for (i
= 0; i
< ssid_len
; i
++) {
5606 } else if (isprint((uchar
)c
)) {
5609 p
+= sprintf(p
, "\\x%02X", c
);
5614 return p
- ssid_buf
;
5617 /* pretty hex print a contiguous buffer */
5619 wl_hexdump(uchar
*dump_buf
, uint nbytes
)
5631 for (i
= 0; i
< nbytes
; i
++) {
5632 if (i
% 16 == 0 && nbytes
> 16) {
5633 p
+= sprintf(p
, "%04d: ", i
); /* line prefix */
5635 p
+= sprintf(p
, "%02x ", dump_buf
[i
]);
5637 printf("%s\n", line
); /* flush line */
5642 /* flush last partial line */
5644 printf("%s\n", line
);
5648 wl_plcphdr(void *wl
, cmd_t
*cmd
, char **argv
)
5654 if ((ret
= wlu_get(wl
, cmd
->get
, &val
, sizeof(int))) < 0)
5657 if (val
== WLC_PLCP_AUTO
)
5659 else if (val
== WLC_PLCP_SHORT
)
5661 else if (val
== WLC_PLCP_LONG
)
5668 if (!stricmp(*argv
, "long"))
5669 val
= WLC_PLCP_AUTO
;
5670 else if (!stricmp(*argv
, "auto"))
5671 val
= WLC_PLCP_SHORT
;
5672 else if (!stricmp(*argv
, "debug"))
5673 val
= WLC_PLCP_LONG
;
5677 return wlu_set(wl
, cmd
->set
, &val
, sizeof(int));
5681 /* WLC_GET_RADIO and WLC_SET_RADIO in driver operate on radio_disabled which
5682 * is opposite of "wl radio [1|0]". So invert for user.
5683 * In addition, display WL_RADIO_SW_DISABLE and WL_RADIO_HW_DISABLE bits.
5686 wl_radio(void *wl
, cmd_t
*cmd
, char **argv
)
5690 char *endptr
= NULL
;
5695 if ((ret
= wlu_get(wl
, cmd
->get
, &val
, sizeof(int))) < 0)
5698 printf("0x%04x\n", val
);
5703 if (!stricmp(*argv
, "on"))
5704 val
= WL_RADIO_SW_DISABLE
<< 16;
5705 else if (!stricmp(*argv
, "off"))
5706 val
= WL_RADIO_SW_DISABLE
<< 16 | WL_RADIO_SW_DISABLE
;
5708 val
= strtol(*argv
, &endptr
, 0);
5709 if (*endptr
!= '\0') {
5710 /* not all the value string was parsed by strtol */
5714 /* raw bits setting, add the mask if not provided */
5715 if ((val
>> 16) == 0) {
5720 return wlu_set(wl
, cmd
->set
, &val
, sizeof(int));
5725 ver2str(unsigned int vms
, unsigned int vls
)
5727 static char verstr
[100];
5728 unsigned int maj
, year
, month
, day
, build
;
5730 maj
= (vms
>> 16) & 0xFFFF;
5732 /* it is probably a date... */
5733 year
= (vms
>> 16) & 0xFFFF;
5734 month
= vms
& 0xFFFF;
5735 day
= (vls
>> 16) & 0xFFFF;
5736 build
= vls
& 0xFFFF;
5737 sprintf(verstr
, "%d/%d/%d build %d",
5738 month
, day
, year
, build
);
5740 /* it is a tagged release. */
5741 sprintf(verstr
, "%d.%d RC%d.%d",
5742 (vms
>>16)&0xFFFF, vms
&0xFFFF,
5743 (vls
>>16)&0xFFFF, vls
&0xFFFF);
5750 wl_version(void *wl
, cmd_t
*cmd
, char **argv
)
5757 UNUSED_PARAMETER(cmd
);
5758 UNUSED_PARAMETER(argv
);
5761 ver2str(((EPI_MAJOR_VERSION
) << 16) | EPI_MINOR_VERSION
,
5762 (EPI_RC_NUMBER
<< 16) | EPI_INCREMENTAL_NUMBER
));
5764 dump_buf
= malloc(WLC_IOCTL_SMLEN
);
5765 if (dump_buf
== NULL
) {
5766 fprintf(stderr
, "Failed to allocate dump buffer of %d bytes\n", WLC_IOCTL_SMLEN
);
5769 memset(dump_buf
, 0, WLC_IOCTL_SMLEN
);
5771 /* query for 'ver' to get version info */
5772 ret
= wlu_iovar_get(wl
, "ver", dump_buf
, WLC_IOCTL_SMLEN
);
5774 /* if the query is successful, continue on and print the result. */
5776 /* if the query fails, check for a legacy driver that does not support
5777 * the "dump" iovar, and instead issue a WLC_DUMP ioctl.
5780 wlu_iovar_getint(wl
, "bcmerror", &bcmerr
);
5781 if (bcmerr
== BCME_UNSUPPORTED
) {
5782 ret
= wlu_get(wl
, WLC_DUMP
, dump_buf
, WLC_IOCTL_SMLEN
);
5787 fprintf(stderr
, "Error %d on query of driver dump\n", (int)ret
);
5792 /* keep only the first line from the dump buf output */
5793 p
= strchr(dump_buf
, '\n');
5796 printf("%s\n", dump_buf
);
5804 wl_rateparam(void *wl
, cmd_t
*cmd
, char **argv
)
5810 val
[0] = htod32(atoi(*argv
));
5813 val
[1] = htod32(atoi(*argv
));
5814 return wlu_set(wl
, cmd
->set
, val
, 2 * sizeof(val
));
5818 * -s --ssid=ssid_list
5819 * -t T --scan_type=T : [active|passive]
5820 * --bss_type=T : [infra|bss|adhoc|ibss]
5830 /* Parse a comma-separated list from list_str into ssid array, starting
5831 * at index idx. Max specifies size of the ssid array. Parses ssids
5832 * and returns updated idx; if idx >= max not all fit, the excess have
5833 * not been copied. Returns -1 on empty string, or on ssid too long.
5836 wl_parse_ssid_list(char* list_str
, wlc_ssid_t
* ssid
, int idx
, int max
)
5840 if (list_str
== NULL
)
5843 for (str
= list_str
; str
!= NULL
; str
= ptr
) {
5844 if ((ptr
= strchr(str
, ',')) != NULL
)
5847 if (strlen(str
) > DOT11_MAX_SSID_LEN
) {
5848 fprintf(stderr
, "ssid <%s> exceeds %d\n", str
, DOT11_MAX_SSID_LEN
);
5851 if (strlen(str
) == 0)
5852 ssid
[idx
].SSID_len
= 0;
5855 strcpy((char*)ssid
[idx
].SSID
, str
);
5856 ssid
[idx
].SSID_len
= strlen(str
);
5865 wl_scan_prep(void *wl
, cmd_t
*cmd
, char **argv
, wl_scan_params_t
*params
, int *params_size
)
5870 char *p
, *eq
, *valstr
, *endptr
= NULL
;
5872 bool positional_param
;
5880 wlc_ssid_t ssids
[WL_SCAN_PARAMS_SSID_MAX
];
5882 UNUSED_PARAMETER(wl
);
5883 UNUSED_PARAMETER(cmd
);
5885 memcpy(¶ms
->bssid
, ðer_bcast
, ETHER_ADDR_LEN
);
5886 params
->bss_type
= DOT11_BSSTYPE_ANY
;
5887 params
->scan_type
= 0;
5888 params
->nprobes
= -1;
5889 params
->active_time
= -1;
5890 params
->passive_time
= -1;
5891 params
->home_time
= -1;
5892 params
->channel_num
= 0;
5893 memset(ssids
, 0, WL_SCAN_PARAMS_SSID_MAX
* sizeof(wlc_ssid_t
));
5895 /* skip the command name */
5899 while ((p
= *argv
) != NULL
) {
5901 positional_param
= FALSE
;
5902 memset(key
, 0, sizeof(key
));
5908 positional_param
= TRUE
;
5911 else if (!strcmp(p
, "--")) {
5915 else if (!strncmp(p
, "--", 2)) {
5916 eq
= strchr(p
, '=');
5919 "wl_scan: missing \" = \" in long param \"%s\"\n", p
);
5923 keylen
= eq
- (p
+ 2);
5924 if (keylen
> 63) keylen
= 63;
5925 memcpy(key
, p
+ 2, keylen
);
5928 if (*valstr
== '\0') {
5930 "wl_scan: missing value after \" = \" in long param \"%s\"\n", p
);
5935 else if (!strncmp(p
, "-", 1)) {
5937 if (strlen(p
) > 2) {
5939 "wl_scan: only single char options, error on param \"%s\"\n", p
);
5943 if (*argv
== NULL
) {
5945 "wl_scan: missing value parameter after \"%s\"\n", p
);
5952 positional_param
= TRUE
;
5956 /* parse valstr as int just in case */
5958 val
= (int)strtol(valstr
, &endptr
, 0);
5959 if (*endptr
== '\0') {
5960 /* not all the value string was parsed by strtol */
5965 if (opt
== 's' || !strcmp(key
, "ssid") || positional_param
) {
5966 nssid
= wl_parse_ssid_list(valstr
, ssids
, nssid
, WL_SCAN_PARAMS_SSID_MAX
);
5972 if (opt
== 't' || !strcmp(key
, "scan_type")) {
5973 if (!strcmp(valstr
, "active")) {
5974 params
->scan_type
= 0;
5975 } else if (!strcmp(valstr
, "passive")) {
5976 params
->scan_type
= WL_SCANFLAGS_PASSIVE
;
5977 } else if (!strcmp(valstr
, "prohibit")) {
5978 params
->scan_type
= WL_SCANFLAGS_PROHIBITED
;
5981 "scan_type value should be \"active\" "
5982 "or \"passive\", but got \"%s\"\n", valstr
);
5987 if (!strcmp(key
, "bss_type")) {
5988 if (!strcmp(valstr
, "bss") || !strcmp(valstr
, "infra")) {
5989 params
->bss_type
= DOT11_BSSTYPE_INFRASTRUCTURE
;
5990 } else if (!strcmp(valstr
, "ibss") || !strcmp(valstr
, "adhoc")) {
5991 params
->bss_type
= DOT11_BSSTYPE_INDEPENDENT
;
5992 } else if (!strcmp(valstr
, "any")) {
5993 params
->bss_type
= DOT11_BSSTYPE_ANY
;
5996 "bss_type value should be "
5997 "\"bss\", \"ibss\", or \"any\", but got \"%s\"\n", valstr
);
6002 if (opt
== 'b' || !strcmp(key
, "bssid")) {
6003 if (!wl_ether_atoe(valstr
, ¶ms
->bssid
)) {
6005 "could not parse \"%s\" as an ethernet MAC address\n", valstr
);
6010 if (opt
== 'n' || !strcmp(key
, "nprobes")) {
6013 "could not parse \"%s\" as an int for value nprobes\n", valstr
);
6017 params
->nprobes
= val
;
6019 if (opt
== 'a' || !strcmp(key
, "active")) {
6022 "could not parse \"%s\" as an int for active dwell time\n",
6027 params
->active_time
= val
;
6029 if (opt
== 'p' || !strcmp(key
, "passive")) {
6032 "could not parse \"%s\" as an int for passive dwell time\n",
6037 params
->passive_time
= val
;
6039 if (opt
== 'h' || !strcmp(key
, "home")) {
6042 "could not parse \"%s\" as an int for home channel dwell time\n",
6047 params
->home_time
= val
;
6049 if (opt
== 'c' || !strcmp(key
, "channels")) {
6050 nchan
= wl_parse_channel_list(valstr
, params
->channel_list
,
6053 fprintf(stderr
, "error parsing channel list arg\n");
6060 if (nssid
> WL_SCAN_PARAMS_SSID_MAX
) {
6061 fprintf(stderr
, "ssid count %d exceeds max of %d\n",
6062 nssid
, WL_SCAN_PARAMS_SSID_MAX
);
6067 params
->nprobes
= htod32(params
->nprobes
);
6068 params
->active_time
= htod32(params
->active_time
);
6069 params
->passive_time
= htod32(params
->passive_time
);
6070 params
->home_time
= htod32(params
->home_time
);
6072 for (i
= 0; i
< nchan
; i
++) {
6073 params
->channel_list
[i
] = htodchanspec(params
->channel_list
[i
]);
6076 for (i
= 0; i
< nssid
; i
++) {
6077 ssids
[i
].SSID_len
= htod32(ssids
[i
].SSID_len
);
6080 /* For a single ssid, use the single fixed field */
6083 memcpy(¶ms
->ssid
, &ssids
[0], sizeof(ssids
[0]));
6086 /* Copy ssid array if applicable */
6088 i
= OFFSETOF(wl_scan_params_t
, channel_list
) + nchan
* sizeof(uint16
);
6089 i
= ROUNDUP(i
, sizeof(uint32
));
6090 if (i
+ nssid
* sizeof(wlc_ssid_t
) > (uint
)*params_size
) {
6091 fprintf(stderr
, "additional ssids exceed params_size\n");
6096 p
= (char*)params
+ i
;
6097 memcpy(p
, ssids
, nssid
* sizeof(wlc_ssid_t
));
6098 p
+= nssid
* sizeof(wlc_ssid_t
);
6100 p
= (char*)params
->channel_list
+ nchan
* sizeof(uint16
);
6103 params
->channel_num
= htod32((nssid
<< WL_SCAN_PARAMS_NSSID_SHIFT
) |
6104 (nchan
& WL_SCAN_PARAMS_COUNT_MASK
));
6105 *params_size
= p
- (char*)params
+ nssid
* sizeof(wlc_ssid_t
);
6112 wl_scan(void *wl
, cmd_t
*cmd
, char **argv
)
6114 int params_size
= WL_SCAN_PARAMS_FIXED_SIZE
+ WL_NUMCHANNELS
* sizeof(uint16
);
6115 wl_scan_params_t
*params
;
6118 params_size
+= WL_SCAN_PARAMS_SSID_MAX
* sizeof(wlc_ssid_t
);
6119 params
= (wl_scan_params_t
*)malloc(params_size
);
6120 if (params
== NULL
) {
6121 fprintf(stderr
, "Error allocating %d bytes for scan params\n", params_size
);
6124 memset(params
, 0, params_size
);
6126 err
= wl_scan_prep(wl
, cmd
, argv
, params
, ¶ms_size
);
6129 err
= wlu_set(wl
, cmd
->set
, params
, params_size
);
6137 extern time_t time(time_t *ptr
);
6140 wl_escan(void *wl
, cmd_t
*cmd
, char **argv
)
6142 int params_size
= (WL_SCAN_PARAMS_FIXED_SIZE
+ OFFSETOF(wl_escan_params_t
, params
)) +
6143 (WL_NUMCHANNELS
* sizeof(uint16
));
6144 wl_escan_params_t
*params
;
6146 uint16 action
= WL_SCAN_ACTION_START
;
6148 if (!stricmp(*argv
, "escan"))
6149 /* start an escan */
6150 action
= WL_SCAN_ACTION_START
;
6151 else if (!stricmp(*argv
, "escanabort"))
6152 /* abort an escan */
6153 action
= WL_SCAN_ACTION_ABORT
;
6155 printf("unknown escan command: %s\n", *argv
);
6159 params_size
+= WL_SCAN_PARAMS_SSID_MAX
* sizeof(wlc_ssid_t
);
6160 params
= (wl_escan_params_t
*)malloc(params_size
);
6161 if (params
== NULL
) {
6162 fprintf(stderr
, "Error allocating %d bytes for scan params\n", params_size
);
6165 memset(params
, 0, params_size
);
6167 err
= wl_scan_prep(wl
, cmd
, argv
, ¶ms
->params
, ¶ms_size
);
6170 params
->version
= htod32(ESCAN_REQ_VERSION
);
6171 params
->action
= htod16(action
);
6174 srand((unsigned)time(NULL
));
6175 params
->sync_id
= htod16(rand() & 0xffff);
6177 params
->sync_id
= htod16(4321);
6178 #endif /* #if defined(linux) */
6180 params_size
+= OFFSETOF(wl_escan_params_t
, params
);
6181 err
= wlu_iovar_setbuf(wl
, "escan", params
, params_size
, buf
, WLC_IOCTL_MAXLEN
);
6189 wl_iscan(void *wl
, cmd_t
*cmd
, char **argv
)
6191 int params_size
= (WL_SCAN_PARAMS_FIXED_SIZE
+ OFFSETOF(wl_iscan_params_t
, params
)) +
6192 (WL_NUMCHANNELS
* sizeof(uint16
));
6193 wl_iscan_params_t
*params
;
6195 uint16 action
= WL_SCAN_ACTION_START
;
6197 uint16 iscan_duration
= 0;
6199 if (!stricmp(*argv
, "iscan_s"))
6200 action
= WL_SCAN_ACTION_START
;
6201 else if (!stricmp(*argv
, "iscan_c"))
6202 action
= WL_SCAN_ACTION_CONTINUE
;
6204 printf("unknown iscan command: %s\n", *argv
);
6208 /* look for iscan_duration parameter */
6210 while (*p
!= NULL
) {
6211 if (!strcmp(*p
, "-d") || !strncmp(*p
, "--duration=", 11)) {
6215 if (!strcmp(*p
, "-d"))
6219 val
= (int)strtol(valptr
, &endptr
, 0);
6220 if (*endptr
!= '\0') {
6222 "could not parse \"%s\" as an int for duration\n",
6227 iscan_duration
= (uint16
) val
;
6233 params_size
+= WL_SCAN_PARAMS_SSID_MAX
* sizeof(wlc_ssid_t
);
6234 params
= (wl_iscan_params_t
*)malloc(params_size
);
6235 if (params
== NULL
) {
6236 fprintf(stderr
, "Error allocating %d bytes for scan params\n", params_size
);
6239 memset(params
, 0, params_size
);
6241 err
= wl_scan_prep(wl
, cmd
, argv
, ¶ms
->params
, ¶ms_size
);
6244 params
->version
= htod32(ISCAN_REQ_VERSION
);
6245 params
->action
= htod16(action
);
6246 params
->scan_duration
= htod16(iscan_duration
);
6247 params_size
+= OFFSETOF(wl_iscan_params_t
, params
);
6248 err
= wlu_iovar_setbuf(wl
, "iscan", params
, params_size
, buf
, WLC_IOCTL_MAXLEN
);
6257 wl_parse_assoc_params(char **argv
, wl_assoc_params_t
*params
)
6260 char *p
, *eq
, *valstr
;
6269 while ((p
= *argv
) != NULL
) {
6271 memset(key
, 0, sizeof(key
));
6278 else if (!strcmp(p
, "--")) {
6282 else if (!strncmp(p
, "--", 2)) {
6283 eq
= strchr(p
, '=');
6285 fprintf(stderr
, "wl_parse_assoc_params: missing \" = \" in "
6286 "long param \"%s\"\n", p
);
6290 keylen
= eq
- (p
+ 2);
6291 if (keylen
> 63) keylen
= 63;
6292 memcpy(key
, p
+ 2, keylen
);
6295 if (*valstr
== '\0') {
6296 fprintf(stderr
, "wl_parse_assoc_params: missing value after "
6297 "\" = \" in long param \"%s\"\n", p
);
6302 else if (!strncmp(p
, "-", 1)) {
6304 if (strlen(p
) > 2) {
6305 fprintf(stderr
, "wl_parse_assoc_params: only single char options, "
6306 "error on param \"%s\"\n", p
);
6310 if (*argv
== NULL
) {
6311 fprintf(stderr
, "wl_parse_assoc_params: missing value parameter "
6312 "after \"%s\"\n", p
);
6321 /* handle -o v or --option=val */
6322 if (opt
== 'b' || !stricmp(key
, "bssid")) {
6323 if (!wl_ether_atoe(valstr
, ¶ms
->bssid
)) {
6324 fprintf(stderr
, "could not parse as an ethernet MAC address\n");
6329 else if (opt
== 'c' || !strcmp(key
, "chanspecs")) {
6330 params
->chanspec_num
=
6331 wl_parse_chanspec_list(valstr
, params
->chanspec_list
, WL_NUMCHANNELS
);
6332 if (params
->chanspec_num
== -1) {
6333 fprintf(stderr
, "error parsing chanspec list arg\n");
6340 /* prepare the chanspec using the channel number and the user provided options */
6341 for (i
= 0; i
< params
->chanspec_num
; i
++) {
6342 params
->chanspec_list
[i
] = htodchanspec(params
->chanspec_list
[i
]);
6344 params
->chanspec_num
= htod32(params
->chanspec_num
);
6350 /* wl reassoc <bssid>
6352 * -c CL, --chanspecs=CL, where CL is a comma or space separated list of chanspecs
6355 wl_reassoc(void *wl
, cmd_t
*cmd
, char **argv
)
6357 int params_size
= WL_REASSOC_PARAMS_FIXED_SIZE
+ WL_NUMCHANNELS
* sizeof(chanspec_t
);
6358 wl_reassoc_params_t
*params
;
6361 UNUSED_PARAMETER(cmd
);
6363 if (*++argv
== NULL
) {
6364 fprintf(stderr
, "no arguments to wl_reassoc\n");
6368 params
= (wl_reassoc_params_t
*)malloc(params_size
);
6369 if (params
== NULL
) {
6370 fprintf(stderr
, "Error allocating %d bytes for scan params\n", params_size
);
6373 memset(params
, 0, params_size
);
6375 if (!wl_ether_atoe(*argv
, ¶ms
->bssid
)) {
6376 fprintf(stderr
, "could not parse %s as an Ethernet MAC address\n", *argv
);
6380 /* default to plain old ioctl */
6381 params_size
= ETHER_ADDR_LEN
;
6383 if (*++argv
!= NULL
) {
6384 if ((err
= wl_parse_reassoc_params(argv
, params
)) != BCME_OK
) {
6385 fprintf(stderr
, "could not parse reassociation parameters\n");
6388 params_size
= WL_REASSOC_PARAMS_FIXED_SIZE
+
6389 dtoh32(params
->chanspec_num
) * sizeof(chanspec_t
);
6392 err
= wlu_set(wl
, WLC_REASSOC
, params
, params_size
);
6399 #ifdef EXTENDED_SCAN
6401 * -s --ssid=ssid1 ssid2 ssid3
6402 * -b --split_scan=0 : [split_scan]
6403 * -t --scan_type=0 : [background/forcedbackground/foreground]
6408 wl_extdscan(void *wl
, cmd_t
*cmd
, char **argv
)
6410 wl_extdscan_params_t
*params
;
6411 int params_size
= WL_EXTDSCAN_PARAMS_FIXED_SIZE
+
6412 (WL_NUMCHANNELS
* sizeof(chan_scandata_t
));
6414 char *p
, *eq
, *valstr
, *endptr
;
6416 bool positional_param
;
6425 fprintf(stderr
, "params alloc size is %d\n", params_size
);
6426 params
= (wl_extdscan_params_t
*)malloc(params_size
);
6427 if (params
== NULL
) {
6428 fprintf(stderr
, "Error allocating %d bytes for scan params\n", params_size
);
6431 memset(params
, 0, params_size
);
6433 params
->scan_type
= EXTDSCAN_FORCEDBACKGROUND_SCAN
;
6434 params
->nprobes
= 3;
6435 params
->band
= WLC_BAND_2G
;
6436 params
->split_scan
= 0;
6438 /* skip the command name */
6441 if (*argv
== NULL
) {
6442 fprintf(stderr
, "no arguments to wl_extdscan\n");
6447 while ((p
= *argv
) != NULL
) {
6449 positional_param
= FALSE
;
6450 memset(key
, 0, sizeof(key
));
6456 positional_param
= TRUE
;
6459 else if (!strcmp(p
, "--")) {
6463 else if (!strncmp(p
, "--", 2)) {
6464 eq
= strchr(p
, '=');
6467 "wl_extdscan: missing \" = \" in long param \"%s\"\n", p
);
6471 keylen
= eq
- (p
+ 2);
6472 if (keylen
> 63) keylen
= 63;
6473 memcpy(key
, p
+ 2, keylen
);
6476 if (*valstr
== '\0') {
6478 "extdscan: missing value after \" = \" in long param \"%s\"\n", p
);
6483 else if (!strncmp(p
, "-", 1)) {
6485 if (strlen(p
) > 2) {
6487 "extdscan: only single char options, error on param \"%s\"\n", p
);
6491 if (*argv
== NULL
) {
6493 "extdscan: missing value parameter after \"%s\"\n", p
);
6500 positional_param
= TRUE
;
6504 /* parse valstr as int just in case */
6506 val
= (int)strtol(valstr
, &endptr
, 0);
6507 if (*endptr
== '\0') {
6508 /* not all the value string was parsed by strtol */
6513 if (opt
== 's' || !strcmp(key
, "ssid") || positional_param
) {
6514 nssid
= wl_parse_ssid_list(valstr
, params
->ssid
,
6515 nssid
, WLC_EXTDSCAN_MAX_SSID
);
6521 if (opt
== 'b' || !strcmp(key
, "band")) {
6522 if (!strcmp(valstr
, "5G")) {
6523 params
->band
= WLC_BAND_5G
;
6525 else if (!strcmp(valstr
, "2.4G")) {
6526 params
->band
= WLC_BAND_2G
;
6528 else if (!strcmp(valstr
, "all")) {
6529 params
->band
= WLC_BAND_ALL
;
6532 "scan_type value should be \"5G\" "
6533 "or \"2.4G\" " "or \"all\" but got \"%s\"\n", valstr
);
6538 if (opt
== 't' || !strcmp(key
, "scan_type")) {
6539 if (!strcmp(valstr
, "background")) {
6540 params
->scan_type
= EXTDSCAN_BACKGROUND_SCAN
;
6541 } else if (!strcmp(valstr
, "fbackground")) {
6542 params
->scan_type
= EXTDSCAN_FORCEDBACKGROUND_SCAN
;
6543 } else if (!strcmp(valstr
, "foreground")) {
6544 params
->scan_type
= EXTDSCAN_FOREGROUND_SCAN
;
6547 "scan_type value should be \"background\" "
6548 "or \"fbackground\" " "or \"foreground\" but got \"%s\"\n", valstr
);
6553 if (opt
== 'n' || !strcmp(key
, "nprobes")) {
6556 "could not parse \"%s\" as an int for value nprobes\n", valstr
);
6560 params
->nprobes
= val
;
6562 if (opt
== 'x' || !strcmp(key
, "split_scan")) {
6564 params
->split_scan
= 1;
6566 if (opt
== 'c' || !strcmp(key
, "channels")) {
6567 params
->channel_num
= wl_parse_extdchannel_list(valstr
,
6568 params
->channel_list
, WL_NUMCHANNELS
);
6569 if (params
->channel_num
== -1) {
6570 fprintf(stderr
, "error parsing channel list arg\n");
6577 if (nssid
> WLC_EXTDSCAN_MAX_SSID
) {
6578 fprintf(stderr
, "ssid count %d exceeds max of %d\n",
6579 nssid
, WLC_EXTDSCAN_MAX_SSID
);
6584 params_size
= WL_EXTDSCAN_PARAMS_FIXED_SIZE
+
6585 (params
->channel_num
* sizeof(chan_scandata_t
));
6587 fprintf(stderr
, "ssid list is %s(%d) %s(%d) %s(%d) %s(%d) %s(%d)\n",
6588 (char *)¶ms
->ssid
[0].SSID
, params
->ssid
[0].SSID_len
,
6589 (char *)¶ms
->ssid
[1].SSID
, params
->ssid
[1].SSID_len
,
6590 (char *)¶ms
->ssid
[2].SSID
, params
->ssid
[2].SSID_len
,
6591 (char *)¶ms
->ssid
[3].SSID
, params
->ssid
[3].SSID_len
,
6592 (char *)¶ms
->ssid
[4].SSID
, params
->ssid
[4].SSID_len
);
6593 if (params
->split_scan
)
6594 fprintf(stderr
, "split scan is enabled\n");
6596 fprintf(stderr
, "split scan is not enabled\n");
6598 fprintf(stderr
, "scan type is %d, nprobes are %d, band is %d, channels are %d\n",
6599 params
->scan_type
, params
->nprobes
, params
->band
, params
->channel_num
);
6601 fprintf(stderr
, "params size is %d\n", params_size
);
6602 params
->scan_type
= htodenum(params
->scan_type
);
6603 for (i
= 0; i
< WLC_EXTDSCAN_MAX_SSID
; i
++) {
6604 params
->ssid
[i
].SSID_len
= htod32(params
->ssid
[i
].SSID_len
);
6606 for (i
= 0; i
< params
->channel_num
; i
++) {
6607 params
->channel_list
[i
].channel
= htodchanspec(params
->channel_list
[i
].channel
);
6608 params
->channel_list
[i
].channel_mintime
=
6609 htod32(params
->channel_list
[i
].channel_mintime
);
6610 params
->channel_list
[i
].channel_maxtime
=
6611 htod32(params
->channel_list
[i
].channel_maxtime
);
6613 params
->channel_num
= htod32(params
->channel_num
);
6614 err
= wlu_var_setbuf(wl
, cmd
->name
, params
, params_size
);
6622 wl_parse_extdchannel_list(char* list_str
, chan_scandata_t
* channel_list
, int channel_num
)
6629 if (list_str
== NULL
)
6634 while (*str
!= '\0') {
6635 val
= (int)strtol(str
, &endptr
, 0);
6636 if (endptr
== str
) {
6638 "could not parse channel number starting at"
6639 " substring \"%s\" in list:\n%s\n",
6643 str
= endptr
+ strspn(endptr
, " ,");
6645 if (num
== channel_num
) {
6646 fprintf(stderr
, "too many channels (more than %d) in channel list:\n%s\n",
6647 channel_num
, list_str
);
6650 channel_list
->channel
= (uint16
)val
;
6657 #endif /* EXTENDED_SCAN */
6660 wl_parse_channel_list(char* list_str
, uint16
* channel_list
, int channel_num
)
6665 char* endptr
= NULL
;
6667 if (list_str
== NULL
)
6672 while (*str
!= '\0') {
6673 val
= (int)strtol(str
, &endptr
, 0);
6674 if (endptr
== str
) {
6676 "could not parse channel number starting at"
6677 " substring \"%s\" in list:\n%s\n",
6681 str
= endptr
+ strspn(endptr
, " ,");
6683 if (num
== channel_num
) {
6684 fprintf(stderr
, "too many channels (more than %d) in channel list:\n%s\n",
6685 channel_num
, list_str
);
6689 channel_list
[num
++] = (uint16
)val
;
6696 wl_parse_chanspec_list(char *list_str
, chanspec_t
*chanspec_list
, int chanspec_num
)
6699 chanspec_t chanspec
;
6703 if ((next
= list_str
) == NULL
)
6706 while ((len
= strcspn(next
, " ,")) > 0) {
6707 if (len
>= sizeof(str
)) {
6708 fprintf(stderr
, "string \"%s\" before ',' or ' ' is too long\n", next
);
6711 strncpy(str
, next
, len
);
6713 chanspec
= wf_chspec_aton(str
);
6714 if (chanspec
== 0) {
6715 fprintf(stderr
, "could not parse chanspec starting at "
6716 "\"%s\" in list:\n%s\n", str
, list_str
);
6719 if (num
== chanspec_num
) {
6720 fprintf(stderr
, "too many chanspecs (more than %d) in chanspec list:\n%s\n",
6721 chanspec_num
, list_str
);
6724 chanspec_list
[num
++] = chanspec
;
6726 next
+= strspn(next
, " ,");
6732 /* channel info structure */
6734 uint chan
; /* channel number */
6735 uint freq
; /* in Mhz */
6738 static chan_info_t chan_info
[] = {
6798 freq2channel(uint freq
)
6802 for (i
= 0; i
< (int)ARRAYSIZE(chan_info
); i
++) {
6803 if (chan_info
[i
].freq
== freq
)
6804 return (chan_info
[i
].chan
);
6810 dump_rateset(uint8
*rates
, uint count
)
6817 for (i
= 0; i
< count
; i
++) {
6818 r
= rates
[i
] & 0x7f;
6819 b
= rates
[i
] & 0x80;
6822 printf("%d%s%s ", (r
/ 2), (r
% 2)?".5":"", b
?"(b)":"");
6827 /* Helper routine to print the infrastructure mode while pretty printing the BSS list */
6829 capmode2str(uint16 capability
)
6831 capability
&= (DOT11_CAP_ESS
| DOT11_CAP_IBSS
);
6833 if (capability
== DOT11_CAP_ESS
)
6835 else if (capability
== DOT11_CAP_IBSS
)
6842 * Traverse a string of 1-byte tag/1-byte length/variable-length value
6843 * triples, returning a pointer to the substring whose first element
6847 wlu_parse_tlvs(uint8
*tlv_buf
, int buflen
, uint key
)
6855 /* find tagged parameter */
6856 while (totlen
>= 2) {
6863 /* validate remaining totlen */
6864 if ((tag
== key
) && (totlen
>= (len
+ 2)))
6868 totlen
-= (len
+ 2);
6875 wlu_bcmp(const void *b1
, const void *b2
, int len
)
6877 return (memcmp(b1
, b2
, len
));
6880 /* Is this body of this tlvs entry a WPA entry? If */
6881 /* not update the tlvs buffer pointer/length */
6883 wlu_is_wpa_ie(uint8
**wpaie
, uint8
**tlvs
, uint
*tlvs_len
)
6887 /* If the contents match the WPA_OUI and type=1 */
6888 if ((ie
[1] >= 6) && !wlu_bcmp(&ie
[2], WPA_OUI
"\x01", 4)) {
6892 /* point to the next ie */
6894 /* calculate the length of the rest of the buffer */
6895 *tlvs_len
-= (int)(ie
- *tlvs
);
6896 /* update the pointer to the start of the buffer */
6903 wl_dump_wpa_rsn_ies(uint8
* cp
, uint len
)
6906 uint parse_len
= len
;
6910 while ((wpaie
= wlu_parse_tlvs(parse
, parse_len
, DOT11_MNG_WPA_ID
)))
6911 if (wlu_is_wpa_ie(&wpaie
, &parse
, &parse_len
))
6914 wl_rsn_ie_dump((bcm_tlv_t
*)wpaie
);
6916 rsnie
= wlu_parse_tlvs(cp
, len
, DOT11_MNG_RSN_ID
);
6918 wl_rsn_ie_dump((bcm_tlv_t
*)rsnie
);
6924 wl_rsn_ie_dump(bcm_tlv_t
*ie
)
6928 wpa_ie_fixed_t
*wpa
= NULL
;
6929 rsn_parse_info_t rsn_info
;
6932 int unicast_count
= 0;
6934 uint16 capabilities
;
6938 if (ie
->id
== DOT11_MNG_RSN_ID
) {
6940 memcpy(std_oui
, WPA2_OUI
, WPA_OUI_LEN
);
6941 err
= wl_rsn_ie_parse_info(ie
->data
, ie
->len
, &rsn_info
);
6944 memcpy(std_oui
, WPA_OUI
, WPA_OUI_LEN
);
6945 wpa
= (wpa_ie_fixed_t
*)ie
;
6946 err
= wl_rsn_ie_parse_info((uint8
*)&wpa
->version
, wpa
->length
- WPA_IE_OUITYPE_LEN
,
6949 if (err
|| rsn_info
.version
!= WPA_VERSION
)
6957 /* Check for multicast suite */
6958 if (rsn_info
.mcast
) {
6959 printf("\tmulticast cipher: ");
6960 if (!wlu_bcmp(rsn_info
.mcast
->oui
, std_oui
, 3)) {
6961 switch (rsn_info
.mcast
->type
) {
6962 case WPA_CIPHER_NONE
:
6965 case WPA_CIPHER_WEP_40
:
6968 case WPA_CIPHER_WEP_104
:
6971 case WPA_CIPHER_TKIP
:
6974 case WPA_CIPHER_AES_OCB
:
6975 printf("AES-OCB\n");
6977 case WPA_CIPHER_AES_CCM
:
6978 printf("AES-CCMP\n");
6981 printf("Unknown-%s(#%d)\n", rsn
? "RSN" : "WPA",
6982 rsn_info
.mcast
->type
);
6987 printf("Unknown-%02X:%02X:%02X(#%d) ",
6988 rsn_info
.mcast
->oui
[0], rsn_info
.mcast
->oui
[1],
6989 rsn_info
.mcast
->oui
[2], rsn_info
.mcast
->type
);
6993 /* Check for unicast suite(s) */
6994 if (rsn_info
.ucast
) {
6995 unicast_count
= ltoh16_ua(&rsn_info
.ucast
->count
);
6996 printf("\tunicast ciphers(%d): ", unicast_count
);
6997 for (i
= 0; i
< unicast_count
; i
++) {
6998 suite
= &rsn_info
.ucast
->list
[i
];
6999 if (!wlu_bcmp(suite
->oui
, std_oui
, 3)) {
7000 switch (suite
->type
) {
7001 case WPA_CIPHER_NONE
:
7004 case WPA_CIPHER_WEP_40
:
7007 case WPA_CIPHER_WEP_104
:
7010 case WPA_CIPHER_TKIP
:
7013 case WPA_CIPHER_AES_OCB
:
7016 case WPA_CIPHER_AES_CCM
:
7017 printf("AES-CCMP ");
7020 printf("WPA-Unknown-%s(#%d) ", rsn
? "RSN" : "WPA",
7026 printf("Unknown-%02X:%02X:%02X(#%d) ",
7027 suite
->oui
[0], suite
->oui
[1], suite
->oui
[2],
7033 /* Authentication Key Management */
7035 akm_count
= ltoh16_ua(&rsn_info
.akm
->count
);
7036 printf("\tAKM Suites(%d): ", akm_count
);
7037 for (i
= 0; i
< akm_count
; i
++) {
7038 suite
= &rsn_info
.akm
->list
[i
];
7039 if (!wlu_bcmp(suite
->oui
, std_oui
, 3)) {
7040 switch (suite
->type
) {
7044 case RSN_AKM_UNSPECIFIED
:
7051 printf("Unknown-%s(#%d) ",
7052 rsn
? "RSN" : "WPA", suite
->type
);
7057 printf("Unknown-%02X:%02X:%02X(#%d) ",
7058 suite
->oui
[0], suite
->oui
[1], suite
->oui
[2],
7066 if (rsn_info
.capabilities
) {
7067 capabilities
= ltoh16_ua(rsn_info
.capabilities
);
7068 printf("\tCapabilities(0x%04x): ", capabilities
);
7070 printf("%sPre-Auth, ", (capabilities
& RSN_CAP_PREAUTH
) ? "" : "No ");
7072 printf("%sPairwise, ", (capabilities
& RSN_CAP_NOPAIRWISE
) ? "No " : "");
7074 cntrs
= wl_rsn_ie_decode_cntrs((capabilities
& RSN_CAP_PTK_REPLAY_CNTR_MASK
) >>
7075 RSN_CAP_PTK_REPLAY_CNTR_SHIFT
);
7077 printf("%d PTK Replay Ctr%s", cntrs
, (cntrs
> 1)?"s":"");
7080 cntrs
= wl_rsn_ie_decode_cntrs(
7081 (capabilities
& RSN_CAP_GTK_REPLAY_CNTR_MASK
) >>
7082 RSN_CAP_GTK_REPLAY_CNTR_SHIFT
);
7084 printf("%d GTK Replay Ctr%s\n", cntrs
, (cntrs
> 1)?"s":"");
7089 printf("\tNo %s Capabilities advertised\n", rsn
? "RSN" : "WPA");
7094 /* Validates and parses the RSN or WPA IE contents into a rsn_parse_info_t structure
7095 * Returns 0 on success, or 1 if the information in the buffer is not consistant with
7096 * an RSN IE or WPA IE.
7097 * The buf pointer passed in should be pointing at the version field in either an RSN IE
7101 wl_rsn_ie_parse_info(uint8
* rsn_buf
, uint len
, rsn_parse_info_t
*rsn
)
7105 memset(rsn
, 0, sizeof(rsn_parse_info_t
));
7108 if (len
< sizeof(uint16
))
7111 rsn
->version
= ltoh16_ua(rsn_buf
);
7112 len
-= sizeof(uint16
);
7113 rsn_buf
+= sizeof(uint16
);
7115 /* Multicast Suite */
7116 if (len
< sizeof(wpa_suite_mcast_t
))
7119 rsn
->mcast
= (wpa_suite_mcast_t
*)rsn_buf
;
7120 len
-= sizeof(wpa_suite_mcast_t
);
7121 rsn_buf
+= sizeof(wpa_suite_mcast_t
);
7124 if (len
< sizeof(uint16
))
7127 count
= ltoh16_ua(rsn_buf
);
7129 if (len
< (sizeof(uint16
) + count
* sizeof(wpa_suite_t
)))
7132 rsn
->ucast
= (wpa_suite_ucast_t
*)rsn_buf
;
7133 len
-= (sizeof(uint16
) + count
* sizeof(wpa_suite_t
));
7134 rsn_buf
+= (sizeof(uint16
) + count
* sizeof(wpa_suite_t
));
7137 if (len
< sizeof(uint16
))
7140 count
= ltoh16_ua(rsn_buf
);
7142 if (len
< (sizeof(uint16
) + count
* sizeof(wpa_suite_t
)))
7145 rsn
->akm
= (wpa_suite_auth_key_mgmt_t
*)rsn_buf
;
7146 len
-= (sizeof(uint16
) + count
* sizeof(wpa_suite_t
));
7147 rsn_buf
+= (sizeof(uint16
) + count
* sizeof(wpa_suite_t
));
7150 if (len
< sizeof(uint16
))
7153 rsn
->capabilities
= rsn_buf
;
7159 wl_rsn_ie_decode_cntrs(uint cntr_field
)
7163 switch (cntr_field
) {
7164 case RSN_CAP_1_REPLAY_CNTR
:
7167 case RSN_CAP_2_REPLAY_CNTRS
:
7170 case RSN_CAP_4_REPLAY_CNTRS
:
7173 case RSN_CAP_16_REPLAY_CNTRS
:
7186 wl_dump_raw_ie(bcm_tlv_t
*ie
, uint len
)
7192 } else if (len
== 1) {
7193 printf("IE header truncated: ID: 0x%02X\n", ie
->id
);
7195 } else if (len
< (uint
)(ie
->len
+ TLV_HDR_LEN
)) {
7196 printf("IE data truncated: ID: 0x%02X Len: %d\n", ie
->id
, ie
->len
);
7197 dump_len
= len
- TLV_HDR_LEN
;
7199 printf("ID: 0x%02X Len: %d\n", ie
->id
, ie
->len
);
7203 /* choose how to format the data based on data len */
7206 else if (dump_len
> 0)
7210 wl_hexdump(ie
->data
, dump_len
);
7212 if (dump_len
< ie
->len
)
7213 printf("<missing %d bytes>\n", ie
->len
- dump_len
);
7219 /* Pretty print the BSS list */
7221 dump_networks(char *network_buf
)
7223 wl_scan_results_t
*list
= (wl_scan_results_t
*)network_buf
;
7227 if (list
->count
== 0)
7229 else if (list
->version
!= WL_BSS_INFO_VERSION
&&
7230 list
->version
!= LEGACY2_WL_BSS_INFO_VERSION
&&
7231 list
->version
!= LEGACY_WL_BSS_INFO_VERSION
) {
7232 fprintf(stderr
, "Sorry, your driver has bss_info_version %d "
7233 "but this program supports only version %d.\n",
7234 list
->version
, WL_BSS_INFO_VERSION
);
7238 bi
= list
->bss_info
;
7239 for (i
= 0; i
< list
->count
; i
++, bi
= (wl_bss_info_t
*)((int8
*)bi
+ dtoh32(bi
->length
))) {
7245 dump_bss_info(wl_bss_info_t
*bi
)
7247 char ssidbuf
[SSID_FMT_BUF_LEN
];
7248 char chspec_str
[CHANSPEC_STR_LEN
];
7249 wl_bss_info_107_t
*old_bi
;
7252 /* Convert version 107 to 109 */
7253 if (dtoh32(bi
->version
) == LEGACY_WL_BSS_INFO_VERSION
) {
7254 old_bi
= (wl_bss_info_107_t
*)bi
;
7255 bi
->chanspec
= CH20MHZ_CHSPEC(old_bi
->channel
);
7256 bi
->ie_length
= old_bi
->ie_length
;
7257 bi
->ie_offset
= sizeof(wl_bss_info_107_t
);
7260 wl_format_ssid(ssidbuf
, bi
->SSID
, bi
->SSID_len
);
7262 printf("SSID: \"%s\"\n", ssidbuf
);
7264 printf("Mode: %s\t", capmode2str(dtoh16(bi
->capability
)));
7265 printf("RSSI: %d dBm\t", (int16
)(dtoh16(bi
->RSSI
)));
7268 * SNR has valid value in only 109 version.
7269 * So print SNR for 109 version only.
7271 if (dtoh32(bi
->version
) == WL_BSS_INFO_VERSION
) {
7272 printf("SNR: %d dB\t", (int16
)(dtoh16(bi
->SNR
)));
7275 printf("noise: %d dBm\t", bi
->phy_noise
);
7277 bi
->flags
= dtoh16(bi
->flags
);
7279 if (bi
->flags
& WL_BSS_FLAGS_FROM_BEACON
) printf("FromBcn ");
7280 if (bi
->flags
& WL_BSS_FLAGS_FROM_CACHE
) printf("Cached ");
7281 if (bi
->flags
& WL_BSS_FLAGS_RSSI_ONCHANNEL
) printf("RSSI on-channel ");
7284 printf("Channel: %s\n", wf_chspec_ntoa(dtohchanspec(bi
->chanspec
), chspec_str
));
7286 printf("BSSID: %s\t", wl_ether_etoa(&bi
->BSSID
));
7288 printf("Capability: ");
7289 bi
->capability
= dtoh16(bi
->capability
);
7290 if (bi
->capability
& DOT11_CAP_ESS
) printf("ESS ");
7291 if (bi
->capability
& DOT11_CAP_IBSS
) printf("IBSS ");
7292 if (bi
->capability
& DOT11_CAP_POLLABLE
) printf("Pollable ");
7293 if (bi
->capability
& DOT11_CAP_POLL_RQ
) printf("PollReq ");
7294 if (bi
->capability
& DOT11_CAP_PRIVACY
) printf("WEP ");
7295 if (bi
->capability
& DOT11_CAP_SHORT
) printf("ShortPre ");
7296 if (bi
->capability
& DOT11_CAP_PBCC
) printf("PBCC ");
7297 if (bi
->capability
& DOT11_CAP_AGILITY
) printf("Agility ");
7298 if (bi
->capability
& DOT11_CAP_SHORTSLOT
) printf("ShortSlot ");
7299 if (bi
->capability
& DOT11_CAP_CCK_OFDM
) printf("CCK-OFDM ");
7302 printf("Supported Rates: ");
7303 dump_rateset(bi
->rateset
.rates
, dtoh32(bi
->rateset
.count
));
7305 if (dtoh32(bi
->ie_length
))
7306 wl_dump_wpa_rsn_ies((uint8
*)(((uint8
*)bi
) + dtoh16(bi
->ie_offset
)),
7307 dtoh32(bi
->ie_length
));
7309 if (dtoh32(bi
->version
) != LEGACY_WL_BSS_INFO_VERSION
&& bi
->n_cap
) {
7310 printf("802.11N Capable:\n");
7311 bi
->chanspec
= dtohchanspec(bi
->chanspec
);
7312 printf("\tChanspec: %sGHz channel %d %dMHz (0x%x)\n",
7313 CHSPEC_IS2G(bi
->chanspec
)?"2.4":"5", CHSPEC_CHANNEL(bi
->chanspec
),
7314 CHSPEC_IS40(bi
->chanspec
) ? 40 : (CHSPEC_IS20(bi
->chanspec
) ? 20 : 10),
7316 printf("\tControl channel: %d\n", bi
->ctl_ch
);
7317 printf("\t802.11N Capabilities: ");
7318 if (dtoh32(bi
->nbss_cap
) & HT_CAP_40MHZ
)
7320 if (dtoh32(bi
->nbss_cap
) & HT_CAP_SHORT_GI_20
)
7322 if (dtoh32(bi
->nbss_cap
) & HT_CAP_SHORT_GI_40
)
7324 printf("\n\tSupported MCS : [ ");
7325 for (mcs_idx
= 0; mcs_idx
< (MCSSET_LEN
* 8); mcs_idx
++)
7326 if (isset(bi
->basic_mcs
, mcs_idx
))
7327 printf("%d ", mcs_idx
);
7335 _wl_dump_lq(void *wl
)
7337 int ret
= BCME_OK
, noise
= 0;
7338 wl_lq_t
*plq
= NULL
;
7341 memset(buf
, 0, sizeof(wl_lq_t
));
7343 /* Display stats when disabled */
7344 if ((ret
= wlu_get(wl
, WLC_GET_PHY_NOISE
, &noise
, sizeof(int))) < 0) {
7345 printf("wlc_get noise failed with retcode:%d\n", ret
);
7349 if ((ret
= wlu_var_getbuf_sm (wl
, "monitor_lq_status", NULL
, 0, &ptr
)) < 0) {
7350 printf("wlc_get lq_status failed with retcode:%d\n", ret
);
7354 plq
= (wl_lq_t
*)ptr
;
7356 if (!plq
->isvalid
) {
7357 printf("Stats collection currently disabled"
7358 "['wl monitor_lq 1' to enable statistics collection]\n");
7362 noise
= dtoh32(noise
);
7363 plq
->rssi
[LQ_IDX_MIN
] = dtoh32(plq
->rssi
[LQ_IDX_MIN
]);
7364 plq
->rssi
[LQ_IDX_MAX
] = dtoh32(plq
->rssi
[LQ_IDX_MAX
]);
7365 plq
->rssi
[LQ_IDX_AVG
] = dtoh32(plq
->rssi
[LQ_IDX_AVG
]);
7367 printf("rss: %d, %d, %d\nsnr: %d, %d, %d\n",
7368 plq
->rssi
[LQ_IDX_MIN
],
7369 plq
->rssi
[LQ_IDX_AVG
],
7370 plq
->rssi
[LQ_IDX_MAX
],
7371 plq
->rssi
[LQ_IDX_MIN
]-noise
,
7372 plq
->rssi
[LQ_IDX_AVG
]-noise
,
7373 plq
->rssi
[LQ_IDX_MAX
]-noise
);
7379 wl_dump_lq(void *wl
, cmd_t
*cmd
, char **argv
)
7383 UNUSED_PARAMETER(cmd
);
7386 ret
= _wl_dump_lq(wl
);
7392 wl_monitor_lq(void *wl
, cmd_t
*cmd
, char **argv
)
7395 char *endptr
= NULL
;
7396 char **startptr
= argv
;
7398 if (!*++startptr
) { /* Get */
7399 wl_varint(wl
, cmd
, argv
);
7402 int val
= *startptr
[0];
7403 val
= strtol(*startptr
, &endptr
, 0);
7405 if (*endptr
!= '\0') {
7411 if (val
== LQ_STOP_MONITOR
) {
7412 ret
= _wl_dump_lq(wl
);
7415 wl_varint(wl
, cmd
, argv
); /* Standard set call after getting stats */
7419 } /* wl_monitor_lq */
7422 wl_dump_networks(void *wl
, cmd_t
*cmd
, char **argv
)
7425 char *dump_buf
, *dump_buf_orig
;
7429 dump_buf_orig
= dump_buf
= malloc(WL_DUMP_BUF_LEN
);
7430 if (dump_buf
== NULL
) {
7431 fprintf(stderr
, "Failed to allocate dump buffer of %d bytes\n", WL_DUMP_BUF_LEN
);
7435 iscan
= (cmd
->get
!= WLC_SCAN_RESULTS
);
7437 int buflen
= 1920; /* usually fits about 10 BSS infos */
7440 char *endptr
= NULL
;
7441 buflen
= strtol(*argv
, &endptr
, 0);
7442 if (*endptr
!= '\0') {
7447 ret
= wl_get_iscan(wl
, dump_buf
, buflen
);
7449 ret
= wl_get_scan(wl
, WLC_SCAN_RESULTS
, dump_buf
, WL_DUMP_BUF_LEN
);
7453 status
= dtoh32(((wl_iscan_results_t
*)dump_buf
)->status
);
7454 dump_buf
+= OFFSETOF(wl_iscan_results_t
, results
);
7456 dump_networks(dump_buf
);
7459 case WL_SCAN_RESULTS_PARTIAL
:
7460 printf("iscanresults incomplete\n");
7462 case WL_SCAN_RESULTS_SUCCESS
:
7463 printf("iscanresults complete\n");
7465 case WL_SCAN_RESULTS_PENDING
:
7466 printf("iscanresults pending\n");
7468 case WL_SCAN_RESULTS_ABORTED
:
7469 printf("iscanresults aborted\n");
7472 printf("iscanresults returned unknown status %d\n", status
);
7479 free(dump_buf_orig
);
7484 wl_dump_chanlist(void *wl
, cmd_t
*cmd
, char **argv
)
7486 uint32 chan_buf
[WL_NUMCHANNELS
+ 1];
7487 wl_uint32_list_t
*list
;
7491 UNUSED_PARAMETER(argv
);
7493 list
= (wl_uint32_list_t
*)(void *)chan_buf
;
7494 list
->count
= htod32(WL_NUMCHANNELS
);
7495 ret
= wlu_get(wl
, cmd
->get
, chan_buf
, sizeof(chan_buf
));
7499 for (i
= 0; i
< dtoh32(list
->count
); i
++)
7500 printf("%d ", dtoh32(list
->element
[i
]));
7506 wl_cur_mcsset(void *wl
, cmd_t
*cmd
, char **argv
)
7510 UNUSED_PARAMETER(cmd
);
7511 UNUSED_PARAMETER(argv
);
7513 memset(buf
, 0, WLC_IOCTL_SMLEN
);
7514 ret
= wlu_iovar_get(wl
, "cur_mcsset", &buf
[0], MCSSET_LEN
);
7518 wl_print_mcsset(buf
);
7525 wl_dump_chanspecs(void *wl
, cmd_t
*cmd
, char **argv
)
7528 const char* fn_name
= "wl_dump_chanspecs";
7529 wl_uint32_list_t
*list
;
7530 chanspec_t c
= 0, *chanspec
;
7534 bool band_set
= FALSE
, bw_set
= FALSE
;
7535 char abbrev
[WLC_CNTRY_BUF_SZ
] = ""; /* default.. current locale */
7536 char chspec_str
[CHANSPEC_STR_LEN
];
7538 UNUSED_PARAMETER(cmd
);
7539 UNUSED_PARAMETER(argv
);
7541 memset(buf
, 0, WLC_IOCTL_MAXLEN
);
7543 strcpy(buf
, "chanspecs");
7544 buflen
= strlen(buf
) + 1;
7546 /* toss the command name */
7549 /* Validate arguments if any */
7551 miniopt_init(&to
, fn_name
, NULL
, FALSE
);
7552 while ((opt_err
= miniopt(&to
, argv
)) != -1) {
7557 argv
+= to
.consumed
;
7559 if (to
.opt
== 'b') {
7562 "%s: could not parse \"%s\" as an int for band\n",
7563 fn_name
, to
.valstr
);
7567 if ((to
.val
!= 5) && (to
.val
!= 2)) {
7569 "%s: invalid band %d\n",
7575 c
|= WL_CHANSPEC_BAND_5G
;
7577 c
|= WL_CHANSPEC_BAND_2G
;
7580 if (to
.opt
== 'w') {
7583 "%s: could not parse \"%s\" as an int for"
7585 fn_name
, to
.valstr
);
7589 if ((to
.val
!= 20) && (to
.val
!= 40)) {
7591 "%s: invalid bandwidth %d\n",
7597 c
|= WL_CHANSPEC_BW_20
;
7599 c
|= WL_CHANSPEC_BW_40
;
7602 if (to
.opt
== 'c') {
7605 "%s: please provide country abbrev \n", fn_name
);
7609 strncpy(abbrev
, to
.valstr
, WLC_CNTRY_BUF_SZ
- 1);
7610 abbrev
[WLC_CNTRY_BUF_SZ
- 1] = '\0';
7613 if (!bw_set
|| !band_set
) {
7615 fprintf(stderr
, "%s: you need to set a band, '-b <5|2>'\n",
7618 fprintf(stderr
, "%s: you need to set a bandwidth, '-w <20|40>'\n",
7625 /* Add chanspec argument */
7626 chanspec
= (chanspec_t
*) (buf
+ buflen
);
7627 *chanspec
= htodchanspec(c
);
7628 buflen
+= (sizeof(chanspec_t
));
7630 /* Add country abbrev */
7631 strncpy(buf
+ buflen
, abbrev
, WLC_CNTRY_BUF_SZ
);
7632 buflen
+= WLC_CNTRY_BUF_SZ
;
7635 list
= (wl_uint32_list_t
*)(buf
+ buflen
);
7636 list
->count
= htod32(WL_NUMCHANSPECS
);
7637 buflen
+= sizeof(uint32
)*(WL_NUMCHANSPECS
+ 1);
7639 ret
= wlu_get(wl
, WLC_GET_VAR
, &buf
[0], buflen
);
7643 list
= (wl_uint32_list_t
*)buf
;
7644 for (i
= 0; i
< dtoh32(list
->count
); i
++) {
7645 c
= (chanspec_t
)dtoh32(list
->element
[i
]);
7646 wf_chspec_ntoa(c
, chspec_str
);
7647 printf("%s (0x%04x)\n", chspec_str
, c
);
7657 wl_channels_in_country(void *wl
, cmd_t
*cmd
, char **argv
)
7659 wl_channels_in_country_t
*cic
;
7663 cic
= (wl_channels_in_country_t
*)buf
;
7664 cic
->buflen
= WLC_IOCTL_MAXLEN
;
7667 /* country abbrev must follow */
7669 fprintf(stderr
, "missing country abbrev\n");
7673 len
= strlen(*argv
);
7674 if ((len
> 3) || (len
< 2)) {
7675 fprintf(stderr
, "invalid country abbrev: %s\n", *argv
);
7679 strcpy(cic
->country_abbrev
, *argv
);
7681 /* band must follow */
7683 fprintf(stderr
, "missing band\n");
7687 if (!stricmp(*argv
, "a"))
7688 cic
->band
= WLC_BAND_5G
;
7689 else if (!stricmp(*argv
, "b"))
7690 cic
->band
= WLC_BAND_2G
;
7692 fprintf(stderr
, "unsupported band: %s\n", *argv
);
7696 cic
->buflen
= htod32(cic
->buflen
);
7697 cic
->band
= htod32(cic
->band
);
7698 cic
->count
= htod32(cic
->count
);
7699 ret
= wlu_get(wl
, cmd
->get
, buf
, WLC_IOCTL_MAXLEN
);
7703 for (i
= 0; i
< dtoh32(cic
->count
); i
++)
7704 printf("%d ", dtoh32(cic
->channel
[i
]));
7711 wl_get_scan(void *wl
, int opc
, char *scan_buf
, uint buf_len
)
7713 wl_scan_results_t
*list
= (wl_scan_results_t
*)scan_buf
;
7716 list
->buflen
= htod32(buf_len
);
7717 ret
= wlu_get(wl
, opc
, scan_buf
, buf_len
);
7722 list
->buflen
= dtoh32(list
->buflen
);
7723 list
->version
= dtoh32(list
->version
);
7724 list
->count
= dtoh32(list
->count
);
7725 if (list
->buflen
== 0) {
7728 } else if (list
->version
!= WL_BSS_INFO_VERSION
&&
7729 list
->version
!= LEGACY2_WL_BSS_INFO_VERSION
&&
7730 list
->version
!= LEGACY_WL_BSS_INFO_VERSION
) {
7731 fprintf(stderr
, "Sorry, your driver has bss_info_version %d "
7732 "but this program supports only version %d.\n",
7733 list
->version
, WL_BSS_INFO_VERSION
);
7742 wl_get_iscan(void *wl
, char *scan_buf
, uint buf_len
)
7744 wl_iscan_results_t list
;
7745 wl_scan_results_t
*results
;
7748 memset(&list
, '\0', sizeof(list
));
7749 list
.results
.buflen
= htod32(buf_len
);
7750 ret
= wlu_iovar_getbuf(wl
, "iscanresults", &list
, WL_ISCAN_RESULTS_FIXED_SIZE
,
7751 scan_buf
, WLC_IOCTL_MAXLEN
);
7758 results
= &((wl_iscan_results_t
*)scan_buf
)->results
;
7759 results
->buflen
= dtoh32(results
->buflen
);
7760 results
->version
= dtoh32(results
->version
);
7761 results
->count
= dtoh32(results
->count
);
7762 if (results
->buflen
== 0) {
7763 printf("wl_get_iscan buflen 0\n");
7764 results
->version
= 0;
7766 } else if (results
->version
!= WL_BSS_INFO_VERSION
&&
7767 results
->version
!= LEGACY2_WL_BSS_INFO_VERSION
&&
7768 results
->version
!= LEGACY_WL_BSS_INFO_VERSION
) {
7769 fprintf(stderr
, "Sorry, your driver has bss_info_version %d "
7770 "but this program supports only version %d.\n",
7771 results
->version
, WL_BSS_INFO_VERSION
);
7772 results
->buflen
= 0;
7780 wl_spect(void *wl
, cmd_t
*cmd
, char **argv
)
7783 char *endptr
= NULL
;
7786 if ((ret
= wlu_get(wl
, cmd
->get
, &spect
, sizeof(spect
))) < 0) {
7790 spect
= dtoh32(spect
);
7792 case SPECT_MNGMT_OFF
:
7796 case SPECT_MNGMT_LOOSE_11H
:
7797 printf("Loose interpretation of 11h spec - may join non 11h AP.\n");
7800 case SPECT_MNGMT_STRICT_11H
:
7801 printf("Strict interpretation of 11h spec - may not join non 11h AP.\n");
7804 case SPECT_MNGMT_STRICT_11D
:
7805 printf("802.11d mode\n");
7808 case SPECT_MNGMT_LOOSE_11H_D
:
7809 printf("Loose interpretation of 11h+d spec - may join non-11h APs\n");
7813 printf("invalid value 0x%x\n", spect
);
7819 spect
= strtol(*argv
, &endptr
, 0);
7820 if (*endptr
!= '\0')
7823 if (spect
< SPECT_MNGMT_OFF
|| spect
> SPECT_MNGMT_LOOSE_11H_D
)
7826 spect
= htod32(spect
);
7827 return wlu_set(wl
, cmd
->set
, &spect
, sizeof(spect
));
7832 wl_status(void *wl
, cmd_t
*cmd
, char **argv
)
7835 struct ether_addr bssid
;
7837 char ssidbuf
[SSID_FMT_BUF_LEN
];
7840 UNUSED_PARAMETER(cmd
);
7841 UNUSED_PARAMETER(argv
);
7843 if ((ret
= wlu_get(wl
, WLC_GET_BSSID
, &bssid
, ETHER_ADDR_LEN
)) == 0) {
7844 /* The adapter is associated. */
7845 *(uint32
*)buf
= htod32(WLC_IOCTL_MAXLEN
);
7846 if ((ret
= wlu_get(wl
, WLC_GET_BSS_INFO
, buf
, WLC_IOCTL_MAXLEN
)) < 0)
7849 bi
= (wl_bss_info_t
*)(buf
+ 4);
7850 if (dtoh32(bi
->version
) == WL_BSS_INFO_VERSION
||
7851 dtoh32(bi
->version
) == LEGACY2_WL_BSS_INFO_VERSION
||
7852 dtoh32(bi
->version
) == LEGACY_WL_BSS_INFO_VERSION
)
7855 fprintf(stderr
, "Sorry, your driver has bss_info_version %d "
7856 "but this program supports only version %d.\n",
7857 bi
->version
, WL_BSS_INFO_VERSION
);
7859 printf("Not associated. Last associated with ");
7861 if ((ret
= wlu_get(wl
, WLC_GET_SSID
, &ssid
, sizeof(wlc_ssid_t
))) < 0) {
7866 wl_format_ssid(ssidbuf
, ssid
.SSID
, dtoh32(ssid
.SSID_len
));
7867 printf("SSID: \"%s\"\n", ssidbuf
);
7874 wl_deauth_rc(void *wl
, cmd_t
*cmd
, char **argv
)
7880 fprintf(stderr
, "STA MAC must be specified\n");
7883 } else if (!wl_ether_atoe(*argv
, &scb_val
.ea
)) {
7884 fprintf(stderr
, "Malformed STA MAC parameter\n");
7887 } else if (!*++argv
) {
7888 /* No reason code furnished, so driver will use its default */
7889 ret
= wlu_set(wl
, WLC_SCB_DEAUTHENTICATE
, &scb_val
.ea
,
7893 scb_val
.val
= htod32((uint32
)strtoul(*argv
, NULL
, 0));
7894 ret
= wlu_set(wl
, cmd
->set
, &scb_val
, sizeof(scb_val
));
7900 wl_wpa_auth(void *wl
, cmd_t
*cmd
, char **argv
)
7911 /* Keep the numeric values in the staticly initialized
7912 * help string consistent. Unfortunately, there isn't
7913 * an automatic way for that.
7915 {{WPA_AUTH_NONE
, "WPA-NONE"},
7916 {WPA_AUTH_UNSPECIFIED
, "WPA-802.1x"},
7917 {WPA_AUTH_PSK
, "WPA-PSK"},
7918 {WPA2_AUTH_UNSPECIFIED
, "WPA2-802.1x"},
7919 {WPA2_AUTH_PSK
, "WPA2-PSK"},
7920 {WPA_AUTH_DISABLED
, "disabled"}};
7922 /* skip the command name */
7925 /* parse a bsscfg_idx option if present */
7926 if ((ret
= wl_cfg_option(argv
, cmd
->name
, &bsscfg_idx
, &consumed
)) != 0)
7932 /* no arg, so this is a GET. */
7935 ret
= wlu_iovar_getint(wl
, "wpa_auth", &wpa_auth
);
7937 ret
= wl_bssiovar_getint(wl
, "wpa_auth", bsscfg_idx
, &wpa_auth
);
7942 /* Show all AKM suites enabled */
7943 printf("0x%x", wpa_auth
);
7945 if (wpa_auth
== WPA_AUTH_DISABLED
)
7946 printf(" Disabled");
7948 for (i
= 0; i
< (int)ARRAYSIZE(auth_mode
); i
++) {
7949 if (wpa_auth
& auth_mode
[i
].val
)
7950 printf(" %s", auth_mode
[i
].name
);
7958 /* there's an arg, so this is a SET. */
7961 /* Validate the user input range */
7962 if (isdigit((int)*argv
[0])) {
7963 unsigned int range
= 0;
7965 /* param is a number; look for value in the list */
7966 wpa_auth
= strtoul(*argv
, NULL
, 0);
7968 /* Validate the user input range */
7970 for (i
= 0; i
< (int)ARRAYSIZE(auth_mode
); i
++)
7971 range
|= auth_mode
[i
].val
;
7973 range
= (~range
) & 0xFFFF;
7975 if (range
& wpa_auth
) {
7987 unsigned int range
= 0;
7992 for (i
= 0; i
< (int)ARRAYSIZE(auth_mode
); i
++)
7993 range
|= auth_mode
[i
].val
;
7995 range
= (~range
) & (0xFFFF);
8004 for (j
= 0; j
< arg_count
; j
++) {
8009 /* treat param as string to be matched in list */
8010 for (i
= 0; i
< (int)ARRAYSIZE(auth_mode
); i
++) {
8011 if (!stricmp(auth_mode
[i
].name
, *argv
)) {
8014 wpa_auth
|= auth_mode
[i
].val
;
8017 /* traverse the list */
8024 if ((found
== FALSE
) || (range
& wpa_auth
))
8030 fprintf(stderr
, "%s is not a valid WPA auth mode\n", *argv
);
8033 ret
= wlu_iovar_setint(wl
, "wpa_auth", wpa_auth
);
8035 ret
= wl_bssiovar_setint(wl
, "wpa_auth", bsscfg_idx
, wpa_auth
);
8042 fprintf(stderr
, "Inavlid user argument.\n");
8043 fprintf(stderr
, "Values may be a bitvector or list of names from the set.\n");
8045 for (i
= 0; i
< (int)ARRAYSIZE(auth_mode
); i
++) {
8046 fprintf(stderr
, "\n0x%04x %s", auth_mode
[i
].val
, auth_mode
[i
].name
);
8054 wl_set_pmk(void *wl
, cmd_t
*cmd
, char **argv
)
8062 key_len
= strlen(*argv
);
8063 if (key_len
< WSEC_MIN_PSK_LEN
|| key_len
> WSEC_MAX_PSK_LEN
) {
8064 fprintf(stderr
, "passphrase must be between %d and %d characters long\n",
8065 WSEC_MIN_PSK_LEN
, WSEC_MAX_PSK_LEN
);
8068 psk
.key_len
= htod16((ushort
) key_len
);
8069 psk
.flags
= htod16(WSEC_PASSPHRASE
);
8070 memcpy(psk
.key
, *argv
, key_len
);
8071 return wlu_set(wl
, cmd
->set
, &psk
, sizeof(psk
));
8075 wl_wsec(void *wl
, cmd_t
*cmd
, char **argv
)
8080 char *endptr
= NULL
;
8083 UNUSED_PARAMETER(cmd
);
8087 /* parse a bsscfg_idx option if present */
8088 if ((error
= wl_cfg_option(argv
, "wsec", &bsscfg_idx
, &consumed
)) != 0)
8095 if (consumed
== 0) {
8096 error
= wlu_get(wl
, WLC_GET_WSEC
, &wsec
, sizeof(uint32
));
8097 wsec
= dtoh32(wsec
);
8100 error
= wl_bssiovar_getint(wl
, "wsec", bsscfg_idx
, &wsec
);
8106 if (!stricmp(*argv
, "off"))
8109 wsec
= strtol(*argv
, &endptr
, 0);
8110 if (*endptr
!= '\0') {
8111 /* not all the value string was parsed by strtol */
8116 if (consumed
== 0) {
8117 wsec
= htod32(wsec
);
8118 error
= wlu_set(wl
, WLC_SET_WSEC
, &wsec
, sizeof(uint32
));
8121 error
= wl_bssiovar_setint(wl
, "wsec", bsscfg_idx
, wsec
);
8128 parse_wep(char **argv
, wl_wsec_key_t
*key
, bool options
)
8131 unsigned char *data
= key
->data
;
8132 char *keystr
= *argv
;
8134 switch (strlen(keystr
)) {
8138 key
->len
= strlen(keystr
);
8139 memcpy(data
, keystr
, key
->len
+ 1);
8145 /* strip leading 0x */
8146 if (!strnicmp(keystr
, "0x", 2))
8155 key
->len
= strlen(keystr
) / 2;
8157 strncpy(hex
, keystr
, 2);
8158 *data
++ = (char) strtoul(hex
, NULL
, 16);
8168 key
->algo
= CRYPTO_ALGO_WEP1
;
8171 key
->algo
= CRYPTO_ALGO_WEP128
;
8174 /* default to AES-CCM */
8175 key
->algo
= CRYPTO_ALGO_AES_CCM
;
8178 key
->algo
= CRYPTO_ALGO_TKIP
;
8184 /* Set as primary key by default */
8185 key
->flags
|= WL_PRIMARY_KEY
;
8190 if (!strnicmp("ccm", *argv
, 3) && key
->len
== 16)
8191 key
->algo
= CRYPTO_ALGO_AES_CCM
;
8193 else if (!strnicmp("wapi", *argv
, 4) && key
->len
== 32)
8194 key
->algo
= CRYPTO_ALGO_SMS4
;
8195 #endif /* BCMWAPI_WPI */
8196 else if (!strnicmp("ocb", *argv
, 3) && key
->len
== 16)
8197 key
->algo
= CRYPTO_ALGO_AES_OCB_MPDU
;
8198 else if (!strnicmp("notx", *argv
, 4))
8199 key
->flags
&= ~WL_PRIMARY_KEY
;
8200 else if (!wl_ether_atoe(*argv
, &key
->ea
))
8201 memset(&key
->ea
, 0, ETHER_ADDR_LEN
);
8209 wl_primary_key(void *wl
, cmd_t
*cmd
, char **argv
)
8211 int i
, val
, ret
= 0;
8217 if (wlu_get(wl
, cmd
->get
, &val
, sizeof(val
)) < 0) {
8221 printf("Key %d is primary\n", i
);
8224 } while (++i
< DOT11_MAX_DEFAULT_KEYS
);
8225 printf("No primary key set\n");
8228 val
= htod32(atoi(*argv
));
8229 ret
= wlu_set(wl
, cmd
->set
, &val
, sizeof(val
));
8235 wl_addwep(void *wl
, cmd_t
*cmd
, char **argv
)
8242 memset(&key
, 0, sizeof(key
));
8246 /* parse a bsscfg_idx option if present */
8247 if ((error
= wl_cfg_option(argv
, "addwep", &bsscfg_idx
, &consumed
)) != 0)
8252 /* GET operation not allowed */
8256 key
.index
= atoi(*argv
++);
8259 fprintf(stderr
, "No key specified\n");
8262 if (parse_wep(argv
, &key
, TRUE
))
8265 key
.index
= htod32(key
.index
);
8266 key
.len
= htod32(key
.len
);
8267 key
.algo
= htod32(key
.algo
);
8268 key
.flags
= htod32(key
.flags
);
8270 if (consumed
== 0) {
8271 error
= wlu_set(wl
, cmd
->set
, &key
, sizeof(key
));
8273 error
= wl_bssiovar_setbuf(wl
, "wsec_key", bsscfg_idx
,
8274 &key
, sizeof(key
), buf
, WLC_IOCTL_MAXLEN
);
8281 wl_rmwep(void *wl
, cmd_t
*cmd
, char **argv
)
8288 memset(&key
, 0, sizeof(key
));
8292 /* parse a bsscfg_idx option if present */
8293 if ((error
= wl_cfg_option(argv
, "rmwep", &bsscfg_idx
, &consumed
)) != 0)
8298 /* GET operation not allowed */
8302 key
.index
= htod32(atoi(*argv
++));
8305 if (!(wl_ether_atoe(*argv
, &key
.ea
)))
8309 if (consumed
== 0) {
8310 error
= wlu_set(wl
, cmd
->set
, &key
, sizeof(key
));
8312 error
= wlu_var_setbuf(wl
, "wsec_key", &key
, sizeof(key
));
8322 {WSEC_GEN_MIC_ERROR
, "mic_error"},
8323 {WSEC_GEN_REPLAY
, "replay"},
8324 {WSEC_GEN_ICV_ERROR
, "icv_error"},
8325 {WSEC_GEN_MFP_ACT_ERROR
, "act_error"},
8326 {WSEC_GEN_MFP_DISASSOC_ERROR
, "disassoc_error"},
8327 {WSEC_GEN_MFP_DEAUTH_ERROR
, "deauth_error"},
8333 wl_wsec_test(void *wl
, cmd_t
*cmd
, char **argv
)
8337 char *endptr
= NULL
, *wsec_buf
= NULL
;
8338 uint32 val
, last_val
;
8344 val
= strtol(*argv
, &endptr
, 0);
8345 if (endptr
== *argv
) {
8346 /* the value string was not parsed by strtol */
8347 for (i
= 0; wsec_test
[i
].value
; i
++)
8348 if (stricmp(wsec_test
[i
].string
, *argv
) == 0) {
8349 val
= wsec_test
[i
].value
;
8352 if (wsec_test
[i
].value
== 0)
8358 case WSEC_GEN_REPLAY
:
8359 case WSEC_GEN_MIC_ERROR
:
8360 case WSEC_GEN_ICV_ERROR
:
8361 case WSEC_GEN_MFP_ACT_ERROR
:
8362 case WSEC_GEN_MFP_DISASSOC_ERROR
:
8363 case WSEC_GEN_MFP_DEAUTH_ERROR
:
8365 fprintf(stderr
, "insufficient arguments\n");
8368 len
= sizeof(wl_wsec_key_t
) + 4;
8369 wsec_buf
= malloc(len
);
8370 *(uint32
*)wsec_buf
= htod32(val
);
8371 key
= (wl_wsec_key_t
*)&wsec_buf
[4];
8372 memset(key
, 0, sizeof(wl_wsec_key_t
));
8373 /* If it doesn't look like an ether addr, suppose it's a key index */
8374 if (!(wl_ether_atoe(*argv
, &key
->ea
))) {
8375 memset(&key
->ea
, 0, ETHER_ADDR_LEN
);
8376 key
->index
= htod32(atoi(*argv
));
8384 err
= wlu_set(wl
, cmd
->set
, wsec_buf
, len
);
8389 fprintf(stderr
, "wsec test_type may be a number or name from the following set:");
8390 last_val
= 0xffffffff;
8391 for (i
= 0; (val
= wsec_test
[i
].value
); i
++) {
8392 if (val
!= last_val
)
8393 fprintf(stderr
, "\n0x%04x %s", val
, wsec_test
[i
].string
);
8395 fprintf(stderr
, ", %s", wsec_test
[i
].string
);
8398 fprintf(stderr
, "\n");
8405 wl_keys(void *wl
, cmd_t
*cmd
, char **argv
)
8415 int empty_first
, empty_last
;
8418 UNUSED_PARAMETER(argv
);
8420 if ((ret
= wlu_iovar_getint(wl
, "wsec", &wep_is_on
)) < 0)
8421 fprintf(stderr
, "Could not query wsec status.\n");
8423 empty_first
= empty_last
= -1;
8425 for (i
= 0; ; i
++) { /* The upper limit is not known here. */
8426 u
.index
= htod32(i
);
8427 ret
= wlu_get(wl
, cmd
->get
, &u
, sizeof(u
));
8428 empty
= (ETHER_ISNULLADDR(&u
.key
.ea
) && dtoh32(u
.key
.algo
) == CRYPTO_ALGO_OFF
);
8430 if (empty_first
!= -1 &&
8431 (ret
< 0 || !empty
)) {
8432 if (empty_first
== empty_last
)
8433 printf("%3d: <empty>\n", empty_first
);
8435 printf("%3d - %3d: <empty>\n", empty_first
, empty_last
);
8436 empty_first
= empty_last
= -1;
8440 /* If at least one beyond the defaults could be read,
8441 * not knowing the limit must have been the error.
8443 return (i
>= DOT11_MAX_DEFAULT_KEYS
) ? 0 : ret
;
8446 /* Key may not have been set yet */
8447 if (i
< DOT11_MAX_DEFAULT_KEYS
)
8450 if (empty_first
== -1) empty_first
= i
;
8454 addr
= wl_ether_etoa(&u
.key
.ea
);
8456 printf("%3d: %-17s Key %d: %s ", i
, addr
, dtoh32(u
.key
.index
),
8457 bcm_crypto_algo_name(dtoh32(u
.key
.algo
)));
8459 if (wep_is_on
&& dtoh32(u
.key
.flags
) & WL_PRIMARY_KEY
)
8463 if (dtoh32(u
.key
.len
) == 0)
8464 printf("No key present");
8466 if (dtoh32(u
.key
.flags
) & WL_SOFT_KEY
)
8468 printf("len %d, data 0x", dtoh32(u
.key
.len
));
8469 for (j
= 0; j
< dtoh32(u
.key
.len
); j
++)
8470 printf("%02X", u
.key
.data
[j
]);
8472 for (j
= 0; j
< dtoh32(u
.key
.len
); j
++)
8473 if (!isprint(u
.key
.data
[j
]))
8475 if (j
== dtoh32(u
.key
.len
))
8476 printf(" (%.*s)", (int)dtoh32(u
.key
.len
), u
.key
.data
);
8487 wl_tsc(void *wl
, cmd_t
*cmd
, char **argv
)
8491 uint8 tsc
[DOT11_WPA_KEY_RSC_LEN
];
8500 fprintf(stderr
, "Key index %d out of range. Should be positive.\n", idx
);
8503 u
.index
= htod32(idx
);
8504 if ((ret
= wlu_get(wl
, cmd
->get
, &u
, sizeof(u
))) < 0)
8506 lo
= u
.tsc
[0] | (u
.tsc
[1] << 8) | (u
.tsc
[2] << 16) | (u
.tsc
[3] << 24);
8507 hi
= u
.tsc
[4] | (u
.tsc
[5] << 8) | (u
.tsc
[6] << 16) | (u
.tsc
[7] << 24);
8509 printf("Key %d TSC: 0x%04x:%08x\n", idx
, hi
, lo
);
8514 wl_txppr_print(txppr_t
*ppr
, int cck
, int isht
)
8517 uint n
= isht
? WL_NUM_3x3_ELEMENTS
: WL_NUM_2x2_ELEMENTS
;
8518 uint offset
= isht
? WL_NUM_3x3_ELEMENTS
: 0;
8520 const char *str
= "";
8524 printf("CCK %2d %2d %2d %2d\n", ppr
->cck
[0], ppr
->cck
[1],
8525 ppr
->cck
[2], ppr
->cck
[3]);
8527 printf("CCK CDD 1x2 %2d %2d %2d %2d\n",
8528 ppr
->cck_cdd
.s1x2
[0], ppr
->cck_cdd
.s1x2
[1],
8529 ppr
->cck_cdd
.s1x2
[2], ppr
->cck_cdd
.s1x2
[3]);
8530 printf("CCK CDD 1x3 %2d %2d %2d %2d\n",
8531 ppr
->cck_cdd
.s1x3
[0], ppr
->cck_cdd
.s1x3
[1],
8532 ppr
->cck_cdd
.s1x3
[2], ppr
->cck_cdd
.s1x3
[3]);
8535 printf("OFDM %2d %2d %2d %2d %2d %2d %2d %2d\n",
8536 ppr
->ofdm
[0], ppr
->ofdm
[1], ppr
->ofdm
[2], ppr
->ofdm
[3],
8537 ppr
->ofdm
[4], ppr
->ofdm
[5], ppr
->ofdm
[6], ppr
->ofdm
[7]);
8538 printf("OFDM-CDD %2d %2d %2d %2d %2d %2d %2d %2d\n",
8539 ppr
->ofdm_cdd
[0], ppr
->ofdm_cdd
[1], ppr
->ofdm_cdd
[2], ppr
->ofdm_cdd
[3],
8540 ppr
->ofdm_cdd
[4], ppr
->ofdm_cdd
[5], ppr
->ofdm_cdd
[6], ppr
->ofdm_cdd
[7]);
8541 for (i
= 0; i
< n
; i
++) {
8542 switch (i
+ offset
) {
8545 ptr
= ppr
->u20
.n
.siso
;
8549 ptr
= ppr
->u20
.n
.cdd
;
8553 ptr
= ppr
->u20
.n
.stbc
;
8557 ptr
= ppr
->u20
.n
.sdm
;
8564 str
= "1 Nsts 1 Tx ";
8565 ptr
= ppr
->u20
.ht
.s1x1
;
8568 str
= "1 Nsts 2 Tx ";
8569 ptr
= ppr
->u20
.ht
.s1x2
;
8572 str
= "1 Nsts 3 Tx ";
8573 ptr
= ppr
->ht
.u20s1x3
;
8576 str
= "2 Nsts 2 Tx ";
8577 ptr
= ppr
->u20
.ht
.s2x2
;
8580 str
= "2 Nsts 3 Tx ";
8581 ptr
= ppr
->ht
.u20s2x3
;
8584 str
= "3 Nsts 3 Tx ";
8585 ptr
= ppr
->u20
.ht
.s3x3
;
8591 printf("%s %2d %2d %2d %2d %2d %2d %2d %2d\n",
8592 str
, ptr
[0], ptr
[1], ptr
[2], ptr
[3], ptr
[4], ptr
[5], ptr
[6], ptr
[7]);
8595 printf("\n40MHz:\n");
8596 printf("OFDM %2d %2d %2d %2d %2d %2d %2d %2d\n",
8597 ppr
->ofdm_40
[0], ppr
->ofdm_40
[1], ppr
->ofdm_40
[2], ppr
->ofdm_40
[3],
8598 ppr
->ofdm_40
[4], ppr
->ofdm_40
[5], ppr
->ofdm_40
[6], ppr
->ofdm_40
[7]);
8599 printf("OFDM-CDD %2d %2d %2d %2d %2d %2d %2d %2d\n",
8600 ppr
->ofdm_40_cdd
[0], ppr
->ofdm_40_cdd
[1], ppr
->ofdm_40_cdd
[2], ppr
->ofdm_40_cdd
[3],
8601 ppr
->ofdm_40_cdd
[4], ppr
->ofdm_40_cdd
[5], ppr
->ofdm_40_cdd
[6], ppr
->ofdm_40_cdd
[7]);
8602 for (i
= 0; i
< n
; i
++) {
8603 switch (i
+ offset
) {
8606 ptr
= ppr
->u40
.n
.siso
;
8610 ptr
= ppr
->u40
.n
.cdd
;
8614 ptr
= ppr
->u40
.n
.stbc
;
8618 ptr
= ppr
->u40
.n
.sdm
;
8625 str
= "1 Nsts 1 Tx ";
8626 ptr
= ppr
->u40
.ht
.s1x1
;
8629 str
= "1 Nsts 2 Tx ";
8630 ptr
= ppr
->u40
.ht
.s1x2
;
8633 str
= "1 Nsts 3 Tx ";
8634 ptr
= ppr
->ht
.u40s1x3
;
8637 str
= "2 Nsts 2 Tx ";
8638 ptr
= ppr
->u40
.ht
.s2x2
;
8641 str
= "2 Nsts 3 Tx ";
8642 ptr
= ppr
->ht
.u40s2x3
;
8645 str
= "3 Nsts 3 Tx ";
8646 ptr
= ppr
->u40
.ht
.s3x3
;
8652 printf("%s %2d %2d %2d %2d %2d %2d %2d %2d\n",
8653 str
, ptr
[0], ptr
[1], ptr
[2], ptr
[3], ptr
[4], ptr
[5], ptr
[6], ptr
[7]);
8655 printf("MCS32 %2d\n", ppr
->mcs32
);
8657 printf("\n20 in 40MHz:\n");
8659 printf("CCK %2d %2d %2d %2d\n", ppr
->cck_20ul
[0], ppr
->cck_20ul
[1],
8660 ppr
->cck_20ul
[2], ppr
->cck_20ul
[3]);
8662 printf("CCK CDD 1x2 %2d %2d %2d %2d\n",
8663 ppr
->cck_20ul_cdd
.s1x2
[0], ppr
->cck_20ul_cdd
.s1x2
[1],
8664 ppr
->cck_20ul_cdd
.s1x2
[2], ppr
->cck_20ul_cdd
.s1x2
[3]);
8665 printf("CCK CDD 1x3 %2d %2d %2d %2d\n",
8666 ppr
->cck_20ul_cdd
.s1x3
[0], ppr
->cck_20ul_cdd
.s1x3
[1],
8667 ppr
->cck_20ul_cdd
.s1x3
[2], ppr
->cck_20ul_cdd
.s1x3
[3]);
8670 printf("OFDM %2d %2d %2d %2d %2d %2d %2d %2d\n",
8671 ppr
->ofdm_20ul
[0], ppr
->ofdm_20ul
[1], ppr
->ofdm_20ul
[2], ppr
->ofdm_20ul
[3],
8672 ppr
->ofdm_20ul
[4], ppr
->ofdm_20ul
[5], ppr
->ofdm_20ul
[6], ppr
->ofdm_20ul
[7]);
8673 printf("OFDM-CDD %2d %2d %2d %2d %2d %2d %2d %2d\n",
8674 ppr
->ofdm_20ul_cdd
[0], ppr
->ofdm_20ul_cdd
[1],
8675 ppr
->ofdm_20ul_cdd
[2], ppr
->ofdm_20ul_cdd
[3],
8676 ppr
->ofdm_20ul_cdd
[4], ppr
->ofdm_20ul_cdd
[5],
8677 ppr
->ofdm_20ul_cdd
[6], ppr
->ofdm_20ul_cdd
[7]);
8678 for (i
= 0; i
< n
; i
++) {
8681 str
= "1 Nsts 1 Tx ";
8682 ptr
= ppr
->ht20ul
.s1x1
;
8685 str
= "1 Nsts 2 Tx ";
8686 ptr
= ppr
->ht20ul
.s1x2
;
8689 str
= "1 Nsts 3 Tx ";
8690 ptr
= ppr
->ht
.ul20s1x3
;
8693 str
= "2 Nsts 2 Tx ";
8694 ptr
= ppr
->ht20ul
.s2x2
;
8697 str
= "2 Nsts 3 Tx ";
8698 ptr
= ppr
->ht
.ul20s2x3
;
8701 str
= "3 Nsts 3 Tx ";
8702 ptr
= ppr
->ht20ul
.s3x3
;
8708 printf("%s %2d %2d %2d %2d %2d %2d %2d %2d\n",
8709 str
, ptr
[0], ptr
[1], ptr
[2], ptr
[3], ptr
[4], ptr
[5], ptr
[6], ptr
[7]);
8715 wl_get_current_txppr(void *wl
, cmd_t
*cmd
, char **argv
)
8719 chanspec_t chanspec
;
8720 char chanspec_str
[CHANSPEC_STR_LEN
];
8721 wl_txppr_t txppr
, *wl_txppr
;
8723 memset(&txppr
, 0, sizeof(wl_txppr_t
));
8726 fprintf(stderr
, "Ignoring arguments for %s\n", cmd
->name
);
8728 txppr
.ver
= WL_TXPPR_VERSION
;
8729 txppr
.len
= WL_TXPPR_LENGTH
;
8730 if ((err
= wlu_iovar_getbuf(wl
, "curppr", &txppr
, sizeof(wl_txppr_t
),
8731 buf
, WLC_IOCTL_MAXLEN
)) < 0)
8734 wl_txppr
= (wl_txppr_t
*)buf
;
8736 wl_txppr
->flags
= dtoh32(wl_txppr
->flags
);
8737 wl_txppr
->chanspec
= dtohchanspec(wl_txppr
->chanspec
);
8738 wl_txppr
->local_chanspec
= dtohchanspec(wl_txppr
->local_chanspec
);
8740 chanspec
= wl_txppr
->chanspec
;
8741 mimo
= (wl_txppr
->flags
& WL_TX_POWER_F_HT
) |
8742 (wl_txppr
->flags
& WL_TX_POWER_F_MIMO
) |
8743 (wl_txppr
->flags
& WL_TX_POWER_F_SISO
);
8746 printf("Current channel:\t %s\n",
8747 wf_chspec_ntoa(wl_txppr
->chanspec
, chanspec_str
));
8748 printf("BSS channel:\t\t %s\n",
8749 wf_chspec_ntoa(wl_txppr
->local_chanspec
, chanspec_str
));
8750 printf("Power/Rate Dump (in 1/2dB): Channel %d\n", CHSPEC_CHANNEL(chanspec
));
8751 wl_txppr_print((txppr_t
*)wl_txppr
->ppr
, CHSPEC_IS2G(chanspec
),
8752 (mimo
& WL_TX_POWER_F_MIMO
));
8757 wl_get_current_power(void *wl
, cmd_t
*cmd
, char **argv
)
8762 chanspec_t chanspec
;
8763 char chanspec_str
[CHANSPEC_STR_LEN
];
8766 wlc_rev_info_t revinfo
;
8769 memset(&power
, 0, sizeof(power
));
8773 fprintf(stderr
, "Ignoring arguments for %s\n", cmd
->name
);
8775 /* Check for legacy driver by supplying a short buffer
8776 * Legacy drivers do not return an error.
8778 err
= wlu_get(wl
, cmd
->get
, &buf
[0], 4);
8779 use_new_power
= (err
!= 0);
8782 return wl_curpower_legacy(wl
);
8784 /* Check for legacy driver by supplying a power structure with
8785 * 45 rates instead of 101 rates. The Legacy driver will not
8786 * return an error in which case the wl curpower command will
8787 * print the output in the old format using 45 rates.
8789 err
= wl_curpower_legacy2(wl
, cmd
);
8794 if ((err
= wlu_get(wl
, cmd
->get
, &power
, sizeof(power
))) < 0)
8797 /* get PHYTYPE as well */
8798 memset(&revinfo
, 0, sizeof(revinfo
));
8799 if ((err
= wlu_get(wl
, WLC_GET_REVINFO
, &revinfo
, sizeof(revinfo
))) != 0)
8801 phytype
= dtoh32(revinfo
.phytype
);
8804 power
.flags
= dtoh32(power
.flags
);
8805 power
.chanspec
= dtohchanspec(power
.chanspec
);
8806 power
.local_chanspec
= dtohchanspec(power
.local_chanspec
);
8808 chanspec
= power
.chanspec
;
8809 mimo
= (power
.flags
& WL_TX_POWER_F_HT
) |
8810 (power
.flags
& WL_TX_POWER_F_MIMO
) |
8811 (power
.flags
& WL_TX_POWER_F_SISO
);
8814 printf("Power Control:\t\t %s, %s\n",
8815 (power
.flags
& WL_TX_POWER_F_ENABLED
) ? "On" : "Off",
8816 (power
.flags
& WL_TX_POWER_F_HW
) ? "HW" : "SW");
8817 printf("Current channel:\t %s\n",
8818 wf_chspec_ntoa(power
.chanspec
, chanspec_str
));
8819 printf("BSS channel:\t\t %s\n",
8820 wf_chspec_ntoa(power
.local_chanspec
, chanspec_str
));
8821 printf("BSS Local Max:\t\t%2d.%-2d dBm\n",
8822 DIV_QUO(power
.local_max
, 4), DIV_REM(power
.local_max
, 4));
8823 printf("BSS Local Constraint:\t%2d.%-2d dB\n",
8824 DIV_QUO(power
.local_constraint
, 4), DIV_REM(power
.local_constraint
, 4));
8825 printf("User Target:\t\t%2d.%-2d dBm\n",
8826 DIV_QUO(power
.user_limit
[0], 4), DIV_REM(power
.user_limit
[0], 4));
8827 printf("SROM antgain:\t\t 2G: %d.%d dB, 5G: %d.%d dB\n\n",
8828 DIV_QUO(power
.antgain
[0], 4), DIV_REM(power
.antgain
[0], 4),
8829 DIV_QUO(power
.antgain
[1], 4), DIV_REM(power
.antgain
[1], 4));
8831 printf("Regulatory Limits:\n");
8832 wl_txpwr_array_print(power
.reg_limit
, CHSPEC_IS2G(chanspec
), mimo
);
8835 printf("Board Limits:\n");
8836 wl_txpwr_array_print(power
.board_limit
, CHSPEC_IS2G(chanspec
), mimo
);
8839 printf("Power Target:\n");
8840 wl_txpwr_array_print(power
.target
, CHSPEC_IS2G(chanspec
), mimo
);
8843 /* print the different power estimate combinations */
8845 printf("Maximum Power Target among all rates:\t");
8846 for (i
= 0; i
< power
.rf_cores
; i
++)
8848 DIV_QUO(power
.tx_power_max
[i
], 4),
8849 DIV_REM(power
.tx_power_max
[i
], 4));
8852 printf("Rate index with Maximum Power Target:\t");
8853 for (i
= 0; i
< power
.rf_cores
; i
++)
8854 printf("%d ", power
.tx_power_max_rate_ind
[i
]);
8857 printf("Last adjusted est. power :\t");
8858 for (i
= 0; i
< power
.rf_cores
; i
++)
8860 DIV_QUO(power
.est_Pout
[i
], 4),
8861 DIV_REM(power
.est_Pout
[i
], 4));
8864 printf("Last est. power:\t%d.%d dBm\n",
8865 DIV_QUO(power
.est_Pout
[0], 4),
8866 DIV_REM(power
.est_Pout
[0], 4));
8869 if (!mimo
&& CHSPEC_IS2G(chanspec
)) {
8870 printf("Last CCK est. power:\t%d.%d dBm\n",
8871 DIV_QUO(power
.est_Pout_cck
, 4),
8872 DIV_REM(power
.est_Pout_cck
, 4));
8879 wl_txpwr_array_print(uint8
*pwr
, int cck
, int mimo
)
8883 bool isnphy
= FALSE
;
8887 wl_txpwr_range_print(pwr
, WL_TX_POWER_CCK_FIRST
, WL_NUM_RATES_CCK
,
8890 wl_txpwr_range_print(pwr
, WL_TX_POWER_CCK_CDD_S1x2_FIRST
, WL_NUM_RATES_CCK
,
8891 "CCK CDD 1x2 ", &newline
);
8892 wl_txpwr_range_print(pwr
, WL_TX_POWER_CCK_CDD_S1x3_FIRST
, WL_NUM_RATES_CCK
,
8893 "CCK CDD 1x3 ", &newline
);
8899 wl_txpwr_range_print(pwr
, WL_TX_POWER_OFDM20_FIRST
, WL_NUM_RATES_OFDM
,
8900 "Legacy OFDM ", &newline
);
8901 } else if (mimo
== WL_TX_POWER_F_SISO
) {
8902 /* Legacy OFDM 20MHz SISO rates */
8903 wl_txpwr_range_print(pwr
, WL_TX_POWER_OFDM20_FIRST
, WL_NUM_RATES_OFDM
,
8904 "Legacy OFDM 20MHz SISO ", &newline
);
8906 /* MCS 20MHz SISO rates */
8907 wl_txpwr_range_print(pwr
, WL_TX_POWER_MCS20_SISO_FIRST_SSN
,
8908 WL_NUM_RATES_MCS_1STREAM
, "MCS 0-7 20MHz SISO ", &newline
);
8910 /* MCS 40MHz SISO rates */
8911 wl_txpwr_range_print(pwr
, WL_TX_POWER_MCS20_SISO_FIRST_SSN
,
8912 WL_NUM_RATES_MCS_1STREAM
, "MCS 0-7 40MHz SISO ", &newline
);
8914 if ((mimo
& WL_TX_POWER_F_HT
) != WL_TX_POWER_F_HT
)
8916 /* Legacy OFDM 20MHz SISO rates */
8917 wl_txpwr_range_print(pwr
, WL_TX_POWER_OFDM20_FIRST
, WL_NUM_RATES_OFDM
,
8918 "Legacy OFDM 20MHz SISO ", &newline
);
8920 /* Legacy OFDM 20MHz CDD rates */
8921 wl_txpwr_range_print(pwr
, WL_TX_POWER_OFDM20_CDD_FIRST
, WL_NUM_RATES_OFDM
,
8922 "Legacy OFDM 20MHz CDD ", &newline
);
8924 /* MCS 20MHz SISO rates */
8925 offset
= isnphy
? WL_TX_POWER_MCS20_SISO_FIRST
: WL_TX_POWER_20_S1x1_FIRST
;
8926 wl_txpwr_range_print(pwr
, offset
, WL_NUM_RATES_MCS_1STREAM
,
8927 isnphy
? "MCS 0-7 20MHz SISO " : "MCS 0-7 20MHz 1 Tx ", &newline
);
8929 /* MCS 20MHz CDD rates */
8930 offset
= isnphy
? WL_TX_POWER_MCS20_CDD_FIRST
: WL_TX_POWER_20_S1x2_FIRST
;
8931 wl_txpwr_range_print(pwr
, offset
, WL_NUM_RATES_MCS_1STREAM
,
8932 isnphy
? "MCS 0-7 20MHz CDD " : "MCS 0-7 20MHz 2 Tx ", &newline
);
8934 /* MCS 20MHz STBC rates */
8935 offset
= isnphy
? WL_TX_POWER_MCS20_STBC_FIRST
: WL_TX_POWER_20_S1x3_FIRST
;
8936 wl_txpwr_range_print(pwr
, offset
, WL_NUM_RATES_MCS_1STREAM
,
8937 isnphy
? "MCS 0-7 20MHz STBC " : "MCS 0-7 20MHz 3 Tx ", &newline
);
8941 /* MCS 0-7 20MHz STBC 2x2 rates */
8942 wl_txpwr_range_print(pwr
, WL_TX_POWER_HT_STBC_S2x2_FIRST
,
8943 WL_NUM_RATES_MCS_1STREAM
, "MCS 0-7 20MHz STBC 2 Tx ",
8945 /* MCS 0-7 20MHz STBC 2x3 rates */
8946 wl_txpwr_range_print(pwr
, WL_TX_POWER_HT_STBC_S2x3_FIRST
,
8947 WL_NUM_RATES_MCS_1STREAM
, "MCS 0-7 20MHz STBC 3 Tx ",
8951 /* MCS 20MHz SDM rates */
8952 offset
= isnphy
? WL_TX_POWER_MCS20_SDM_FIRST
: WL_TX_POWER_20_S2x2_FIRST
;
8953 wl_txpwr_range_print(pwr
, offset
, WL_NUM_RATES_MCS_1STREAM
,
8954 isnphy
? "MCS 8-15 20MHz SDM " : "MCS 8-15 20MHz 2 Tx ", &newline
);
8957 /* 20MHz MCS 8-15 with 3 Tx Chain */
8958 wl_txpwr_range_print(pwr
, WL_TX_POWER_20_S2x3_FIRST
,
8959 WL_NUM_RATES_MCS_1STREAM
, "MCS 8-15 20MHz 3 Tx ", &newline
);
8960 /* 20MHz MCS 16-23 with 3 Tx Chain */
8961 wl_txpwr_range_print(pwr
, WL_TX_POWER_20_S3x3_FIRST
,
8962 WL_NUM_RATES_MCS_1STREAM
, "MCS 16-23 20MHz 3 Tx ", &newline
);
8965 /* Legacy OFDM 40MHz SISO rates */
8966 wl_txpwr_range_print(pwr
, WL_TX_POWER_OFDM40_FIRST
, WL_NUM_RATES_OFDM
,
8967 "Legacy OFDM 40MHz SISO ", &newline
);
8969 /* Legacy OFDM 40MHz CDD rates */
8970 wl_txpwr_range_print(pwr
, WL_TX_POWER_OFDM40_CDD_FIRST
, WL_NUM_RATES_OFDM
,
8971 "Legacy OFDM 40MHz CDD ", &newline
);
8973 /* MCS 40MHz SISO rates */
8974 offset
= isnphy
? WL_TX_POWER_MCS40_SISO_FIRST
: WL_TX_POWER_40_S1x1_FIRST
;
8975 wl_txpwr_range_print(pwr
, offset
, WL_NUM_RATES_MCS_1STREAM
,
8976 isnphy
? "MCS 0-7 40MHz SISO " : "MCS 0-7 40MHz 1 Tx ", &newline
);
8978 /* MCS 40MHz CDD rates */
8979 offset
= isnphy
? WL_TX_POWER_MCS40_CDD_FIRST
: WL_TX_POWER_40_S1x2_FIRST
;
8980 wl_txpwr_range_print(pwr
, offset
, WL_NUM_RATES_MCS_1STREAM
,
8981 isnphy
? "MCS 0-7 40MHz CDD " : "MCS 0-7 40MHz 2 Tx ", &newline
);
8983 /* MCS 40MHz STBC rates */
8984 offset
= isnphy
? WL_TX_POWER_MCS40_STBC_FIRST
: WL_TX_POWER_40_S1x3_FIRST
;
8985 wl_txpwr_range_print(pwr
, offset
, WL_NUM_RATES_MCS_1STREAM
,
8986 isnphy
? "MCS 0-7 40MHz STBC " : "MCS 0-7 40MHz 3 Tx ", &newline
);
8990 /* MCS 0-7 40MHz STBC 2x2 rates */
8991 wl_txpwr_range_print(pwr
, WL_TX_POWER_HT_STBC_40_S2x2_FIRST
,
8992 WL_NUM_RATES_MCS_1STREAM
, "MCS 0-7 40MHz STBC 2 Tx ",
8994 /* MCS 0-7 40MHz STBC 2x3 rates */
8995 wl_txpwr_range_print(pwr
, WL_TX_POWER_HT_STBC_40_S2x3_FIRST
,
8996 WL_NUM_RATES_MCS_1STREAM
, "MCS 0-7 40MHz STBC 3 Tx ",
9000 /* MCS 40MHz SDM rates */
9001 offset
= isnphy
? WL_TX_POWER_MCS40_SDM_FIRST
: WL_TX_POWER_40_S2x2_FIRST
;
9002 wl_txpwr_range_print(pwr
, offset
, WL_NUM_RATES_MCS_1STREAM
,
9003 isnphy
? "MCS 8-15 40MHz SDM " : "MCS 8-15 40MHz 2 Tx ", &newline
);
9006 /* 40MHz MCS 8-15 with 3 Tx Chain */
9007 wl_txpwr_range_print(pwr
, WL_TX_POWER_40_S2x3_FIRST
,
9008 WL_NUM_RATES_MCS_1STREAM
, "MCS 8-15 40MHz 3 Tx ", &newline
);
9009 /* 40MHz MCS 16-23 with 3 Tx Chain */
9010 wl_txpwr_range_print(pwr
, WL_TX_POWER_40_S3x3_FIRST
,
9011 WL_NUM_RATES_MCS_1STREAM
, "MCS 16-23 40MHz 3 Tx ", &newline
);
9014 wl_txpwr_range_print(pwr
, WL_TX_POWER_MCS_32
, WL_NUM_RATES_MCS32
,
9015 "MCS 32 ", &newline
);
9021 /* 20 in 40MHz CCK rates */
9022 wl_txpwr_range_print(pwr
, WL_TX_POWER_20UL_CCK_FIRST
, WL_NUM_RATES_CCK
,
9023 "20UL CCK ", &newline
);
9024 wl_txpwr_range_print(pwr
, WL_TX_POWER_CCK_20U_CDD_S1x2_FIRST
,
9025 WL_NUM_RATES_CCK
, "20UL CCK CDD 1x2 ", &newline
);
9026 wl_txpwr_range_print(pwr
, WL_TX_POWER_CCK_20U_CDD_S1x3_FIRST
,
9027 WL_NUM_RATES_CCK
, "20UL CCK CDD 1x3 ", &newline
);
9029 /* 20 in 40MHz OFDM rates */
9030 wl_txpwr_range_print(pwr
, WL_TX_POWER_20UL_OFDM_FIRST
, WL_NUM_RATES_OFDM
,
9031 "20UL Legacy OFDM ", &newline
);
9033 /* 20 in 40MHz OFDM CDD rates */
9034 wl_txpwr_range_print(pwr
, WL_TX_POWER_20UL_OFDM_CDD_FIRST
, WL_NUM_RATES_OFDM
,
9035 "20UL Legacy OFDM CDD ", &newline
);
9037 /* 20 in 40MHz MCS 0-7 rates 1 Tx chain */
9038 wl_txpwr_range_print(pwr
, WL_TX_POWER_20UL_S1x1_FIRST
, WL_NUM_RATES_MCS_1STREAM
,
9039 "MCS 0-7 20UL 1 Tx ", &newline
);
9041 /* 20 in 40MHz MCS 0-7 rates 2 Tx chain */
9042 wl_txpwr_range_print(pwr
, WL_TX_POWER_20UL_S1x2_FIRST
, WL_NUM_RATES_MCS_1STREAM
,
9043 "MCS 0-7 20UL 2 Tx ", &newline
);
9045 /* 20 in 40MHz MCS 0-7 rates 3 Tx chain */
9046 wl_txpwr_range_print(pwr
, WL_TX_POWER_20UL_S1x3_FIRST
, WL_NUM_RATES_MCS_1STREAM
,
9047 "MCS 0-7 20UL 3 Tx ", &newline
);
9049 /* 20 in 40MHz MCS 8-15 rates 2 Tx chain */
9050 wl_txpwr_range_print(pwr
, WL_TX_POWER_20UL_S2x2_FIRST
, WL_NUM_RATES_MCS_1STREAM
,
9051 "MCS 8-15 20UL 2 Tx ", &newline
);
9053 /* 20 in 40MHz MCS 8-15 rates 3 Tx chain */
9054 wl_txpwr_range_print(pwr
, WL_TX_POWER_20UL_S2x3_FIRST
, WL_NUM_RATES_MCS_1STREAM
,
9055 "MCS 8-15 20UL 3 Tx ", &newline
);
9057 /* 20 in 40MHz MCS 16-23 rates 3 Tx chain */
9058 wl_txpwr_range_print(pwr
, WL_TX_POWER_20UL_S3x3_FIRST
, WL_NUM_RATES_MCS_1STREAM
,
9059 "MCS 16-23 20UL 3 Tx ", &newline
);
9062 /* 20 in 40MHz MCS 0-7 STBC 2x2 rates */
9063 wl_txpwr_range_print(pwr
, WL_TX_POWER_HT_STBC_UL20_S2x2_FIRST
,
9064 WL_NUM_RATES_MCS_1STREAM
, "MCS 0-7 20UL STBC 2 Tx ",
9066 /* 20 in 40MHz MCS 0-7 STBC 2x3 rates */
9067 wl_txpwr_range_print(pwr
, WL_TX_POWER_HT_STBC_UL20_S2x3_FIRST
,
9068 WL_NUM_RATES_MCS_1STREAM
, "MCS 0-7 20UL STBC 3 Tx ",
9079 wl_txpwr_range_print(uint8
*pwr
, int start
, int count
, const char* label
, int *newline
)
9081 if (wl_array_uniform(pwr
, start
, count
)) {
9082 /* need a newline for abbreviated printout */
9085 printf("%s: %2d.%-2d", label
,
9086 DIV_QUO(pwr
[start
], 4),
9087 DIV_REM(pwr
[start
], 4));
9090 /* need a newline for a full row printout */
9093 printf("%s: ", label
);
9094 wl_txpwr_row_print(pwr
, start
, count
);
9101 wl_txpwr_row_print(uint8
*pwr
, int start
, int count
)
9105 for (i
= 0, rate
= start
; i
< count
; i
++, rate
++)
9107 DIV_QUO(pwr
[rate
], 4),
9108 DIV_REM(pwr
[rate
], 4));
9111 /* return TRUE if all the values in the array are uniformly the same */
9113 wl_array_uniform(uint8
*pwr
, int start
, int count
)
9117 for (i
= 1, rate
= start
+ 1; i
< count
; i
++, rate
++)
9118 if (pwr
[rate
] != pwr
[rate
- 1])
9125 wl_curpower_legacy2(void *wl
, cmd_t
*cmd
)
9130 chanspec_t chanspec
;
9131 char chanspec_str
[CHANSPEC_STR_LEN
];
9132 tx_power_legacy2_t power
;
9134 if ((err
= wlu_get(wl
, cmd
->get
, &power
, sizeof(power
))) < 0)
9137 power
.flags
= dtoh32(power
.flags
);
9138 power
.chanspec
= dtohchanspec(power
.chanspec
);
9139 power
.local_chanspec
= dtohchanspec(power
.local_chanspec
);
9141 chanspec
= power
.chanspec
;
9142 mimo
= (power
.flags
& WL_TX_POWER_F_MIMO
);
9144 printf("Power Control:\t\t %s, %s\n",
9145 (power
.flags
& WL_TX_POWER_F_ENABLED
) ? "On" : "Off",
9146 (power
.flags
& WL_TX_POWER_F_HW
) ? "HW" : "SW");
9147 printf("Current channel:\t %s\n",
9148 wf_chspec_ntoa(power
.chanspec
, chanspec_str
));
9149 printf("BSS channel:\t\t %s\n",
9150 wf_chspec_ntoa(power
.local_chanspec
, chanspec_str
));
9151 printf("BSS Local Max:\t\t%2d.%-2d dBm\n",
9152 DIV_QUO(power
.local_max
, 4), DIV_REM(power
.local_max
, 4));
9153 printf("BSS Local Constraint:\t%2d.%-2d dB\n",
9154 DIV_QUO(power
.local_constraint
, 4), DIV_REM(power
.local_constraint
, 4));
9155 printf("User Target:\t\t%2d.%-2d dBm\n",
9156 DIV_QUO(power
.user_limit
[0], 4), DIV_REM(power
.user_limit
[0], 4));
9157 printf("SROM antgain:\t\t 2G: %d.%d dB, 5G: %d.%d dB\n\n",
9158 DIV_QUO(power
.antgain
[0], 4), DIV_REM(power
.antgain
[0], 4),
9159 DIV_QUO(power
.antgain
[1], 4), DIV_REM(power
.antgain
[1], 4));
9161 printf("Regulatory Limits:\n");
9162 wl_txpwr_array_print_legacy2(power
.reg_limit
, CHSPEC_IS2G(chanspec
), mimo
);
9165 printf("Board Limits:\n");
9166 wl_txpwr_array_print_legacy2(power
.board_limit
, CHSPEC_IS2G(chanspec
), mimo
);
9169 printf("Power Target:\n");
9170 wl_txpwr_array_print_legacy2(power
.target
, CHSPEC_IS2G(chanspec
), mimo
);
9173 /* print the different power estimate combinations */
9175 printf("Last est. power:\t");
9176 for (i
= 0; i
< power
.rf_cores
; i
++)
9178 DIV_QUO(power
.est_Pout
[i
], 4),
9179 DIV_REM(power
.est_Pout
[i
], 4));
9182 printf("Last est. power:\t%d.%d dBm\n",
9183 DIV_QUO(power
.est_Pout
[0], 4),
9184 DIV_REM(power
.est_Pout
[0], 4));
9187 if (!mimo
&& CHSPEC_IS2G(chanspec
)) {
9188 printf("Last CCK est. power:\t%d.%d dBm\n",
9189 DIV_QUO(power
.est_Pout_cck
, 4),
9190 DIV_REM(power
.est_Pout_cck
, 4));
9197 wl_txpwr_array_print_legacy2(uint8
*pwr
, int cck
, int mimo
)
9203 wl_txpwr_range_print_legacy2(pwr
, WL_TX_POWER_CCK_FIRST
, WL_NUM_RATES_CCK
,
9207 wl_txpwr_range_print_legacy2(pwr
, WL_TX_POWER_OFDM20_FIRST
, WL_NUM_RATES_OFDM
, "OFDM",
9211 /* MCS 20MHz rates */
9212 wl_txpwr_range_print_legacy2(pwr
, WL_TX_POWER_MCS20_FIRST
, WL_NUM_RATES_MCS_1STREAM
,
9213 "MCS 20MHz", &newline
);
9215 /* MCS 40MHz rates */
9216 wl_txpwr_range_print_legacy2(pwr
, WL_TX_POWER_MCS40_FIRST
, WL_NUM_RATES_MCS_1STREAM
,
9217 "MCS 40MHz", &newline
);
9225 wl_txpwr_range_print_legacy2(uint8
*pwr
, int start
, int count
, const char* label
, int *newline
)
9227 if (wl_array_uniform(pwr
, start
, count
)) {
9228 /* need a space for abbreviated printout */
9231 printf("%s: %2d.%-2d", label
,
9232 DIV_QUO(pwr
[start
], 4),
9233 DIV_REM(pwr
[start
], 4));
9236 /* need a newline for a full row printout */
9239 printf("%s: ", label
);
9240 wl_txpwr_row_print(pwr
, start
, count
);
9248 wl_curpower_legacy(void *wl
)
9254 chanspec_t chanspec
;
9255 char chanspec_str
[CHANSPEC_STR_LEN
];
9256 tx_power_legacy_t power
;
9259 err
= wlu_iovar_getint(wl
, "eirp", &eirp
);
9263 if ((err
= wlu_iovar_getint(wl
, "chanspec", &val
)) < 0)
9265 chanspec
= (chanspec_t
)val
;
9266 wf_chspec_ntoa(chanspec
, chanspec_str
);
9268 if ((err
= wlu_get(wl
, WLC_CURRENT_PWR
, &power
, sizeof(power
))) < 0)
9271 printf("Current channel:\t\t %s\n",
9272 wf_chspec_ntoa(chanspec
, chanspec_str
));
9273 printf("User Target:\t\t\t%2d.%-2d dBm\n",
9274 DIV_QUO(power
.txpwr_band_max
[0], 4),
9275 DIV_REM(power
.txpwr_band_max
[0], 4));
9276 printf("Regulatory Local Max:\t\t%2d.%-2d dBm\n",
9277 DIV_QUO(power
.txpwr_local_max
, 4),
9278 DIV_REM(power
.txpwr_local_max
, 4));
9279 printf("Regulatory Local Constraint:\t%2d.%-2d dB\n",
9280 DIV_QUO(power
.txpwr_local_constraint
, 4),
9281 DIV_REM(power
.txpwr_local_constraint
, 4));
9282 printf("Antgain used in Channel Max:\t %s\n",
9284 "Yes, channel is EIRP" : "No, channel is Conducted");
9285 printf("Hardware Power Control:\t\t ");
9288 if ((err
= wlu_get(wl
, WLC_GET_UCFLAGS
, &flags
, sizeof(flags
))) >= 0) {
9289 flags
= dtoh32(flags
);
9290 printf("%s\n", (flags
& 0x80) ? "HW PWRCTL On" : "HW PWRCTL Off");
9293 printf("Regulatory Channel Max:\t\t%2d.%-2d dBm\n",
9294 DIV_QUO(power
.txpwr_chan_reg_max
, 4),
9295 DIV_REM(power
.txpwr_chan_reg_max
, 4));
9296 printf("SROM antgain:\t\t\t 2G: %d.%d dB, 5G: %d.%d dB\n\n",
9297 DIV_QUO(power
.txpwr_antgain
[0], 4),
9298 DIV_REM(power
.txpwr_antgain
[0], 4),
9299 DIV_QUO(power
.txpwr_antgain
[1], 4),
9300 DIV_REM(power
.txpwr_antgain
[1], 4));
9302 printf("Min of Reg & Local Limits:\n");
9304 for (i
= 0; i
< 4; i
++)
9306 DIV_QUO(power
.txpwr_limit
[i
], 4),
9307 DIV_REM(power
.txpwr_limit
[i
], 4));
9308 printf("\nOFDM:\t ");
9309 for (; i
< NUM_PWRCTRL_RATES
; i
++)
9311 DIV_QUO(power
.txpwr_limit
[i
], 4),
9312 DIV_REM(power
.txpwr_limit
[i
], 4));
9315 /* band specific info */
9316 if (CHSPEC_IS2G(chanspec
)) {
9318 printf("Last B phy CCK est. power:\t%2d.%-2d dBm\n",
9319 DIV_QUO(power
.txpwr_est_Pout
[0], 4),
9320 DIV_REM(power
.txpwr_est_Pout
[0], 4));
9321 printf("Last B phy OFDM est. power:\t%2d.%-2d dBm\n",
9322 DIV_QUO(power
.txpwr_est_Pout_gofdm
, 4),
9323 DIV_REM(power
.txpwr_est_Pout_gofdm
, 4));
9326 printf("Srom limit B/G:\n");
9328 for (i
= 0; i
< 4; i
++)
9329 printf("%d.%d ", DIV_QUO(power
.txpwr_bphy_cck_max
[i
], 4),
9330 DIV_REM(power
.txpwr_bphy_cck_max
[i
], 4));
9331 printf("\nOFDM:\t ");
9332 for (; i
< NUM_PWRCTRL_RATES
; i
++)
9333 printf("%d.%d ", DIV_QUO(power
.txpwr_bphy_cck_max
[i
], 4),
9334 DIV_REM(power
.txpwr_bphy_cck_max
[i
], 4));
9337 printf("Last B phy target power:\n");
9339 for (i
= 0; i
< 4; i
++)
9340 printf("%d.%d ", DIV_QUO(power
.txpwr_target
[0][i
], 4),
9341 DIV_REM(power
.txpwr_target
[0][i
], 4));
9342 printf("\nOFDM:\t ");
9343 for (; i
< NUM_PWRCTRL_RATES
; i
++)
9344 printf("%d.%d ", DIV_QUO(power
.txpwr_target
[0][i
], 4),
9345 DIV_REM(power
.txpwr_target
[0][i
], 4));
9349 printf("Last A phy est. power:\t\t%2d.%-2d dBm\n",
9350 DIV_QUO(power
.txpwr_est_Pout
[1], 4),
9351 DIV_REM(power
.txpwr_est_Pout
[1], 4));
9352 printf("Srom limit A:\n");
9354 for (i
= 4; i
< NUM_PWRCTRL_RATES
; i
++)
9355 printf("%d.%d ", DIV_QUO(power
.txpwr_aphy_max
[i
], 4),
9356 DIV_REM(power
.txpwr_aphy_max
[i
], 4));
9359 printf("Last A phy target power:\n");
9361 for (i
= 4; i
< NUM_PWRCTRL_RATES
; i
++)
9362 printf("%d.%d ", DIV_QUO(power
.txpwr_target
[1][i
], 4),
9363 DIV_REM(power
.txpwr_target
[1][i
], 4));
9371 wl_get_instant_power(void *wl
, cmd_t
*cmd
, char **argv
)
9374 tx_inst_power_t
*power
;
9377 UNUSED_PARAMETER(cmd
);
9378 UNUSED_PARAMETER(argv
);
9380 strcpy(buf
, "txinstpwr");
9381 if ((ret
= wlu_get(wl
, WLC_GET_VAR
, &buf
[0], WLC_IOCTL_MAXLEN
)) < 0) {
9385 power
= (tx_inst_power_t
*)buf
;
9386 /* Make the most of the info returned in band_list!
9390 * NOTE: NO a and b/g case ...
9392 if ((ret
= wlu_get(wl
, WLC_GET_BANDLIST
, band_list
, sizeof(band_list
))) < 0)
9394 band_list
[0] = dtoh32(band_list
[0]);
9395 band_list
[1] = dtoh32(band_list
[1]);
9396 band_list
[2] = dtoh32(band_list
[2]);
9398 /* If B/G is present it's always the lower index */
9399 if (band_list
[1] == WLC_BAND_2G
) {
9400 printf("Last B phy CCK est. power:\t%2d.%d dBm\n",
9401 DIV_QUO(power
->txpwr_est_Pout
[0], 4),
9402 DIV_REM(power
->txpwr_est_Pout
[0], 4));
9403 printf("Last B phy OFDM est. power:\t%2d.%d dBm\n",
9404 DIV_QUO(power
->txpwr_est_Pout_gofdm
, 4),
9405 DIV_REM(power
->txpwr_est_Pout_gofdm
, 4));
9411 if (band_list
[1] == WLC_BAND_5G
|| (band_list
[0] > 1 && band_list
[2] == WLC_BAND_5G
)) {
9412 printf("Last A phy est. power:\t\t%2d.%d dBm\n",
9413 DIV_QUO(power
->txpwr_est_Pout
[1], 4),
9414 DIV_REM(power
->txpwr_est_Pout
[1], 4));
9421 wl_evm(void *wl
, cmd_t
*cmd
, char **argv
)
9427 fprintf(stderr
, "Need to specify at least one parameter\n");
9431 if (!stricmp(*argv
, "off"))
9434 val
[0] = atoi(*argv
);
9436 /* set optional parameters to default */
9437 val
[1] = 4; /* rate in 500Kb units */
9438 val
[2] = 0; /* This is ignored */
9440 /* Get optional rate and convert to 500Kb units */
9442 val
[1] = rate_string2int(*argv
);
9444 val
[0] = htod32(val
[0]);
9445 val
[1] = htod32(val
[1]);
9446 val
[2] = htod32(val
[2]);
9447 return wlu_set(wl
, cmd
->set
, val
, sizeof(val
));
9450 /* wl join <ssid> [key <0-3>:xxxxx]
9452 * [amode open|shared|openshared|wpa|wpapsk|wpa2|wpa2psk|wpanone]
9455 * -b MAC, --bssid=MAC, where MAC is in xx:xx:xx:xx:xx:xx format
9456 * -c CL, --chanspecs=CL, where CL is a comma or space separated list of chanspecs
9459 wl_join(void *wl
, cmd_t
*cmd
, char **argv
)
9461 int ret
= BCME_OK
, idx
= 0;
9462 wl_join_params_t
*join_params
;
9463 int join_params_size
;
9465 int wsec
= 0, auth
= 0, infra
= 1;
9466 int wpa_auth
= WPA_AUTH_DISABLED
;
9469 UNUSED_PARAMETER(cmd
);
9473 /* allocate the max storage */
9474 join_params_size
= WL_JOIN_PARAMS_FIXED_SIZE
+ WL_NUMCHANNELS
* sizeof(chanspec_t
);
9475 if ((join_params
= malloc(join_params_size
)) == NULL
) {
9476 fprintf(stderr
, "Error allocating %d bytes for assoc params\n", join_params_size
);
9479 memset(join_params
, 0, join_params_size
);
9480 memcpy(&join_params
->params
.bssid
, ðer_bcast
, ETHER_ADDR_LEN
);
9482 /* verify that SSID was specified and is a valid length */
9483 if (!*argv
|| (strlen(*argv
) > DOT11_MAX_SSID_LEN
)) {
9488 join_params
->ssid
.SSID_len
= strlen(*argv
);
9489 memcpy(join_params
->ssid
.SSID
, *argv
, join_params
->ssid
.SSID_len
);
9490 /* default to plain old ioctl */
9491 join_params_size
= sizeof(wlc_ssid_t
);
9493 /* get current wsec */
9494 if (wlu_iovar_getint(wl
, "wsec", &wsec
) < 0)
9498 if (!stricmp(*argv
, "wepkey") || !stricmp(*argv
, "wep") || !stricmp(*argv
, "key")) {
9499 /* specified wep key */
9500 memset(&key
, 0, sizeof(key
));
9505 /* WEP index specified */
9506 if (*(argv
[0]+1) == ':') {
9507 idx
= *argv
[0] - 0x30;
9508 if (idx
< 0 || idx
> 3) {
9509 fprintf(stderr
, "Invalid key index %d specified\n", idx
);
9513 argv
[0] += 2; /* colon + digit */
9517 if (parse_wep(argv
, &key
, FALSE
)) {
9522 key
.index
= htod32(key
.index
);
9523 key
.len
= htod32(key
.len
);
9524 key
.algo
= htod32(key
.algo
);
9525 key
.flags
= htod32(key
.flags
);
9527 if ((ret
= wlu_set(wl
, WLC_SET_KEY
, &key
, sizeof(wl_wsec_key_t
))) < 0) {
9531 wsec
|= WEP_ENABLED
;
9533 /* specified infrastructure mode */
9534 else if (!stricmp(*argv
, "imode") ||
9535 !stricmp(*argv
, "infra") ||
9536 !stricmp(*argv
, "mode")) {
9538 fprintf(stderr
, "%s %s: expected argument after \"infra\" keyword "
9539 "but command line ended.\n", wlu_av0
, cmd_name
);
9542 } else if (!stricmp(*argv
, "ibss") ||
9543 !stricmp(*argv
, "adhoc") ||
9544 !stricmp(*argv
, "ad-hoc")) {
9546 } else if (!stricmp(*argv
, "bss") ||
9547 !stricmp(*argv
, "managed") ||
9548 !strnicmp(*argv
, "infra", 5)) {
9551 fprintf(stderr
, "%s %s: unrecongnized parameter \"%s\" after "
9552 "\"infra\" keyword\n", wlu_av0
, cmd_name
, *argv
);
9557 /* specified authentication mode */
9558 else if (!stricmp(*argv
, "amode") || !strnicmp(*argv
, "auth", 4)) {
9563 if (!stricmp(*argv
, "open"))
9564 auth
= WL_AUTH_OPEN_SYSTEM
;
9565 else if (!stricmp(*argv
, "shared"))
9566 auth
= WL_AUTH_SHARED_KEY
;
9567 else if (!stricmp(*argv
, "openshared"))
9568 auth
= WL_AUTH_OPEN_SHARED
;
9569 else if (!stricmp(*argv
, "wpanone"))
9570 wpa_auth
= WPA_AUTH_NONE
;
9571 else if (!stricmp(*argv
, "wpa"))
9572 wpa_auth
= WPA_AUTH_UNSPECIFIED
;
9573 else if (!stricmp(*argv
, "wpapsk"))
9574 wpa_auth
= WPA_AUTH_PSK
;
9575 else if (!stricmp(*argv
, "wpa2"))
9576 wpa_auth
= WPA2_AUTH_UNSPECIFIED
;
9577 else if (!stricmp(*argv
, "wpa2psk"))
9578 wpa_auth
= WPA2_AUTH_PSK
;
9584 /* optional assoc params */
9585 else if ((ret
= wl_parse_assoc_params(argv
, &join_params
->params
)) == BCME_OK
) {
9586 join_params_size
= WL_JOIN_PARAMS_FIXED_SIZE
+
9587 dtoh32(join_params
->params
.chanspec_num
) * sizeof(chanspec_t
);
9591 fprintf(stderr
, "%s %s: unable to parse parameter \"%s\"\n",
9592 wlu_av0
, cmd_name
, *argv
);
9597 /* set infrastructure mode */
9598 infra
= htod32(infra
);
9599 if ((ret
= wlu_set(wl
, WLC_SET_INFRA
, &infra
, sizeof(int))) < 0)
9602 /* set authentication mode */
9603 auth
= htod32(auth
);
9604 if ((ret
= wlu_set(wl
, WLC_SET_AUTH
, &auth
, sizeof(int))) < 0)
9608 if ((ret
= wlu_iovar_setint(wl
, "wsec", wsec
)) < 0)
9611 /* set WPA_auth mode */
9612 wpa_auth
= htod32(wpa_auth
);
9613 if ((ret
= wlu_set(wl
, WLC_SET_WPA_AUTH
, &wpa_auth
, sizeof(wpa_auth
))) < 0)
9616 /* set ssid with extend assoc params (if any) */
9617 join_params
->ssid
.SSID_len
= htod32(join_params
->ssid
.SSID_len
);
9618 ret
= wlu_set(wl
, WLC_SET_SSID
, join_params
, join_params_size
);
9625 /* Set or Get the "bssid" iovar, with an optional config index argument:
9626 * wl bssid [-C N]|[--cfg=N] bssid
9633 * specify the config index N
9634 * If cfg index not given on a set, the WLC_SET_BSSID ioctl will be used
9637 wl_bssid(void *wl
, cmd_t
*cmd
, char **argv
)
9639 struct ether_addr ea
;
9644 UNUSED_PARAMETER(cmd
);
9648 /* parse a bsscfg_idx option if present */
9649 if ((error
= wl_cfg_option(argv
, "bssid", &bsscfg_idx
, &consumed
)) != 0)
9654 if (*argv
== NULL
) {
9655 if (consumed
== 0) {
9656 /* no config index, use WLC_GET_BSSID on the interface */
9657 error
= wlu_get(wl
, WLC_GET_BSSID
, &ea
, ETHER_ADDR_LEN
);
9659 /* use "bssid" iovar since a config option was given */
9660 error
= wl_bssiovar_get(wl
, "bssid", bsscfg_idx
, &ea
, ETHER_ADDR_LEN
);
9664 printf("%s\n", wl_ether_etoa(&ea
));
9668 if (!wl_ether_atoe(*argv
, &ea
))
9671 if (consumed
== 0) {
9672 /* no config index given, use WLC_SET_BSSID */
9673 error
= wlu_set(wl
, WLC_SET_BSSID
, &ea
, ETHER_ADDR_LEN
);
9675 /* use "bssid" iovar since a config option was given */
9676 error
= wl_bssiovar_set(wl
, "bssid", bsscfg_idx
, &ea
, ETHER_ADDR_LEN
);
9682 /* Set or Get the "ssid" iovar, with an optional config index argument:
9683 * wl ssid [-C N]|[--cfg=N] ssid
9690 * specify the config index N
9691 * If cfg index not given on a set, the WLC_SET_SSID ioctl will be used
9694 wl_ssid(void *wl
, cmd_t
*cmd
, char **argv
)
9696 char ssidbuf
[SSID_FMT_BUF_LEN
];
9697 wlc_ssid_t ssid
= { 0, {0} };
9704 /* parse a bsscfg_idx option if present */
9705 if ((error
= wl_cfg_option(argv
, "ssid", &bsscfg_idx
, &consumed
)) != 0)
9710 if (*argv
== NULL
) {
9711 if (consumed
== 0) {
9712 /* no config index, use WLC_GET_SSID on the interface */
9713 if (cmd
->get
== WLC_GET_SSID
)
9714 error
= wlu_get(wl
, WLC_GET_SSID
, &ssid
, sizeof(ssid
));
9716 error
= wlu_iovar_get(wl
, cmd
->name
, &ssid
, sizeof(ssid
));
9718 if (cmd
->get
== WLC_GET_SSID
) {
9719 /* use "ssid" iovar since a config option was given */
9720 error
= wl_bssiovar_get(wl
, "ssid", bsscfg_idx
, &ssid
,
9723 error
= wl_bssiovar_get(wl
, cmd
->name
, bsscfg_idx
, &ssid
,
9730 ssid
.SSID_len
= dtoh32(ssid
.SSID_len
);
9731 wl_format_ssid(ssidbuf
, ssid
.SSID
, ssid
.SSID_len
);
9732 printf("Current %s: \"%s\"\n",
9733 (cmd
->get
== WLC_GET_SSID
)? "SSID": cmd
->name
,
9736 if (strlen(argv
[0]) > DOT11_MAX_SSID_LEN
) {
9737 fprintf(stderr
, "SSID arg \"%s\" must be 32 chars or less\n", argv
[0]);
9740 ssid
.SSID_len
= strlen(argv
[0]);
9741 memcpy(ssid
.SSID
, argv
[0], ssid
.SSID_len
);
9743 wl_format_ssid(ssidbuf
, ssid
.SSID
, ssid
.SSID_len
);
9744 printf("Setting %s: \"%s\"\n", (cmd
->set
== WLC_SET_SSID
)? "SSID": cmd
->name
,
9747 ssid
.SSID_len
= htod32(ssid
.SSID_len
);
9748 if (consumed
== 0) {
9749 /* no config index given, use WLC_SET_SSID */
9750 if (cmd
->set
== WLC_SET_SSID
) {
9751 error
= wlu_set(wl
, WLC_SET_SSID
, &ssid
, sizeof(wlc_ssid_t
));
9753 error
= wlu_iovar_set(wl
, cmd
->name
, &ssid
, sizeof(wlc_ssid_t
));
9756 if (cmd
->set
== WLC_SET_SSID
) {
9757 /* use "ssid" iovar since a config option was given */
9758 error
= wl_bssiovar_set(wl
, "ssid", bsscfg_idx
, &ssid
,
9759 sizeof(wlc_ssid_t
));
9761 error
= wl_bssiovar_set(wl
, cmd
->name
, bsscfg_idx
, &ssid
,
9762 sizeof(wlc_ssid_t
));
9769 wl_smfs_map_type(uint8 type
)
9771 static const struct {uint8 type
; char name
[32];} type_names
[] = {
9772 {SMFS_TYPE_AUTH
, "Authentication_Request"},
9773 {SMFS_TYPE_ASSOC
, "Association_Request"},
9774 {SMFS_TYPE_REASSOC
, "Reassociation_Request"},
9775 {SMFS_TYPE_DISASSOC_TX
, "Disassociation_Request_TX"},
9776 {SMFS_TYPE_DISASSOC_RX
, "Disassociation_Request_RX"},
9777 {SMFS_TYPE_DEAUTH_TX
, "Deauthentication_Request_TX"},
9778 {SMFS_TYPE_DEAUTH_RX
, "Deauthentication_Request_RX"}
9781 const char *tname
= "UNKNOWN";
9784 for (i
= 0; i
< ARRAYSIZE(type_names
); i
++) {
9785 if (type_names
[i
].type
== type
)
9786 tname
= type_names
[i
].name
;
9792 wl_disp_smfs(char *inbuf
)
9794 static const char *codename
[] = {"Status_code", "Reason_code"};
9795 wl_smf_stats_t
*smf_stats
;
9796 wl_smfs_elem_t
*elemt
= NULL
;
9798 const char *namebuf
;
9802 smf_stats
= (wl_smf_stats_t
*) inbuf
;
9803 namebuf
= wl_smfs_map_type(smf_stats
->type
);
9805 version
= dtoh32(smf_stats
->version
);
9806 if (version
!= SMFS_VERSION
) {
9807 fprintf(stderr
, "Sorry, your driver has smfs_version %d "
9808 "but this program supports only version %d.\n",
9809 version
, SMFS_VERSION
);
9813 printf("Frame type: %s\n", namebuf
);
9814 printf("\tIgnored Count: %d\n", dtoh32(smf_stats
->ignored_cnt
));
9815 printf("\tMalformed Count: %d\n", dtoh32(smf_stats
->malformed_cnt
));
9817 len
= dtoh16(smf_stats
->length
);
9818 count
= dtoh32(smf_stats
->count_total
);
9821 namebuf
= codename
[dtoh32(smf_stats
->codetype
)];
9822 printf("\tSuccessful/Failed Count:\n");
9823 elemt
= &smf_stats
->elem
[0];
9827 printf("\t\t%s %d Count: %d\n", namebuf
, dtoh16(elemt
->code
),
9828 dtoh32(elemt
->count
));
9838 * Check for the smfstats parameters. One of defined parameters can be passed in.
9841 wl_smfs_option(char **argv
, int* idx
, int *consumed
, int* clear
)
9845 char const * smfs_opt
[] = {"auth", "assoc", "reassoc", "disassoc_tx",
9846 "disassoc_rx", "deauth_tx", "deauth_rx"};
9847 char const * clear_opt
= "clear";
9849 char const * cur_opt
;
9851 if (*argv
== NULL
) {
9857 for (i
= 0; i
< SMFS_TYPE_MAX
; i
++) {
9858 cur_opt
= smfs_opt
[i
];
9859 if (!strcmp(p
, cur_opt
)) {
9866 if (!strcmp(p
, clear_opt
))
9873 /* Get or Clear (set) the "smfstats" iovar, with an optional config index argument:
9874 * wl smfstats [-C N]|[--cfg=N] 0
9881 * specify the config index N
9882 * If cfg index not given on a set, the WLC_SET_SMF_STATS ioctl will be used
9885 wl_smfstats(void *wl
, cmd_t
*cmd
, char **argv
)
9888 int cfg_consumed
= 0, smfs_consumed
= 0;
9898 /* parse a bsscfg_idx option if present */
9899 if ((err
= wl_cfg_option(argv
, "smfstats", &bsscfg_idx
, &cfg_consumed
)) != 0)
9902 argv
+= cfg_consumed
;
9904 if ((err
= wl_smfs_option(argv
, &smf_index
, &smfs_consumed
, &smfs_clear
)) != 0)
9908 if (cfg_consumed
== 0) {
9909 if (smfs_consumed
) {
9910 err
= wlu_iovar_getbuf(wl
, "smfstats", &smf_index
, sizeof(int),
9911 buf
, WLC_IOCTL_SMLEN
);
9916 for (i
= 0; i
< SMFS_TYPE_MAX
; i
++) {
9918 err
= wlu_iovar_getbuf(wl
, "smfstats", &smf_index
,
9919 sizeof(int), buf
, WLC_IOCTL_SMLEN
);
9925 /* use "stats" iovar since a config option was given */
9926 if (smfs_consumed
) {
9927 err
= wl_bssiovar_getbuf(wl
, "smfstats", bsscfg_idx
, &smf_index
,
9928 sizeof(int), buf
, WLC_IOCTL_SMLEN
);
9933 for (i
= 0; i
< SMFS_TYPE_MAX
; i
++) {
9935 err
= wl_bssiovar_getbuf(wl
, "smfstats", bsscfg_idx
,
9936 &smf_index
, sizeof(int), buf
, WLC_IOCTL_SMLEN
);
9947 if (cfg_consumed
== 0)
9948 err
= wlu_iovar_setint(wl
, "smfstats", val
);
9950 err
= wl_bssiovar_setint(wl
, "smfstats", bsscfg_idx
, val
);
9958 wl_tssi(void *wl
, cmd_t
*cmd
, char **argv
)
9963 UNUSED_PARAMETER(argv
);
9967 if ((ret
= wlu_get(wl
, cmd
->get
, &val
, sizeof(int))) < 0)
9971 printf("CCK %d OFDM %d\n", (val
& 0xff), (val
>> 8) & 0xff);
9975 /* Quarter dBm units to mW
9976 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
9977 * Table is offset so the last entry is largest mW value that fits in
9981 #define QDBM_OFFSET 153 /* QDBM_OFFSET */
9982 #define QDBM_TABLE_LEN 40 /* QDBM_TABLE_LEN */
9984 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
9985 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
9987 #define QDBM_TABLE_LOW_BOUND 6493 /* QDBM_TABLE_LOW_BOUND */
9989 /* Largest mW value that will round down to the last table entry,
9990 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
9991 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) + mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
9993 #define QDBM_TABLE_HIGH_BOUND 64938 /* QDBM_TABLE_HIGH_BOUND */
9995 static const uint16 nqdBm_to_mW_map
[QDBM_TABLE_LEN
] = {
9996 /* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
9997 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
9998 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
9999 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
10000 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
10001 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
10005 wl_qdbm_to_mw(uint8 qdbm
)
10008 int idx
= qdbm
- QDBM_OFFSET
;
10010 if (idx
> QDBM_TABLE_LEN
) {
10011 /* clamp to max uint16 mW value */
10015 /* scale the qdBm index up to the range of the table 0-40
10016 * where an offset of 40 qdBm equals a factor of 10 mW.
10023 /* return the mW value scaled down to the correct factor of 10,
10024 * adding in factor/2 to get proper rounding.
10026 return ((nqdBm_to_mW_map
[idx
] + factor
/2) / factor
);
10030 wl_mw_to_qdbm(uint16 mw
)
10037 /* handle boundary case */
10041 offset
= QDBM_OFFSET
;
10043 /* move mw into the range of the table */
10044 while (mw_uint
< QDBM_TABLE_LOW_BOUND
) {
10049 for (qdbm
= 0; qdbm
< QDBM_TABLE_LEN
-1; qdbm
++) {
10050 boundary
= nqdBm_to_mW_map
[qdbm
] +
10051 (nqdBm_to_mW_map
[qdbm
+1] - nqdBm_to_mW_map
[qdbm
])/2;
10052 if (mw_uint
< boundary
) break;
10055 qdbm
+= (uint8
)offset
;
10060 #define UNIT_MW 1 /* UNIT_MW */
10061 #define UNIT_QDBM 2 /* UNIT_QDBM */
10062 #define UNIT_DBM 3 /* UNIT_DBM */
10064 wl_txpwr1(void *wl
, cmd_t
*cmd
, char **argv
)
10066 int ret
, val
, new_val
= 0, unit
;
10067 const char *name
= "qtxpower";
10068 bool override
= FALSE
;
10073 if ((ret
= wlu_iovar_getint(wl
, name
, &val
)) < 0)
10076 override
= ((val
& WL_TXPWR_OVERRIDE
) != 0);
10077 val
&= ~WL_TXPWR_OVERRIDE
;
10078 printf("TxPower is %d qdbm, %d.%d dbm, %d mW Override is %s\n",
10079 val
, DIV_QUO(val
, 4), DIV_REM(val
, 4),
10080 wl_qdbm_to_mw((uint8
)(MIN(val
, 0xff))),
10081 override
? "On" : "Off");
10085 unit
= UNIT_DBM
; /* default units */
10087 /* override can be used in combo with any unit */
10088 if (!strcmp(*argv
, "-o")) {
10094 if (!strcmp(*argv
, "-d")) {
10098 else if (!strcmp(*argv
, "-q")) {
10102 else if (!strcmp(*argv
, "-m")) {
10107 /* override can be used in combo with any unit */
10108 if (!strcmp(*argv
, "-o")) {
10119 val
= 127; /* Max val of 127 qdbm */
10129 new_val
= wl_mw_to_qdbm((uint16
)MIN(val
, 0xffff));
10140 new_val
|= WL_TXPWR_OVERRIDE
;
10142 return wlu_iovar_setint(wl
, name
, new_val
);
10147 wl_txpwr(void *wl
, cmd_t
*cmd
, char **argv
)
10151 char *endptr
= NULL
;
10153 const char *name
= "qtxpower";
10155 UNUSED_PARAMETER(cmd
);
10158 if ((error
= wlu_iovar_getint(wl
, name
, &val
)) < 0)
10161 /* Report power in mw with WL_TXPWR_OVERRIDE
10162 * bit indicating the status
10164 override
= ((val
& WL_TXPWR_OVERRIDE
) != 0);
10165 val
&= ~WL_TXPWR_OVERRIDE
;
10166 printf("%d.%d dBm = %d mw. %s\n", DIV_QUO(val
, 4), DIV_REM(val
, 4),
10167 wl_qdbm_to_mw((uint8
)(MIN(val
, 0xff))), (override
? "(Override ON)" : ""));
10170 if (!strcmp(*argv
, "-u")) {
10174 override
= WL_TXPWR_OVERRIDE
;
10176 val
= strtol(*argv
, &endptr
, 0);
10177 if (*endptr
!= '\0') {
10178 /* not all the value string was parsed by strtol */
10182 val
= wl_mw_to_qdbm((uint16
)MIN(val
, 0xffff));
10184 /* wl command input power will override current power set if told so */
10187 return wlu_iovar_setint(wl
, name
, val
);
10192 wl_get_txpwr_limit(void *wl
, cmd_t
*cmd
, char **argv
)
10197 tx_power_legacy_t power
;
10199 UNUSED_PARAMETER(argv
);
10201 ret
= wlu_get(wl
, cmd
->get
, &power
, sizeof(power
));
10205 val_qdbm
= MIN(power
.txpwr_band_max
[0], power
.txpwr_local_max
);
10206 val_mw
= wl_qdbm_to_mw((uint8
)(MIN(val_qdbm
, 0xff)));
10208 printf("%d mW (%d.%d dBm)\n", val_mw
, DIV_QUO(val_qdbm
, 4), DIV_REM(val_qdbm
, 4));
10214 wl_atten(void *wl
, cmd_t
*cmd
, char **argv
)
10224 if ((ret
= wlu_get(wl
, cmd
->get
, &atten
, sizeof(atten_t
))) < 0)
10227 printf("tx %s bb/radio/ctl1 %d/%d/%d\n",
10228 (dtoh16(atten
.auto_ctrl
) ? "auto" : ""),
10229 dtoh16(atten
.bb
), dtoh16(atten
.radio
), dtoh16(atten
.txctl1
));
10236 if (!stricmp(*argv
, "auto")) {
10237 atten
.auto_ctrl
= WL_ATTEN_PCL_ON
;
10239 else if (!stricmp(*argv
, "manual")) {
10240 atten
.auto_ctrl
= WL_ATTEN_PCL_OFF
;
10243 atten
.auto_ctrl
= WL_ATTEN_APP_INPUT_PCL_OFF
;
10245 atten
.bb
= (uint16
)strtoul(*argv
, &endptr
, 0);
10246 if (*endptr
!= '\0') {
10247 /* not all the value string was parsed by strtol */
10254 atten
.radio
= (uint16
)strtoul(*argv
, &endptr
, 0);
10255 if (*endptr
!= '\0') {
10256 /* not all the value string was parsed by strtol */
10263 atten
.txctl1
= (uint16
)strtoul(*argv
, &endptr
, 0);
10264 if (*endptr
!= '\0') {
10265 /* not all the value string was parsed by strtol */
10271 atten
.auto_ctrl
= htod16(atten
.auto_ctrl
);
10272 atten
.bb
= htod16(atten
.bb
);
10273 atten
.radio
= htod16(atten
.radio
);
10274 atten
.txctl1
= htod16(atten
.txctl1
);
10275 return wlu_set(wl
, cmd
->set
, &atten
, sizeof(atten_t
));
10280 wl_maclist(void *wl
, cmd_t
*cmd
, char **argv
)
10283 struct maclist
*maclist
= (struct maclist
*) buf
;
10284 struct ether_addr
*ea
;
10285 uint i
, max
= (WLC_IOCTL_MAXLEN
- sizeof(int)) / ETHER_ADDR_LEN
;
10291 maclist
->count
= htod32(max
);
10292 if ((ret
= wlu_get(wl
, cmd
->get
, maclist
, WLC_IOCTL_MAXLEN
)) < 0)
10294 maclist
->count
= dtoh32(maclist
->count
);
10295 for (i
= 0, ea
= maclist
->ea
; i
< maclist
->count
&& i
< max
; i
++, ea
++)
10296 printf("%s %s\n", cmd
->name
, wl_ether_etoa(ea
));
10302 maclist
->count
= htod32(0);
10303 if (!stricmp(*argv
, "none") || !stricmp(*argv
, "clear"))
10304 return wlu_set(wl
, cmd
->set
, maclist
, sizeof(int));
10306 maclist
->count
= htod32(max
);
10307 if ((ret
= wlu_get(wl
, cmd
->get
, maclist
, WLC_IOCTL_MAXLEN
)) < 0)
10309 /* Append to old list */
10310 maclist
->count
= dtoh32(maclist
->count
);
10311 ea
= &maclist
->ea
[maclist
->count
];
10312 while (*argv
&& maclist
->count
< max
) {
10313 if (!wl_ether_atoe(*argv
, ea
)) {
10314 printf("Problem parsing MAC address \"%s\".\n", *argv
);
10322 len
= sizeof(maclist
->count
) + maclist
->count
* sizeof(maclist
->ea
);
10323 maclist
->count
= htod32(maclist
->count
);
10324 return wlu_set(wl
, cmd
->set
, maclist
, len
);
10329 wl_maclist_1(void *wl
, cmd_t
*cmd
, char **argv
)
10331 struct maclist
*maclist
;
10332 struct ether_addr
*ea
;
10336 strcpy(buf
, argv
[0]);
10338 if ((ret
= wlu_get(wl
, cmd
->get
, buf
, WLC_IOCTL_MAXLEN
)) < 0)
10341 maclist
= (struct maclist
*)buf
;
10343 for (i
= 0, ea
= maclist
->ea
; i
< dtoh32(maclist
->count
); i
++, ea
++)
10344 printf("%s %s\n", cmd
->name
, wl_ether_etoa(ea
));
10349 wl_out(void *wl
, cmd_t
*cmd
, char **argv
)
10351 UNUSED_PARAMETER(cmd
);
10352 UNUSED_PARAMETER(argv
);
10354 return wlu_set(wl
, WLC_OUT
, NULL
, 0);
10358 wl_band(void *wl
, cmd_t
*cmd
, char **argv
)
10363 UNUSED_PARAMETER(cmd
);
10369 if (*argv
== NULL
) { /* get current band */
10370 if ((error
= wlu_get(wl
, WLC_GET_BAND
, &band
, sizeof(uint
))) < 0)
10372 band
= dtoh32(band
);
10374 if (band
== WLC_BAND_AUTO
)
10376 else if (band
== WLC_BAND_5G
)
10378 else if (band
== WLC_BAND_2G
)
10381 printf("unrecognized band value %d\n", band
);
10382 } else { /* set the band */
10383 if (!stricmp(*argv
, "auto"))
10384 band
= WLC_BAND_AUTO
;
10385 else if (!stricmp(*argv
, "a"))
10386 band
= WLC_BAND_5G
;
10387 else if (!stricmp(*argv
, "b"))
10388 band
= WLC_BAND_2G
;
10390 printf("unsupported band: %s\n", *argv
);
10394 band
= htod32(band
);
10395 error
= wlu_set(wl
, WLC_SET_BAND
, &band
, sizeof(uint
));
10402 wl_bandlist(void *wl
, cmd_t
*cmd
, char **argv
)
10408 UNUSED_PARAMETER(cmd
);
10414 if ((error
= wlu_get(wl
, WLC_GET_BANDLIST
, list
, sizeof(list
))) < 0)
10416 list
[0] = dtoh32(list
[0]);
10417 list
[1] = dtoh32(list
[1]);
10418 list
[2] = dtoh32(list
[2]);
10420 /* list[0] is count, followed by 'count' bands */
10425 for (i
= 1; i
<= list
[0]; i
++)
10426 if (list
[i
] == WLC_BAND_5G
)
10428 else if (list
[i
] == WLC_BAND_2G
)
10438 wl_phylist(void *wl
, cmd_t
*cmd
, char **argv
)
10440 char phylist_buf
[128];
10444 UNUSED_PARAMETER(cmd
);
10450 if ((error
= wlu_get(wl
, WLC_GET_PHYLIST
, phylist_buf
, sizeof(phylist_buf
))) < 0)
10456 printf("%c ", *cp
);
10463 #define UPGRADE_BUFSIZE 512 /* upgrade buffer size */
10465 #define UPGRADE_BUFSIZE 1024 /* upgrade buffer size */
10469 wl_upgrade(void *wl
, cmd_t
*cmd
, char **argv
)
10471 #if !defined(BWL_FILESYSTEM_SUPPORT)
10472 UNUSED_PARAMETER(wl
); UNUSED_PARAMETER(cmd
); UNUSED_PARAMETER(argv
);
10474 #elif defined(_CFE_)
10475 UNUSED_PARAMETER(wl
); UNUSED_PARAMETER(cmd
); UNUSED_PARAMETER(argv
);
10476 return CFE_ERR_UNSUPPORTED
;
10482 char buf
[UPGRADE_BUFSIZE
];
10490 if (!(fp
= fopen(*argv
, "rb"))) {
10491 fprintf(stderr
, "%s: No such file or directory\n", *argv
);
10495 printf("Programming %s...", *argv
);
10498 block
.offset
= htod32(offset
);
10499 while ((len
= fread(block
.buf
, 1, sizeof(block
.buf
), fp
))) {
10500 if ((ret
= wlu_set(wl
, cmd
->set
, &block
, 4 + len
)) < 0)
10503 block
.offset
= htod32(offset
);
10510 printf("\nerror reading %s\n", *argv
);
10512 long status
= WLC_UPGRADE_PENDING
;
10515 printf("\nCommitting image to flash...\n");
10516 while (status
== WLC_UPGRADE_PENDING
) {
10519 if ((ret
= wlu_get(wl
, WLC_UPGRADE_STATUS
,
10520 &status
, sizeof(status
))) < 0) {
10521 /* the first attempt to get status will
10522 * likely fail due to dev reset
10528 status
= dtoh32(status
);
10530 if (status
== WLC_UPGRADE_SUCCESS
)
10531 printf("\nDone\n\nSuccessfully downloaded %d bytes\n", block
.offset
);
10533 fprintf(stderr
, "\n*** UPGRADE FAILED! *** (status %ld)\n", status
);
10538 #endif /* BWL_FILESYSTEM_SUPPORT */
10541 #include <bcmnvram.h>
10544 wl_otpw(void *wl
, cmd_t
*cmd
, char **argv
)
10546 #if !defined(BWL_FILESYSTEM_SUPPORT)
10547 UNUSED_PARAMETER(wl
); UNUSED_PARAMETER(cmd
); UNUSED_PARAMETER(argv
);
10549 #elif defined(_CFE_)
10550 UNUSED_PARAMETER(wl
); UNUSED_PARAMETER(cmd
); UNUSED_PARAMETER(argv
);
10551 return CFE_ERR_UNSUPPORTED
;
10555 struct nvram_header
*nvr
;
10556 char *p
, otpw_buf
[1024 - 128];
10563 if (!(fp
= fopen(*argv
, "rb"))) {
10564 fprintf(stderr
, "%s: No such file or directory\n", *argv
);
10568 len
= fread(otpw_buf
, 1, sizeof(otpw_buf
) - 1, fp
);
10569 if ((ret
= ferror(fp
))) {
10570 printf("\nerror %d reading %s\n", ret
, *argv
);
10575 printf("\nFile %s too large\n", *argv
);
10580 /* Got the bits, do they look like the output of nvserial? */
10581 nvr
= (struct nvram_header
*)otpw_buf
;
10582 if (nvr
->magic
== NVRAM_MAGIC
) {
10583 if (cmd
->set
== WLC_OTPW
) {
10584 printf("File %s looks like an nvserial file, use nvotpw\n", *argv
);
10589 len
= nvr
->len
- sizeof(struct nvram_header
);
10591 otpw_buf
[len
++] = '\0';
10593 p
= (char *)(nvr
+ 1);
10596 if (cmd
->set
== WLC_NVOTPW
) {
10597 printf("File %s is not an nvserial file\n", *argv
);
10602 printf("File %s has an odd length (%d)\n", *argv
, len
);
10610 printf("Writing %d bytes from %s file %s to otp ...\n", len
, msg
, *argv
);
10613 if ((ret
= wlu_set(wl
, cmd
->set
, p
, len
)) < 0) {
10614 printf("\nError %d writing %s to otp\n", ret
, *argv
);
10620 #endif /* BWL_FILESYSTEM_SUPPORT */
10624 wl_get_pktcnt(void *wl
, cmd_t
*cmd
, char **argv
)
10627 get_pktcnt_t pktcnt
;
10629 UNUSED_PARAMETER(argv
);
10631 memset(&pktcnt
, 0, sizeof(pktcnt
));
10632 if ((ret
= wlu_get(wl
, cmd
->get
, &pktcnt
, sizeof(pktcnt
))) < 0)
10635 printf("Receive: good packet %d, bad packet %d, othercast good packet %d\n",
10636 dtoh32(pktcnt
.rx_good_pkt
), dtoh32(pktcnt
.rx_bad_pkt
),
10637 dtoh32(pktcnt
.rx_ocast_good_pkt
));
10638 printf("Transmit: good packet %d, bad packet %d\n",
10639 dtoh32(pktcnt
.tx_good_pkt
), dtoh32(pktcnt
.tx_bad_pkt
));
10645 wl_interfere(void *wl
, cmd_t
*cmd
, char **argv
)
10649 char *endptr
= NULL
;
10655 if ((ret
= wlu_get(wl
, cmd
->get
, &mode
, sizeof(mode
))) < 0)
10657 mode
= dtoh32(mode
);
10658 switch (mode
& 0x7f) {
10659 case INTERFERE_NONE
:
10660 printf("All interference mitigation is disabled. (mode 0)\n");
10663 printf("Non-wireless LAN Interference mitigation is enabled. (mode 1)\n");
10666 printf("Wireless LAN Interference mitigation is enabled. (mode 2)\n");
10669 printf("Auto Wireless LAN Interference mitigation is enabled and ");
10670 if (mode
& AUTO_ACTIVE
)
10671 printf("active. (mode 3)\n");
10673 printf("not active. (mode 3)\n");
10676 case WLAN_AUTO_W_NOISE
:
10677 printf("Auto Wireless LAN Interference mitigation is enabled and ");
10678 if (mode
& AUTO_ACTIVE
)
10679 printf("active, ");
10681 printf("not active, ");
10683 printf("and noise reduction is enabled. (mode 4)\n");
10688 mode
= INTERFERE_NONE
;
10689 val
= strtol(*argv
, &endptr
, 0);
10690 if (*endptr
!= '\0')
10695 mode
= INTERFERE_NONE
;
10701 mode
= WLAN_MANUAL
;
10707 mode
= WLAN_AUTO_W_NOISE
;
10713 mode
= htod32(mode
);
10714 return wlu_set(wl
, cmd
->set
, &mode
, sizeof(mode
));
10719 wl_interfere_override(void *wl
, cmd_t
*cmd
, char **argv
)
10729 if ((ret
= wlu_get(wl
, cmd
->get
, &mode
, sizeof(mode
))) < 0) {
10732 mode
= dtoh32(mode
);
10734 case INTERFERE_NONE
:
10735 printf("Interference override NONE, "
10736 "all mitigation disabled. (mode 0)\n");
10739 printf("Interference override enabled. "
10740 " Non-wireless LAN Interference mitigation is enabled. (mode 1)\n");
10743 printf("Interference override enabled. "
10744 " Wireless LAN Interference mitigation is enabled. (mode 2)\n");
10747 printf("Interference override enabled. "
10748 " Interference mitigation is enabled and ");
10749 if (mode
& AUTO_ACTIVE
)
10750 printf("active. (mode 3)\n");
10752 printf("not active. (mode 3)\n");
10755 case WLAN_AUTO_W_NOISE
:
10756 printf("Interference override enabled. "
10757 " Interference mitigation is enabled and ");
10758 if (mode
& AUTO_ACTIVE
)
10759 printf("active, ");
10761 printf("not active, ");
10763 printf("and noise reduction is enabled. (mode 4)\n");
10765 case INTERFERE_OVRRIDE_OFF
:
10766 printf("Interference override disabled. \n");
10771 mode
= INTERFERE_NONE
;
10772 val
= strtol(*argv
, &endptr
, 0);
10773 if (*endptr
!= '\0')
10778 mode
= INTERFERE_NONE
;
10784 mode
= WLAN_MANUAL
;
10790 mode
= WLAN_AUTO_W_NOISE
;
10792 case INTERFERE_OVRRIDE_OFF
:
10793 mode
= INTERFERE_OVRRIDE_OFF
;
10799 mode
= htod32(mode
);
10800 return wlu_set(wl
, cmd
->set
, &mode
, sizeof(mode
));
10804 static cntry_name_t
*
10805 wlc_cntry_name_to_country(char *long_name
)
10807 cntry_name_t
*cntry
;
10808 for (cntry
= cntry_names
; cntry
->name
&&
10809 stricmp(long_name
, cntry
->name
); cntry
++);
10810 return (!cntry
->name
? NULL
: cntry
);
10813 static cntry_name_t
*
10814 wlc_cntry_abbrev_to_country(const char *abbrev
)
10816 cntry_name_t
*cntry
;
10817 if (!*abbrev
|| strlen(abbrev
) > 3 || strlen(abbrev
) < 2)
10819 for (cntry
= cntry_names
; cntry
->name
&&
10820 strnicmp(abbrev
, cntry
->abbrev
, strlen(abbrev
)); cntry
++);
10821 return (!cntry
->name
? NULL
: cntry
);
10825 wl_parse_country_spec(const char *spec
, char *ccode
, int *regrev
)
10828 char *endptr
= NULL
;
10832 revstr
= strchr(spec
, '/');
10835 rev
= strtol(revstr
+ 1, &endptr
, 10);
10836 if (*endptr
!= '\0') {
10837 /* not all the value string was parsed by strtol */
10839 "Could not parse \"%s\" as a regulatory revision "
10840 "in the country string \"%s\"\n",
10842 return USAGE_ERROR
;
10847 ccode_len
= (int)(uintptr
)(revstr
- spec
);
10849 ccode_len
= (int)strlen(spec
);
10851 if (ccode_len
> 3) {
10853 "Could not parse a 2-3 char country code "
10854 "in the country string \"%s\"\n",
10856 return USAGE_ERROR
;
10859 memcpy(ccode
, spec
, ccode_len
);
10860 ccode
[ccode_len
] = '\0';
10867 wl_country(void *wl
, cmd_t
*cmd
, char **argv
)
10869 cntry_name_t
*cntry
;
10870 wl_country_t cspec
= {{0}, 0, {0}};
10875 /* skip the command name */
10878 /* find the arg count */
10882 /* check arg list count */
10884 fprintf(stderr
, "Too many arguments (%d) for command %s\n", argc
, cmd
->name
);
10885 return USAGE_ERROR
;
10890 const char* name
= "<unknown>";
10892 /* first try the country iovar */
10893 err
= wlu_iovar_get(wl
, "country", &cspec
, sizeof(cspec
));
10896 cntry
= wlc_cntry_abbrev_to_country(cspec
.country_abbrev
);
10898 name
= cntry
->name
;
10900 printf("%s (%s/%d) %s\n",
10901 cspec
.country_abbrev
, cspec
.ccode
, cspec
.rev
, name
);
10906 /* if there was an error other than BCME_UNSUPPORTED, fail now */
10907 wlu_iovar_getint(wl
, "bcmerror", &bcmerr
);
10908 if (bcmerr
!= BCME_UNSUPPORTED
)
10911 /* if the "country" iovar is unsupported, try the WLC_SET_COUNTRY ioctl */
10912 if ((err
= wlu_get(wl
, cmd
->get
, &buf
[0], WLC_IOCTL_SMLEN
)))
10914 if (strlen(buf
) == 0) {
10915 printf("No country set\n");
10919 cntry
= wlc_cntry_abbrev_to_country(buf
);
10921 name
= cntry
->name
;
10923 printf("%s () %s\n", buf
, name
);
10927 if (!stricmp(*argv
, "list")) {
10929 const char* abbrev
;
10930 wl_country_list_t
*cl
= (wl_country_list_t
*)buf
;
10932 cl
->buflen
= WLC_IOCTL_MAXLEN
;
10935 /* band may follow */
10937 cl
->band_set
= TRUE
;
10938 if (!stricmp(*argv
, "a"))
10939 cl
->band
= WLC_BAND_5G
;
10940 else if (!stricmp(*argv
, "b") || !stricmp(*argv
, "g"))
10941 cl
->band
= WLC_BAND_2G
;
10943 printf("unsupported band: %s\n", *argv
);
10947 cl
->band_set
= FALSE
;
10950 cl
->buflen
= htod32(cl
->buflen
);
10951 cl
->band_set
= htod32(cl
->band_set
);
10952 cl
->band
= htod32(cl
->band
);
10953 cl
->count
= htod32(cl
->count
);
10954 err
= wlu_get(wl
, WLC_GET_COUNTRY_LIST
, buf
, WLC_IOCTL_MAXLEN
);
10958 printf("Supported countries: country code and long name\n");
10959 for (i
= 0; i
< dtoh32(cl
->count
); i
++) {
10960 abbrev
= &cl
->country_abbrev
[i
*WLC_CNTRY_BUF_SZ
];
10961 cntry
= wlc_cntry_abbrev_to_country(abbrev
);
10962 printf("%s\t%s\n", abbrev
, cntry
? cntry
->name
: "");
10967 memset(&cspec
, 0, sizeof(cspec
));
10971 /* check for the first arg being a country name, e.g. "United States",
10972 * or country spec, "US/1", or just a country code, "US"
10974 if ((cntry
= wlc_cntry_name_to_country(argv
[0])) != NULL
) {
10975 /* arg matched a country name */
10976 memcpy(cspec
.country_abbrev
, cntry
->abbrev
, WLC_CNTRY_BUF_SZ
);
10979 /* parse a country spec, e.g. "US/1", or a country code.
10980 * cspec.rev will be -1 if not specified.
10982 err
= wl_parse_country_spec(argv
[0], cspec
.country_abbrev
, &cspec
.rev
);
10987 "Argument \"%s\" could not be parsed as a country name, "
10988 "country code, or country code and regulatory revision.\n",
10990 return USAGE_ERROR
;
10993 /* if the arg was a country spec, then fill out ccdoe and rev,
10994 * and leave country_abbrev defaulted to the ccode
10996 if (cspec
.rev
!= -1)
10997 memcpy(cspec
.ccode
, cspec
.country_abbrev
, WLC_CNTRY_BUF_SZ
);
10999 /* for two args, the first needs to be a country code or country spec */
11000 err
= wl_parse_country_spec(argv
[0], cspec
.ccode
, &cspec
.rev
);
11003 "Argument 1 \"%s\" could not be parsed as a country code, or "
11004 "country code and regulatory revision.\n",
11006 return USAGE_ERROR
;
11009 /* the second arg needs to be a country name or country code */
11010 if ((cntry
= wlc_cntry_name_to_country(argv
[1])) != NULL
) {
11011 /* arg matched a country name */
11012 memcpy(cspec
.country_abbrev
, cntry
->abbrev
, WLC_CNTRY_BUF_SZ
);
11015 err
= wl_parse_country_spec(argv
[1], cspec
.country_abbrev
, &rev
);
11018 "Argument \"%s\" had a revision. Arg 2 must be "
11019 "a country name or country code without a revision\n",
11021 return USAGE_ERROR
;
11027 "Argument 2 \"%s\" could not be parsed as "
11028 "a country name or country code\n",
11030 return USAGE_ERROR
;
11034 /* first try the country iovar */
11035 if (cspec
.rev
== -1 && cspec
.ccode
[0] == '\0')
11036 err
= wlu_iovar_set(wl
, "country", &cspec
, WLC_CNTRY_BUF_SZ
);
11038 err
= wlu_iovar_set(wl
, "country", &cspec
, sizeof(cspec
));
11043 /* if there was an error other than BCME_UNSUPPORTED, fail now */
11044 wlu_iovar_getint(wl
, "bcmerror", &bcmerr
);
11045 if (bcmerr
!= BCME_UNSUPPORTED
)
11048 /* if the "country" iovar is unsupported, try the WLC_SET_COUNTRY ioctl if possible */
11050 if (cspec
.rev
!= -1 || cspec
.ccode
[0] != '\0') {
11052 "Driver does not support full country spec interface, "
11053 "only a country name or code may be sepcified\n");
11057 /* use the legacy ioctl */
11058 err
= wlu_set(wl
, WLC_SET_COUNTRY
, cspec
.country_abbrev
, WLC_CNTRY_BUF_SZ
);
11064 wl_country_ie_override(void *wl
, cmd_t
*cmd
, char **argv
)
11069 /* skip the command name */
11072 /* find the arg count */
11080 if ((error
= wlu_var_getbuf(wl
, cmd
->name
, NULL
, 0, &ptr
)) < 0)
11083 ie
= (bcm_tlv_t
*)ptr
;
11085 printf("ie tag:0x%x ie len:0x%x ie data:", ie
->id
, ie
->len
);
11087 for (i
= 0; i
< ie
->len
; i
++)
11088 printf("0x%x ", ie
->data
[i
]);
11096 char *endptr
= NULL
;
11098 int8 ie_len
, pad
= 0;
11100 /* retrieve the ie len in advance to check for padding */
11101 ie_len
= (int8
)strtol(*(argv
+ 1), NULL
, 0);
11103 fprintf(stderr
, "country ie len is odd(%d), padding by 1 octet\n", ie_len
);
11107 valsp
= (uchar
*)malloc(argc
+ pad
);
11108 if (valsp
== NULL
) {
11109 fprintf(stderr
, "Error allocating %d bytes country ie\n", argc
);
11112 memset(valsp
, 0, argc
+ pad
);
11114 for (i
= 0; i
< argc
; i
++, argv
++) {
11116 valsp
[i
] = strtol(*argv
, &endptr
, 0);
11118 /* make sure all the value string was parsed by strtol */
11119 if (*endptr
!= '\0')
11123 /* update ie len if padded */
11126 valsp
[ie_len
+ TLV_HDR_LEN
] = 0;
11129 return wlu_var_setbuf(wl
, cmd
->name
, valsp
, argc
+ pad
);
11133 #define ACI_SPIN "spin"
11134 #define ACI_ENTER "enter"
11135 #define ACI_EXIT "exit"
11136 #define ACI_GLITCH "glitch"
11138 #define NPHY_ACI_ADCPWR_ENTER "adcpwr_enter"
11139 #define NPHY_ACI_ADCPWR_EXIT "adcpwr_exit"
11140 #define NPHY_ACI_REPEAT_CTR "repeat"
11141 #define NPHY_ACI_NUM_SAMPLES "samples"
11142 #define NPHY_ACI_UNDETECT "undetect_sz"
11143 #define NPHY_ACI_LOPWR "loaci"
11144 #define NPHY_ACI_MDPWR "mdaci"
11145 #define NPHY_ACI_HIPWR "hiaci"
11146 #define NPHY_ACI_NOISE_NOASSOC_GLITCH_TH_UP "nphy_noise_noassoc_glitch_th_up"
11147 #define NPHY_ACI_NOISE_NOASSOC_GLITCH_TH_DN "nphy_noise_noassoc_glitch_th_dn"
11148 #define NPHY_ACI_NOISE_ASSOC_GLITCH_TH_UP "nphy_noise_assoc_glitch_th_up"
11149 #define NPHY_ACI_NOISE_ASSOC_GLITCH_TH_DN "nphy_noise_assoc_glitch_th_dn"
11150 #define NPHY_ACI_NOISE_ASSOC_ACI_GLITCH_TH_UP "nphy_noise_assoc_aci_glitch_th_up"
11151 #define NPHY_ACI_NOISE_ASSOC_ACI_GLITCH_TH_DN "nphy_noise_assoc_aci_glitch_th_dn"
11152 #define NPHY_ACI_NOISE_NOASSOC_ENTER_TH "nphy_noise_noassoc_enter_th"
11153 #define NPHY_ACI_NOISE_ASSOC_ENTER_TH "nphy_noise_assoc_enter_th"
11154 #define NPHY_ACI_NOISE_ASSOC_RX_GLITCH_BADPLCP_ENTER_TH \
11155 "nphy_noise_assoc_rx_glitch_badplcp_enter_th"
11156 #define NPHY_ACI_NOISE_ASSOC_CRSIDX_INCR "nphy_noise_assoc_crsidx_incr"
11157 #define NPHY_ACI_NOISE_NOASSOC_CRSIDX_INCR "nphy_noise_noassoc_crsidx_incr"
11158 #define NPHY_ACI_NOISE_CRSIDX_DECR "nphy_noise_crsidx_decr"
11161 #if defined(BWL_FILESYSTEM_SUPPORT)
11162 #if !defined(_CFE_)
11164 wl_do_samplecollect_n(void *wl
, wl_samplecollect_args_t
*collect
, uint8
*buff
, FILE *fp
)
11169 ret
= wlu_iovar_getbuf(wl
, "sample_collect", collect
, sizeof(wl_samplecollect_args_t
),
11170 buff
, WLC_SAMPLECOLLECT_MAXLEN
);
11175 /* bytes 1:0 indicate capture length */
11176 while ((nbytes
= ltoh16_ua(buff
))) {
11178 ret
= fwrite(buff
, 1, nbytes
, fp
);
11179 if (ret
!= nbytes
) {
11180 fprintf(stderr
, "Error writing %d bytes to file, rc %d!\n",
11185 fprintf(stderr
, "Wrote %d bytes\n", nbytes
);
11193 wl_do_samplecollect(void *wl
, wl_samplecollect_args_t
*collect
, int sampledata_version
,
11194 uint32
*buff
, FILE *fp
)
11196 uint16 nbytes
, tag
;
11197 uint32 flag
, *header
, sync
;
11200 wl_sampledata_t
*sample_collect
;
11201 wl_sampledata_t sample_data
, *psample
;
11203 err
= wlu_iovar_getbuf(wl
, "sample_collect", collect
, sizeof(wl_samplecollect_args_t
),
11204 buff
, WLC_SAMPLECOLLECT_MAXLEN
);
11209 sample_collect
= (wl_sampledata_t
*)buff
;
11210 header
= (uint32
*)&sample_collect
[1];
11211 tag
= ltoh16_ua(&sample_collect
->tag
);
11212 if (tag
!= WL_SAMPLEDATA_HEADER_TYPE
) {
11213 fprintf(stderr
, "Expect SampleData Header type %d, receive type %d\n",
11214 WL_SAMPLEDATA_HEADER_TYPE
, tag
);
11218 nbytes
= ltoh16_ua(&sample_collect
->length
);
11219 flag
= ltoh32_ua(&sample_collect
->flag
);
11220 sync
= ltoh32_ua(&header
[0]);
11221 if (sync
!= 0xACDC2009) {
11222 fprintf(stderr
, "Header sync word mismatch (0x%08x)\n", sync
);
11226 err
= fwrite((uint8
*)header
, 1, nbytes
, fp
);
11227 if (err
!= (int)nbytes
)
11228 fprintf(stderr
, "Failed write file-header to file %d\n", err
);
11230 memset(&sample_data
, 0, sizeof(wl_sampledata_t
));
11231 sample_data
.version
= sampledata_version
;
11232 sample_data
.size
= htol16(sizeof(wl_sampledata_t
));
11234 /* new format, used in htphy */
11236 sample_data
.tag
= htol16(WL_SAMPLEDATA_TYPE
);
11237 sample_data
.length
= htol16(WLC_SAMPLECOLLECT_MAXLEN
);
11239 sample_data
.flag
= htol32((flag
& 0xff));
11241 err
= wlu_iovar_getbuf(wl
, "sample_data", &sample_data
, sizeof(wl_sampledata_t
),
11242 buff
, WLC_SAMPLECOLLECT_MAXLEN
);
11244 fprintf(stderr
, "Error reading back sample collected data\n");
11249 ptr
= (uint8
*)buff
+ sizeof(wl_sampledata_t
);
11250 psample
= (wl_sampledata_t
*)buff
;
11251 tag
= ltoh16_ua(&psample
->tag
);
11252 nbytes
= ltoh16_ua(&psample
->length
);
11253 flag
= ltoh32_ua(&psample
->flag
);
11254 if (tag
!= WL_SAMPLEDATA_TYPE
) {
11255 fprintf(stderr
, "Expect SampleData type %d, receive type %d\n",
11256 WL_SAMPLEDATA_TYPE
, tag
);
11261 fprintf(stderr
, "Done retrieving sample data\n");
11265 err
= fwrite(ptr
, 1, nbytes
, fp
);
11266 if (err
!= (int)nbytes
) {
11267 fprintf(stderr
, "Error writing %d bytes to file, rc %d!\n",
11272 printf("Wrote %d bytes\n", err
);
11274 } while (flag
& WL_SAMPLEDATA_MORE_DATA
);
11278 #endif /* defined(BWL_FILESYSTEM_SUPPORT) */
11281 wl_sample_collect(void *wl
, cmd_t
*cmd
, char **argv
)
11283 #if !defined(BWL_FILESYSTEM_SUPPORT)
11284 UNUSED_PARAMETER(wl
); UNUSED_PARAMETER(cmd
); UNUSED_PARAMETER(argv
);
11286 #elif defined(_CFE_)
11287 UNUSED_PARAMETER(wl
); UNUSED_PARAMETER(cmd
); UNUSED_PARAMETER(argv
);
11288 return CFE_ERR_UNSUPPORTED
;
11291 uint8
*buff
= NULL
;
11292 wl_samplecollect_args_t collect
;
11293 const char *fname
= "sample_collect.dat";
11294 wlc_rev_info_t revinfo
;
11295 uint32 phytype
, phyrev
;
11298 /* Default setting for sampledata_version */
11299 int sampledata_version
= htol16(WL_SAMPLEDATA_T_VERSION
);
11301 UNUSED_PARAMETER(cmd
);
11303 memset(&revinfo
, 0, sizeof(revinfo
));
11304 ret
= wlu_get(wl
, WLC_GET_REVINFO
, &revinfo
, sizeof(revinfo
));
11308 phytype
= dtoh32(revinfo
.phytype
);
11309 phyrev
= dtoh32(revinfo
.phyrev
);
11311 /* Assign some default params first */
11312 /* 60us is roughly the max we can store (for NPHY with NREV < 7). */
11313 collect
.coll_us
= 60;
11314 collect
.cores
= -1;
11315 /* extended settings */
11316 collect
.trigger
= TRIGGER_NOW
;
11318 collect
.post_dur
= 10;
11319 collect
.pre_dur
= 10;
11320 collect
.gpio_sel
= 0;
11321 collect
.downsamp
= FALSE
;
11322 collect
.be_deaf
= FALSE
;
11323 collect
.timeout
= 1000;
11324 collect
.agc
= FALSE
;
11325 collect
.filter
= FALSE
;
11326 collect
.version
= WL_SAMPLECOLLECT_T_VERSION
;
11327 collect
.length
= sizeof(wl_samplecollect_args_t
);
11329 /* Skip the command name */
11335 if (argv
[1] == NULL
)
11337 if (!strcmp(s
, "-f"))
11339 else if (!strcmp(s
, "-u"))
11340 collect
.coll_us
= atoi(argv
[1]);
11341 else if (!strcmp(s
, "-c"))
11342 collect
.cores
= atoi(argv
[1]);
11343 /* extended settings */
11344 else if (!strcmp(s
, "-t")) {
11345 /* event trigger */
11346 if (!strcmp(argv
[1], "crs"))
11347 collect
.trigger
= TRIGGER_CRS
;
11348 else if (!strcmp(argv
[1], "crs_deassert"))
11349 collect
.trigger
= TRIGGER_CRSDEASSERT
;
11350 else if (!strcmp(argv
[1], "good_fcs"))
11351 collect
.trigger
= TRIGGER_GOODFCS
;
11352 else if (!strcmp(argv
[1], "bad_fcs"))
11353 collect
.trigger
= TRIGGER_BADFCS
;
11354 else if (!strcmp(argv
[1], "bad_plcp"))
11355 collect
.trigger
= TRIGGER_BADPLCP
;
11356 else if (!strcmp(argv
[1], "crs_glitch"))
11357 collect
.trigger
= TRIGGER_CRSGLITCH
;
11359 else if (!strcmp(s
, "-m")) {
11360 if (!strcmp(argv
[1], "gpio")) {
11361 if (phytype
== WLC_PHY_TYPE_HT
) {
11365 collect
.mode
= 0xff;
11368 collect
.mode
= atoi(argv
[1]);
11371 else if (!strcmp(s
, "-b"))
11372 collect
.pre_dur
= atoi(argv
[1]);
11373 else if (!strcmp(s
, "-a"))
11374 collect
.post_dur
= atoi(argv
[1]);
11375 else if (!strcmp(s
, "-g"))
11376 collect
.gpio_sel
= atoi(argv
[1]);
11377 else if (!strcmp(s
, "-d"))
11378 collect
.downsamp
= atoi(argv
[1]);
11379 else if (!strcmp(s
, "-e"))
11380 collect
.be_deaf
= atoi(argv
[1]);
11381 else if (!strcmp(s
, "-i"))
11382 collect
.timeout
= atoi(argv
[1]);
11383 else if (!strcmp(s
, "--agc")) {
11384 /* perform software agc for sample collect */
11385 collect
.agc
= atoi(argv
[1]);
11387 else if (!strcmp(s
, "--filter")) {
11388 /* Set HPC for LPF to lowest possible value (0x1) */
11389 collect
.filter
= atoi(argv
[1]);
11391 else if (!strcmp(s
, "-v"))
11392 sampledata_version
= atoi(argv
[1]);
11399 buff
= malloc(WLC_SAMPLECOLLECT_MAXLEN
);
11400 if (buff
== NULL
) {
11401 fprintf(stderr
, "Failed to allocate dump buffer of %d bytes\n",
11402 WLC_SAMPLECOLLECT_MAXLEN
);
11405 memset(buff
, 0, WLC_SAMPLECOLLECT_MAXLEN
);
11407 if ((fp
= fopen(fname
, "wb")) == NULL
) {
11408 fprintf(stderr
, "Problem opening file %s\n", fname
);
11413 if (phytype
== WLC_PHY_TYPE_HT
) {
11414 ret
= wl_do_samplecollect(wl
, &collect
, sampledata_version
, (uint32
*)buff
, fp
);
11415 } else if (phytype
== WLC_PHY_TYPE_N
) {
11417 ret
= wl_do_samplecollect_n(wl
, &collect
, buff
, fp
);
11419 ret
= wl_do_samplecollect(wl
, &collect
, sampledata_version
,
11420 (uint32
*)buff
, fp
);
11425 if (buff
) free(buff
);
11426 if (fp
) fclose(fp
);
11428 #endif /* !BWL_FILESYSTEM_SUPPORT */
11432 wl_ampdu_activate_test(void *wl
, cmd_t
*cmd
, char **argv
)
11435 const char *cmdname
= "ampdu_activate_test";
11442 UNUSED_PARAMETER(cmd
);
11444 if ((param
= *++argv
) == NULL
)
11445 return USAGE_ERROR
;
11447 x
.val1
= atoi(param
);
11448 if ((param
= *++argv
)) {
11449 x
.val2
= atoi(param
);
11450 printf("%d %d\n", x
.val1
, x
.val2
);
11451 err
= wlu_var_setbuf(wl
, cmdname
, &x
, sizeof(x
));
11457 wl_ampdu_tid(void *wl
, cmd_t
*cmd
, char **argv
)
11460 const char *cmdname
= "ampdu_tid";
11461 struct ampdu_tid_control atc
, *reply
;
11466 UNUSED_PARAMETER(cmd
);
11468 if ((param
= *++argv
) == NULL
)
11469 return USAGE_ERROR
;
11473 return USAGE_ERROR
;
11476 if ((param
= *++argv
)) {
11477 atc
.enable
= atoi(param
);
11478 err
= wlu_var_setbuf(wl
, cmdname
, &atc
, sizeof(atc
));
11480 if ((err
= wlu_var_getbuf_sm(wl
, cmdname
, &atc
, sizeof(atc
), &ptr
) < 0))
11482 reply
= (struct ampdu_tid_control
*)ptr
;
11483 printf("AMPDU for tid %d: %d\n", tid
, reply
->enable
);
11489 wl_ampdu_retry_limit_tid(void *wl
, cmd_t
*cmd
, char **argv
)
11492 const char *cmdname
= "ampdu_retry_limit_tid";
11493 struct ampdu_retry_tid retry_limit
, *reply
;
11498 UNUSED_PARAMETER(cmd
);
11500 if ((param
= *++argv
) == NULL
)
11501 return USAGE_ERROR
;
11505 return USAGE_ERROR
;
11506 retry_limit
.tid
= tid
;
11508 if ((param
= *++argv
)) {
11509 retry_limit
.retry
= atoi(param
);
11510 err
= wlu_var_setbuf(wl
, cmdname
, &retry_limit
, sizeof(retry_limit
));
11512 if ((err
= wlu_var_getbuf(wl
, cmdname
, &retry_limit
,
11513 sizeof(retry_limit
), &ptr
)) < 0)
11515 reply
= (struct ampdu_retry_tid
*)ptr
;
11516 printf("AMPDU retry limit for tid %d: %d\n", tid
, reply
->retry
);
11522 wl_ampdu_rr_retry_limit_tid(void *wl
, cmd_t
*cmd
, char **argv
)
11525 const char *cmdname
= "ampdu_rr_retry_limit_tid";
11526 struct ampdu_retry_tid retry_limit
, *reply
;
11531 UNUSED_PARAMETER(cmd
);
11533 if ((param
= *++argv
) == NULL
)
11534 return USAGE_ERROR
;
11538 return USAGE_ERROR
;
11539 retry_limit
.tid
= tid
;
11541 if ((param
= *++argv
)) {
11542 retry_limit
.retry
= atoi(param
);
11543 err
= wlu_var_setbuf(wl
, cmdname
, &retry_limit
, sizeof(retry_limit
));
11545 if ((err
= wlu_var_getbuf(wl
, cmdname
, &retry_limit
,
11546 sizeof(retry_limit
), &ptr
)) < 0)
11548 reply
= (struct ampdu_retry_tid
*)ptr
;
11549 printf("AMPDU regular rate retry limit for tid %d: %d\n", tid
, reply
->retry
);
11556 wl_ampdu_send_addba(void *wl
, cmd_t
*cmd
, char **argv
)
11559 const char *cmdname
= "ampdu_send_addba";
11560 struct ampdu_ea_tid aet
;
11563 UNUSED_PARAMETER(cmd
);
11565 if ((param
= *++argv
) == NULL
)
11566 return USAGE_ERROR
;
11570 return USAGE_ERROR
;
11575 printf("error: missing address\n");
11576 return USAGE_ERROR
;
11579 if (!wl_ether_atoe(*argv
, &aet
.ea
)) {
11580 printf("error: could not parse MAC address %s\n", *argv
);
11584 return wlu_var_setbuf(wl
, cmdname
, &aet
, sizeof(aet
));
11588 wl_ampdu_send_delba(void *wl
, cmd_t
*cmd
, char **argv
)
11591 const char *cmdname
= "ampdu_send_delba";
11592 struct ampdu_ea_tid aet
;
11595 UNUSED_PARAMETER(cmd
);
11597 if ((param
= *++argv
) == NULL
)
11598 return USAGE_ERROR
;
11602 return USAGE_ERROR
;
11607 printf("error: missing address\n");
11608 return USAGE_ERROR
;
11611 if (!wl_ether_atoe(*argv
, &aet
.ea
)) {
11612 printf("error: could not parse MAC address %s\n", *argv
);
11616 return wlu_var_setbuf(wl
, cmdname
, &aet
, sizeof(aet
));
11620 wl_dpt_deny(void *wl
, cmd_t
*cmd
, char **argv
)
11622 const char *cmdname
= "dpt_deny";
11625 UNUSED_PARAMETER(cmd
);
11628 return USAGE_ERROR
;
11632 if (!strcmp("add", *argv
))
11633 info
.mode
= DPT_DENY_LIST_ADD
;
11634 else if (!strcmp("remove", *argv
))
11635 info
.mode
= DPT_DENY_LIST_REMOVE
;
11637 printf("error: invalid mode string\n");
11638 return USAGE_ERROR
;
11643 printf("error: missing mode value\n");
11644 return USAGE_ERROR
;
11647 if (!wl_ether_atoe(*argv
, &info
.ea
)) {
11648 printf("error: could not parse MAC address %s\n", *argv
);
11652 return wlu_var_setbuf(wl
, cmdname
, &info
, sizeof(info
));
11656 wl_dpt_endpoint(void *wl
, cmd_t
*cmd
, char **argv
)
11658 const char *cmdname
= "dpt_endpoint";
11661 UNUSED_PARAMETER(cmd
);
11664 return USAGE_ERROR
;
11668 if (!strcmp("create", *argv
))
11669 info
.mode
= DPT_MANUAL_EP_CREATE
;
11670 else if (!strcmp("modify", *argv
))
11671 info
.mode
= DPT_MANUAL_EP_MODIFY
;
11672 else if (!strcmp("delete", *argv
))
11673 info
.mode
= DPT_MANUAL_EP_DELETE
;
11675 printf("error: invalid mode string\n");
11676 return USAGE_ERROR
;
11681 printf("error: missing ea\n");
11682 return USAGE_ERROR
;
11685 if (!wl_ether_atoe(*argv
, &info
.ea
)) {
11686 printf("error: could not parse MAC address %s\n", *argv
);
11690 return wlu_var_setbuf(wl
, cmdname
, &info
, sizeof(info
));
11694 wl_actframe(void *wl
, cmd_t
*cmd
, char **argv
)
11696 wl_action_frame_t
* action_frame
;
11697 wl_af_params_t
* af_params
;
11698 struct ether_addr ea
;
11702 UNUSED_PARAMETER(cmd
);
11704 if (!argv
[1] || !argv
[2]) {
11705 fprintf(stderr
, "Too few arguments\n");
11710 for (argc
= 0; argv
[argc
]; argc
++)
11713 if ((af_params
= (wl_af_params_t
*) malloc(WL_WIFI_AF_PARAMS_SIZE
)) == NULL
) {
11714 printf("wl_actframe: unable to allocate frame \n");
11717 af_params
->channel
= 0;
11718 af_params
->dwell_time
= -1;
11719 action_frame
= &af_params
->action_frame
;
11721 /* Add the packet Id */
11722 action_frame
->packetId
= (uint32
)(uintptr
)action_frame
;
11724 /* convert the ea string into an ea struct */
11725 if (!wl_ether_atoe(argv
[1], &ea
)) {
11726 free(action_frame
);
11727 printf(" ERROR: no valid ether addr provided\n");
11730 memcpy(&action_frame
->da
, (char*)&ea
, ETHER_ADDR_LEN
);
11731 /* set default BSSID */
11732 memcpy(&af_params
->BSSID
, (char*)&ea
, ETHER_ADDR_LEN
);
11734 /* add the length */
11736 action_frame
->len
= htod16(strlen(argv
[2])) / 2;
11739 /* add the channel */
11740 if (argc
> 3 && argv
[3]) {
11741 af_params
->channel
= htod32(atoi(argv
[3]));
11744 /* add the dwell_time */
11745 if (argc
> 4 && argv
[4]) {
11746 af_params
->dwell_time
= htod32(atoi(argv
[4]));
11749 /* add the BSSID */
11750 if (argc
> 5 && argv
[5]) {
11751 if (!wl_ether_atoe(argv
[5], &ea
)) {
11752 free(action_frame
);
11753 printf(" ERROR: no valid ether addr provided\n");
11756 memcpy(&af_params
->BSSID
, (char*)&ea
, ETHER_ADDR_LEN
);
11759 if ((err
= get_ie_data ((uchar
*)argv
[2],
11760 &action_frame
->data
[0],
11761 action_frame
->len
))) {
11763 fprintf(stderr
, "Error parsing data arg\n");
11766 err
= wlu_var_setbuf(wl
, "actframe", af_params
, WL_WIFI_AF_PARAMS_SIZE
);
11775 wl_dpt_pmk(void *wl
, cmd_t
*cmd
, char **argv
)
11777 const char *cmdname
= "dpt_pmk";
11781 UNUSED_PARAMETER(cmd
);
11784 return USAGE_ERROR
;
11786 key_len
= strlen(*argv
);
11787 if (key_len
< WSEC_MIN_PSK_LEN
|| key_len
> WSEC_MAX_PSK_LEN
) {
11788 fprintf(stderr
, "passphrase must be between %d and %d characters long\n",
11789 WSEC_MIN_PSK_LEN
, WSEC_MAX_PSK_LEN
);
11792 psk
.key_len
= htod16((ushort
) key_len
);
11793 psk
.flags
= htod16(WSEC_PASSPHRASE
);
11794 memcpy(psk
.key
, *argv
, key_len
);
11796 return wlu_var_setbuf(wl
, cmdname
, &psk
, sizeof(wsec_pmk_t
));
11800 wl_dpt_fname(void *wl
, cmd_t
*cmd
, char **argv
)
11803 const char *cmdname
= "dpt_fname";
11805 dpt_fname_t fname
, *reply
;
11808 UNUSED_PARAMETER(cmd
);
11810 if ((param
= *++argv
)) {
11811 fname
.len
= strlen(param
);
11812 if (fname
.len
>= (DPT_FNAME_LEN
- 1)) {
11813 fprintf(stderr
, "Name must be less than 32 characters\n");
11816 memcpy(fname
.name
, param
, fname
.len
);
11817 fname
.name
[fname
.len
] = '\0';
11818 err
= wlu_var_setbuf(wl
, cmdname
, &fname
, sizeof(fname
));
11820 if ((err
= wlu_var_getbuf(wl
, cmdname
, &fname
, sizeof(fname
), &ptr
) < 0))
11822 reply
= (dpt_fname_t
*)ptr
;
11823 printf("%s\n", reply
->name
);
11829 wl_dpt_list(void *wl
, cmd_t
*cmd
, char **argv
)
11836 return USAGE_ERROR
;
11838 strcpy(buf
, cmd
->name
);
11839 if ((err
= wlu_get(wl
, cmd
->get
, buf
, WLC_IOCTL_MAXLEN
)))
11842 list
= (dpt_list_t
*) buf
;
11844 printf("List of DPT connections:\n");
11845 for (i
= 0; i
< list
->num
; i
++) {
11846 printf("%s: status 0x%x rx %d tx %d rssi %d\n",
11847 list
->status
[i
].name
,
11848 list
->status
[i
].status
,
11849 list
->status
[i
].sta
.rx_ucast_pkts
,
11850 list
->status
[i
].sta
.tx_pkts
,
11851 list
->status
[i
].rssi
);
11857 #define MATCH_OP(op, opstr) (strlen(op) == strlen(opstr) && strncmp(op, opstr, strlen(op)) == 0)
11860 wl_HCI_cmd(void *wl
, cmd_t
*cmd
, char **argv
)
11863 char buf
[HCI_CMD_PREAMBLE_SIZE
+ HCI_CMD_DATA_SIZE
];
11866 amp_hci_cmd_t
*cpkt
= (amp_hci_cmd_t
*)&cbuf
.buf
[0];
11870 UNUSED_PARAMETER(cmd
);
11873 return USAGE_ERROR
;
11875 /* recognize and encode operations */
11877 if (MATCH_OP(op
, "Read_Link_Quality")) {
11878 cpkt
->opcode
= HCI_Read_Link_Quality
;
11879 } else if (MATCH_OP(op
, "Read_Local_AMP_Info")) {
11880 cpkt
->opcode
= HCI_Read_Local_AMP_Info
;
11881 } else if (MATCH_OP(op
, "Read_Local_AMP_ASSOC")) {
11882 cpkt
->opcode
= HCI_Read_Local_AMP_ASSOC
;
11883 } else if (MATCH_OP(op
, "Write_Remote_AMP_ASSOC")) {
11884 cpkt
->opcode
= HCI_Write_Remote_AMP_ASSOC
;
11885 } else if (MATCH_OP(op
, "Create_Physical_Link")) {
11886 cpkt
->opcode
= HCI_Create_Physical_Link
;
11887 } else if (MATCH_OP(op
, "Accept_Physical_Link_Request")) {
11888 cpkt
->opcode
= HCI_Accept_Physical_Link_Request
;
11889 } else if (MATCH_OP(op
, "Disconnect_Physical_Link")) {
11890 cpkt
->opcode
= HCI_Disconnect_Physical_Link
;
11891 } else if (MATCH_OP(op
, "Create_Logical_Link")) {
11892 cpkt
->opcode
= HCI_Create_Logical_Link
;
11893 } else if (MATCH_OP(op
, "Accept_Logical_Link")) {
11894 cpkt
->opcode
= HCI_Accept_Logical_Link
;
11895 } else if (MATCH_OP(op
, "Disconnect_Logical_Link")) {
11896 cpkt
->opcode
= HCI_Disconnect_Logical_Link
;
11897 } else if (MATCH_OP(op
, "Logical_Link_Cancel")) {
11898 cpkt
->opcode
= HCI_Logical_Link_Cancel
;
11899 } else if (MATCH_OP(op
, "Short_Range_Mode")) {
11900 cpkt
->opcode
= HCI_Short_Range_Mode
;
11901 } else if (MATCH_OP(op
, "Read_Connection_Accept_Timeout")) {
11902 cpkt
->opcode
= HCI_Read_Connection_Accept_Timeout
;
11903 } else if (MATCH_OP(op
, "Write_Connection_Accept_Timeout")) {
11904 cpkt
->opcode
= HCI_Write_Connection_Accept_Timeout
;
11905 } else if (MATCH_OP(op
, "Read_Link_Supervision_Timeout")) {
11906 cpkt
->opcode
= HCI_Read_Link_Supervision_Timeout
;
11907 } else if (MATCH_OP(op
, "Write_Link_Supervision_Timeout")) {
11908 cpkt
->opcode
= HCI_Write_Link_Supervision_Timeout
;
11909 } else if (MATCH_OP(op
, "Reset")) {
11910 cpkt
->opcode
= HCI_Reset
;
11911 } else if (MATCH_OP(op
, "Enhanced_Flush")) {
11912 cpkt
->opcode
= HCI_Enhanced_Flush
;
11913 } else if (MATCH_OP(op
, "Read_Best_Effort_Flush_Timeout")) {
11914 cpkt
->opcode
= HCI_Read_Best_Effort_Flush_Timeout
;
11915 } else if (MATCH_OP(op
, "Write_Best_Effort_Flush_Timeout")) {
11916 cpkt
->opcode
= HCI_Write_Best_Effort_Flush_Timeout
;
11917 } else if (MATCH_OP(op
, "Read_Logical_Link_Accept_Timeout")) {
11918 cpkt
->opcode
= HCI_Read_Logical_Link_Accept_Timeout
;
11919 } else if (MATCH_OP(op
, "Write_Logical_Link_Accept_Timeout")) {
11920 cpkt
->opcode
= HCI_Write_Logical_Link_Accept_Timeout
;
11921 } else if (MATCH_OP(op
, "Read_Buffer_Size")) {
11922 cpkt
->opcode
= HCI_Read_Buffer_Size
;
11923 } else if (MATCH_OP(op
, "Read_Data_Block_Size")) {
11924 cpkt
->opcode
= HCI_Read_Data_Block_Size
;
11925 } else if (MATCH_OP(op
, "Set_Event_Mask_Page_2")) {
11926 cpkt
->opcode
= HCI_Set_Event_Mask_Page_2
;
11927 } else if (MATCH_OP(op
, "Flow_Spec_Modify")) {
11928 cpkt
->opcode
= HCI_Flow_Spec_Modify
;
11929 } else if (MATCH_OP(op
, "Read_Local_Version_Info")) {
11930 cpkt
->opcode
= HCI_Read_Local_Version_Info
;
11931 } else if (MATCH_OP(op
, "Read_Local_Supported_Commands")) {
11932 cpkt
->opcode
= HCI_Read_Local_Supported_Commands
;
11933 } else if (MATCH_OP(op
, "Read_Failed_Contact_Counter")) {
11934 cpkt
->opcode
= HCI_Read_Failed_Contact_Counter
;
11935 } else if (MATCH_OP(op
, "Reset_Failed_Contact_Counter")) {
11936 cpkt
->opcode
= HCI_Reset_Failed_Contact_Counter
;
11938 printf("unsupported HCI command: %s\n", op
);
11943 while (*argv
&& (plen
< HCI_CMD_DATA_SIZE
)) {
11944 cpkt
->parms
[plen
++] = (uint8
)strtol(*argv
++, NULL
, 0);
11948 return wlu_var_setbuf(wl
, cmd
->name
, cpkt
, HCI_CMD_PREAMBLE_SIZE
+ plen
);
11952 wl_HCI_ACL_data(void *wl
, cmd_t
*cmd
, char **argv
)
11954 /* Align struct. Also declare static so that large array isn't allocated
11958 uint8 buf
[HCI_ACL_DATA_PREAMBLE_SIZE
+ 2048];
11962 amp_hci_ACL_data_t
*dpkt
= (amp_hci_ACL_data_t
*)&g_wlu_hci_dbuf
.buf
[0];
11966 return USAGE_ERROR
;
11968 /* get logical link handle */
11969 dpkt
->handle
= (HCI_ACL_DATA_BC_FLAGS
| HCI_ACL_DATA_PB_FLAGS
);
11970 dpkt
->handle
|= (uint16
)strtol(*argv
++, NULL
, 0);
11974 while (*argv
&& (dlen
< 2048)) {
11975 dpkt
->data
[dlen
++] = (uint8
)strtol(*argv
++, NULL
, 0);
11979 return wlu_var_setbuf(wl
, cmd
->name
, dpkt
, HCI_ACL_DATA_PREAMBLE_SIZE
+ dlen
);
11983 wl_get_btamp_log(void *wl
, cmd_t
*cmd
, char **argv
)
11991 UNUSED_PARAMETER(cmd
);
11994 val_name
= *argv
++;
11997 if ((err
= wlu_var_getbuf_sm (wl
, cmd
->name
, NULL
, 0, &ptr
)))
11999 state
= (uint8
*)ptr
;
12002 for (i
= 0; i
< BTA_STATE_LOG_SZ
; i
++, idx
--) {
12003 j
= (idx
& (BTA_STATE_LOG_SZ
- 1));
12004 switch (state
[j
]) {
12006 printf("%2d: HCI Reset\n", state
[j
]);
12008 case HCIReadLocalAMPInfo
:
12009 printf("%2d: HCI Read Local AMPInfo\n", state
[j
]);
12011 case HCIReadLocalAMPASSOC
:
12012 printf("%2d: HCI Read Local AMPASSOC\n", state
[j
]);
12014 case HCIWriteRemoteAMPASSOC
:
12015 printf("%2d: HCI Write Remote AMPASSOC\n", state
[j
]);
12017 case HCICreatePhysicalLink
:
12018 printf("%2d: HCI Create Physical Link\n", state
[j
]);
12020 case HCIAcceptPhysicalLinkRequest
:
12021 printf("%2d: HCI Accept Physical Link Request\n", state
[j
]);
12023 case HCIDisconnectPhysicalLink
:
12024 printf("%2d: HCI Disconnect Physical Link\n", state
[j
]);
12026 case HCICreateLogicalLink
:
12027 printf("%2d: HCI Create Logical Link\n", state
[j
]);
12029 case HCIAcceptLogicalLink
:
12030 printf("%2d: HCI Accept Logical Link\n", state
[j
]);
12032 case HCIDisconnectLogicalLink
:
12033 printf("%2d: HCI Disconnect Logical Link\n", state
[j
]);
12035 case HCILogicalLinkCancel
:
12036 printf("%2d: HCI Logical Link Cancel\n", state
[j
]);
12038 case HCIAmpStateChange
:
12039 printf("%2d: HCI Amp State Change\n", state
[j
]);
12047 err
= wlu_iovar_setint(wl
, val_name
, (int)idx
);
12051 #endif /* WLBTAMP */
12054 * RADAR detection parameter control
12057 wl_radar_args(void *wl
, cmd_t
*cmd
, char **argv
)
12060 wl_radar_args_t ra
;
12062 /* Skip the command name */
12065 if (*argv
== NULL
) {
12068 if ((ret
= wlu_iovar_get(wl
, cmd
->name
, &ra
, sizeof(ra
))) < 0)
12071 if (ra
.version
!= WL_RADAR_ARGS_VERSION
) {
12072 printf("\tIncorrect version of RADAR_ARGS struct: expected %d; got %d\n",
12073 WL_RADAR_ARGS_VERSION
, ra
.version
);
12076 printf("version %d npulses %d ncontig %d min_pw %d max_pw %d thresh0 0x%x "
12078 ra
.version
, ra
.npulses
, ra
.ncontig
, ra
.min_pw
,
12079 ra
.max_pw
, ra
.thresh0
, ra
.thresh1
);
12080 printf("blank 0x%x fmdemodcfg 0x%x npulses_lp %d min_pw_lp %d "
12082 ra
.blank
, ra
.fmdemodcfg
, ra
.npulses_lp
, ra
.min_pw_lp
,
12084 printf("min_fm_lp %d max_span_lp %d min_deltat %d max_deltat %d\n",
12085 ra
.min_fm_lp
, ra
.max_span_lp
, ra
.min_deltat
, ra
.max_deltat
);
12087 printf("autocorr 0x%x st_level_time 0x%x t2_min %d fra_pulse_err %d\n",
12088 ra
.autocorr
, ra
.st_level_time
, ra
.t2_min
, ra
.fra_pulse_err
);
12089 printf("npulses_fra %d npulses_stg2 %d npulses_stg3 %d percal_mask 0x%x quant %d\n",
12090 ra
.npulses_fra
, ra
.npulses_stg2
, ra
.npulses_stg3
, ra
.percal_mask
,
12092 printf("min_burst_intv_lp %d max_burst_intv_lp %d nskip_rst_lp %d max_pw_tol %d "
12093 "feature_mask 0x%x\n",
12094 ra
.min_burst_intv_lp
, ra
.max_burst_intv_lp
, ra
.nskip_rst_lp
,
12095 ra
.max_pw_tol
, ra
.feature_mask
);
12098 char *endptr
= NULL
;
12099 int val_count
= 30;
12104 for (i
= 0; i
< val_count
; i
++, argv
++) {
12105 /* verify that there is another arg */
12109 vals
[i
] = strtol(*argv
, &endptr
, 0);
12111 /* make sure all the value string was parsed by strtol */
12112 if (*endptr
!= '\0')
12118 ra
.version
= *pval
++;
12119 ra
.npulses
= *pval
++;
12120 ra
.ncontig
= *pval
++;
12121 ra
.min_pw
= *pval
++;
12122 ra
.max_pw
= *pval
++;
12123 ra
.thresh0
= (uint16
)*pval
++;
12124 ra
.thresh1
= (uint16
)*pval
++;
12125 ra
.blank
= (uint16
)*pval
++;
12126 ra
.fmdemodcfg
= (uint16
)*pval
++;
12127 ra
.npulses_lp
= *pval
++;
12128 ra
.min_pw_lp
= *pval
++;
12129 ra
.max_pw_lp
= *pval
++;
12130 ra
.min_fm_lp
= *pval
++;
12131 ra
.max_span_lp
= *pval
++;
12132 ra
.min_deltat
= *pval
++;
12133 ra
.max_deltat
= *pval
++;
12134 ra
.autocorr
= (uint16
)*pval
++;
12135 ra
.st_level_time
= (uint16
)*pval
++;
12136 ra
.t2_min
= (uint16
)*pval
++;
12137 ra
.fra_pulse_err
= (uint32
)*pval
++;
12138 ra
.npulses_fra
= (int)*pval
++;
12139 ra
.npulses_stg2
= (int)*pval
++;
12140 ra
.npulses_stg3
= (int)*pval
++;
12141 ra
.percal_mask
= (int)*pval
++;
12142 ra
.quant
= (int)*pval
++;
12143 ra
.min_burst_intv_lp
= (uint32
)*pval
++;
12144 ra
.max_burst_intv_lp
= (uint32
)*pval
++;
12145 ra
.nskip_rst_lp
= (int)*pval
++;
12146 ra
.max_pw_tol
= (int)*pval
++;
12147 ra
.feature_mask
= (uint16
)*pval
++;
12149 return wlu_var_setbuf(wl
, cmd
->name
, &ra
, sizeof(wl_radar_args_t
));
12155 wl_radar_thrs(void *wl
, cmd_t
*cmd
, char **argv
)
12158 wl_radar_thr_t radar_thrs
;
12168 for (i
= 0; i
< val_count
; i
++, argv
++) {
12169 /* verify that there is another arg */
12173 vals
[i
] = (uint16
)strtol(*argv
, &endptr
, 0);
12175 /* make sure all the value string was parsed by strtol */
12176 if (*endptr
!= '\0')
12180 radar_thrs
.version
= WL_RADAR_THR_VERSION
;
12182 /* Order thresh0_20_lo, thresh1_20_lo, thresh0_40_lo, thresh1_40_lo
12183 * thresh0_20_hi, thresh1_20_hi, thresh0_40_hi, thresh1_40_hi
12186 radar_thrs
.thresh0_20_lo
= (uint16
)*pval
++;
12187 radar_thrs
.thresh1_20_lo
= (uint16
)*pval
++;
12188 radar_thrs
.thresh0_40_lo
= (uint16
)*pval
++;
12189 radar_thrs
.thresh1_40_lo
= (uint16
)*pval
++;
12190 radar_thrs
.thresh0_20_hi
= (uint16
)*pval
++;
12191 radar_thrs
.thresh1_20_hi
= (uint16
)*pval
++;
12192 radar_thrs
.thresh0_40_hi
= (uint16
)*pval
++;
12193 radar_thrs
.thresh1_40_hi
= (uint16
)*pval
++;
12195 return wlu_var_setbuf(wl
, cmd
->name
, &radar_thrs
, sizeof(wl_radar_thr_t
));
12201 wl_dfs_status(void *wl
, cmd_t
*cmd
, char **argv
)
12204 wl_dfs_status_t
*dfs_status_ptr
;
12206 const char *dfs_cacstate_str
[WL_DFS_CACSTATES
] = {
12208 "PRE-ISM Channel Availability Check(CAC)",
12209 "In-Service Monitoring(ISM)",
12210 "Channel Switching Announcement(CSA)",
12211 "POST-ISM Channel Availability Check",
12212 "PRE-ISM Ouf Of Channels(OOC)",
12213 "POST-ISM Out Of Channels(OOC)"
12218 UNUSED_PARAMETER(argv
);
12220 if ((ret
= wlu_var_getbuf(wl
, cmd
->name
, NULL
, 0, &ptr
)) < 0)
12223 dfs_status_ptr
= (wl_dfs_status_t
*)ptr
;
12225 dfs_status_ptr
->state
= dtoh32(dfs_status_ptr
->state
);
12226 dfs_status_ptr
->duration
= dtoh32(dfs_status_ptr
->duration
);
12227 dfs_status_ptr
->chanspec_cleared
= dtohchanspec(dfs_status_ptr
->chanspec_cleared
);
12229 if (dfs_status_ptr
->state
>= WL_DFS_CACSTATES
) {
12230 printf("Unknown dfs state %d.\n", dfs_status_ptr
->state
);
12234 printf("state %s time elapsed %dms radar channel cleared by dfs ",
12235 dfs_cacstate_str
[dfs_status_ptr
->state
], dfs_status_ptr
->duration
);
12237 if (dfs_status_ptr
->chanspec_cleared
) {
12238 printf("channel spec %d channel %d\n", dfs_status_ptr
->chanspec_cleared
,
12239 CHSPEC_CHANNEL(dfs_status_ptr
->chanspec_cleared
));
12249 wl_wds_wpa_role_old(void *wl
, cmd_t
*cmd
, char **argv
)
12252 uint
*sup
= remote
;
12254 UNUSED_PARAMETER(argv
);
12256 if (wlu_get(wl
, WLC_WDS_GET_REMOTE_HWADDR
, remote
, sizeof(remote
)) < 0) {
12257 printf("Unable to get remote endpoint's hwaddr\n");
12260 if (wlu_get(wl
, cmd
->get
, remote
, sizeof(remote
)) < 0) {
12261 printf("Unable to get local endpoint's WPA role\n");
12264 printf("Local endpoing's WPA role: %s\n", dtoh32(*sup
) ? "supplicant" : "authenticator");
12270 * wlu_reg2args is a generic function that is used for setting/getting
12271 * WL_IOVAR variables that require address for read, and
12272 * address + data for write.
12275 wlu_reg2args(void *wl
, cmd_t
*cmd
, char **argv
)
12285 len
= sizeof(int_val
);
12286 int_val
= htod32(strtoul(argv
[1], &endptr
, 0));
12287 memcpy(var
, (char *)&int_val
, sizeof(int_val
));
12294 int_val
= htod32(strtoul(argv
[2], &endptr
, 0));
12295 memcpy(&var
[len
], (char *)&int_val
, sizeof(int_val
));
12296 len
+= sizeof(int_val
);
12299 if (wlu_var_getbuf(wl
, cmd
->name
, var
, sizeof(var
), &ptr
) < 0)
12302 printf("0x%x\n", dtoh32(*(int *)ptr
));
12305 wlu_var_setbuf(wl
, cmd
->name
, &var
, sizeof(var
));
12310 * wlu_reg3args is a generic function that is used for setting/getting
12311 * WL_IOVAR variables that require address + offset for read, and
12312 * address + offset + data for write.
12315 wlu_reg3args(void *wl
, cmd_t
*cmd
, char **argv
)
12327 if (!argv
[1] || !argv
[2]) {
12328 printf("Wrong syntax => dev offset [val]\n");
12338 for (i
= 1; i
<= numargs
; i
++) {
12339 int_val
= htod32(strtoul(argv
[i
], &endptr
, 0));
12340 memcpy(&var
[len
], (char *)&int_val
, sizeof(int_val
));
12341 len
+= sizeof(int_val
);
12345 if (wlu_var_getbuf(wl
, cmd
->name
, var
, sizeof(var
), &ptr
) < 0)
12348 printf("0x%x\n", dtoh32(*(int *)ptr
));
12351 wlu_var_setbuf(wl
, cmd
->name
, &var
, sizeof(var
));
12356 wl_coma(void *wl
, cmd_t
*cmd
, char **argv
)
12368 printf("Wrong syntax => coma [reset-time] [delay]\n");
12374 } else if (!argv
[3]) {
12380 for (i
= 1; i
<= numargs
; i
++) {
12381 int_val
= htod32(strtoul(argv
[i
], &endptr
, 0));
12382 memcpy(&var
[len
], (char *)&int_val
, sizeof(int_val
));
12383 len
+= sizeof(int_val
);
12386 err
= wlu_var_setbuf(wl
, cmd
->name
, &var
, sizeof(var
));
12392 wl_tpc_lm(void *wl
, cmd_t
*cmd
, char **argv
)
12399 UNUSED_PARAMETER(argv
);
12401 if ((ret
= wlu_iovar_getint(wl
, cmd
->name
, (&v
))) < 0)
12405 stalm
= val
& 0xff;
12406 aplm
= (val
>> 8) & 0xff;
12408 printf("TPC: APs link margin:%d\t STAs link margin:%d\n", aplm
, stalm
);
12415 wl_wds_wpa_role(void *wl
, cmd_t
*cmd
, char **argv
)
12421 if (strlen("wds_wpa_role") + 1 + ETHER_ADDR_LEN
+ 1 > sizeof(var
))
12423 /* build var required by WLC_GET|SET_VAR */
12424 len
= sprintf(var
, "%s", "wds_wpa_role") + 1;
12426 if (wlu_get(wl
, WLC_WDS_GET_REMOTE_HWADDR
, mac
, ETHER_ADDR_LEN
) < 0) {
12427 printf("Unable to get remote endpoint's hwaddr\n");
12430 len
+= ETHER_ADDR_LEN
+ 1;
12432 sup
= mac
+ ETHER_ADDR_LEN
;
12433 switch ((uchar
)(*sup
= atoi(argv
[1]))) {
12434 case WL_WDS_WPA_ROLE_AUTH
:
12435 case WL_WDS_WPA_ROLE_SUP
:
12436 case WL_WDS_WPA_ROLE_AUTO
:
12437 if (wlu_set(wl
, cmd
->set
, var
, len
) < 0)
12438 printf("Unable to set local endpoint's WPA role\n");
12441 printf("Invalid WPA role %s. %u:authenticator, %u:supplicant, %u:auto\n",
12442 argv
[1], WL_WDS_WPA_ROLE_AUTH
,
12443 WL_WDS_WPA_ROLE_SUP
, WL_WDS_WPA_ROLE_AUTO
);
12447 else if (wlu_get(wl
, cmd
->get
, var
, len
) < 0) {
12448 printf("Unable to get local endpoint's WPA role\n");
12453 printf("Local endpoint's WPA role: %s\n", *sup
? "supplicant" : "authenticator");
12459 wl_measure_req(void *wl
, cmd_t
*cmd
, char **argv
)
12462 struct ether_addr ea
;
12465 printf("error: missing arguments\n");
12469 if (!stricmp(*argv
, "tpc"))
12470 val
= WLC_MEASURE_TPC
;
12471 else if (!stricmp(*argv
, "basic"))
12472 val
= WLC_MEASURE_CHANNEL_BASIC
;
12473 else if (!stricmp(*argv
, "cca"))
12474 val
= WLC_MEASURE_CHANNEL_CCA
;
12475 else if (!stricmp(*argv
, "rpi"))
12476 val
= WLC_MEASURE_CHANNEL_RPI
;
12478 printf("error: unknown measurement type %s\n", *argv
);
12484 printf("error: missing target address\n");
12488 if (!wl_ether_atoe(*argv
, &ea
)) {
12489 printf("error: could not parse MAC address %s\n", *argv
);
12494 memcpy(&buf
[0], &val
, sizeof(uint32
));
12495 memcpy(&buf
[4], ea
.octet
, ETHER_ADDR_LEN
);
12497 return wlu_set(wl
, cmd
->set
, buf
, sizeof(uint32
) + ETHER_ADDR_LEN
);
12501 wl_send_quiet(void *wl
, cmd_t
*cmd
, char **argv
)
12503 dot11_quiet_t quiet
;
12506 printf("error: missing arguments\n");
12509 /* Order is count, duration, offset */
12510 quiet
.count
= atoi(*argv
);
12512 printf("error: missing arguments\n");
12515 quiet
.duration
= atoi(*argv
);
12517 printf("error: missing arguments\n");
12520 quiet
.offset
= atoi(*argv
);
12523 quiet
.duration
= htod16(quiet
.duration
);
12524 quiet
.offset
= htod16(quiet
.offset
);
12525 return (wlu_set(wl
, cmd
->set
, &quiet
, sizeof(quiet
)));
12529 wl_send_csa(void *wl
, cmd_t
*cmd
, char **argv
)
12532 wl_chan_switch_t csa_arg
;
12534 /* Order is mode, count channel */
12536 printf("error: missing arguments\n");
12539 csa_arg
.mode
= atoi(*argv
) ? 1 : 0;
12541 printf("error: missing count\n");
12544 csa_arg
.count
= atoi(*argv
);
12546 printf("error: missing channel\n");
12550 if ((csa_arg
.chspec
= wf_chspec_aton(*argv
))) {
12551 csa_arg
.chspec
= htodchanspec(csa_arg
.chspec
);
12552 err
= wlu_var_setbuf(wl
, cmd
->name
, &csa_arg
, sizeof(csa_arg
));
12554 printf("Error: bad parameters \"%s\"\n", *argv
);
12562 wl_var_setint(void *wl
, cmd_t
*cmd
, char **argv
)
12566 char *endptr
= NULL
;
12568 UNUSED_PARAMETER(cmd
);
12571 printf("set: missing arguments\n");
12578 printf("set: missing value argument for set of \"%s\"\n", varname
);
12582 val
= strtol(*argv
, &endptr
, 0);
12583 if (*endptr
!= '\0') {
12584 /* not all the value string was parsed by strtol */
12585 printf("set: error parsing value \"%s\" as an integer for set of \"%s\"\n",
12590 return wlu_iovar_setint(wl
, varname
, val
);
12594 wl_var_get(void *wl
, cmd_t
*cmd
, char **argv
)
12599 UNUSED_PARAMETER(cmd
);
12602 printf("get: missing arguments\n");
12609 printf("get: error, extra arg \"%s\"\n", *argv
);
12613 strcpy(buf
, varname
);
12615 while (*p
!= '\0') {
12616 *p
= tolower((int)*p
);
12619 return (wlu_get(wl
, WLC_GET_VAR
, &buf
[0], WLC_IOCTL_MAXLEN
));
12623 wl_var_getinthex(void *wl
, cmd_t
*cmd
, char **argv
)
12628 if ((err
= wl_var_get(wl
, cmd
, argv
)))
12631 val
= dtoh32(*(int32
*)buf
);
12633 printf("0x%08x\n", val
);
12639 wl_var_getint(void *wl
, cmd_t
*cmd
, char **argv
)
12644 if ((err
= wl_var_get(wl
, cmd
, argv
)))
12647 val
= dtoh32(*(int32
*)buf
);
12650 printf("%d\n", val
);
12652 printf("%d (0x%x)\n", val
, val
);
12658 wl_var_getandprintstr(void *wl
, cmd_t
*cmd
, char **argv
)
12662 if ((err
= wl_var_get(wl
, cmd
, argv
)))
12665 printf("%s\n", buf
);
12669 /* Variation: Like getandprint, but allow an int arg to be passed */
12671 wl_var_setintandprintstr(void *wl
, cmd_t
*cmd
, char **argv
)
12676 char *endptr
= NULL
;
12678 UNUSED_PARAMETER(cmd
);
12681 printf("set: missing arguments\n");
12690 val
= strtol(*argv
, &endptr
, 0);
12691 if (*endptr
!= '\0') {
12692 /* not all the value string was parsed by strtol */
12693 printf("set: error parsing value \"%s\" as an integer for set of \"%s\"\n",
12700 err
= wlu_iovar_getbuf(wl
, varname
, &val
, sizeof(int), buf
, WLC_IOCTL_MAXLEN
);
12705 printf("%s\n", buf
);
12710 wl_printlasterror(void *wl
)
12712 char error_str
[128];
12714 if (wlu_iovar_get(wl
, "bcmerrorstr", error_str
, sizeof(error_str
)) != 0) {
12715 fprintf(stderr
, "%s: \nError getting the last error\n", wlu_av0
);
12717 fprintf(stderr
, "%s: %s\n", wlu_av0
, error_str
);
12721 /* just issue a wl_var_setint() or a wl_var_getint() if there is a 2nd arg */
12723 wl_varint(void *wl
, cmd_t
*cmd
, char *argv
[])
12726 return (wl_var_setint(wl
, cmd
, argv
));
12728 return (wl_var_getint(wl
, cmd
, argv
));
12732 wlu_var_getbuf(void *wl
, const char *iovar
, void *param
, int param_len
, void **bufptr
)
12736 memset(buf
, 0, WLC_IOCTL_MAXLEN
);
12737 strcpy(buf
, iovar
);
12739 /* include the null */
12740 len
= strlen(iovar
) + 1;
12743 memcpy(&buf
[len
], param
, param_len
);
12747 return wlu_get(wl
, WLC_GET_VAR
, &buf
[0], WLC_IOCTL_MAXLEN
);
12750 /* get buffer for smaller sizes upto 256 bytes */
12752 wlu_var_getbuf_sm(void *wl
, const char *iovar
, void *param
, int param_len
, void **bufptr
)
12756 memset(buf
, 0, WLC_IOCTL_SMLEN
);
12757 strcpy(buf
, iovar
);
12759 /* include the null */
12760 len
= strlen(iovar
) + 1;
12763 memcpy(&buf
[len
], param
, param_len
);
12767 return wlu_get(wl
, WLC_GET_VAR
, &buf
[0], WLC_IOCTL_SMLEN
);
12770 /* Get buffer for medium sizes upto 1500 bytes */
12772 wlu_var_getbuf_med(void *wl
, const char *iovar
, void *param
, int param_len
, void **bufptr
)
12776 memset(buf
, 0, WLC_IOCTL_MEDLEN
);
12777 strcpy(buf
, iovar
);
12779 /* include the null */
12780 len
= strlen(iovar
) + 1;
12783 memcpy(&buf
[len
], param
, param_len
);
12787 return wlu_get(wl
, WLC_GET_VAR
, &buf
[0], WLC_IOCTL_MEDLEN
);
12792 wlu_var_setbuf(void *wl
, const char *iovar
, void *param
, int param_len
)
12796 memset(buf
, 0, WLC_IOCTL_MAXLEN
);
12797 strcpy(buf
, iovar
);
12799 /* include the null */
12800 len
= strlen(iovar
) + 1;
12803 memcpy(&buf
[len
], param
, param_len
);
12807 return wlu_set(wl
, WLC_SET_VAR
, &buf
[0], len
);
12811 wl_var_void(void *wl
, cmd_t
*cmd
, char **argv
)
12813 UNUSED_PARAMETER(argv
);
12818 return wlu_var_setbuf(wl
, cmd
->name
, NULL
, 0);
12822 * format an iovar buffer
12823 * iovar name is converted to lower case
12826 wl_iovar_mkbuf(const char *name
, char *data
, uint datalen
, char *iovar_buf
, uint buflen
, int *perr
)
12831 iovar_len
= strlen(name
) + 1;
12833 /* check for overflow */
12834 if ((iovar_len
+ datalen
) > buflen
) {
12835 *perr
= BCME_BUFTOOSHORT
;
12839 /* copy data to the buffer past the end of the iovar name string */
12841 memmove(&iovar_buf
[iovar_len
], data
, datalen
);
12843 /* copy the name to the beginning of the buffer */
12844 strcpy(iovar_buf
, name
);
12846 /* wl command line automatically converts iovar names to lower case for
12850 while (*p
!= '\0') {
12851 *p
= tolower((int)*p
);
12856 return (iovar_len
+ datalen
);
12861 * get named iovar providing both parameter and i/o buffers
12862 * iovar name is converted to lower case
12865 wlu_iovar_getbuf(void* wl
, const char *iovar
,
12866 void *param
, int paramlen
, void *bufptr
, int buflen
)
12870 wl_iovar_mkbuf(iovar
, param
, paramlen
, bufptr
, buflen
, &err
);
12874 return wlu_get(wl
, WLC_GET_VAR
, bufptr
, buflen
);
12878 * set named iovar providing both parameter and i/o buffers
12879 * iovar name is converted to lower case
12882 wlu_iovar_setbuf(void* wl
, const char *iovar
,
12883 void *param
, int paramlen
, void *bufptr
, int buflen
)
12888 iolen
= wl_iovar_mkbuf(iovar
, param
, paramlen
, bufptr
, buflen
, &err
);
12892 return wlu_set(wl
, WLC_SET_VAR
, bufptr
, iolen
);
12896 * get named iovar without parameters into a given buffer
12897 * iovar name is converted to lower case
12900 wlu_iovar_get(void *wl
, const char *iovar
, void *outbuf
, int len
)
12902 char smbuf
[WLC_IOCTL_SMLEN
];
12905 /* use the return buffer if it is bigger than what we have on the stack */
12906 if (len
> (int)sizeof(smbuf
)) {
12907 err
= wlu_iovar_getbuf(wl
, iovar
, NULL
, 0, outbuf
, len
);
12909 memset(smbuf
, 0, sizeof(smbuf
));
12910 err
= wlu_iovar_getbuf(wl
, iovar
, NULL
, 0, smbuf
, sizeof(smbuf
));
12912 memcpy(outbuf
, smbuf
, len
);
12919 * set named iovar given the parameter buffer
12920 * iovar name is converted to lower case
12923 wlu_iovar_set(void *wl
, const char *iovar
, void *param
, int paramlen
)
12925 char smbuf
[WLC_IOCTL_SMLEN
*2];
12927 memset(smbuf
, 0, sizeof(smbuf
));
12929 return wlu_iovar_setbuf(wl
, iovar
, param
, paramlen
, smbuf
, sizeof(smbuf
));
12933 * get named iovar as an integer value
12934 * iovar name is converted to lower case
12937 wlu_iovar_getint(void *wl
, const char *iovar
, int *pval
)
12941 ret
= wlu_iovar_get(wl
, iovar
, pval
, sizeof(int));
12944 *pval
= dtoh32(*pval
);
12950 * set named iovar given an integer parameter
12951 * iovar name is converted to lower case
12954 wlu_iovar_setint(void *wl
, const char *iovar
, int val
)
12957 return wlu_iovar_set(wl
, iovar
, &val
, sizeof(int));
12961 * format a bsscfg indexed iovar buffer
12964 wl_bssiovar_mkbuf(const char *iovar
, int bssidx
, void *param
,
12965 int paramlen
, void *bufptr
, int buflen
, int *perr
)
12967 const char *prefix
= "bsscfg:";
12973 prefixlen
= strlen(prefix
); /* length of bsscfg prefix */
12974 namelen
= strlen(iovar
) + 1; /* length of iovar name + null */
12975 iolen
= prefixlen
+ namelen
+ sizeof(int) + paramlen
;
12977 /* check for overflow */
12978 if (buflen
< 0 || iolen
> (uint
)buflen
) {
12979 *perr
= BCME_BUFTOOSHORT
;
12985 /* copy prefix, no null */
12986 memcpy(p
, prefix
, prefixlen
);
12989 /* copy iovar name including null */
12990 memcpy(p
, iovar
, namelen
);
12993 /* bss config index as first param */
12994 bssidx
= htod32(bssidx
);
12995 memcpy(p
, &bssidx
, sizeof(int32
));
12996 p
+= sizeof(int32
);
12998 /* parameter buffer follows */
13000 memcpy(p
, param
, paramlen
);
13007 * set named & bss indexed driver iovar providing both parameter and i/o buffers
13010 wl_bssiovar_setbuf(void* wl
, const char *iovar
, int bssidx
,
13011 void *param
, int paramlen
, void *bufptr
, int buflen
)
13016 iolen
= wl_bssiovar_mkbuf(iovar
, bssidx
, param
, paramlen
, bufptr
, buflen
, &err
);
13020 return wlu_set(wl
, WLC_SET_VAR
, bufptr
, iolen
);
13024 * get named & bss indexed driver iovar providing both parameter and i/o buffers
13027 wl_bssiovar_getbuf(void* wl
, const char *iovar
, int bssidx
,
13028 void *param
, int paramlen
, void *bufptr
, int buflen
)
13032 wl_bssiovar_mkbuf(iovar
, bssidx
, param
, paramlen
, bufptr
, buflen
, &err
);
13036 return wlu_get(wl
, WLC_GET_VAR
, bufptr
, buflen
);
13040 * get named & bss indexed driver variable to buffer value
13043 wl_bssiovar_get(void *wl
, const char *iovar
, int bssidx
, void *outbuf
, int len
)
13045 char smbuf
[WLC_IOCTL_SMLEN
];
13048 /* use the return buffer if it is bigger than what we have on the stack */
13049 if (len
> (int)sizeof(smbuf
)) {
13050 err
= wl_bssiovar_getbuf(wl
, iovar
, bssidx
, NULL
, 0, outbuf
, len
);
13052 memset(smbuf
, 0, sizeof(smbuf
));
13053 err
= wl_bssiovar_getbuf(wl
, iovar
, bssidx
, NULL
, 0, smbuf
, sizeof(smbuf
));
13055 memcpy(outbuf
, smbuf
, len
);
13062 * set named & bss indexed driver variable to buffer value
13065 wl_bssiovar_set(void *wl
, const char *iovar
, int bssidx
, void *param
, int paramlen
)
13067 char smbuf
[WLC_IOCTL_SMLEN
];
13069 memset(smbuf
, 0, sizeof(smbuf
));
13071 return wl_bssiovar_setbuf(wl
, iovar
, bssidx
, param
, paramlen
, smbuf
, sizeof(smbuf
));
13075 * get named & bsscfg indexed driver variable as an int value
13078 wl_bssiovar_getint(void *wl
, const char *iovar
, int bssidx
, int *pval
)
13082 ret
= wl_bssiovar_get(wl
, iovar
, bssidx
, pval
, sizeof(int));
13085 *pval
= dtoh32(*pval
);
13091 * set named & bsscfg indexed driver variable to int value
13094 wl_bssiovar_setint(void *wl
, const char *iovar
, int bssidx
, int val
)
13097 return wl_bssiovar_set(wl
, iovar
, bssidx
, &val
, sizeof(int));
13101 wl_nvdump(void *wl
, cmd_t
*cmd
, char **argv
)
13104 const char *iovar
= "nvram_dump";
13107 UNUSED_PARAMETER(cmd
);
13109 /* skip the "nvdump/nvram_dump" command name */
13113 printf("nvdump error: extra arg \"%s\"\n", *argv
);
13117 if ((err
= wlu_var_getbuf(wl
, iovar
, NULL
, 0, &p
)) < 0) {
13118 if ((err
= wlu_get(wl
, WLC_NVRAM_DUMP
, &buf
[0], WLC_IOCTL_MAXLEN
)))
13122 printf("%s\n", (char *)p
);
13128 wl_nvget(void *wl
, cmd_t
*cmd
, char **argv
)
13132 const char *iovar
= "nvram_get";
13135 UNUSED_PARAMETER(cmd
);
13137 /* skip the "nvget/nvram_get" command name */
13141 printf("nvget: missing arguments\n");
13148 printf("nvget error: extra arg \"%s\"\n", *argv
);
13152 if ((err
= wlu_var_getbuf(wl
, iovar
, varname
, strlen(varname
) + 1, &p
)) < 0) {
13154 strcpy(buf
, varname
);
13155 if ((err
= wlu_get(wl
, WLC_NVRAM_GET
, &buf
[0], WLC_IOCTL_MAXLEN
)))
13159 printf("%s\n", buf
);
13165 wl_nvset(void *wl
, cmd_t
*cmd
, char **argv
)
13169 UNUSED_PARAMETER(cmd
);
13171 /* skip the "nvset" command name if present */
13172 if (!strcmp("nvset", *argv
))
13176 printf("nvset: missing arguments\n");
13184 "nvset error: extra arg \"%s\"; format is name=value (no spaces around '=')\n",
13189 if (!strchr(varname
, '=')) {
13191 "nvset error: no '=' in \"%s\", format is name=value (no spaces around '=')\n",
13196 strcpy(buf
, varname
);
13198 return (wlu_set(wl
, WLC_NVRAM_SET
, &buf
[0], strlen(buf
) + 1));
13202 wl_chan_info(void *wl
, cmd_t
*cmd
, char **argv
)
13206 int buflen
, err
, first
, last
, minutes
;
13215 last
= first
= atoi(*argv
);
13217 printf(" Usage: %s [channel | All ]\n", cmd
->name
);
13223 for (; first
<= last
; first
++) {
13224 channel
= first
& WL_CHANSPEC_CHAN_MASK
;
13226 channel
|= WL_CHANSPEC_BAND_2G
;
13228 channel
|= WL_CHANSPEC_BAND_5G
;
13230 strcpy(buf
, "per_chan_info");
13231 buflen
= strlen(buf
) + 1;
13232 param
= (char *)(buf
+ buflen
);
13233 channel
= htod32(channel
);
13234 memcpy(param
, (char*)&channel
, sizeof(channel
));
13236 if ((err
= wlu_get(wl
, cmd
->get
, buf
, WLC_IOCTL_MAXLEN
)))
13239 channel
= dtoh32(channel
);
13240 bitmap
= dtoh32(*(uint
*)buf
);
13241 minutes
= (bitmap
>> 24) & 0xff;
13243 if (!(bitmap
& WL_CHAN_VALID_HW
)) {
13245 printf("Invalid Channel\n");
13249 if (!(bitmap
& WL_CHAN_VALID_SW
)) {
13251 printf("Not supported in current locale\n");
13255 printf("Channel %d\t", channel
& WL_CHANSPEC_CHAN_MASK
);
13257 if (bitmap
& WL_CHAN_BAND_5G
)
13262 if (bitmap
& WL_CHAN_RADAR
) {
13263 printf(", RADAR Sensitive");
13265 if (bitmap
& WL_CHAN_RESTRICTED
) {
13266 printf(", Restricted");
13268 if (bitmap
& WL_CHAN_PASSIVE
) {
13269 printf(", Passive");
13271 if (bitmap
& WL_CHAN_INACTIVE
) {
13272 printf(", Temporarily Out of Service for %d minutes", minutes
);
13281 wl_test_tssi(void *wl
, cmd_t
*cmd
, char **argv
)
13285 char* endptr
= NULL
;
13287 /* toss the command name */
13293 val
= htod32(strtol(*argv
, &endptr
, 0));
13294 if (*endptr
!= '\0') {
13295 /* not all the value string was parsed by strtol */
13296 printf("set: error parsing value \"%s\" as an integer\n", *argv
);
13300 ret
= wlu_iovar_getbuf(wl
, cmd
->name
, &val
, sizeof(val
),
13301 buf
, WLC_IOCTL_MAXLEN
);
13306 val
= dtoh32(*(int*)buf
);
13314 wl_test_tssi_offs(void *wl
, cmd_t
*cmd
, char **argv
)
13318 char* endptr
= NULL
;
13320 /* toss the command name */
13326 val
= htod32(strtol(*argv
, &endptr
, 0));
13327 if (*endptr
!= '\0') {
13328 /* not all the value string was parsed by strtol */
13329 printf("set: error parsing value \"%s\" as an integer\n", *argv
);
13333 ret
= wlu_iovar_getbuf(wl
, cmd
->name
, &val
, sizeof(val
),
13334 buf
, WLC_IOCTL_MAXLEN
);
13339 val
= dtoh32(*(int*)buf
);
13347 wl_sta_info(void *wl
, cmd_t
*cmd
, char **argv
)
13350 struct ether_addr ea
;
13354 /* convert the ea string into an ea struct */
13355 if (!*++argv
|| !wl_ether_atoe(*argv
, &ea
)) {
13356 printf(" ERROR: no valid ether addr provided\n");
13360 strcpy(buf
, "sta_info");
13361 buflen
= strlen(buf
) + 1;
13362 param
= (char *)(buf
+ buflen
);
13363 memcpy(param
, (char*)&ea
, ETHER_ADDR_LEN
);
13365 if ((err
= wlu_get(wl
, cmd
->get
, buf
, WLC_IOCTL_MEDLEN
)))
13368 /* display the sta info */
13369 sta
= (sta_info_t
*)buf
;
13370 sta
->ver
= dtoh16(sta
->ver
);
13372 /* Report unrecognized version */
13373 if (sta
->ver
> WL_STA_VER
) {
13374 printf(" ERROR: unknown driver station info version %d\n", sta
->ver
);
13378 sta
->len
= dtoh16(sta
->len
);
13379 sta
->cap
= dtoh16(sta
->cap
);
13380 sta
->flags
= dtoh32(sta
->flags
);
13381 sta
->idle
= dtoh32(sta
->idle
);
13382 sta
->rateset
.count
= dtoh32(sta
->rateset
.count
);
13383 sta
->in
= dtoh32(sta
->in
);
13384 sta
->listen_interval_inms
= dtoh32(sta
->listen_interval_inms
);
13386 printf(" STA %s:\n", *argv
);
13387 printf("\t rateset ");
13388 dump_rateset(sta
->rateset
.rates
, sta
->rateset
.count
);
13389 printf("\n\t idle %d seconds\n", sta
->idle
);
13390 printf("\t in network %d seconds\n", sta
->in
);
13391 printf("\t state:%s%s%s\n",
13392 (sta
->flags
& WL_STA_AUTHE
) ? " AUTHENTICATED" : "",
13393 (sta
->flags
& WL_STA_ASSOC
) ? " ASSOCIATED" : "",
13394 (sta
->flags
& WL_STA_AUTHO
) ? " AUTHORIZED" : "");
13396 printf("\t flags 0x%x:%s%s%s%s%s%s%s%s%s\n",
13398 (sta
->flags
& WL_STA_BRCM
) ? " BRCM" : "",
13399 (sta
->flags
& WL_STA_ABCAP
) ? " ABCAP" : "",
13400 (sta
->flags
& WL_STA_WME
) ? " WME" : "",
13401 (sta
->flags
& WL_STA_PS
) ? " PS" : "",
13402 (sta
->flags
& WL_STA_APSD_BE
) ? " APSD_BE" : "",
13403 (sta
->flags
& WL_STA_APSD_BK
) ? " APSD_BK" : "",
13404 (sta
->flags
& WL_STA_APSD_VI
) ? " APSD_VI" : "",
13405 (sta
->flags
& WL_STA_APSD_VO
) ? " APSD_VO" : "",
13406 (sta
->flags
& WL_STA_N_CAP
) ? " N_CAP" : "");
13408 /* Driver didn't return extended station info */
13409 if (sta
->len
< sizeof(sta_info_t
))
13412 if (sta
->flags
& WL_STA_SCBSTATS
)
13414 printf("\t tx pkts: %d\n", dtoh32(sta
->tx_pkts
));
13415 printf("\t tx failures: %d\n", dtoh32(sta
->tx_failures
));
13416 printf("\t rx ucast pkts: %d\n", dtoh32(sta
->rx_ucast_pkts
));
13417 printf("\t rx mcast/bcast pkts: %d\n", dtoh32(sta
->rx_mcast_pkts
));
13418 printf("\t rate of last tx pkt: %d kbps\n", dtoh32(sta
->tx_rate
));
13419 printf("\t rate of last rx pkt: %d kbps\n", dtoh32(sta
->rx_rate
));
13420 printf("\t rx decrypt succeeds: %d\n", dtoh32(sta
->rx_decrypt_succeeds
));
13421 printf("\t rx decrypt failures: %d\n", dtoh32(sta
->rx_decrypt_failures
));
13428 wl_revinfo(void *wl
, cmd_t
*cmd
, char **argv
)
13432 wlc_rev_info_t revinfo
;
13434 UNUSED_PARAMETER(cmd
);
13435 UNUSED_PARAMETER(argv
);
13437 memset(&revinfo
, 0, sizeof(revinfo
));
13439 err
= wlu_get(wl
, WLC_GET_REVINFO
, &revinfo
, sizeof(revinfo
));
13444 printf("vendorid 0x%x\n", dtoh32(revinfo
.vendorid
));
13445 printf("deviceid 0x%x\n", dtoh32(revinfo
.deviceid
));
13446 printf("radiorev 0x%x\n", dtoh32(revinfo
.radiorev
));
13447 printf("chipnum 0x%x\n", dtoh32(revinfo
.chipnum
));
13448 printf("chiprev 0x%x\n", dtoh32(revinfo
.chiprev
));
13449 printf("chippackage 0x%x\n", dtoh32(revinfo
.chippkg
));
13450 printf("corerev 0x%x\n", dtoh32(revinfo
.corerev
));
13451 printf("boardid 0x%x\n", dtoh32(revinfo
.boardid
));
13452 printf("boardvendor 0x%x\n", dtoh32(revinfo
.boardvendor
));
13453 printf("boardrev %s\n", bcm_brev_str(dtoh32(revinfo
.boardrev
), b
));
13454 printf("driverrev 0x%x\n", dtoh32(revinfo
.driverrev
));
13455 printf("ucoderev 0x%x\n", dtoh32(revinfo
.ucoderev
));
13456 printf("bus 0x%x\n", dtoh32(revinfo
.bus
));
13457 printf("phytype 0x%x\n", dtoh32(revinfo
.phytype
));
13458 printf("phyrev 0x%x\n", dtoh32(revinfo
.phyrev
));
13459 printf("anarev 0x%x\n", dtoh32(revinfo
.anarev
));
13465 wl_rm_request(void *wl
, cmd_t
*cmd
, char **argv
)
13468 const char* fn_name
= "wl_rm_request";
13469 wl_rm_req_t
*rm_ptr
;
13471 wl_rm_req_elt_t req
;
13475 bool in_measure
= FALSE
;
13477 UNUSED_PARAMETER(cmd
);
13479 memset(buf
, 0, WLC_IOCTL_MAXLEN
);
13480 memset(&rm
, 0, WL_RM_REQ_FIXED_LEN
);
13481 memset(&req
, 0, sizeof(wl_rm_req_elt_t
));
13483 strcpy(buf
, "rm_req");
13484 buflen
= strlen(buf
) + 1;
13486 rm_ptr
= (wl_rm_req_t
*)(buf
+ buflen
);
13487 buflen
+= WL_RM_REQ_FIXED_LEN
;
13489 /* toss the command name */
13492 miniopt_init(&to
, fn_name
, "p", FALSE
);
13493 while ((opt_err
= miniopt(&to
, argv
)) != -1) {
13494 if (opt_err
== 1) {
13498 argv
+= to
.consumed
;
13500 if (to
.opt
== 't') {
13501 if (!to
.good_int
) {
13503 "%s: could not parse \"%s\" as an int for the token\n",
13504 fn_name
, to
.valstr
);
13512 req
.token
= to
.val
;
13514 if (to
.opt
== 'c') {
13515 if (!to
.good_int
) {
13517 "%s: could not parse \"%s\" as an int for channel\n",
13518 fn_name
, to
.valstr
);
13523 req
.chanspec
= to
.val
& WL_CHANSPEC_CHAN_MASK
;
13524 req
.chanspec
|= WL_CHANSPEC_BW_20
| WL_CHANSPEC_CTL_SB_NONE
;
13525 req
.chanspec
|= ((to
.val
<= 14) ? WL_CHANSPEC_BAND_2G
:
13526 WL_CHANSPEC_BAND_5G
);
13528 if (to
.opt
== 'd') {
13529 if (!to
.good_int
) {
13531 "%s: could not parse \"%s\" as an int for duration\n",
13532 fn_name
, to
.valstr
);
13539 if (to
.opt
== 'p') {
13540 req
.flags
= WL_RM_FLAG_PARALLEL
;
13543 if (to
.positional
) {
13544 if (!strcmp(to
.valstr
, "basic")) {
13545 type
= WL_RM_TYPE_BASIC
;
13546 } else if (!strcmp(to
.valstr
, "cca")) {
13547 type
= WL_RM_TYPE_CCA
;
13548 } else if (!strcmp(to
.valstr
, "rpi")) {
13549 type
= WL_RM_TYPE_RPI
;
13552 "%s: could not parse \"%s\" as a measurement type\n",
13553 fn_name
, to
.valstr
);
13557 /* complete the previous measurement */
13559 req
.chanspec
= htodchanspec(req
.chanspec
);
13560 req
.token
= htod32(req
.token
);
13561 req
.tsf_h
= htod32(req
.tsf_h
);
13562 req
.tsf_l
= htod32(req
.tsf_l
);
13563 req
.dur
= htod32(req
.dur
);
13564 memcpy(buf
+ buflen
, &req
, sizeof(wl_rm_req_elt_t
));
13565 buflen
+= sizeof(wl_rm_req_elt_t
);
13567 req
.chanspec
= dtohchanspec(req
.chanspec
);
13568 req
.token
= dtoh32(req
.token
);
13569 req
.tsf_h
= dtoh32(req
.tsf_h
);
13570 req
.tsf_l
= dtoh32(req
.tsf_l
);
13571 req
.dur
= dtoh32(req
.dur
);
13572 /* measure to measure default param update */
13573 req
.token
++; /* each measure gets a new token */
13574 req
.flags
= 0; /* measure flags are cleared between measures */
13577 req
.type
= (int8
)type
;
13581 /* complete the last measurement */
13583 req
.chanspec
= htodchanspec(req
.chanspec
);
13584 req
.token
= htod32(req
.token
);
13585 req
.tsf_h
= htod32(req
.tsf_h
);
13586 req
.tsf_l
= htod32(req
.tsf_l
);
13587 req
.dur
= htod32(req
.dur
);
13588 memcpy(buf
+ buflen
, &req
, sizeof(wl_rm_req_elt_t
));
13589 buflen
+= sizeof(wl_rm_req_elt_t
);
13593 if (rm
.count
== 0) {
13594 fprintf(stderr
, "%s: no measurement requests specified\n",
13600 rm
.token
= htod32(rm
.token
);
13601 rm
.count
= htod32(rm
.count
);
13602 memcpy(rm_ptr
, &rm
, WL_RM_REQ_FIXED_LEN
);
13604 err
= wlu_set(wl
, WLC_SET_VAR
, &buf
[0], buflen
);
13611 wl_rm_report(void *wl
, cmd_t
*cmd
, char **argv
)
13613 wl_rm_rep_t
*rep_set
;
13614 wl_rm_rep_elt_t rep
;
13625 UNUSED_PARAMETER(cmd
);
13626 UNUSED_PARAMETER(argv
);
13628 strcpy(buf
, "rm_rep");
13630 err
= wlu_get(wl
, WLC_GET_VAR
, &buf
[0], WLC_IOCTL_MAXLEN
);
13635 rep_set
= (wl_rm_rep_t
*)buf
;
13636 rep_set
->token
= dtoh32(rep_set
->token
);
13637 rep_set
->len
= dtoh32(rep_set
->len
);
13639 printf("Measurement Report: token %d, length %d\n", rep_set
->token
, rep_set
->len
);
13641 len
= rep_set
->len
;
13642 data
= (uint8
*)rep_set
->rep
;
13643 for (; len
> 0; (len
-= rep
.len
), (data
+= rep
.len
)) {
13644 if (len
>= WL_RM_REP_ELT_FIXED_LEN
)
13645 memcpy(&rep
, data
, WL_RM_REP_ELT_FIXED_LEN
);
13649 rep
.chanspec
= dtohchanspec(rep
.chanspec
);
13650 rep
.token
= dtoh32(rep
.token
);
13651 rep
.tsf_h
= dtoh32(rep
.tsf_h
);
13652 rep
.tsf_l
= dtoh32(rep
.tsf_l
);
13653 rep
.dur
= dtoh32(rep
.dur
);
13654 rep
.len
= dtoh32(rep
.len
);
13656 data
+= WL_RM_REP_ELT_FIXED_LEN
;
13657 len
-= WL_RM_REP_ELT_FIXED_LEN
;
13659 if (rep
.type
== WL_RM_TYPE_BASIC
)
13661 else if (rep
.type
== WL_RM_TYPE_CCA
)
13663 else if (rep
.type
== WL_RM_TYPE_RPI
)
13669 printf("\nReport : %s\n", name
);
13671 printf("\nReport : %d <unknown>\n", rep
.type
);
13674 if (rep
.flags
& WL_RM_FLAG_PARALLEL
) {
13675 if (p
!= extra
) p
+= sprintf(p
, " | ");
13676 p
+= sprintf(p
, "Parallel");
13678 if (rep
.flags
& WL_RM_FLAG_LATE
) {
13679 if (p
!= extra
) p
+= sprintf(p
, " | ");
13680 p
+= sprintf(p
, "Late");
13682 if (rep
.flags
& WL_RM_FLAG_INCAPABLE
) {
13683 if (p
!= extra
) p
+= sprintf(p
, " | ");
13684 p
+= sprintf(p
, "Incapable");
13686 if (rep
.flags
& WL_RM_FLAG_REFUSED
) {
13687 if (p
!= extra
) p
+= sprintf(p
, " | ");
13688 p
+= sprintf(p
, "Refused");
13692 printf("flags : 0x%02x (%s)\n", rep
.flags
, extra
);
13694 printf("flags : 0x%02x\n", rep
.flags
);
13696 printf("token : %4d\n", rep
.token
);
13698 if (rep
.flags
& (WL_RM_FLAG_LATE
|
13699 WL_RM_FLAG_INCAPABLE
|
13700 WL_RM_FLAG_REFUSED
)) {
13704 channel
= CHSPEC_CHANNEL(rep
.chanspec
);
13705 aband
= CHSPEC_IS5G(rep
.chanspec
);
13707 printf("channel : %4d %s\n", channel
,
13708 aband
? "(a)":"(b)");
13709 printf("start tsf: 0x%x:%08x\n", rep
.tsf_h
, rep
.tsf_l
);
13710 printf("duration : %4d TU\n", rep
.dur
);
13712 if (len
< (int)rep
.len
) {
13713 printf("Error: partial report element, %d report bytes "
13714 "remain, element claims %d\n",
13719 if (rep
.type
== WL_RM_TYPE_BASIC
) {
13720 if (rep
.len
>= 4) {
13721 memcpy(&val
, data
, sizeof(uint32
));
13723 printf("Basic bits: 0x%08x\n", val
);
13725 } else if (rep
.type
== WL_RM_TYPE_CCA
) {
13726 if (rep
.len
>= 4) {
13727 memcpy(&val
, data
, sizeof(uint32
));
13729 printf("Carrier Fraction: %d / 255\n", val
);
13731 } else if (rep
.type
== WL_RM_TYPE_RPI
) {
13732 if (rep
.len
>= sizeof(wl_rm_rpi_rep_t
)) {
13733 wl_rm_rpi_rep_t rpi_rep
;
13737 memcpy(&rpi_rep
, data
, sizeof(wl_rm_rpi_rep_t
));
13739 for (bin
= 0; bin
< 8; bin
++) {
13740 max
= rpi_rep
.rpi_max
[bin
];
13742 printf(" Power <= %3d: ",
13745 printf(" %3d < Power <= %3d: ",
13748 printf(" %3d < Power : ",
13751 printf("%3d\n", rpi_rep
.rpi
[bin
]);
13761 wl_join_pref(void *wl
, cmd_t
*cmd
, char **argv
)
13766 int remaining_bytes
;
13770 UNUSED_PARAMETER(cmd
);
13772 strcpy(buf
, "join_pref");
13778 for (i
= len
+ 1, len
+= 1 + strlen(data
) / 2;
13779 (i
< len
) && (i
< (int)WLC_IOCTL_MAXLEN
); i
++) {
13783 buf
[i
] = (uint8
)strtoul(hex
, NULL
, 16);
13785 err
= wlu_set(wl
, WLC_SET_VAR
, buf
, i
);
13788 else if (!(err
= wlu_get(wl
, WLC_GET_VAR
, buf
, WLC_IOCTL_MAXLEN
))) {
13789 len
= dtoh32(*(int *)buf
);
13790 data
= buf
+ sizeof(int);
13791 for (i
= 0; i
< len
; i
++)
13792 printf("%02x", data
[i
]);
13794 /* pretty print the join pref elements */
13795 remaining_bytes
= len
;
13796 ie
= (bcm_tlv_t
*)data
;
13797 if (!bcm_valid_tlv(ie
, remaining_bytes
))
13800 wl_join_pref_print_ie(ie
);
13801 ie
= bcm_next_tlv(ie
, &remaining_bytes
);
13808 wl_join_pref_print_ie(bcm_tlv_t
*ie
)
13819 case WL_JOIN_PREF_RSSI
:
13820 printf("Pref RSSI\n");
13822 printf("\t<%d extra bytes in pref data>\n", ie
->len
);
13824 case WL_JOIN_PREF_BAND
:
13825 printf("Pref BAND: ");
13827 printf("len = %d <band pref data truncated>\n", ie
->len
);
13831 band
= ie
->data
[1];
13832 if (band
== WLC_BAND_AUTO
)
13833 printf("0x%x AUTO (no preference)\n", band
);
13834 else if (band
== WLC_BAND_5G
)
13835 printf("0x%x 5 GHz\n", band
);
13836 else if (band
== WLC_BAND_2G
)
13837 printf("0x%x 2.4 GHz\n", band
);
13838 else if (band
== WLJP_BAND_ASSOC_PREF
)
13839 printf("0x%x Use ASSOC_PREFER value\n", band
);
13841 printf("0x%x\n", band
);
13844 printf("\t<%d extra bytes in pref data>\n", ie
->len
- 1);
13847 case WL_JOIN_PREF_WPA
:
13848 printf("Pref WPA: ");
13850 printf("len = %d <WPA pref data truncated>\n", ie
->len
);
13853 count
= ie
->data
[1];
13854 printf("%d ACP Specs\n", count
);
13856 data_bytes
= ie
->len
- 2;
13857 suite_len
= 4; /* WPA Suite Selector length, OUI + type */
13858 suite
= ie
->data
+ 2;
13860 for (i
= 0; i
< (int)count
; i
++) {
13861 if (data_bytes
< 3 * suite_len
)
13865 wl_join_pref_print_akm(suite
);
13868 suite
= suite
+ suite_len
;
13869 /* Unicast Cipher Suite */
13871 wl_join_pref_print_cipher_suite(suite
);
13874 suite
= suite
+ suite_len
;
13875 /* Multicast Cipher Suite */
13877 if (!memcmp(suite
, WL_WPA_ACP_MCS_ANY
, suite_len
))
13880 wl_join_pref_print_cipher_suite(suite
);
13883 suite
= suite
+ suite_len
;
13884 data_bytes
-= 3 * suite_len
;
13888 printf("\t<expected %d more specs, %d bytes>\n",
13889 count
- i
, suite_len
* (count
- i
));
13890 if (data_bytes
> 0)
13891 printf("\t<%d extra bytes>\n", data_bytes
);
13893 case WL_JOIN_PREF_RSSI_DELTA
:
13894 printf("RSSI Delta for Pref BAND: ");
13896 printf("len = %d <rssi delta pref data truncated>\n", ie
->len
);
13900 band
= ie
->data
[1];
13901 if (band
== WLC_BAND_AUTO
)
13902 printf("0x%x AUTO (no preference)\n", band
);
13903 else if (band
== WLC_BAND_5G
)
13904 printf("0x%x 5 GHz\n", band
);
13905 else if (band
== WLC_BAND_2G
)
13906 printf("0x%x 2.4 GHz\n", band
);
13908 printf("0x%x\n", band
);
13910 printf("RSSI boost %ddb\n", ie
->data
[0]);
13914 printf("Pref 0x%x: len = %d\n", ie
->id
, ie
->len
);
13915 for (i
= 0; i
< ie
->len
; i
++)
13916 printf("%02x", ie
->data
[i
]);
13925 wl_join_pref_print_akm(uint8
* suite
)
13927 uint8 type
= suite
[3];
13928 const char *oui_name
;
13930 if (!memcmp(suite
, WPA_OUI
, 3))
13932 else if (!memcmp(suite
, WPA2_OUI
, 3))
13938 if (type
== RSN_AKM_NONE
)
13939 printf("%s-NONE", oui_name
);
13940 else if (type
== RSN_AKM_UNSPECIFIED
)
13941 printf("%s", oui_name
);
13942 else if (type
== RSN_AKM_UNSPECIFIED
)
13943 printf("%s-PSK", oui_name
);
13945 printf("%s/0x%x", oui_name
, type
);
13947 printf("0x%02x%02x%02x/0x%02x", suite
[0], suite
[1], suite
[2], suite
[3]);
13952 wl_join_pref_print_cipher_suite(uint8
* suite
)
13954 uint8 type
= suite
[3];
13955 const char *oui_name
;
13957 if (!memcmp(suite
, WPA_OUI
, 3))
13959 else if (!memcmp(suite
, WPA2_OUI
, 3))
13965 if (type
== WPA_CIPHER_NONE
)
13966 printf("%s/NONE", oui_name
);
13967 else if (type
== WPA_CIPHER_WEP_40
)
13968 printf("%s/WEP40", oui_name
);
13969 else if (type
== WPA_CIPHER_TKIP
)
13970 printf("%s/TKIP", oui_name
);
13971 else if (type
== WPA_CIPHER_AES_CCM
)
13972 printf("%s/AES", oui_name
);
13973 else if (type
== WPA_CIPHER_WEP_104
)
13974 printf("%s/WEP104", oui_name
);
13976 printf("%s/0x%x", oui_name
, type
);
13978 printf("0x%02x%02x%02x/0x%02x", suite
[0], suite
[1], suite
[2], suite
[3]);
13983 wl_assoc_pref(void *wl
, cmd_t
*cmd
, char **argv
)
13990 if (!strcmp(argv
[1], "auto") || !strcmp(argv
[1], "0"))
13991 assoc_pref
= WLC_BAND_AUTO
;
13992 else if (!strcmp(argv
[1], "a") || !strcmp(argv
[1], "1"))
13993 assoc_pref
= WLC_BAND_5G
;
13994 else if (!strcmp(argv
[1], "b") || !strcmp(argv
[1], "g") || !strcmp(argv
[1], "2"))
13995 assoc_pref
= WLC_BAND_2G
;
13998 assoc_pref
= htod32(assoc_pref
);
13999 err
= wlu_set(wl
, cmd
->set
, &assoc_pref
, sizeof(assoc_pref
));
14002 else if (!(err
= wlu_get(wl
, cmd
->get
, &assoc_pref
, sizeof(assoc_pref
)))) {
14003 assoc_pref
= dtoh32(assoc_pref
);
14004 switch (assoc_pref
) {
14005 case WLC_BAND_AUTO
:
14019 static const char ac_names
[AC_COUNT
][6] = {"AC_BE", "AC_BK", "AC_VI", "AC_VO"};
14022 * Get or set WME per-AC transmit parameters
14025 wme_tx_params(void *wl
, cmd_t
*cmd
, char **argv
)
14027 char *val_p
, *ac_str
, *param
;
14030 wme_tx_params_t cur_params
[AC_COUNT
], new_params
[AC_COUNT
];
14034 UNUSED_PARAMETER(cmd
);
14038 buflen
= WLC_IOCTL_MAXLEN
;
14041 * Get current acparams, using buf as an input buffer.
14042 * Return data is array of 4 ACs of wme params.
14045 strcpy(buf
, "wme_tx_params");
14046 if ((err
= wlu_get(wl
, WLC_GET_VAR
, &buf
[0], buflen
)) < 0) {
14049 memcpy(&cur_params
, buf
, WL_WME_TX_PARAMS_IO_BYTES
);
14051 if ((ac_str
= *argv
++) == NULL
) {
14052 printf("WME TX params: \n");
14053 for (aci
= 0; aci
< AC_COUNT
; aci
++) {
14054 printf("%s: short %d. sfb %d. long %d. lfb %d. max %d\n", ac_names
[aci
],
14055 cur_params
[aci
].short_retry
,
14056 cur_params
[aci
].short_fallback
,
14057 cur_params
[aci
].long_retry
,
14058 cur_params
[aci
].long_fallback
,
14059 cur_params
[aci
].max_rate
);
14063 if (strcmp(ac_str
, "be") == 0) {
14065 } else if (strcmp(ac_str
, "bk") == 0) {
14067 } else if (strcmp(ac_str
, "vi") == 0) {
14069 } else if (strcmp(ac_str
, "vo") == 0) {
14072 printf("Unknown access class: %s\n", ac_str
);
14073 return USAGE_ERROR
;
14076 /* Preload new values with current values */
14077 memcpy(&new_params
, &cur_params
, sizeof(new_params
));
14078 while ((param
= *argv
++) != NULL
) {
14079 if ((val_p
= *argv
++) == NULL
) {
14080 printf("Need value following %s\n", param
);
14081 return USAGE_ERROR
;
14084 val
= (int)strtoul(val_p
, NULL
, 0);
14085 /* All values must fit in uint8 */
14086 if (!strcmp(param
, "short")) {
14087 new_params
[aci
].short_retry
= (uint8
)val
;
14088 } else if (!strcmp(param
, "sfb")) {
14089 new_params
[aci
].short_fallback
= (uint8
)val
;
14090 } else if (!strcmp(param
, "long")) {
14091 new_params
[aci
].long_retry
= (uint8
)val
;
14092 } else if (!strcmp(param
, "lfb")) {
14093 new_params
[aci
].long_fallback
= (uint8
)val
;
14094 } else if ((!strcmp(param
, "max_rate")) || (!strcmp(param
, "max")) ||
14095 (!strcmp(param
, "rate"))) {
14097 new_params
[aci
].max_rate
= (uint8
)val
;
14099 printf("Unknown parameter: %s\n", param
);
14100 return USAGE_ERROR
;
14102 if (val
> chk_lim
) {
14103 printf("Value for %s must be < %d\n", param
, chk_lim
+ 1);
14104 return USAGE_ERROR
;
14107 strcpy(buf
, "wme_tx_params");
14108 memcpy(buf
+ strlen(buf
) + 1, new_params
, WL_WME_TX_PARAMS_IO_BYTES
);
14109 err
= wlu_set(wl
, WLC_SET_VAR
, &buf
[0], buflen
);
14116 * Get or Set WME Access Class (AC) parameters
14117 * wl wme_ac ap|sta [be|bk|vi|vo [ecwmax|ecwmin|txop|aifsn|acm <value>] ...]
14118 * Without args past ap|sta, print current values
14121 wl_wme_ac_req(void *wl
, cmd_t
*cmd
, char **argv
)
14124 edcf_acparam_t acparam_cur
[AC_COUNT
], acparam_new
[AC_COUNT
], *acp
;
14125 char *ac_str
, *param
, *val
;
14127 int aci
, aifsn
, ecwmin
, ecwmax
, txop
;
14133 if ((err
= wlu_get(wl
, WLC_GET_AP
, &ap_mode
, sizeof(ap_mode
))))
14135 ap_mode
= dtoh32(ap_mode
);
14137 if ((param
= *argv
++) == NULL
)
14138 return USAGE_ERROR
;
14140 if (!strcmp(param
, "ap"))
14142 else if (!strcmp(param
, "sta"))
14145 return USAGE_ERROR
;
14147 if (!ap_mode
&& !sta_param
) {
14148 fprintf(stderr
, "Can't work with AP parameters on STA\n");
14149 return USAGE_ERROR
;
14153 * On call to wlu_get, buf contains the NUL-terminated
14154 * string "wme_ac_sta" or "wme_ac_ap".
14155 * On return, gotten data starts at beginning of buf.
14157 * On call to wlu_set, buf contains the NUL-terminated
14158 * string "wme_ac_sta" or "wme_ac_ap", followed by the data.
14159 * Only a return value is returned.
14163 strcpy(buf
, "wme_ac_sta");
14165 strcpy(buf
, "wme_ac_ap");
14167 buflen
= WLC_IOCTL_MAXLEN
;
14170 * Get current acparams, using buf as an input buffer.
14171 * Return data is array of 4 ACs of wme params.
14174 if ((err
= wlu_get(wl
, cmd
->get
, &buf
[0], buflen
)) < 0)
14177 memcpy(&acparam_cur
, buf
, sizeof(acparam_cur
));
14179 if ((ac_str
= *argv
++) == NULL
) {
14180 printf("AC Parameters %s\n",
14181 ap_mode
? (sta_param
? "advertised for STA" : "for AP") : "for STA");
14183 for (aci
= 0; aci
< AC_COUNT
; aci
++) {
14184 acp
= &acparam_cur
[aci
];
14185 acp
->TXOP
= dtoh16(acp
->TXOP
);
14186 if (((acp
->ACI
& EDCF_ACI_MASK
) >> EDCF_ACI_SHIFT
) != aci
)
14187 printf("Warning: AC params out of order\n");
14188 acm
= (acp
->ACI
& EDCF_ACM_MASK
) ? 1 : 0;
14189 aifsn
= acp
->ACI
& EDCF_AIFSN_MASK
;
14190 ecwmin
= acp
->ECW
& EDCF_ECWMIN_MASK
;
14191 ecwmax
= (acp
->ECW
& EDCF_ECWMAX_MASK
) >> EDCF_ECWMAX_SHIFT
;
14193 printf("%s: raw: ACI 0x%x ECW 0x%x TXOP 0x%x\n",
14195 acp
->ACI
, acp
->ECW
, acp
->TXOP
);
14196 printf(" dec: aci %d acm %d aifsn %d "
14197 "ecwmin %d ecwmax %d txop 0x%x\n",
14198 aci
, acm
, aifsn
, ecwmin
, ecwmax
, txop
);
14199 /* CWmin = 2^(ECWmin) - 1 */
14200 /* CWmax = 2^(ECWmax) - 1 */
14201 /* TXOP = number of 32 us units */
14202 printf(" eff: CWmin %d CWmax %d TXop %dusec\n",
14203 EDCF_ECW2CW(ecwmin
), EDCF_ECW2CW(ecwmax
), EDCF_TXOP2USEC(txop
));
14208 if (strcmp(ac_str
, "be") == 0)
14210 else if (strcmp(ac_str
, "bk") == 0)
14212 else if (strcmp(ac_str
, "vi") == 0)
14214 else if (strcmp(ac_str
, "vo") == 0)
14217 return USAGE_ERROR
;
14219 /* Preload new values with current values */
14220 memcpy(&acparam_new
, &acparam_cur
, sizeof(acparam_new
));
14222 acp
= &acparam_new
[aci
];
14224 while ((param
= *argv
++) != NULL
) {
14225 if ((val
= *argv
++) == NULL
)
14226 return USAGE_ERROR
;
14228 if (!strcmp(param
, "acm")) {
14229 if (!stricmp(val
, "on") || !stricmp(val
, "1"))
14230 acp
->ACI
|= EDCF_ACM_MASK
;
14231 else if (!stricmp(val
, "off") || !stricmp(val
, "0"))
14232 acp
->ACI
&= ~EDCF_ACM_MASK
;
14234 fprintf(stderr
, "acm value must be 1|0\n");
14235 return USAGE_ERROR
;
14237 } else if (!strcmp(param
, "aifsn")) {
14238 aifsn
= (int)strtol(val
, NULL
, 0);
14239 if (aifsn
>= EDCF_AIFSN_MIN
&& aifsn
<= EDCF_AIFSN_MAX
)
14241 (acp
->ACI
& ~EDCF_AIFSN_MASK
) |
14242 (aifsn
& EDCF_AIFSN_MASK
);
14244 fprintf(stderr
, "aifsn %d out of range (%d-%d)\n",
14245 aifsn
, EDCF_AIFSN_MIN
, EDCF_AIFSN_MAX
);
14246 return USAGE_ERROR
;
14248 } else if (!strcmp(param
, "ecwmax")) {
14249 ecwmax
= (int)strtol(val
, NULL
, 0);
14250 if (ecwmax
>= EDCF_ECW_MIN
&& ecwmax
<= EDCF_ECW_MAX
)
14252 ((ecwmax
<< EDCF_ECWMAX_SHIFT
) & EDCF_ECWMAX_MASK
) |
14253 (acp
->ECW
& EDCF_ECWMIN_MASK
);
14255 fprintf(stderr
, "ecwmax %d out of range (%d-%d)\n",
14256 ecwmax
, EDCF_ECW_MIN
, EDCF_ECW_MAX
);
14257 return USAGE_ERROR
;
14259 } else if (!strcmp(param
, "ecwmin")) {
14260 ecwmin
= (int)strtol(val
, NULL
, 0);
14261 if (ecwmin
>= EDCF_ECW_MIN
&& ecwmin
<= EDCF_ECW_MAX
)
14263 ((acp
->ECW
& EDCF_ECWMAX_MASK
) |
14264 (ecwmin
& EDCF_ECWMIN_MASK
));
14266 fprintf(stderr
, "ecwmin %d out of range (%d-%d)\n",
14267 ecwmin
, EDCF_ECW_MIN
, EDCF_ECW_MAX
);
14268 return USAGE_ERROR
;
14270 } else if (!strcmp(param
, "txop")) {
14271 txop
= (int)strtol(val
, NULL
, 0);
14272 if (txop
>= EDCF_TXOP_MIN
&& txop
<= EDCF_TXOP_MAX
)
14273 acp
->TXOP
= htod16(txop
);
14275 fprintf(stderr
, "txop %d out of range (%d-%d)\n",
14276 txop
, EDCF_TXOP_MIN
, EDCF_TXOP_MAX
);
14277 return USAGE_ERROR
;
14280 fprintf(stderr
, "unexpected param %s\n", param
);
14281 return USAGE_ERROR
;
14286 * Now use buf as an output buffer.
14287 * Put WME acparams after "wme_ac\0" in buf.
14288 * NOTE: only one of the four ACs can be set at a time.
14291 strcpy(buf
, "wme_ac_sta");
14293 strcpy(buf
, "wme_ac_ap");
14295 memcpy(buf
+ strlen(buf
) + 1, acp
, sizeof(edcf_acparam_t
));
14297 err
= wlu_set(wl
, cmd
->set
, &buf
[0], buflen
);
14304 * Get or Set WME APSD control parameters
14305 * wl wme_apsd_sta <max_sp_len> <be> <bk> <vi> <vo>
14306 * <max_sp_len> is 0 (all), 2, 4, or 6
14307 * <be>, <bk>, <vi>, <vo> are each 0 or 1 for APSD enable
14308 * with no args, print current values
14311 wl_wme_apsd_sta(void *wl
, cmd_t
*cmd
, char **argv
)
14318 int msp
, max_sp_len
, be
, bk
, vi
, vo
;
14320 if ((err
= wlu_get(wl
, WLC_GET_AP
, &ap_mode
, sizeof(ap_mode
))))
14324 printf("%s: STA only\n", cmd
->name
);
14328 /* Display current params if no args, else set params */
14330 memset(buf
, 0, WLC_IOCTL_MAXLEN
);
14331 strcpy(buf
, "wme_qosinfo");
14332 buflen
= WLC_IOCTL_MAXLEN
;
14336 if (param
== NULL
) {
14337 if ((err
= wlu_get(wl
, cmd
->get
, &buf
[0], buflen
)) < 0)
14340 memcpy(&qosinfo
, buf
, sizeof(qosinfo
));
14341 qosinfo
= dtoh32(qosinfo
);
14343 msp
= (qosinfo
& WME_QI_STA_MAXSPLEN_MASK
) >> WME_QI_STA_MAXSPLEN_SHIFT
;
14344 be
= (qosinfo
& WME_QI_STA_APSD_BE_MASK
) >> WME_QI_STA_APSD_BE_SHIFT
;
14345 bk
= (qosinfo
& WME_QI_STA_APSD_BK_MASK
) >> WME_QI_STA_APSD_BK_SHIFT
;
14346 vi
= (qosinfo
& WME_QI_STA_APSD_VI_MASK
) >> WME_QI_STA_APSD_VI_SHIFT
;
14347 vo
= (qosinfo
& WME_QI_STA_APSD_VO_MASK
) >> WME_QI_STA_APSD_VO_SHIFT
;
14349 max_sp_len
= msp
* 2;
14351 printf("Max SP Length = %d, APSD: BE=%d BK=%d VI=%d VO=%d\n",
14352 max_sp_len
, be
, bk
, vi
, vo
);
14354 max_sp_len
= (int)strtol(param
, 0, 0);
14355 if ((param
= *++argv
) == NULL
)
14357 be
= (int)strtol(param
, 0, 0);
14358 if ((param
= *++argv
) == NULL
)
14360 bk
= (int)strtol(param
, 0, 0);
14361 if ((param
= *++argv
) == NULL
)
14363 vi
= (int)strtol(param
, 0, 0);
14364 if ((param
= *++argv
) == NULL
)
14366 vo
= (int)strtol(param
, 0, 0);
14368 if (((be
| bk
| vi
| vo
) & ~1) | (max_sp_len
& ~6)) {
14369 printf("%s: Invalid parameter\n", cmd
->name
);
14373 msp
= max_sp_len
/ 2;
14375 qosinfo
= (msp
<< WME_QI_STA_MAXSPLEN_SHIFT
) & WME_QI_STA_MAXSPLEN_MASK
;
14376 qosinfo
|= (be
<< WME_QI_STA_APSD_BE_SHIFT
) & WME_QI_STA_APSD_BE_MASK
;
14377 qosinfo
|= (bk
<< WME_QI_STA_APSD_BK_SHIFT
) & WME_QI_STA_APSD_BK_MASK
;
14378 qosinfo
|= (vi
<< WME_QI_STA_APSD_VI_SHIFT
) & WME_QI_STA_APSD_VI_MASK
;
14379 qosinfo
|= (vo
<< WME_QI_STA_APSD_VO_SHIFT
) & WME_QI_STA_APSD_VO_MASK
;
14381 qosinfo
= htod32(qosinfo
);
14382 memcpy(&buf
[strlen(buf
) + 1], &qosinfo
, sizeof(qosinfo
));
14384 err
= wlu_set(wl
, cmd
->set
, &buf
[0], buflen
);
14391 * Get or Set WME discard policy
14392 * wl wme_dp <be> <bk> <vi> <vo>
14393 * <be>, <bk>, <vi>, <vo> are each 0/1 for discard newest/oldest first
14394 * with no args, print current values
14397 wl_wme_dp(void *wl
, cmd_t
*cmd
, char **argv
)
14403 int be
, bk
, vi
, vo
;
14405 /* Display current params if no args, else set params */
14407 memset(buf
, 0, WLC_IOCTL_MAXLEN
);
14408 strcpy(buf
, "wme_dp");
14409 buflen
= WLC_IOCTL_MAXLEN
;
14413 if (param
== NULL
) {
14414 if ((err
= wlu_get(wl
, cmd
->get
, &buf
[0], buflen
)) < 0)
14417 memcpy(&dp
, buf
, sizeof(dp
));
14420 be
= (dp
>> AC_BE
) & 1;
14421 bk
= (dp
>> AC_BK
) & 1;
14422 vi
= (dp
>> AC_VI
) & 1;
14423 vo
= (dp
>> AC_VO
) & 1;
14425 printf("Discard oldest first: BE=%d BK=%d VI=%d VO=%d\n", be
, bk
, vi
, vo
);
14427 be
= (int)strtol(param
, 0, 0);
14428 if ((param
= *++argv
) == NULL
)
14430 bk
= (int)strtol(param
, 0, 0);
14431 if ((param
= *++argv
) == NULL
)
14433 vi
= (int)strtol(param
, 0, 0);
14434 if ((param
= *++argv
) == NULL
)
14436 vo
= (int)strtol(param
, 0, 0);
14438 if ((be
| bk
| vi
| vo
) & ~1) {
14439 printf("%s: Invalid parameter\n", cmd
->name
);
14443 dp
= (be
<< AC_BE
) | (bk
<< AC_BK
) | (vi
<< AC_VI
) | (vo
<< AC_VO
);
14446 memcpy(&buf
[strlen(buf
) + 1], &dp
, sizeof(dp
));
14448 err
= wlu_set(wl
, cmd
->set
, &buf
[0], buflen
);
14455 * Get or Set WME lifetime parameter
14456 * "wl lifetime be|bk|vi|vo [<value>]"},
14457 * with no args, print current values
14460 wl_lifetime(void *wl
, cmd_t
*cmd
, char **argv
)
14465 const char *cmdname
= "lifetime";
14466 wl_lifetime_t lifetime
, *reply
;
14469 UNUSED_PARAMETER(cmd
);
14471 if ((param
= *++argv
) == NULL
)
14472 return USAGE_ERROR
;
14474 if (strcmp(param
, "be") == 0)
14476 else if (strcmp(param
, "bk") == 0)
14478 else if (strcmp(param
, "vi") == 0)
14480 else if (strcmp(param
, "vo") == 0)
14483 fprintf(stderr
, "unexpected param %s\n", param
);
14484 return USAGE_ERROR
;
14487 if ((val
= *++argv
) == NULL
) {
14488 lifetime
.ac
= htod32(ac
);
14489 if ((err
= wlu_var_getbuf(wl
, cmdname
, &lifetime
, sizeof(lifetime
),
14492 reply
= (wl_lifetime_t
*) ptr
;
14493 reply
->ac
= dtoh32(reply
->ac
);
14494 reply
->lifetime
= dtoh32(reply
->lifetime
);
14495 printf("Lifetime for access class '%s' is %dms\n", param
, reply
->lifetime
);
14498 lifetime
.ac
= htod32(ac
);
14499 lifetime
.lifetime
= htod32((uint
)strtol(val
, 0, 0));
14500 err
= wlu_var_setbuf(wl
, cmdname
, &lifetime
, sizeof(lifetime
));
14507 wl_add_ie(void *wl
, cmd_t
*cmd
, char **argv
)
14509 UNUSED_PARAMETER(cmd
);
14511 return (wl_vndr_ie(wl
, "add", argv
));
14515 wl_del_ie(void *wl
, cmd_t
*cmd
, char **argv
)
14517 UNUSED_PARAMETER(cmd
);
14519 return (wl_vndr_ie(wl
, "del", argv
));
14523 wl_vndr_ie(void *wl
, const char *command
, char **argv
)
14525 vndr_ie_setbuf_t
*ie_setbuf
;
14527 int ielen
, datalen
, buflen
, iecount
;
14530 int bsscfg_idx
= 0;
14533 if (!argv
[1] || !argv
[2] || !argv
[3]) {
14534 fprintf(stderr
, "Too few arguments\n");
14538 /* parse a bsscfg_idx option if present */
14539 if ((ret
= wl_cfg_option(argv
+ 1, argv
[0], &bsscfg_idx
, &consumed
)) != 0)
14542 argv
= argv
+ consumed
;
14546 pktflag
= (uint
)strtol(argv
[1], 0, 0);
14549 ~(VNDR_IE_BEACON_FLAG
|
14550 VNDR_IE_PRBRSP_FLAG
|
14551 VNDR_IE_ASSOCRSP_FLAG
|
14552 VNDR_IE_AUTHRSP_FLAG
|
14553 VNDR_IE_PRBREQ_FLAG
|
14554 VNDR_IE_ASSOCREQ_FLAG
|
14555 VNDR_IE_IWAPID_FLAG
))) {
14556 fprintf(stderr
, "Invalid packet flag 0x%x (%d)\n", pktflag
, pktflag
);
14560 ielen
= atoi(argv
[2]);
14561 if (ielen
> VNDR_IE_MAX_LEN
) {
14562 fprintf(stderr
, "IE length is %d, should be <= %d\n", ielen
, VNDR_IE_MAX_LEN
);
14565 else if (ielen
< VNDR_IE_MIN_LEN
) {
14566 fprintf(stderr
, "IE length is %d, should be >= %d\n", ielen
, VNDR_IE_MIN_LEN
);
14570 if (strlen(argv
[3]) != OUI_STR_SIZE
) {
14571 fprintf(stderr
, "Invalid OUI length %d\n", (int)strlen(argv
[3]));
14575 datalen
= ielen
- VNDR_IE_MIN_LEN
;
14578 fprintf(stderr
, "Data bytes should be specified for IE of length %d",
14583 /* Ensure each data byte is 2 characters long */
14584 if ((int)strlen (argv
[4]) < (datalen
* 2)) {
14585 fprintf(stderr
, "Please specify all the data bytes for this IE\n");
14591 if (datalen
== 0 && (argv
[4] != NULL
))
14592 fprintf(stderr
, "Ignoring data bytes for IE of length %d", ielen
);
14594 buflen
= sizeof(vndr_ie_setbuf_t
) + datalen
- 1;
14596 ie_setbuf
= (vndr_ie_setbuf_t
*) malloc(buflen
);
14598 if (ie_setbuf
== NULL
) {
14599 fprintf(stderr
, "memory alloc failure\n");
14603 /* Copy the vndr_ie SET command ("add"/"del") to the buffer */
14604 strncpy(ie_setbuf
->cmd
, command
, VNDR_IE_CMD_LEN
- 1);
14605 ie_setbuf
->cmd
[VNDR_IE_CMD_LEN
- 1] = '\0';
14608 /* Buffer contains only 1 IE */
14609 iecount
= htod32(1);
14610 memcpy((void *)&ie_setbuf
->vndr_ie_buffer
.iecount
, &iecount
, sizeof(int));
14613 * The packet flag bit field indicates the packets that will
14616 pktflag
= htod32(pktflag
);
14617 memcpy((void *)&ie_setbuf
->vndr_ie_buffer
.vndr_ie_list
[0].pktflag
,
14618 &pktflag
, sizeof(uint32
));
14620 /* Now, add the IE to the buffer */
14621 ie_setbuf
->vndr_ie_buffer
.vndr_ie_list
[0].vndr_ie_data
.len
= (uchar
) ielen
;
14623 if ((err
= get_oui_bytes ((uchar
*)argv
[3],
14624 &ie_setbuf
->vndr_ie_buffer
.vndr_ie_list
[0].vndr_ie_data
.oui
[0]))) {
14626 fprintf(stderr
, "Error parsing OUI arg\n");
14631 if ((err
= get_ie_data ((uchar
*)argv
[4],
14632 &ie_setbuf
->vndr_ie_buffer
.vndr_ie_list
[0].vndr_ie_data
.data
[0],
14635 fprintf(stderr
, "Error parsing data arg\n");
14640 if (bsscfg_idx
== -1)
14641 err
= wlu_var_setbuf(wl
, "vndr_ie", ie_setbuf
, buflen
);
14643 err
= wl_bssiovar_setbuf(wl
, "vndr_ie", bsscfg_idx
,
14644 ie_setbuf
, buflen
, buf
, WLC_IOCTL_MAXLEN
);
14652 wl_list_ie(void *wl
, cmd_t
*cmd
, char **argv
)
14656 int tot_ie
, pktflag
, iecount
, count
, datalen
, col
;
14657 vndr_ie_buf_t
*ie_getbuf
;
14658 vndr_ie_info_t
*ie_info
;
14663 UNUSED_PARAMETER(cmd
);
14664 UNUSED_PARAMETER(argv
);
14666 err
= wlu_var_getbuf(wl
, "vndr_ie", NULL
, 0, &ptr
);
14668 ie_getbuf
= (vndr_ie_buf_t
*)ptr
;
14669 memcpy(&tot_ie
, (void *)&ie_getbuf
->iecount
, sizeof(int));
14670 tot_ie
= dtoh32(tot_ie
);
14671 printf("Total IEs %d\n", tot_ie
);
14673 iebuf
= (uchar
*)&ie_getbuf
->vndr_ie_list
[0];
14675 for (iecount
= 0; iecount
< tot_ie
; iecount
++) {
14676 ie_info
= (vndr_ie_info_t
*) iebuf
;
14677 memcpy(&pktflag
, (void *)&ie_info
->pktflag
, sizeof(uint32
));
14678 pktflag
= dtoh32(pktflag
);
14679 iebuf
+= sizeof(uint32
);
14683 ie
= &ie_info
->vndr_ie_data
;
14684 printf("IE index = %d\n", iecount
);
14685 printf("-----------------\n");
14686 printf("Pkt Flg = 0x%x\n", pktflag
);
14687 printf("Length = %d\n", ie
->len
);
14688 printf("OUI = %02x:%02x:%02x\n",
14689 ie
->oui
[0], ie
->oui
[1], ie
->oui
[2]);
14692 data
= &ie
->data
[0];
14693 datalen
= ie
->len
- VNDR_IE_MIN_LEN
;
14694 for (count
= 0; (count
< datalen
);) {
14695 for (col
= 0; (col
< MAX_DATA_COLS
) &&
14696 (count
< datalen
); col
++, count
++) {
14697 printf("%02x ", *data
++);
14702 iebuf
+= ie
->len
+ VNDR_IE_HDR_LEN
;
14706 fprintf(stderr
, "Error %d getting IOVar\n", err
);
14713 wl_rand(void *wl
, cmd_t
*cmd
, char **argv
)
14720 UNUSED_PARAMETER(argv
);
14722 if ((err
= wlu_var_getbuf (wl
, cmd
->name
, NULL
, 0, &ptr
)))
14725 randbuf
= (char *)ptr
;
14726 memcpy(&randnum
, randbuf
, sizeof(uint16
));
14727 printf("%d\n", randnum
);
14732 #define PRVAL(name) pbuf += sprintf(pbuf, "%s %d ", #name, dtoh32(cnt.name))
14733 #define PRNL() pbuf += sprintf(pbuf, "\n")
14736 wl_counters(void *wl
, cmd_t
*cmd
, char **argv
)
14745 UNUSED_PARAMETER(argv
);
14747 if ((err
= wlu_var_getbuf_med (wl
, cmd
->name
, NULL
, 0, &ptr
)))
14750 statsbuf
= (char *)ptr
;
14751 memcpy(&cnt
, statsbuf
, sizeof(cnt
));
14752 cnt
.version
= dtoh16(cnt
.version
);
14753 cnt
.length
= dtoh16(cnt
.length
);
14755 if (cnt
.version
> WL_CNT_T_VERSION
) {
14756 printf("\tIncorrect version of counters struct: expected %d; got %d\n",
14757 WL_CNT_T_VERSION
, cnt
.version
);
14760 else if (cnt
.version
!= WL_CNT_T_VERSION
) {
14761 printf("\tIncorrect version of counters struct: expected %d; got %d\n",
14762 WL_CNT_T_VERSION
, cnt
.version
);
14763 printf("\tDisplayed values may be incorrect\n");
14766 /* summary stat counter line */
14767 PRVAL(txframe
); PRVAL(txbyte
); PRVAL(txretrans
); PRVAL(txerror
);
14768 PRVAL(rxframe
); PRVAL(rxbyte
); PRVAL(rxerror
); PRNL();
14770 PRVAL(txprshort
); PRVAL(txdmawar
); PRVAL(txnobuf
); PRVAL(txnoassoc
);
14771 PRVAL(txchit
); PRVAL(txcmiss
); PRVAL(txcongest
); PRNL();
14773 PRVAL(reset
); PRVAL(txserr
); PRVAL(txphyerr
); PRVAL(txphycrs
);
14774 PRVAL(txfail
); PRVAL(tbtt
); PRNL();
14776 pbuf
+= sprintf(pbuf
, "d11_txfrag %d d11_txmulti %d d11_txretry %d d11_txretrie %d\n",
14777 dtoh32(cnt
.txfrag
), dtoh32(cnt
.txmulti
), dtoh32(cnt
.txretry
), dtoh32(cnt
.txretrie
));
14779 pbuf
+= sprintf(pbuf
, "d11_txrts %d d11_txnocts %d d11_txnoack %d d11_txfrmsnt %d\n",
14780 dtoh32(cnt
.txrts
), dtoh32(cnt
.txnocts
), dtoh32(cnt
.txnoack
), dtoh32(cnt
.txfrmsnt
));
14782 PRVAL(rxcrc
); PRVAL(rxnobuf
); PRVAL(rxnondata
); PRVAL(rxbadds
);
14783 PRVAL(rxbadcm
); PRVAL(rxdup
); PRVAL(rxfragerr
); PRNL();
14785 PRVAL(rxrunt
); PRVAL(rxgiant
); PRVAL(rxnoscb
); PRVAL(rxbadproto
);
14786 PRVAL(rxbadsrcmac
); PRNL();
14788 pbuf
+= sprintf(pbuf
, "d11_rxfrag %d d11_rxmulti %d d11_rxundec %d\n",
14789 dtoh32(cnt
.rxfrag
), dtoh32(cnt
.rxmulti
), dtoh32(cnt
.rxundec
));
14791 PRVAL(rxctl
); PRVAL(rxbadda
); PRVAL(rxfilter
); PRNL();
14793 pbuf
+= sprintf(pbuf
, "rxuflo: ");
14794 for (i
= 0; i
< NFIFO
; i
++)
14795 pbuf
+= sprintf(pbuf
, "%d ", dtoh32(cnt
.rxuflo
[i
]));
14796 pbuf
+= sprintf(pbuf
, "\n");
14797 PRVAL(txallfrm
); PRVAL(txrtsfrm
); PRVAL(txctsfrm
); PRVAL(txackfrm
); PRNL();
14798 PRVAL(txdnlfrm
); PRVAL(txbcnfrm
); PRVAL(txtplunfl
); PRVAL(txphyerr
); PRNL();
14799 pbuf
+= sprintf(pbuf
, "txfunfl: ");
14800 for (i
= 0; i
< NFIFO
; i
++)
14801 pbuf
+= sprintf(pbuf
, "%d ", dtoh32(cnt
.txfunfl
[i
]));
14802 pbuf
+= sprintf(pbuf
, "\n");
14804 /* WPA2 counters */
14806 PRVAL(tkipmicfaill
); PRVAL(tkipicverr
); PRVAL(tkipcntrmsr
); PRNL();
14807 PRVAL(tkipreplay
); PRVAL(ccmpfmterr
); PRVAL(ccmpreplay
); PRNL();
14808 PRVAL(ccmpundec
); PRVAL(fourwayfail
); PRVAL(wepundec
); PRNL();
14809 PRVAL(wepicverr
); PRVAL(decsuccess
); PRVAL(rxundec
); PRNL();
14812 PRVAL(rxfrmtoolong
); PRVAL(rxfrmtooshrt
);
14813 PRVAL(rxinvmachdr
); PRVAL(rxbadfcs
); PRNL();
14814 PRVAL(rxbadplcp
); PRVAL(rxcrsglitch
);
14815 PRVAL(rxstrt
); PRVAL(rxdfrmucastmbss
); PRNL();
14816 PRVAL(rxmfrmucastmbss
); PRVAL(rxcfrmucast
);
14817 PRVAL(rxrtsucast
); PRVAL(rxctsucast
); PRNL();
14818 PRVAL(rxackucast
); PRVAL(rxdfrmocast
);
14819 PRVAL(rxmfrmocast
); PRVAL(rxcfrmocast
); PRNL();
14820 PRVAL(rxrtsocast
); PRVAL(rxctsocast
);
14821 PRVAL(rxdfrmmcast
); PRVAL(rxmfrmmcast
); PRNL();
14822 PRVAL(rxcfrmmcast
); PRVAL(rxbeaconmbss
);
14823 PRVAL(rxdfrmucastobss
); PRVAL(rxbeaconobss
); PRNL();
14824 PRVAL(rxrsptmout
); PRVAL(bcntxcancl
);
14825 PRVAL(rxf0ovfl
); PRVAL(rxf1ovfl
); PRNL();
14826 PRVAL(rxf2ovfl
); PRVAL(txsfovfl
); PRVAL(pmqovfl
); PRNL();
14827 PRVAL(rxcgprqfrm
); PRVAL(rxcgprsqovfl
);
14828 PRVAL(txcgprsfail
); PRVAL(txcgprssuc
); PRNL();
14829 PRVAL(prs_timeout
); PRVAL(rxnack
); PRVAL(frmscons
);
14830 PRVAL(txnack
); PRVAL(txglitch_nack
); PRNL();
14831 PRVAL(txburst
); PRVAL(txphyerror
); PRNL();
14832 PRVAL(txchanrej
); PRNL();
14834 if (cnt
.version
>= 4) {
14835 /* per-rate receive counters */
14836 PRVAL(rx1mbps
); PRVAL(rx2mbps
); PRVAL(rx5mbps5
); PRNL();
14837 PRVAL(rx6mbps
); PRVAL(rx9mbps
); PRVAL(rx11mbps
); PRNL();
14838 PRVAL(rx12mbps
); PRVAL(rx18mbps
); PRVAL(rx24mbps
); PRNL();
14839 PRVAL(rx36mbps
); PRVAL(rx48mbps
); PRVAL(rx54mbps
); PRNL();
14842 if (cnt
.version
>= 5) {
14843 PRVAL(pktengrxducast
); PRVAL(pktengrxdmcast
); PRNL();
14846 if (cnt
.version
>= 6) {
14847 PRVAL(txmpdu_sgi
); PRVAL(rxmpdu_sgi
); PRVAL(txmpdu_stbc
);
14848 PRVAL(rxmpdu_stbc
); PRNL();
14851 pbuf
+= sprintf(pbuf
, "\n");
14852 fputs(buf
, stdout
);
14857 wl_delta_stats(void *wl
, cmd_t
*cmd
, char **argv
)
14860 wl_delta_stats_t cnt
;
14865 UNUSED_PARAMETER(cmd
);
14866 UNUSED_PARAMETER(argv
);
14868 if ((err
= wlu_var_getbuf_med (wl
, cmd
->name
, NULL
, 0, &ptr
)))
14871 statsbuf
= (char *)ptr
;
14872 memcpy(&cnt
, statsbuf
, sizeof(cnt
));
14873 cnt
.version
= dtoh16(cnt
.version
);
14874 cnt
.length
= dtoh16(cnt
.length
);
14876 if (cnt
.version
!= WL_DELTA_STATS_T_VERSION
) {
14877 printf("\tIncorrect version of delta stats struct: expected %d; got %d\n",
14878 WL_DELTA_STATS_T_VERSION
, cnt
.version
);
14882 PRVAL(txframe
); PRVAL(txbyte
); PRVAL(txretrans
); PRVAL(txfail
); PRNL();
14884 PRVAL(rxframe
); PRVAL(rxbyte
); PRNL();
14886 PRVAL(rx1mbps
); PRVAL(rx2mbps
); PRVAL(rx5mbps5
); PRVAL(rx6mbps
); PRNL();
14887 PRVAL(rx9mbps
); PRVAL(rx11mbps
); PRVAL(rx12mbps
); PRVAL(rx18mbps
); PRNL();
14888 PRVAL(rx24mbps
); PRVAL(rx36mbps
); PRVAL(rx48mbps
); PRVAL(rx54mbps
); PRNL();
14890 pbuf
+= sprintf(pbuf
, "\n");
14891 fputs(buf
, stdout
);
14896 wl_wme_counters(void *wl
, cmd_t
*cmd
, char **argv
)
14906 UNUSED_PARAMETER(argv
);
14908 if ((err
= wlu_var_getbuf_sm (wl
, cmd
->name
, NULL
, 0, &ptr
)))
14911 statsbuf
= (char *)ptr
;
14912 memcpy(&cnt
, statsbuf
, sizeof(cnt
));
14913 cnt
.version
= dtoh16(cnt
.version
);
14914 cnt
.length
= dtoh16(cnt
.length
);
14916 if (cnt
.version
!= WL_WME_CNT_VERSION
) {
14917 printf("\tIncorrect version of counters struct: expected %d; got %d\n",
14918 WL_WME_CNT_VERSION
, cnt
.version
);
14922 if ((err
= wlu_get(wl
, WLC_GET_AP
, &ap_mode
, sizeof(ap_mode
)))) {
14925 ap_mode
= dtoh32(ap_mode
);
14927 /* summary stat counter line */
14928 for (ac
= AC_BE
; ac
< AC_COUNT
; ac
++) {
14929 pbuf
+= sprintf(pbuf
, "\n%s: tx frames: %d bytes: %d failed frames: %d "
14930 "failed bytes: %d\n",
14931 ac_names
[ac
], dtoh32(cnt
.tx
[ac
].packets
), dtoh32(cnt
.tx
[ac
].bytes
),
14932 dtoh32(cnt
.tx_failed
[ac
].packets
), dtoh32(cnt
.tx_failed
[ac
].bytes
));
14933 pbuf
+= sprintf(pbuf
, " rx frames: %d bytes: %d failed frames: %d "
14934 "failed bytes: %d\n", dtoh32(cnt
.rx
[ac
].packets
),
14935 dtoh32(cnt
.rx
[ac
].bytes
), dtoh32(cnt
.rx_failed
[ac
].packets
),
14936 dtoh32(cnt
.rx_failed
[ac
].bytes
));
14939 pbuf
+= sprintf(pbuf
, " foward frames: %d bytes: %d \n",
14940 dtoh32(cnt
.forward
[ac
].packets
),
14941 dtoh32(cnt
.forward
[ac
].bytes
));
14943 pbuf
+= sprintf(pbuf
, " tx frames time expired: %d \n",
14944 dtoh32(cnt
.tx_expired
[ac
].packets
));
14946 pbuf
+= sprintf(pbuf
, "\n");
14947 fputs(buf
, stdout
);
14952 wl_devpath(void *wl
, cmd_t
*cmd
, char **argv
)
14958 UNUSED_PARAMETER(argv
);
14960 if ((err
= wlu_var_getbuf_sm (wl
, cmd
->name
, NULL
, 0, &ptr
)))
14963 pbuf
+= strlen(buf
);
14964 sprintf(pbuf
, "\n");
14965 fputs(buf
, stdout
);
14970 wl_diag(void *wl
, cmd_t
*cmd
, char **argv
)
14978 printf(" Usage: %s testindex[1-4]\n", cmd
->name
);
14982 testindex
= atoi(*argv
);
14984 strcpy(buf
, "diag");
14985 buflen
= strlen(buf
) + 1;
14986 param
= (char *)(buf
+ buflen
);
14987 testindex
= htod32(testindex
);
14988 memcpy(param
, (char*)&testindex
, sizeof(testindex
));
14990 if ((err
= wlu_get(wl
, cmd
->get
, buf
, WLC_IOCTL_MAXLEN
)))
14993 testresult
= *(uint32
*)buf
;
14994 testindex
= dtoh32(testindex
);
14995 testresult
= dtoh32(testresult
);
14996 if (testresult
!= 0) {
14997 printf("\ndiag test %d failed(error code %d)\n", testindex
, testresult
);
14999 printf("\ndiag test %d passed\n", testindex
);
15005 wl_phy_rssiant(void *wl
, cmd_t
*cmd
, char **argv
)
15013 printf(" Usage: %s antenna_index[0-3]\n", cmd
->name
);
15017 antindex
= htod32(atoi(*argv
));
15019 strcpy(buf
, "nphy_rssiant");
15020 buflen
= strlen(buf
) + 1;
15021 param
= (char *)(buf
+ buflen
);
15022 memcpy(param
, (char*)&antindex
, sizeof(antindex
));
15024 if ((err
= wlu_get(wl
, cmd
->get
, buf
, WLC_IOCTL_MAXLEN
)))
15027 antindex
= dtoh32(antindex
);
15028 antrssi
= dtoh16(*(int16
*)buf
);
15029 printf("\nnphy_rssiant ant%d = %d\n", antindex
, antrssi
);
15035 get_oui_bytes(uchar
*oui_str
, uchar
*oui
)
15045 for (idx
= 0; idx
< MAX_OUI_SIZE
; idx
++) {
15046 hexstr
[0] = src
[0];
15047 hexstr
[1] = src
[1];
15050 val
= (uchar
) strtoul(hexstr
, NULL
, 16);
15055 if ((idx
< (MAX_OUI_SIZE
- 1)) && (*src
++ != ':'))
15063 get_ie_data(uchar
*data_str
, uchar
*ie_data
, int len
)
15073 for (idx
= 0; idx
< len
; idx
++) {
15074 hexstr
[0] = src
[0];
15075 hexstr
[1] = src
[1];
15078 val
= (uchar
) strtoul(hexstr
, NULL
, 16);
15088 hexstrtobitvec(const char *cp
, uchar
*bitvec
, int veclen
)
15091 int nibble
; /* index of current hex-format nibble to process */
15092 int even
; /* 1 if even number of nibbles, 0 if odd number */
15095 if (cp
[0] == '0' && cp
[1] == 'x')
15098 memset(bitvec
, '\0', veclen
);
15099 nibble
= strlen(cp
);
15102 even
= ((nibble
% 2) == 0);
15104 /* convert from right to left (lsb is rightmost byte) */
15106 while (nibble
>= 0 && i
< veclen
&& (isxdigit((int)cp
[nibble
]) &&
15107 (value
= isdigit((int)cp
[nibble
]) ? cp
[nibble
]-'0' :
15108 (islower((int)cp
[nibble
]) ? toupper((int)cp
[nibble
]) : cp
[nibble
])-'A'+10) < 16)) {
15109 if (even
== ((nibble
+1) % 2)) {
15110 bitvec
[i
] += value
*16;
15117 return ((nibble
== -1 && i
<= veclen
) ? 0 : -1);
15121 wl_bitvec128(void *wl
, cmd_t
*cmd
, char **argv
)
15134 memset(bitvec
, '\0', sizeof(bitvec
));
15135 if (!(err
= hexstrtobitvec(argv
[1], bitvec
, sizeof(bitvec
))))
15136 err
= wlu_var_setbuf(wl
, cmd
->name
, bitvec
, sizeof(bitvec
));
15142 memset(buf
, '\0', WLC_IOCTL_MAXLEN
);
15143 if (!(err
= wlu_var_getbuf(wl
, cmd
->name
, NULL
, 0, &ptr
))) {
15144 vbuf
= (char *)ptr
;
15146 for (i
= (sizeof(bitvec
) - 1); i
>= 0; i
--) {
15147 if (vbuf
[i
] || (i
== 0))
15151 printf("%02x", vbuf
[i
] & 0xff);
15161 wl_auto_channel_sel(void *wl
, cmd_t
*cmd
, char **argv
)
15164 * The following condition(s) must be met when Auto Channel Selection
15166 * - the I/F is up (change radio channel requires it is up?)
15167 * - the AP must not be associated (setting SSID to empty should
15168 * make sure it for us)
15171 wl_uint32_list_t request
;
15175 ret
= wlu_get(wl
, cmd
->get
, &chosen
, sizeof(chosen
));
15176 chosen
= dtoh32(chosen
);
15177 if (ret
>= 0 && chosen
!= 0) {
15178 wf_chspec_ntoa((chanspec_t
)chosen
, buf
);
15179 printf("%s (0x%x)\n", buf
, chosen
);
15184 printf("invalid chanspec (0x%x)\n", chosen
);
15187 if (atoi(*argv
) == 1) {
15188 request
.count
= htod32(0);
15189 ret
= wlu_set(wl
, cmd
->set
, &request
, sizeof(request
));
15190 } else if (atoi(*argv
) == 2) {
15191 ret
= wlu_get(wl
, cmd
->get
, &chosen
, sizeof(chosen
));
15192 if (ret
>= 0 && chosen
!= 0)
15193 ret
= wlu_iovar_setint(wl
, "chanspec", (int)chosen
);
15202 wl_varstr(void *wl
, cmd_t
*cmd
, char **argv
)
15210 if ((error
= wlu_var_getbuf(wl
, cmd
->name
, NULL
, 0, &ptr
)) < 0)
15214 printf("%s\n", str
);
15218 /* str length include NULL */
15219 return wlu_var_setbuf(wl
, cmd
->name
, str
, (strlen(str
)+1));
15223 /* Return TRUE if it's one of the wc cmds. If WC_TOOL is not defined,
15224 * it'll return TRUE by default so all the commands are allowed.
15226 bool wc_cmd_check(const char *cmd_name
)
15229 if (wc_cmds
== NULL
)
15232 for (j
= 0; j
< ARRAYSIZE(wc_cmds
); j
++)
15233 if (strcmp(wc_cmds
[j
], cmd_name
) == 0)
15238 #define NUM_TSLIST_ARG 3 /* minimum number of arguments required for TSLIST */
15239 #define NUM_TSLIST_PER_EA_ARG 3 /* minimum number of arguments required for TSLIST */
15240 #define MIN_NUM_DELTS_ARG 4 /* minimum number of arguments required for DELTS */
15241 #define MIN_NUM_DELTS_EA_ARG 5 /* minimum number of arguments required for DELTS */
15242 #define MIN_NUM_ADDTS_ARG 19 /* minimum number of arguments required for ADDTS */
15243 #define PERIODIC_TRAFFIC 1 /* Periodic traffic type */
15244 #define VO_TID (0 << 1) /* voice TID */
15245 #define VI_TID (1 << 1) /* signal TID */
15246 #define UPLINK_DIRECTION (0 << 5) /* uplink direction traffic stream */
15247 #define DOWNLINK_DIRECTION (1 << 5) /* downlink direction traffic stream */
15248 #define BI_DIRECTION (3 << 5) /* bi direction traffic stream */
15249 #define EDCA_ACCESS (1 << 7) /* EDCA access policy */
15250 #define UAPSD_PSB (1 << 2) /* U-APSD power saving behavior */
15251 #define VO_USER_PRIO (6 << 3) /* voice user priority */
15252 #define VI_USER_PRIO (4 << 3) /* signal user priority */
15253 #define TID_SHIFT 1 /* TID Shift */
15254 #define UP_SHIFT 3 /* UP Shift */
15257 wl_cac_format_tspec_htod(tspec_arg_t
*tspec_arg
)
15259 tspec_arg
->version
= htod16(tspec_arg
->version
);
15260 tspec_arg
->length
= htod16(tspec_arg
->length
);
15261 tspec_arg
->flag
= htod32(tspec_arg
->flag
);
15262 tspec_arg
->nom_msdu_size
= htod16(tspec_arg
->nom_msdu_size
);
15263 tspec_arg
->max_msdu_size
= htod16(tspec_arg
->max_msdu_size
);
15264 tspec_arg
->min_srv_interval
= htod32(tspec_arg
->min_srv_interval
);
15265 tspec_arg
->max_srv_interval
= htod32(tspec_arg
->max_srv_interval
);
15266 tspec_arg
->inactivity_interval
= htod32(tspec_arg
->inactivity_interval
);
15267 tspec_arg
->suspension_interval
= htod32(tspec_arg
->suspension_interval
);
15268 tspec_arg
->srv_start_time
= htod32(tspec_arg
->srv_start_time
);
15269 tspec_arg
->min_data_rate
= htod32(tspec_arg
->min_data_rate
);
15270 tspec_arg
->mean_data_rate
= htod32(tspec_arg
->mean_data_rate
);
15271 tspec_arg
->peak_data_rate
= htod32(tspec_arg
->peak_data_rate
);
15272 tspec_arg
->max_burst_size
= htod32(tspec_arg
->max_burst_size
);
15273 tspec_arg
->delay_bound
= htod32(tspec_arg
->delay_bound
);
15274 tspec_arg
->min_phy_rate
= htod32(tspec_arg
->min_phy_rate
);
15275 tspec_arg
->surplus_bw
= htod16(tspec_arg
->surplus_bw
);
15276 tspec_arg
->medium_time
= htod16(tspec_arg
->medium_time
);
15280 wl_cac_format_tspec_dtoh(tspec_arg_t
*tspec_arg
)
15282 tspec_arg
->version
= dtoh16(tspec_arg
->version
);
15283 tspec_arg
->length
= dtoh16(tspec_arg
->length
);
15284 tspec_arg
->flag
= dtoh32(tspec_arg
->flag
);
15285 tspec_arg
->nom_msdu_size
= dtoh16(tspec_arg
->nom_msdu_size
);
15286 tspec_arg
->max_msdu_size
= dtoh16(tspec_arg
->max_msdu_size
);
15287 tspec_arg
->min_srv_interval
= dtoh32(tspec_arg
->min_srv_interval
);
15288 tspec_arg
->max_srv_interval
= dtoh32(tspec_arg
->max_srv_interval
);
15289 tspec_arg
->inactivity_interval
= dtoh32(tspec_arg
->inactivity_interval
);
15290 tspec_arg
->suspension_interval
= dtoh32(tspec_arg
->suspension_interval
);
15291 tspec_arg
->srv_start_time
= dtoh32(tspec_arg
->srv_start_time
);
15292 tspec_arg
->min_data_rate
= dtoh32(tspec_arg
->min_data_rate
);
15293 tspec_arg
->mean_data_rate
= dtoh32(tspec_arg
->mean_data_rate
);
15294 tspec_arg
->peak_data_rate
= dtoh32(tspec_arg
->peak_data_rate
);
15295 tspec_arg
->max_burst_size
= dtoh32(tspec_arg
->max_burst_size
);
15296 tspec_arg
->delay_bound
= dtoh32(tspec_arg
->delay_bound
);
15297 tspec_arg
->min_phy_rate
= dtoh32(tspec_arg
->min_phy_rate
);
15298 tspec_arg
->surplus_bw
= dtoh16(tspec_arg
->surplus_bw
);
15299 tspec_arg
->medium_time
= dtoh16(tspec_arg
->medium_time
);
15303 static void wl_cac_addts_usage(void)
15305 fprintf(stderr
, "Too few arguments\n");
15306 fprintf(stderr
, "wl cac_addts ver dtoken tid dir psb up a b c d e ...\n");
15307 fprintf(stderr
, "\twhere ver is the structure version\n");
15308 fprintf(stderr
, "\twhere dtoken is the dialog token [range 1-255]\n");
15309 fprintf(stderr
, "\twhere tid is the tspec identifier [range 0-7]\n");
15310 fprintf(stderr
, "\twhere dir is direction [uplink | downlink | bi-directional]\n");
15311 fprintf(stderr
, "\twhere psb is power save mode [legacy|U-APSD]\n");
15312 fprintf(stderr
, "\twhere up is user priority [range 0-7]\n");
15313 fprintf(stderr
, "\twhere a is the nominal MSDU size\n");
15314 fprintf(stderr
, "\twhere b is bool for fixed size msdu [ 0 and 1]\n");
15315 fprintf(stderr
, "\twhere c is the maximum MSDU size\n");
15316 fprintf(stderr
, "\twhere d is the minimum service interval\n");
15317 fprintf(stderr
, "\twhere e is the maximum service interval\n");
15318 fprintf(stderr
, "\twhere f is the inactivity interval\n");
15319 fprintf(stderr
, "\twhere g is the suspension interval\n");
15320 fprintf(stderr
, "\twhere h is the minimum data rate\n");
15321 fprintf(stderr
, "\twhere i is the mean data rate\n");
15322 fprintf(stderr
, "\twhere j is the peak data rate\n");
15323 fprintf(stderr
, "\twhere k is the max burst size\n");
15324 fprintf(stderr
, "\twhere l is the delay bound\n");
15325 fprintf(stderr
, "\twhere m is the surplus bandwidth [fixed point notation]\n");
15328 static void wl_cac_delts_usage(void)
15330 fprintf(stderr
, "Too few arguments\n");
15331 fprintf(stderr
, "wl cac_delts ver a b c \n");
15332 fprintf(stderr
, "\twhere ver is the tspec version\n");
15333 fprintf(stderr
, "\twhere a is byte[0] of tsinfo (bits 0-7)\n");
15334 fprintf(stderr
, "\twhere b is byte[1] of tsinfo (bits 8-15)\n");
15335 fprintf(stderr
, "\twhere c is byte[2] of tsinfo (bits 16-23)\n");
15339 wl_cac(void *wl
, cmd_t
*cmd
, char **argv
)
15344 tspec_arg_t tspec_arg
;
15345 char *endptr
= NULL
;
15347 char *arg1
, *user_argv
;
15348 uint8 direction
= BI_DIRECTION
;
15349 uint8 user_tid
, user_prio
, user_psb
;
15352 if ((wlu_get(wl
, WLC_GET_AP
, &ap_mode
, sizeof(ap_mode
))))
15354 ap_mode
= dtoh32(ap_mode
);
15357 fprintf(stderr
, "This command can only be executed on the STA\n");
15361 if (!strcmp(*argv
, "cac_addts"))
15363 else if (!strcmp(*argv
, "cac_delts"))
15366 fprintf(stderr
, "unknown command\n");
15367 return BCME_BADARG
;
15370 /* eat command name */
15372 (cmd_type
== 1) ? wl_cac_addts_usage():wl_cac_delts_usage();
15373 return BCME_BADARG
;
15376 buflen
= sizeof(tspec_arg_t
);
15377 memset((uint8
*)&tspec_arg
, 0, buflen
);
15379 /* get direction option */
15382 /* Unidirectional DL/UL */
15383 if (!strcmp(arg1
, "UDL") || (!strcmp(arg1
, "UUL")))
15384 direction
= DOWNLINK_DIRECTION
;
15386 if (cmd_type
== 1) {
15393 /* required argments */
15394 if (argc
< MIN_NUM_ADDTS_ARG
) {
15395 wl_cac_addts_usage();
15396 return BCME_BADARG
;
15399 tspec_arg
.length
= sizeof(tspec_arg_t
) - (2 * sizeof(uint16
));
15400 tspec_arg
.version
= (uint16
)strtol(*argv
++, &endptr
, 0);
15401 if (*endptr
!= '\0')
15404 tspec_arg
.dialog_token
= (uint8
)strtol(*argv
++, &endptr
, 0);
15405 if (*endptr
!= '\0')
15408 user_tid
= (uint8
)strtol(*argv
++, &endptr
, 0);
15409 user_tid
<<= TID_SHIFT
;
15410 if (*endptr
!= '\0')
15413 /* store the pointer for parsing */
15414 user_argv
= *argv
++;
15416 if (!strcmp(user_argv
, "uplink"))
15417 direction
= UPLINK_DIRECTION
;
15418 else if (!strcmp(user_argv
, "downlink"))
15419 direction
= DOWNLINK_DIRECTION
;
15420 else if (!strcmp(user_argv
, "bi-directional"))
15421 direction
= BI_DIRECTION
;
15425 /* store the pointer for parsing */
15426 user_argv
= *argv
++;
15428 if (!strcmp(user_argv
, "legacy"))
15430 else if (!strcmp(user_argv
, "U-APSD"))
15431 user_psb
= UAPSD_PSB
;
15435 user_prio
= (uint8
)strtol(*argv
++, &endptr
, 0);
15436 user_prio
<<= UP_SHIFT
;
15437 if (*endptr
!= '\0')
15440 tspec_arg
.tsinfo
.octets
[0] = (uint8
)(user_tid
|
15441 direction
| EDCA_ACCESS
);
15443 tspec_arg
.tsinfo
.octets
[1] = (uint8
)(user_prio
| user_psb
);
15444 tspec_arg
.tsinfo
.octets
[2] = 0x00;
15446 tspec_arg
.nom_msdu_size
= (uint16
)strtol(*argv
++, &endptr
, 0);
15447 if (*endptr
!= '\0')
15450 fixed
= (uint
)strtol(*argv
++, &endptr
, 0);
15451 if (*endptr
!= '\0')
15455 tspec_arg
.nom_msdu_size
|= 0x8000;
15457 tspec_arg
.max_msdu_size
= (uint16
)strtol(*argv
++, &endptr
, 0);
15458 if (*endptr
!= '\0')
15461 tspec_arg
.min_srv_interval
= strtol(*argv
++, &endptr
, 0);
15462 if (*endptr
!= '\0')
15465 tspec_arg
.max_srv_interval
= strtol(*argv
++, &endptr
, 0);
15466 if (*endptr
!= '\0')
15469 tspec_arg
.inactivity_interval
= strtol(*argv
++, &endptr
, 0);
15470 if (*endptr
!= '\0')
15473 tspec_arg
.suspension_interval
= strtol(*argv
++, &endptr
, 0);
15474 if (*endptr
!= '\0')
15477 tspec_arg
.min_data_rate
= strtol(*argv
++, &endptr
, 0);
15478 if (*endptr
!= '\0')
15481 tspec_arg
.mean_data_rate
= strtol(*argv
++, &endptr
, 0);
15482 if (*endptr
!= '\0')
15485 tspec_arg
.peak_data_rate
= strtol(*argv
++, &endptr
, 0);
15486 if (*endptr
!= '\0')
15489 tspec_arg
.max_burst_size
= strtol(*argv
++, &endptr
, 0);
15490 if (*endptr
!= '\0')
15493 tspec_arg
.delay_bound
= strtol(*argv
++, &endptr
, 0);
15494 if (*endptr
!= '\0')
15497 tspec_arg
.surplus_bw
= (uint16
)strtol(*argv
++, &endptr
, 0);
15498 if (*endptr
!= '\0')
15501 tspec_arg
.min_phy_rate
= strtol(*argv
++, &endptr
, 0);
15502 if (*endptr
!= '\0')
15504 printf("Setting min_phy_rate to 0x%x\n", tspec_arg
.min_phy_rate
);
15512 /* required argments */
15513 if (argc
< MIN_NUM_DELTS_ARG
) {
15514 wl_cac_delts_usage();
15515 return BCME_BADARG
;
15518 tspec_arg
.length
= sizeof(tspec_arg_t
) - (2 * sizeof(uint16
));
15519 tspec_arg
.version
= (uint16
)strtol(*argv
++, &endptr
, 0);
15521 if (*endptr
!= '\0')
15524 tspec_arg
.tsinfo
.octets
[0] = (uint8
)strtol(*argv
++, &endptr
, 0);
15525 if (*endptr
!= '\0')
15528 tspec_arg
.tsinfo
.octets
[1] = (uint8
)strtol(*argv
++, &endptr
, 0);
15529 if (*endptr
!= '\0')
15532 tspec_arg
.tsinfo
.octets
[2] = (uint8
)strtol(*argv
++, &endptr
, 0);
15533 if (*endptr
!= '\0')
15537 wl_cac_format_tspec_htod(&tspec_arg
);
15538 err
= wlu_var_setbuf(wl
, cmd
->name
, &tspec_arg
, buflen
);
15544 /* get a list of traffic stream (TSINFO) in driver */
15546 wl_tslist(void *wl
, cmd_t
*cmd
, char **argv
)
15550 int ap_mode
, err
= -1;
15551 struct tslist
*tslist
;
15553 UNUSED_PARAMETER(argv
);
15555 if ((wlu_get(wl
, WLC_GET_AP
, &ap_mode
, sizeof(ap_mode
))))
15557 ap_mode
= dtoh32(ap_mode
);
15560 fprintf(stderr
, "This command can only be executed on the STA\n");
15564 if ((err
= wlu_var_getbuf(wl
, cmd
->name
, NULL
, 0, &ptr
)) < 0)
15567 tslist
= (struct tslist
*)ptr
;
15568 tslist
->count
= dtoh32(tslist
->count
);
15569 for (i
= 0; i
< tslist
->count
; i
++)
15570 printf("tsinfo 0x%02X 0x%02X 0x%02X TID %d User Prio %d Direction %d\n",
15571 tslist
->tsinfo
[i
].octets
[0],
15572 tslist
->tsinfo
[i
].octets
[1],
15573 tslist
->tsinfo
[i
].octets
[2],
15574 WLC_CAC_GET_TID(tslist
->tsinfo
[i
]),
15575 WLC_CAC_GET_USER_PRIO(tslist
->tsinfo
[i
]),
15576 WLC_CAC_GET_DIR(tslist
->tsinfo
[i
]));
15581 /* get specific TSPEC in driver */
15583 wl_tspec(void *wl
, cmd_t
*cmd
, char **argv
)
15586 int ap_mode
, err
= -1;
15587 tspec_arg_t
*ts
, tspec_arg
;
15591 if ((wlu_get(wl
, WLC_GET_AP
, &ap_mode
, sizeof(ap_mode
))))
15593 ap_mode
= dtoh32(ap_mode
);
15596 fprintf(stderr
, "This command can only be executed on the STA\n");
15600 /* eat command name */
15607 /* required argments */
15608 if (argc
< NUM_TSLIST_ARG
) {
15609 fprintf(stderr
, "Too few arguments\n");
15610 fprintf(stderr
, "wl cac_tspec 0xaa 0xbb 0xcc \n");
15611 fprintf(stderr
, "\twhere 0xaa is byte[0] of tsinfo (bits 0-7)\n");
15612 fprintf(stderr
, "\twhere 0xbb is byte[1] of tsinfo (bits 8-15)\n");
15613 fprintf(stderr
, "\twhere 0xcc is byte[2] of tsinfo (bits 16-23)\n");
15614 return BCME_BADARG
;
15617 memset((uint8
*)&tspec_arg
, 0, sizeof(tspec_arg_t
));
15619 tspec_arg
.tsinfo
.octets
[0] = (uint8
)strtol(*argv
++, &temp
, 0);
15623 tspec_arg
.tsinfo
.octets
[1] = (uint8
)strtol(*argv
++, &temp
, 0);
15627 tspec_arg
.tsinfo
.octets
[2] = (uint8
)strtol(*argv
++, &temp
, 0);
15631 if ((err
= wlu_var_getbuf(wl
, cmd
->name
, &tspec_arg
, sizeof(tspec_arg_t
), &ptr
)) < 0)
15634 ts
= (tspec_arg_t
*)ptr
;
15635 wl_cac_format_tspec_dtoh(ts
);
15636 wl_print_tspec(ts
);
15642 /* get/set max bandwidth for each access category in ap */
15644 wme_maxbw_params(void *wl
, cmd_t
*cmd
, char **argv
)
15646 wme_max_bandwidth_t cur_params
, new_params
;
15647 char *val_p
, *ac_str
, *param
;
15656 if ((err
= wlu_get(wl
, WLC_GET_AP
, &ap_mode
, sizeof(ap_mode
))))
15660 printf("%s: AP only\n", cmd
->name
);
15664 buflen
= WLC_IOCTL_MAXLEN
;
15666 /* get the current max bandwidth, using buf as an input buffer. */
15667 strcpy(buf
, "wme_maxbw_params");
15668 if ((err
= wlu_get(wl
, WLC_GET_VAR
, &buf
[0], buflen
)) < 0) {
15672 /* cache the current values */
15673 memcpy(&cur_params
, buf
, sizeof(wme_max_bandwidth_t
));
15675 if ((ac_str
= *argv
) == NULL
) {
15676 printf("WME bandwidth limit: \n");
15677 for (aci
= 0; aci
< AC_COUNT
; aci
++) {
15678 printf("%s: bandwidth limit %d\n", ac_names
[aci
],
15679 cur_params
.ac
[aci
]);
15682 /* preload new values with current values */
15683 memcpy(&new_params
, &cur_params
, sizeof(new_params
));
15684 while ((param
= *argv
++) != NULL
) {
15685 if ((val_p
= *argv
++) == NULL
) {
15686 printf("Need value following %s\n", param
);
15687 return USAGE_ERROR
;
15690 val
= (int)strtoul(val_p
, NULL
, 0);
15692 if (!strcmp(param
, "be")) {
15693 new_params
.ac
[AC_BE
] = (uint32
)val
;
15694 } else if (!strcmp(param
, "bk")) {
15695 new_params
.ac
[AC_BK
] = (uint32
)val
;
15696 } else if (!strcmp(param
, "vi")) {
15697 new_params
.ac
[AC_VI
] = (uint32
)val
;
15698 } else if (!strcmp(param
, "vo")) {
15699 new_params
.ac
[AC_VO
] = (uint32
)val
;
15701 printf("Unknown access category: %s\n", param
);
15702 return USAGE_ERROR
;
15706 strcpy(buf
, "wme_maxbw_params");
15707 memcpy(buf
+ strlen(buf
) + 1, &new_params
, sizeof(wme_max_bandwidth_t
));
15708 err
= wlu_set(wl
, WLC_SET_VAR
, &buf
[0], buflen
);
15715 /* get the tspec list for the given station */
15717 wl_tslist_ea(void *wl
, cmd_t
*cmd
, char **argv
)
15721 int ap_mode
, err
= -1;
15722 struct tslist
*tslist
;
15728 printf("MAC address must be specified\n");
15730 } else if (!wl_ether_atoe(*argv
, &scb_val
.ea
)) {
15731 printf("Malformed MAC address parameter\n");
15735 if ((wlu_get(wl
, WLC_GET_AP
, &ap_mode
, sizeof(ap_mode
))))
15738 ap_mode
= dtoh32(ap_mode
);
15740 if ((err
= wlu_var_getbuf(wl
, cmd
->name
, &scb_val
.ea
, ETHER_ADDR_LEN
, &ptr
)) < 0)
15743 tslist
= (struct tslist
*)ptr
;
15745 for (i
= 0; i
< tslist
->count
; i
++)
15746 printf("tsinfo 0x%02X 0x%02X 0x%02X TID %d User Prio %d Direction %d\n",
15747 tslist
->tsinfo
[i
].octets
[0],
15748 tslist
->tsinfo
[i
].octets
[1],
15749 tslist
->tsinfo
[i
].octets
[2],
15750 WLC_CAC_GET_TID(tslist
->tsinfo
[i
]),
15751 WLC_CAC_GET_USER_PRIO(tslist
->tsinfo
[i
]),
15752 WLC_CAC_GET_DIR(tslist
->tsinfo
[i
]));
15758 /* get specific TSPEC for a STA */
15760 wl_tspec_ea(void *wl
, cmd_t
*cmd
, char **argv
)
15764 tspec_per_sta_arg_t tsea
;
15769 /* eat command name */
15775 /* required argments */
15776 if (argc
< (NUM_TSLIST_PER_EA_ARG
+ 1)) {
15777 fprintf(stderr
, "Too few arguments\n");
15778 fprintf(stderr
, "wl cac_tspec 0xaa 0xbb 0xcc xx:xx:xx:xx:xx:xx\n");
15779 fprintf(stderr
, "\twhere 0xaa is byte[0] of tsinfo (bits 0-7)\n");
15780 fprintf(stderr
, "\twhere 0xbb is byte[1] of tsinfo (bits 8-15)\n");
15781 fprintf(stderr
, "\twhere 0xcc is byte[2] of tsinfo (bits 16-23)\n");
15782 fprintf(stderr
, "\twhere xx:xx:xx:xx:xx:xx is mac address )\n");
15783 return BCME_BADARG
;
15786 memset((uint8
*)&tsea
, 0, sizeof(tspec_per_sta_arg_t
));
15790 ts
->tsinfo
.octets
[0] = (uint8
)strtol(*argv
++, &temp
, 0);
15794 ts
->tsinfo
.octets
[1] = (uint8
)strtol(*argv
++, &temp
, 0);
15798 ts
->tsinfo
.octets
[2] = (uint8
)strtol(*argv
++, &temp
, 0);
15802 /* add the ether address after tsinfo */
15804 printf("MAC address must be specified\n");
15806 } else if (!wl_ether_atoe(*argv
, &tsea
.ea
)) {
15807 printf("Malformed MAC address parameter\n");
15811 if ((err
= wlu_var_getbuf(wl
, cmd
->name
, &tsea
, sizeof(tspec_per_sta_arg_t
), &ptr
)) < 0)
15814 ts
= (tspec_arg_t
*)ptr
;
15815 wl_cac_format_tspec_dtoh(ts
);
15816 wl_print_tspec(ts
);
15823 static const uint8 wlu_wme_fifo2ac
[] = { AC_BK
, AC_BE
, AC_VI
, AC_VO
, AC_BE
,
15825 static const uint8 wlu_prio2fifo
[NUMPRIO
] = {
15826 0, /* 0 BE AC_BE Best Effort */
15827 1, /* 1 BK AC_BK Background */
15828 2, /* 2 -- AC_BK Background */
15829 3, /* 3 EE AC_BE Best Effort */
15830 4, /* 4 CL AC_VI Video */
15831 5, /* 5 VI AC_VI Video */
15832 6, /* 6 VO AC_VO Voice */
15833 7 /* 7 NC AC_VO Voice */
15835 #define WME_PRIO2AC(prio) wlu_wme_fifo2ac[wlu_prio2fifo[(prio)]]
15838 wl_print_tspec(tspec_arg_t
*ts
)
15841 if (ts
->version
!= TSPEC_ARG_VERSION
) {
15842 printf("\tIncorrect version of TSPEC struct: expected %d; got %d\n",
15843 TSPEC_ARG_VERSION
, ts
->version
);
15847 if (ts
->length
< (sizeof(tspec_arg_t
) - (2 * sizeof(uint16
)))) {
15848 printf("\tTSPEC arg length too short: expected %d; got %d\n",
15849 (int)(sizeof(tspec_arg_t
) - (2 * sizeof(uint16
))), ts
->length
);
15853 switch (ts
->flag
& TSPEC_STATUS_MASK
) {
15854 case TSPEC_PENDING
:
15857 case TSPEC_ACCEPTED
:
15860 case TSPEC_REJECTED
:
15868 printf("version %d\n", ts
->version
);
15869 printf("length %d\n", ts
->length
);
15871 printf("TID %d %s\n", WLC_CAC_GET_TID(ts
->tsinfo
), str
);
15872 printf("tsinfo 0x%02x 0x%02x 0x%02x\n", ts
->tsinfo
.octets
[0],
15873 ts
->tsinfo
.octets
[1], ts
->tsinfo
.octets
[2]);
15875 /* breakout bitfields for apsd */
15876 if (WLC_CAC_GET_PSB(ts
->tsinfo
)) {
15877 int ac
= WME_PRIO2AC(WLC_CAC_GET_USER_PRIO(ts
->tsinfo
));
15878 switch (WLC_CAC_GET_DIR(ts
->tsinfo
)) {
15879 case (TS_INFO_UPLINK
>> TS_INFO_DIRECTION_SHIFT
):
15880 printf("AC[%d] : Trigger enabled\n", ac
);
15883 case (TS_INFO_DOWNLINK
>> TS_INFO_DIRECTION_SHIFT
):
15884 printf("AC[%d] : Delivery enabled\n", ac
);
15887 case (TS_INFO_BIDIRECTIONAL
>>
15888 TS_INFO_DIRECTION_SHIFT
):
15889 printf("AC[%d] : Trig & Delv enabled\n", ac
);
15894 ac
= WME_PRIO2AC(WLC_CAC_GET_USER_PRIO(ts
->tsinfo
));
15895 printf("AC [%d] : Legacy Power save\n", ac
);
15899 printf("nom_msdu_size %d %s\n", (ts
->nom_msdu_size
& 0x7fff),
15900 ((ts
->nom_msdu_size
& 0x8000) ? "fixed size" : ""));
15901 printf("max_msdu_size %d\n", ts
->max_msdu_size
);
15902 printf("min_srv_interval %d\n", ts
->min_srv_interval
);
15903 printf("max_srv_interval %d\n", ts
->max_srv_interval
);
15904 printf("inactivity_interval %d\n", ts
->inactivity_interval
);
15905 printf("suspension_interval %d\n", ts
->suspension_interval
);
15906 printf("srv_start_time %d\n", ts
->srv_start_time
);
15907 printf("min_data_rate %d\n", ts
->min_data_rate
);
15908 printf("mean_data_rate %d\n", ts
->mean_data_rate
);
15909 printf("peak_data_rate %d\n", ts
->peak_data_rate
);
15910 printf("max_burst_size %d\n", ts
->max_burst_size
);
15911 printf("delay_bound %d\n", ts
->delay_bound
);
15912 printf("min_phy_rate %d\n", ts
->min_phy_rate
);
15913 printf("surplus_bw %d\n", ts
->surplus_bw
);
15914 printf("medium_time %d\n", ts
->medium_time
);
15918 /* send delts for a specific ea */
15919 /* TODO : Club this with wl_tspec_ea */
15921 wl_cac_delts_ea(void *wl
, cmd_t
*cmd
, char **argv
)
15925 char *endptr
= NULL
;
15926 tspec_per_sta_arg_t tsea
;
15930 /* eat command name */
15936 /* required argments */
15937 if (argc
< (NUM_TSLIST_PER_EA_ARG
+ 1)) {
15938 fprintf(stderr
, "Too few arguments\n");
15939 fprintf(stderr
, "wl cac_delts_ea ver 0xaa 0xbb 0xcc xx:xx:xx:xx:xx:xx\n");
15940 fprintf(stderr
, "\twhere ver is the tspec version\n");
15941 fprintf(stderr
, "\twhere 0xaa is byte[0] of tsinfo (bits 0-7)\n");
15942 fprintf(stderr
, "\twhere 0xbb is byte[1] of tsinfo (bits 8-15)\n");
15943 fprintf(stderr
, "\twhere 0xcc is byte[2] of tsinfo (bits 16-23)\n");
15944 fprintf(stderr
, "\twhere xx:xx:xx:xx:xx:xx is mac address )\n");
15945 return BCME_BADARG
;
15948 memset((uint8
*)&tsea
, 0, sizeof(tspec_per_sta_arg_t
));
15952 ts
->length
= sizeof(tspec_arg_t
) - (2 * sizeof(uint16
));
15953 ts
->version
= (uint16
)strtol(*argv
++, &endptr
, 0);
15955 if (*endptr
!= '\0')
15958 ts
->tsinfo
.octets
[0] = (uint8
)strtol(*argv
++, &endptr
, 0);
15959 if (*endptr
!= '\0')
15962 ts
->tsinfo
.octets
[1] = (uint8
)strtol(*argv
++, &endptr
, 0);
15963 if (*endptr
!= '\0')
15966 ts
->tsinfo
.octets
[2] = (uint8
)strtol(*argv
++, &endptr
, 0);
15967 if (*endptr
!= '\0')
15971 /* add the ether address after tsinfo */
15973 printf("MAC address must be specified\n");
15975 } else if (!wl_ether_atoe(*argv
, &tsea
.ea
)) {
15976 printf("Malformed MAC address parameter\n");
15980 wl_cac_format_tspec_htod(ts
);
15981 if ((err
= wlu_var_getbuf(wl
, cmd
->name
, &tsea
, sizeof(tspec_per_sta_arg_t
), &ptr
)) < 0)
15992 wl_antsel(void *wl
, cmd_t
*cmd
, char **argv
)
15994 const char *ant_sel
= "fixed";
15996 wlc_antselcfg_t val
= {{0}, 0};
15998 char *endptr
= NULL
;
15999 uint32 txchain_bitmap
= 0;
16000 uint16 antsel_mask
= 0;
16002 /* toss the command name */
16003 val_name
= *argv
++;
16008 if ((err
= wlu_iovar_get(wl
, "txchain", &txchain_bitmap
, sizeof(txchain_bitmap
))) < 0)
16011 /* iterate over max 4 chains */
16012 for (i
= 0; i
< 4; i
++) {
16013 if (!(txchain_bitmap
& (1<<i
)))
16014 antsel_mask
|= (0xF << i
* 4);
16017 if ((err
= wlu_iovar_get(wl
, val_name
, &val
, sizeof(wlc_antselcfg_t
))) < 0)
16020 printf("C3C2C1C0: ");
16021 for (i
= ANT_SELCFG_TX_UNICAST
; i
< ANT_SELCFG_MAX
; i
++) {
16022 if (val
.ant_config
[i
] & ANT_SELCFG_AUTO
)
16024 printf("0x%04X %s ",
16025 antsel_mask
| (val
.ant_config
[i
] & ANT_SELCFG_MASK
), ant_sel
);
16030 for (argc
= 0; argv
[argc
]; argc
++);
16032 if ((argc
>= 2 && argc
<= 3) || argc
> ANT_SELCFG_MAX
) {
16033 printf("invalid %d args\n", argc
);
16037 val
.ant_config
[ANT_SELCFG_TX_UNICAST
] = (uint8
)strtol(*argv
++, &endptr
, 0);
16038 printf("UTX 0x%02x\n", val
.ant_config
[ANT_SELCFG_TX_UNICAST
]);
16039 if (*endptr
!= '\0') {
16040 printf("Invaild UTX parameter: %s\n", *argv
);
16044 val
.ant_config
[ANT_SELCFG_RX_UNICAST
] =
16045 val
.ant_config
[ANT_SELCFG_TX_UNICAST
];
16046 val
.ant_config
[ANT_SELCFG_TX_DEF
] = val
.ant_config
[ANT_SELCFG_TX_UNICAST
];
16047 val
.ant_config
[ANT_SELCFG_RX_DEF
] = val
.ant_config
[ANT_SELCFG_TX_UNICAST
];
16049 val
.ant_config
[ANT_SELCFG_RX_UNICAST
] = (uint8
)strtol(*argv
++, &endptr
, 0);
16050 printf("URX 0x%02x\n", val
.ant_config
[ANT_SELCFG_RX_UNICAST
]);
16051 if (*endptr
!= '\0') {
16052 printf("Invaild URX parameter: %s\n", *argv
);
16055 val
.ant_config
[ANT_SELCFG_TX_DEF
] = (uint8
)strtol(*argv
++, &endptr
, 0);
16056 printf("DTX 0x%02x\n", val
.ant_config
[ANT_SELCFG_TX_DEF
]);
16057 if (*endptr
!= '\0') {
16058 printf("Invaild DTX parameter: %s\n", *argv
);
16061 val
.ant_config
[ANT_SELCFG_RX_DEF
] = (uint8
)strtol(*argv
++, &endptr
, 0);
16062 printf("DRX 0x%02x\n", val
.ant_config
[ANT_SELCFG_RX_DEF
]);
16063 if (*endptr
!= '\0') {
16064 printf("Invaild DRX parameter: %s\n", *argv
);
16068 err
= wlu_iovar_set(wl
, val_name
, &val
, sizeof(wlc_antselcfg_t
));
16074 wl_txcore_pwr_offset(void *wl
, cmd_t
*cmd
, char **argv
)
16076 wl_txchain_pwr_offsets_t offsets
;
16082 /* toss the command name */
16086 err
= wlu_iovar_get(wl
, cmd
->name
, &offsets
, sizeof(wl_txchain_pwr_offsets_t
));
16091 printf("txcore offsets qdBm: %d %d %d %d\n",
16092 offsets
.offset
[0], offsets
.offset
[1],
16093 offsets
.offset
[2], offsets
.offset
[3]);
16098 memset(&offsets
, 0, sizeof(wl_txchain_pwr_offsets_t
));
16100 for (i
= 0; i
< WL_NUM_TXCHAIN_MAX
; i
++, argv
++) {
16104 val
= strtol(*argv
, &endptr
, 0);
16105 if (*endptr
!= '\0')
16111 offsets
.offset
[i
] = (int8
)val
;
16114 err
= wlu_iovar_set(wl
, cmd
->name
, &offsets
, sizeof(wl_txchain_pwr_offsets_t
));
16120 wl_txcore(void *wl
, cmd_t
*cmd
, char **argv
)
16123 const char* fn_name
= "wl_txcore";
16124 int err
= 0, opt_err
, val
;
16126 bool streams_set
= FALSE
;
16128 bool core_set
= FALSE
;
16129 uint8 cck_mask
= 0;
16130 bool cck_set
= FALSE
;
16131 uint8 ofdm_mask
= 0;
16132 bool ofdm_set
= FALSE
;
16133 uint8 mcs_mask
[4] = {0, 0, 0, 0}; /* pre-initialize # of streams {core:4 | stream:4} */
16134 bool mcs_set
= FALSE
;
16136 uint32 coremask
[2] = {0, 0};
16138 /* toss the command name */
16144 if ((err
= wlu_iovar_get(wl
, cmd
->name
, &coremask
, sizeof(uint32
)*2)) < 0)
16147 printf("txcore enabled bitmap (Nsts {4..1}) 0x%02x 0x%02x 0x%02x 0x%02x\n",
16148 (coremask
[0] >> 24) & 0xff, (coremask
[0] >> 16) & 0xff,
16149 (coremask
[0] >> 8) & 0xff, coremask
[0] & 0xff);
16150 printf("txcore mask OFDM 0x%02x CCK 0x%02x\n",
16151 (coremask
[1] >> 8) & 0xff, coremask
[1] & 0xff);
16159 miniopt_init(&to
, fn_name
, "w", FALSE
);
16160 while ((opt_err
= miniopt(&to
, argv
)) != -1) {
16161 if (opt_err
== 1) {
16165 argv
+= to
.consumed
;
16167 if (to
.opt
== 's') {
16168 if (!to
.good_int
) {
16170 "%s: could not parse \"%s\" as an int for streams\n",
16171 fn_name
, to
.valstr
);
16175 streams_set
= TRUE
;
16176 streams
= (to
.val
& 0x0f);
16178 fprintf(stderr
, "%s: Nsts > %d\n", fn_name
, to
.val
);
16180 if (to
.opt
== 'c') {
16181 if (!to
.good_int
) {
16183 "%s: could not parse \"%s\" as an int for stf core\n",
16184 fn_name
, to
.valstr
);
16189 core
= (to
.val
& 0x0f) << 4;
16191 fprintf(stderr
, "%s: %1d-stream core cannot be zero\n",
16197 if (to
.opt
== 'o') {
16198 if (!to
.good_int
) {
16200 "%s: could not parse \"%s\" as an int for streams\n",
16201 fn_name
, to
.valstr
);
16206 ofdm_mask
= (to
.val
& 0x0f);
16207 if (ofdm_mask
== 0) {
16208 fprintf(stderr
, "%s: OFDM core cannot be zero\n", fn_name
);
16213 if (to
.opt
== 'k') {
16214 if (!to
.good_int
) {
16216 "%s: could not parse \"%s\" as an int for streams\n",
16217 fn_name
, to
.valstr
);
16222 cck_mask
= (to
.val
& 0x0f);
16223 if (cck_mask
== 0) {
16224 fprintf(stderr
, "%s: CCK core cannot be zero\n", fn_name
);
16230 if (streams_set
&& core_set
) {
16231 streams_set
= core_set
= FALSE
;
16234 mcs_mask
[idx
] = (uint8
)(core
|streams
);
16238 if (streams_set
!= core_set
) {
16239 fprintf(stderr
, "%s: require to set both -s x -c y\n", fn_name
);
16245 coremask
[0] |= mcs_mask
[0] << 0;
16246 coremask
[0] |= mcs_mask
[1] << 8;
16247 coremask
[0] |= mcs_mask
[2] << 16;
16248 coremask
[0] |= mcs_mask
[3] << 24;
16251 coremask
[1] |= cck_mask
;
16253 coremask
[1] |= ofdm_mask
<< 8;
16255 err
= wlu_var_setbuf(wl
, cmd
->name
, coremask
, sizeof(uint32
)*2);
16261 wl_txfifo_sz(void *wl
, cmd_t
*cmd
, char **argv
)
16264 const char *cmdname
= "txfifo_sz";
16265 wl_txfifo_sz_t ts
, *reply
;
16270 UNUSED_PARAMETER(cmd
);
16272 if ((param
= *++argv
) == NULL
)
16273 return USAGE_ERROR
;
16275 fifo
= atoi(param
);
16277 return USAGE_ERROR
;
16279 ts
.magic
= WL_TXFIFO_SZ_MAGIC
;
16281 if ((param
= *++argv
)) {
16282 ts
.size
= atoi(param
);
16283 err
= wlu_var_setbuf(wl
, cmdname
, &ts
, sizeof(ts
));
16285 if ((err
= wlu_var_getbuf_sm(wl
, cmdname
, &ts
, sizeof(ts
), &ptr
) < 0))
16287 reply
= (wl_txfifo_sz_t
*)ptr
;
16288 printf("fifo %d size %d\n", fifo
, reply
->size
);
16294 wl_pfn_set(void *wl
, cmd_t
*cmd
, char **argv
)
16297 wl_pfn_param_t pfn_param
;
16299 UNUSED_PARAMETER(cmd
);
16301 /* Setup default values */
16302 pfn_param
.version
= PFN_VERSION
;
16303 /* Sorting based on list order, no back ground scan, no autoswitch, and immediate scan */
16304 pfn_param
.flags
= (PFN_LIST_ORDER
<< SORT_CRITERIA_BIT
| ENABLE
<< IMMEDIATE_SCAN_BIT
);
16305 /* Scan frequency of 30 sec */
16306 pfn_param
.scan_freq
= 30;
16307 /* RSSI margin of 30 dBm */
16308 pfn_param
.rssi_margin
= 30;
16309 /* Network timeout 60 sec */
16310 pfn_param
.lost_network_timeout
= 60;
16313 if (!stricmp(*argv
, "scanfrq"))
16314 pfn_param
.scan_freq
= atoi(*++argv
);
16316 else if (!stricmp(*argv
, "netimeout"))
16317 pfn_param
.lost_network_timeout
= atoi(*++argv
);
16319 else if (!stricmp(*argv
, "rssi_delta"))
16320 pfn_param
.rssi_margin
= atoi(*++argv
);
16322 else if (!stricmp(*argv
, "sort")) {
16324 pfn_param
.flags
&= ~SORT_CRITERIA_MASK
;
16325 if (!stricmp(*argv
, "listorder"))
16326 pfn_param
.flags
|= (PFN_LIST_ORDER
<< SORT_CRITERIA_BIT
);
16327 else if (!stricmp(*argv
, "rssi"))
16328 pfn_param
.flags
|= (PFN_RSSI
<< SORT_CRITERIA_BIT
);
16330 fprintf(stderr
, "Invalid sort option %s\n", *argv
);
16334 fprintf(stderr
, "Missing sort option\n");
16337 } else if (!stricmp(*argv
, "bkgscan")) {
16339 pfn_param
.flags
&= ~ENABLE_BKGRD_SCAN_MASK
;
16341 pfn_param
.flags
|= (ENABLE
<< ENABLE_BKGRD_SCAN_BIT
);
16343 pfn_param
.flags
|= (DISABLE
<< ENABLE_BKGRD_SCAN_BIT
);
16345 fprintf(stderr
, "Missing bkgscan option\n");
16348 } else if (!stricmp(*argv
, "autoswitch")) {
16349 pfn_param
.flags
&= ~AUTO_NET_SWITCH_MASK
;
16352 pfn_param
.flags
|= (ENABLE
<< AUTO_NET_SWITCH_BIT
);
16354 pfn_param
.flags
|= (DISABLE
<< AUTO_NET_SWITCH_BIT
);
16356 fprintf(stderr
, "Missing autoswitch option\n");
16359 } else if (!stricmp(*argv
, "immediate")) {
16360 pfn_param
.flags
&= ~IMMEDIATE_SCAN_MASK
;
16363 pfn_param
.flags
|= (ENABLE
<< IMMEDIATE_SCAN_BIT
);
16365 pfn_param
.flags
|= (DISABLE
<< IMMEDIATE_SCAN_BIT
);
16367 fprintf(stderr
, "Missing immediate option\n");
16370 } else if (!stricmp(*argv
, "autoconnect")) {
16371 pfn_param
.flags
&= ~AUTO_CONNECT_MASK
;
16374 pfn_param
.flags
|= (ENABLE
<< AUTO_CONNECT_BIT
);
16376 pfn_param
.flags
|= (DISABLE
<< AUTO_CONNECT_BIT
);
16378 fprintf(stderr
, "Missing autoconnect option\n");
16382 fprintf(stderr
, "Invalid parameter %s\n", *argv
);
16387 pfn_param
.version
= htod32(pfn_param
.version
);
16388 pfn_param
.scan_freq
= htod32(pfn_param
.scan_freq
);
16389 pfn_param
.lost_network_timeout
= htod32(pfn_param
.lost_network_timeout
);
16390 pfn_param
.flags
= htod16(pfn_param
.flags
);
16391 pfn_param
.rssi_margin
= htod16(pfn_param
.rssi_margin
);
16392 if ((err
= wlu_iovar_set(wl
, "pfn_set", &pfn_param
, sizeof(wl_pfn_param_t
))))
16400 wl_pfn_add(void *wl
, cmd_t
*cmd
, char **argv
)
16403 wl_pfn_t pfn_element
;
16405 UNUSED_PARAMETER(cmd
);
16407 memset(&pfn_element
, '\0', sizeof(wl_pfn_t
));
16408 memset(key
, '\0', sizeof(key
));
16410 /* Default join setting, open, no WPA, no WEP and bss */
16411 pfn_element
.bss_type
= DOT11_BSSTYPE_INFRASTRUCTURE
;
16412 pfn_element
.auth
= DOT11_OPEN_SYSTEM
;
16413 pfn_element
.wpa_auth
= WPA_AUTH_DISABLED
;
16414 pfn_element
.wsec
= 0;
16415 pfn_element
.infra
= 1;
16418 if (!stricmp(*argv
, "ssid")) {
16420 pfn_element
.ssid
.SSID_len
= strlen(*argv
);
16421 if (pfn_element
.ssid
.SSID_len
> DOT11_MAX_SSID_LEN
) {
16422 fprintf(stderr
, "SSID too long: %s\n", *argv
);
16425 memcpy(pfn_element
.ssid
.SSID
, *argv
, pfn_element
.ssid
.SSID_len
);
16427 } else if (!stricmp(*argv
, "key")) {
16429 strncpy(key
, *argv
, sizeof(key
));
16430 if (strlen(key
) == 0) {
16431 fprintf(stderr
, "Missing value for key\n");
16434 } else if (!stricmp(*argv
, "imode")) {
16436 if (!stricmp(*argv
, "bss")) {
16437 pfn_element
.bss_type
= DOT11_BSSTYPE_INFRASTRUCTURE
;
16438 pfn_element
.infra
= 1;
16439 } else if (!stricmp(*argv
, "ibss")) {
16440 pfn_element
.bss_type
= DOT11_BSSTYPE_INDEPENDENT
;
16441 pfn_element
.infra
= 0;
16443 fprintf(stderr
, "Invalid imode arg %s\n", *argv
);
16448 fprintf(stderr
, "Missing option for imode\n");
16451 } else if (!stricmp(*argv
, "amode")) {
16453 if (!stricmp(*argv
, "open"))
16454 pfn_element
.auth
= DOT11_OPEN_SYSTEM
;
16455 else if (!stricmp(*argv
, "shared"))
16456 pfn_element
.auth
= DOT11_SHARED_KEY
;
16458 fprintf(stderr
, "Invalid imode arg %s\n", *argv
);
16462 fprintf(stderr
, "Missing option for amode\n");
16465 } else if (!stricmp(*argv
, "wpa_auth")) {
16467 int kmax
= sizeof(pfn_element
.pfn_security
.wpa_sec_key
.key
);
16468 if (strlen(key
) == 0) {
16469 fprintf(stderr
, "Key must be specified before wpa_auth\n");
16471 } else if ((int)strlen(key
) > kmax
) {
16472 fprintf(stderr
, "Key too long for wpa_auth\n");
16475 pfn_element
.pfn_security
.wpa_sec_key
.key_len
= strlen(key
);
16476 pfn_element
.pfn_security
.wpa_sec_key
.flags
= WSEC_PASSPHRASE
;
16477 memcpy(pfn_element
.pfn_security
.wpa_sec_key
.key
, key
,
16478 pfn_element
.pfn_security
.wpa_sec_key
.key_len
);
16480 pfn_element
.pfn_security
.wpa_sec_key
.key_len
=
16481 htod16(pfn_element
.pfn_security
.wpa_sec_key
.key_len
);
16482 pfn_element
.pfn_security
.wpa_sec_key
.flags
=
16483 htod16(pfn_element
.pfn_security
.wpa_sec_key
.flags
);
16485 if (!stricmp(*argv
, "wpapsk"))
16486 pfn_element
.wpa_auth
= WPA_AUTH_PSK
;
16487 else if (!stricmp(*argv
, "wpa2psk"))
16488 pfn_element
.wpa_auth
= WPA2_AUTH_PSK
;
16489 else if (!stricmp(*argv
, "wpadisabled"))
16490 pfn_element
.wpa_auth
= WPA_AUTH_DISABLED
;
16492 fprintf(stderr
, "Invalid wpa_auth option %s\n", *argv
);
16496 fprintf(stderr
, "Missing option for wpa_auth\n");
16499 } else if (!stricmp(*argv
, "wsec")) {
16501 if (!stricmp(*argv
, "WEP")) {
16502 char *keystr
[2] = {key
, '\0'};
16504 int kmax
= sizeof(pfn_element
.pfn_security
.sec_key
.data
);
16506 pfn_element
.pfn_security
.sec_key
.index
= 0;
16508 if (strlen(key
) == 0) {
16509 fprintf(stderr
, "Key must be specified "
16510 "before wsec WEP\n");
16512 } else if ((int)strlen(key
) > kmax
) {
16513 fprintf(stderr
, "Key too long for WEP\n");
16515 } else if (parse_wep(keystr
,
16516 &pfn_element
.pfn_security
.sec_key
, FALSE
))
16518 pfn_element
.wsec
= WEP_ENABLED
;
16520 pfn_element
.pfn_security
.sec_key
.index
=
16521 htod32(pfn_element
.pfn_security
.sec_key
.index
);
16522 pfn_element
.pfn_security
.sec_key
.len
=
16523 htod32(pfn_element
.pfn_security
.sec_key
.len
);
16524 pfn_element
.pfn_security
.sec_key
.algo
=
16525 htod32(pfn_element
.pfn_security
.sec_key
.algo
);
16526 pfn_element
.pfn_security
.sec_key
.flags
=
16527 htod32(pfn_element
.pfn_security
.sec_key
.flags
);
16528 } else if (!stricmp(*argv
, "TKIP"))
16529 pfn_element
.wsec
= TKIP_ENABLED
;
16530 else if (!stricmp(*argv
, "AES"))
16531 pfn_element
.wsec
= AES_ENABLED
;
16532 else if (!stricmp(*argv
, "TKIPAES"))
16533 pfn_element
.wsec
= TKIP_ENABLED
| AES_ENABLED
;
16535 fprintf(stderr
, "Invalid wsec option %s\n", *argv
);
16539 fprintf(stderr
, "Missing option for wsec\n");
16543 fprintf(stderr
, "Invalid parameter %s\n", *argv
);
16548 pfn_element
.ssid
.SSID_len
= htod32(pfn_element
.ssid
.SSID_len
);
16549 pfn_element
.bss_type
= htod32(pfn_element
.bss_type
);
16550 pfn_element
.infra
= htod32(pfn_element
.infra
);
16551 pfn_element
.auth
= htod32(pfn_element
.auth
);
16552 pfn_element
.wpa_auth
= htod32(pfn_element
.wpa_auth
);
16553 pfn_element
.wsec
= htod32(pfn_element
.wsec
);
16554 if ((err
= wlu_iovar_set(wl
, "pfn_add", &pfn_element
, sizeof(wl_pfn_t
))))
16561 wl_pfn(void *wl
, cmd_t
*cmd
, char **argv
)
16565 UNUSED_PARAMETER(cmd
);
16569 err
= wlu_iovar_setint(wl
, "pfn", (val
? 1 : 0));
16571 err
= wlu_iovar_getint(wl
, "pfn", &val
);
16581 wl_pfn_event_check(void *wl
, cmd_t
*cmd
, char **argv
)
16584 struct sockaddr_ll sll
;
16586 char ifnames
[IFNAMSIZ
] = {"eth1"};
16587 bcm_event_t
* event
;
16591 struct ether_addr
*addr
;
16592 char eabuf
[ETHER_ADDR_STR_LEN
];
16594 UNUSED_PARAMETER(wl
);
16595 UNUSED_PARAMETER(cmd
);
16598 strncpy(ifnames
, *argv
, IFNAMSIZ
);
16600 memset(&ifr
, 0, sizeof(ifr
));
16601 strncpy(ifr
.ifr_name
, ifnames
, IFNAMSIZ
);
16603 fd
= socket(PF_PACKET
, SOCK_RAW
, hton16(ETHER_TYPE_BRCM
));
16605 printf("Cannot create socket %d\n", fd
);
16609 err
= ioctl(fd
, SIOCGIFINDEX
, &ifr
);
16611 printf("Cannot get index %d\n", err
);
16615 memset(&sll
, 0, sizeof(sll
));
16616 sll
.sll_family
= AF_PACKET
;
16617 sll
.sll_protocol
= hton16(ETHER_TYPE_BRCM
);
16618 sll
.sll_ifindex
= ifr
.ifr_ifindex
;
16619 err
= bind(fd
, (struct sockaddr
*)&sll
, sizeof(sll
));
16621 printf("Cannot get index %d\n", err
);
16626 recv(fd
, data
, sizeof(data
), 0);
16627 event
= (bcm_event_t
*)data
;
16628 addr
= (struct ether_addr
*)&(event
->event
.addr
);
16630 event_type
= ntoh32(event
->event
.event_type
);
16632 if (addr
!= NULL
) {
16633 sprintf(eabuf
, "%02x:%02x:%02x:%02x:%02x:%02x",
16634 (uchar
)addr
->octet
[0]&0xff,
16635 (uchar
)addr
->octet
[1]&0xff,
16636 (uchar
)addr
->octet
[2]&0xff,
16637 (uchar
)addr
->octet
[3]&0xff,
16638 (uchar
)addr
->octet
[4]&0xff,
16639 (uchar
)addr
->octet
[5]&0xff);
16642 if (ntoh32(event
->event
.datalen
)) {
16643 ssid
= (wlc_ssid_t
*)(data
+ sizeof(bcm_event_t
));
16644 char ssidbuf
[SSID_FMT_BUF_LEN
];
16646 wl_format_ssid(ssidbuf
, ssid
->SSID
, ssid
->SSID_len
);
16648 if (WLC_E_PFN_NET_FOUND
== event_type
)
16649 printf("Network found SSID = %s, SSID_len = %d\n",
16650 ssidbuf
, ssid
->SSID_len
);
16652 if (WLC_E_PFN_NET_LOST
== event_type
)
16653 printf("Network lost SSID = %s, SSID_len = %d\n",
16654 ssidbuf
, ssid
->SSID_len
);
16657 if (WLC_E_LINK
== event_type
|| WLC_E_NDIS_LINK
== event_type
) {
16658 if (ntoh16(event
->event
.flags
) & WLC_EVENT_MSG_LINK
)
16659 printf("MACEVENT Link up :%s\n", eabuf
);
16661 printf("MACEVENT Link down :%s\n", eabuf
);
16668 #define ESCAN_EVENTS_BUFFER_SIZE 2048
16671 wl_escan_event_check(void *wl
, cmd_t
*cmd
, char **argv
)
16673 int fd
, err
, i
, octets
;
16674 struct sockaddr_ll sll
;
16676 char ifnames
[IFNAMSIZ
] = {"eth1"};
16677 uint8 print_flag
= 4;
16678 bcm_event_t
* event
;
16679 uint32 reason
, status
;
16682 struct ether_addr
*addr
;
16683 uint8 event_inds_mask
[WL_EVENTING_MASK_LEN
]; /* 128-bit mask */
16685 wl_escan_result_t
* escan_data
;
16688 UNUSED_PARAMETER(wl
);
16689 UNUSED_PARAMETER(cmd
);
16692 strncpy(ifnames
, *argv
, (IFNAMSIZ
- 1));
16694 print_flag
= atoi(*argv
);
16697 memset(&ifr
, 0, sizeof(ifr
));
16698 strncpy(ifr
.ifr_name
, ifnames
, (IFNAMSIZ
- 1));
16700 memset(event_inds_mask
, '\0', WL_EVENTING_MASK_LEN
);
16701 event_inds_mask
[WLC_E_ESCAN_RESULT
/ 8] |= 1 << (WLC_E_ESCAN_RESULT
% 8);
16702 if ((err
= wlu_iovar_set(wl
, "event_msgs", &event_inds_mask
, WL_EVENTING_MASK_LEN
)))
16705 fd
= socket(PF_PACKET
, SOCK_RAW
, hton16(ETHER_TYPE_BRCM
));
16707 printf("Cannot create socket %d\n", fd
);
16711 err
= ioctl(fd
, SIOCGIFINDEX
, &ifr
);
16713 printf("Cannot get index %d\n", err
);
16717 memset(&sll
, 0, sizeof(sll
));
16718 sll
.sll_family
= AF_PACKET
;
16719 sll
.sll_protocol
= hton16(ETHER_TYPE_BRCM
);
16720 sll
.sll_ifindex
= ifr
.ifr_ifindex
;
16721 err
= bind(fd
, (struct sockaddr
*)&sll
, sizeof(sll
));
16723 printf("Cannot bind %d\n", err
);
16727 data
= (char*)malloc(ESCAN_EVENTS_BUFFER_SIZE
);
16729 if (data
== NULL
) {
16730 printf("Cannot not allocate %d bytes for events receive buffer\n",
16731 ESCAN_EVENTS_BUFFER_SIZE
);
16736 octets
= recv(fd
, data
, ESCAN_EVENTS_BUFFER_SIZE
, 0);
16737 event
= (bcm_event_t
*)data
;
16738 addr
= (struct ether_addr
*)&(event
->event
.addr
);
16740 event_type
= ntoh32(event
->event
.event_type
);
16742 if ((event_type
== WLC_E_ESCAN_RESULT
) && (octets
> 0)) {
16743 escan_data
= (wl_escan_result_t
*)&data
[sizeof(bcm_event_t
)];
16744 reason
= ntoh32(event
->event
.reason
);
16745 status
= ntoh32(event
->event
.status
);
16747 if (print_flag
& 1)
16748 printf("WLC_E_ESCAN_RESULT, (sync_id,status) = (%d,%d)\n",
16749 escan_data
->sync_id
, status
);
16751 if (print_flag
& 2)
16752 for (i
= 0; i
< escan_data
->bss_count
; i
++)
16753 dump_bss_info(&escan_data
->bss_info
[i
]);
16755 if (print_flag
& 4) {
16756 if (status
== WLC_E_STATUS_PARTIAL
) {
16757 printf("sync_id: %d, WLC_E_STATUS_PARTIAL\n",
16758 escan_data
->sync_id
);
16759 for (i
= 0; i
< escan_data
->bss_count
; i
++)
16760 dump_bss_info(&escan_data
->bss_info
[i
]);
16762 if (status
== WLC_E_STATUS_SUCCESS
)
16763 printf("sync_id: %d, WLC_E_STATUS_SUCCESS => SCAN_DONE\n",
16764 escan_data
->sync_id
);
16765 if ((status
!= WLC_E_STATUS_SUCCESS
) &&
16766 (status
!= WLC_E_STATUS_PARTIAL
))
16767 printf("sync_id: %d, status:%d, misc. error/abort\n",
16768 escan_data
->sync_id
, status
);
16771 if (print_flag
& 8) {
16772 int remainder
= escan_data
->bss_info
[0].ie_length
;
16773 int processed
= sizeof(wl_escan_result_t
);
16774 uint8
* iebuf
= &((uint8
*)escan_data
)[sizeof(wl_escan_result_t
)];
16776 if (status
!= WLC_E_STATUS_PARTIAL
)
16779 printf("MOREINFO: (sync_id,buflen,ielen) = (%d,%d,%d)\n",
16780 escan_data
->sync_id
,
16781 escan_data
->buflen
,
16782 escan_data
->bss_info
[0].ie_length
);
16784 /* do a tlv sanity check */
16785 while (remainder
> 0) {
16786 processed
+= 1 + 1 + iebuf
[1];
16787 remainder
-= 1 + 1 + iebuf
[1];
16788 iebuf
+= 1 + 1 + iebuf
[1];
16790 if (processed
>= ESCAN_EVENTS_BUFFER_SIZE
)
16793 if (remainder
!= 0) {
16794 printf("ERROR: IE tlv sanity check failed for "
16795 "(ssid,sync_id,buflen,ielen,remainder) = "
16796 "(%s,%d,%d,%d,%d)\n",
16797 escan_data
->bss_info
[0].SSID
,
16798 escan_data
->sync_id
, escan_data
->buflen
,
16799 escan_data
->bss_info
[0].ie_length
,
16801 iebuf
= &((uint8
*)escan_data
)[sizeof(wl_escan_result_t
)];
16802 if ((escan_data
->buflen
- sizeof(wl_escan_result_t
)) > 0) {
16804 i
< (int)(escan_data
->buflen
-
16805 sizeof(wl_escan_result_t
));
16807 printf("%02x ", iebuf
[i
]);
16816 /* if we ever reach here */
16823 struct escan_bss
*next
;
16824 wl_bss_info_t bss
[1];
16826 #define ESCAN_BSS_FIXED_SIZE 4
16829 wl_escanresults(void *wl
, cmd_t
*cmd
, char **argv
)
16831 int params_size
= (WL_SCAN_PARAMS_FIXED_SIZE
+ OFFSETOF(wl_escan_params_t
, params
)) +
16832 (WL_NUMCHANNELS
* sizeof(uint16
));
16833 wl_escan_params_t
*params
;
16834 int fd
, err
, octets
;
16835 struct sockaddr_ll sll
;
16837 char ifnames
[IFNAMSIZ
] = {"eth1"};
16838 bcm_event_t
*event
;
16839 uint32 reason
, status
;
16842 struct ether_addr
*addr
;
16843 uint8 event_inds_mask
[WL_EVENTING_MASK_LEN
]; /* 128-bit mask */
16844 wl_escan_result_t
*escan_data
;
16845 struct escan_bss
*escan_bss_head
= NULL
;
16846 struct escan_bss
*escan_bss_tail
= NULL
;
16847 struct escan_bss
*result
;
16849 params_size
+= WL_SCAN_PARAMS_SSID_MAX
* sizeof(wlc_ssid_t
);
16850 params
= (wl_escan_params_t
*)malloc(params_size
);
16851 if (params
== NULL
) {
16852 fprintf(stderr
, "Error allocating %d bytes for scan params\n", params_size
);
16855 memset(params
, 0, params_size
);
16857 err
= wl_scan_prep(wl
, cmd
, argv
, ¶ms
->params
, ¶ms_size
);
16861 memset(&ifr
, 0, sizeof(ifr
));
16863 strncpy(ifr
.ifr_name
, ((struct ifreq
*)wl
)->ifr_name
, (IFNAMSIZ
- 1));
16865 strncpy(ifr
.ifr_name
, ifnames
, (IFNAMSIZ
- 1));
16867 memset(event_inds_mask
, '\0', WL_EVENTING_MASK_LEN
);
16868 event_inds_mask
[WLC_E_ESCAN_RESULT
/ 8] |= 1 << (WLC_E_ESCAN_RESULT
% 8);
16869 if ((err
= wlu_iovar_set(wl
, "event_msgs", &event_inds_mask
, WL_EVENTING_MASK_LEN
)))
16872 fd
= socket(PF_PACKET
, SOCK_RAW
, hton16(ETHER_TYPE_BRCM
));
16874 printf("Cannot create socket %d\n", fd
);
16879 err
= ioctl(fd
, SIOCGIFINDEX
, &ifr
);
16881 printf("Cannot get index %d\n", err
);
16885 /* bind the socket first before starting escan so we won't miss any event */
16886 memset(&sll
, 0, sizeof(sll
));
16887 sll
.sll_family
= AF_PACKET
;
16888 sll
.sll_protocol
= hton16(ETHER_TYPE_BRCM
);
16889 sll
.sll_ifindex
= ifr
.ifr_ifindex
;
16890 err
= bind(fd
, (struct sockaddr
*)&sll
, sizeof(sll
));
16892 printf("Cannot bind %d\n", err
);
16896 params
->version
= htod32(ESCAN_REQ_VERSION
);
16897 params
->action
= htod16(WL_SCAN_ACTION_START
);
16900 srand((unsigned)time(NULL
));
16901 params
->sync_id
= htod16(rand() & 0xffff);
16903 params
->sync_id
= htod16(4321);
16904 #endif /* #if defined(linux) */
16906 params_size
+= OFFSETOF(wl_escan_params_t
, params
);
16907 err
= wlu_iovar_setbuf(wl
, "escan", params
, params_size
, buf
, WLC_IOCTL_MAXLEN
);
16909 data
= (char*)malloc(ESCAN_EVENTS_BUFFER_SIZE
);
16911 if (data
== NULL
) {
16912 printf("Cannot not allocate %d bytes for events receive buffer\n",
16913 ESCAN_EVENTS_BUFFER_SIZE
);
16918 /* receive scan result */
16920 octets
= recv(fd
, data
, ESCAN_EVENTS_BUFFER_SIZE
, 0);
16921 event
= (bcm_event_t
*)data
;
16922 addr
= (struct ether_addr
*)&(event
->event
.addr
);
16923 event_type
= ntoh32(event
->event
.event_type
);
16925 if ((event_type
== WLC_E_ESCAN_RESULT
) && (octets
> 0)) {
16926 escan_data
= (wl_escan_result_t
*)&data
[sizeof(bcm_event_t
)];
16927 reason
= ntoh32(event
->event
.reason
);
16928 status
= ntoh32(event
->event
.status
);
16930 if (status
== WLC_E_STATUS_PARTIAL
) {
16931 wl_bss_info_t
*bi
= &escan_data
->bss_info
[0];
16932 wl_bss_info_t
*bss
;
16934 /* check if we've received info of same BSSID */
16935 for (result
= escan_bss_head
; result
; result
= result
->next
) {
16938 #define WLC_BSS_RSSI_ON_CHANNEL 0x0002 /* Copied from wlc.h. Is there a better way to do this? */
16940 if (!wlu_bcmp(bi
->SSID
, bss
->SSID
, ETHER_ADDR_LEN
) &&
16941 CHSPEC_BAND(bi
->chanspec
) ==
16942 CHSPEC_BAND(bss
->chanspec
) &&
16943 bi
->SSID_len
== bss
->SSID_len
&&
16944 !wlu_bcmp(bi
->SSID
, bss
->SSID
, bi
->SSID_len
))
16949 /* New BSS. Allocate memory and save it */
16950 struct escan_bss
*ebss
= malloc(ESCAN_BSS_FIXED_SIZE
16954 perror("can't allocate memory for bss");
16959 memcpy(&ebss
->bss
, bi
, bi
->length
);
16960 if (escan_bss_tail
) {
16961 escan_bss_tail
->next
= ebss
;
16964 escan_bss_head
= ebss
;
16966 escan_bss_tail
= ebss
;
16969 /* We've got this BSS. Update rssi if necessary */
16970 if ((bss
->flags
& WLC_BSS_RSSI_ON_CHANNEL
) ==
16971 (bi
->flags
& WLC_BSS_RSSI_ON_CHANNEL
)) {
16972 /* preserve max RSSI if the measurements are
16973 * both on-channel or both off-channel
16975 bss
->RSSI
= MAX(bss
->RSSI
, bi
->RSSI
);
16976 } else if ((bss
->flags
& WLC_BSS_RSSI_ON_CHANNEL
) &&
16977 (bi
->flags
& WLC_BSS_RSSI_ON_CHANNEL
) == 0) {
16978 /* preserve the on-channel rssi measurement
16979 * if the new measurement is off channel
16981 bss
->RSSI
= bi
->RSSI
;
16982 bss
->flags
|= WLC_BSS_RSSI_ON_CHANNEL
;
16986 else if (status
== WLC_E_STATUS_SUCCESS
) {
16987 /* Escan finished. Let's go dump the results. */
16991 printf("sync_id: %d, status:%d, misc. error/abort\n",
16992 escan_data
->sync_id
, status
);
16998 /* print scan results */
16999 for (result
= escan_bss_head
; result
; result
= result
->next
) {
17000 dump_bss_info(result
->bss
);
17004 /* free scan results */
17005 result
= escan_bss_head
;
17007 struct escan_bss
*tmp
= result
->next
;
17021 wl_event_filter(void *wl
, cmd_t
*cmd
, char **argv
)
17024 uint8 event_inds_mask
[WL_EVENTING_MASK_LEN
]; /* 128-bit mask */
17026 UNUSED_PARAMETER(cmd
);
17027 UNUSED_PARAMETER(argv
);
17029 memset(event_inds_mask
, '\0', WL_EVENTING_MASK_LEN
);
17031 /* Register for following event for pfn */
17032 event_inds_mask
[WLC_E_LINK
/ 8] |= 1 << (WLC_E_LINK
% 8);
17033 event_inds_mask
[WLC_E_PFN_NET_FOUND
/ 8] |= 1 << (WLC_E_PFN_NET_FOUND
% 8);
17034 event_inds_mask
[WLC_E_PFN_NET_LOST
/ 8] |= 1 << (WLC_E_PFN_NET_LOST
% 8);
17036 if ((err
= wlu_iovar_set(wl
, "event_msgs", &event_inds_mask
, WL_EVENTING_MASK_LEN
)))
17043 static dbg_msg_t toe_cmpnt
[] = {
17044 {TOE_TX_CSUM_OL
, "tx_csum_ol"},
17045 {TOE_RX_CSUM_OL
, "rx_csum_ol"},
17049 static dbg_msg_t arpoe_cmpnt
[] = {
17050 {ARP_OL_AGENT
, "agent"},
17051 {ARP_OL_SNOOP
, "snoop"},
17052 {ARP_OL_HOST_AUTO_REPLY
, "host_auto_reply"},
17053 {ARP_OL_PEER_AUTO_REPLY
, "peer_auto_reply"},
17058 * Tcpip Offload Component-wise get/set control.
17061 wl_offload_cmpnt(void *wl
, cmd_t
*cmd
, char **argv
)
17064 uint val
, last_val
= 0, cmpnt_add
= 0, cmpnt_del
= 0;
17066 dbg_msg_t
*dbg_msg
= NULL
;
17070 if (strcmp(cmd
->name
, "toe_ol") == 0)
17071 dbg_msg
= toe_cmpnt
;
17072 else if (strcmp(cmd
->name
, "arp_ol") == 0)
17073 dbg_msg
= arpoe_cmpnt
;
17075 if ((ret
= wlu_var_getbuf(wl
, cmd
->name
, NULL
, 0, &ptr
)) < 0)
17077 cmpnt
= dtoh32(*(int *)ptr
);
17080 printf("0x%x ", cmpnt
);
17081 for (i
= 0; (val
= dbg_msg
[i
].value
); i
++) {
17082 if ((cmpnt
& val
) && (val
!= last_val
))
17083 printf(" %s", dbg_msg
[i
].string
);
17092 if (*s
== '+' || *s
== '-')
17095 cmpnt_del
= ~0; /* make the whole list absolute */
17096 val
= strtoul(s
, &endptr
, 0);
17097 /* not a plain integer if not all the string was parsed by strtoul */
17098 if (*endptr
!= '\0') {
17099 for (i
= 0; (val
= dbg_msg
[i
].value
); i
++)
17100 if (stricmp(dbg_msg
[i
].string
, s
) == 0)
17112 cmpnt
&= ~cmpnt_del
;
17113 cmpnt
|= cmpnt_add
;
17115 cmpnt
= htod32(cmpnt
);
17116 return (wlu_var_setbuf(wl
, cmd
->name
, &cmpnt
, sizeof(int)));
17119 fprintf(stderr
, "msg values may be a list of numbers or names from the following set.\n");
17120 fprintf(stderr
, "Use a + or - prefix to make an incremental change.");
17122 for (i
= 0; (val
= dbg_msg
[i
].value
); i
++) {
17123 if (val
!= last_val
)
17124 fprintf(stderr
, "\n0x%04x %s", val
, dbg_msg
[i
].string
);
17126 fprintf(stderr
, ", %s", dbg_msg
[i
].string
);
17129 fprintf(stderr
, "\n");
17135 * If a host IP address is given, add it to the host-cache, e.g. "wl arp_hostip 192.168.1.1".
17136 * If no address is given, dump all the addresses.
17139 wl_hostip(void *wl
, cmd_t
*cmd
, char **argv
)
17142 struct ipv4_addr ipa_set
, *ipa_get
, null_ipa
;
17147 if ((ret
= wlu_var_getbuf(wl
, cmd
->name
, NULL
, 0, &ptr
)) < 0)
17150 memset(null_ipa
.addr
, 0, IPV4_ADDR_LEN
);
17152 for (ipa_get
= (struct ipv4_addr
*)ptr
;
17153 memcmp(null_ipa
.addr
, ipa_get
->addr
, IPV4_ADDR_LEN
) != 0;
17155 printf("%s\n", wl_iptoa(ipa_get
));
17157 printf("Total %d host addresses\n", (int)(ipa_get
- (struct ipv4_addr
*)ptr
));
17160 if (!wl_atoip(*argv
, &ipa_set
))
17162 /* we add one ip-addr at a time */
17163 return wlu_var_setbuf(wl
, cmd
->name
, &ipa_set
, sizeof(IPV4_ADDR_LEN
));
17170 wl_arp_stats(void *wl
, cmd_t
*cmd
, char **argv
)
17173 struct arp_ol_stats_t
*arpstats
;
17179 if ((ret
= wlu_var_getbuf(wl
, cmd
->name
, NULL
, 0, &ptr
)) < 0)
17181 arpstats
= (struct arp_ol_stats_t
*)ptr
;
17182 printf("host_ip_entries = %d\n", dtoh32(arpstats
->host_ip_entries
));
17183 printf("host_ip_overflow = %d\n", dtoh32(arpstats
->host_ip_overflow
));
17184 printf("arp_table_entries = %d\n", dtoh32(arpstats
->arp_table_entries
));
17185 printf("arp_table_overflow = %d\n", dtoh32(arpstats
->arp_table_overflow
));
17186 printf("host_request = %d\n", dtoh32(arpstats
->host_request
));
17187 printf("host_reply = %d\n", dtoh32(arpstats
->host_reply
));
17188 printf("host_service = %d\n", dtoh32(arpstats
->host_service
));
17189 printf("peer_request = %d\n", dtoh32(arpstats
->peer_request
));
17190 printf("peer_request_drop = %d\n", dtoh32(arpstats
->peer_request_drop
));
17191 printf("peer_reply = %d\n", dtoh32(arpstats
->peer_reply
));
17192 printf("peer_reply_drop = %d\n", dtoh32(arpstats
->peer_reply_drop
));
17193 printf("peer_service = %d\n", dtoh32(arpstats
->peer_service
));
17194 printf("host_ip_entries = %d\n", dtoh32(arpstats
->host_ip_entries
));
17196 printf("Cannot set arp stats, use 'wl arp_stats_clear' to clear the counters\n");
17202 wl_toe_stats(void *wl
, cmd_t
*cmd
, char **argv
)
17205 struct toe_ol_stats_t
*toestats
;
17211 if ((ret
= wlu_var_getbuf(wl
, cmd
->name
, NULL
, 0, &ptr
)) < 0)
17213 toestats
= (struct toe_ol_stats_t
*)ptr
;
17214 printf("tx_summed = %d\n", dtoh32(toestats
->tx_summed
));
17215 printf("tx_iph_fill = %d\n", dtoh32(toestats
->tx_iph_fill
));
17216 printf("tx_tcp_fill = %d\n", dtoh32(toestats
->tx_tcp_fill
));
17217 printf("tx_udp_fill = %d\n", dtoh32(toestats
->tx_udp_fill
));
17218 printf("tx_icmp_fill = %d\n", dtoh32(toestats
->tx_icmp_fill
));
17219 printf("rx_iph_good = %d\n", dtoh32(toestats
->rx_iph_good
));
17220 printf("rx_iph_bad = %d\n", dtoh32(toestats
->rx_iph_bad
));
17221 printf("rx_tcp_good = %d\n", dtoh32(toestats
->rx_tcp_good
));
17222 printf("rx_tcp_bad = %d\n", dtoh32(toestats
->rx_tcp_bad
));
17223 printf("rx_udp_good = %d\n", dtoh32(toestats
->rx_udp_good
));
17224 printf("rx_udp_bad = %d\n", dtoh32(toestats
->rx_udp_bad
));
17225 printf("rx_icmp_good = %d\n", dtoh32(toestats
->rx_icmp_good
));
17226 printf("rx_icmp_bad = %d\n", dtoh32(toestats
->rx_icmp_bad
));
17227 printf("tx_tcp_errinj = %d\n", dtoh32(toestats
->tx_tcp_errinj
));
17228 printf("tx_udp_errinj = %d\n", dtoh32(toestats
->tx_udp_errinj
));
17229 printf("tx_icmp_errinj = %d\n", dtoh32(toestats
->tx_icmp_errinj
));
17230 printf("rx_tcp_errinj = %d\n", dtoh32(toestats
->rx_tcp_errinj
));
17231 printf("rx_udp_errinj = %d\n", dtoh32(toestats
->rx_udp_errinj
));
17232 printf("rx_icmp_errinj = %d\n", dtoh32(toestats
->rx_icmp_errinj
));
17234 printf("Cannot set toe stats, use 'wl toe_stats_clear' to clear the counters\n");
17240 wl_rate_histo(void *wl
, cmd_t
*cmd
, char **argv
)
17242 uint32
*hw_rates_used
, *mcs_rates
;
17244 int i
, err
, total
= 0;
17246 UNUSED_PARAMETER(argv
);
17248 if ((err
= wlu_var_getbuf(wl
, cmd
->name
, NULL
, 0, &ptr
)) < 0)
17251 printf("Rates:\n");
17252 hw_rates_used
= ptr
;
17253 for (i
= 0; i
<= WLC_MAXRATE
; i
++) {
17254 if (hw_rates_used
[i
]) {
17255 total
+= hw_rates_used
[i
];
17257 printf("%.2d\t%d.%d Mbit/s\n",
17258 hw_rates_used
[i
], DIV_QUO(i
, 2), DIV_REM(i
, 2)/10);
17260 printf("%.2d\t%d Mbit/s\n",
17261 hw_rates_used
[i
], DIV_QUO(i
, 2));
17265 printf("MCS indexes:\n");
17267 mcs_rates
= &hw_rates_used
[i
];
17268 for (i
= 0; i
<= WLC_MAXMCS
; i
++) {
17269 if (mcs_rates
[i
]) {
17270 total
+= mcs_rates
[i
];
17271 printf("%d\tMCS %d\n", mcs_rates
[i
], i
);
17278 wl_pkteng_stats(void *wl
, cmd_t
*cmd
, char **argv
)
17280 wl_pkteng_stats_t
*stats
;
17284 UNUSED_PARAMETER(argv
);
17286 if ((err
= wlu_var_getbuf(wl
, cmd
->name
, NULL
, 0, &ptr
)) < 0)
17290 printf("Lost frame count %d\n", stats
->lostfrmcnt
);
17291 printf("RSSI %d\n", stats
->rssi
);
17292 printf("Signal to noise ratio %d\n", stats
->snr
);
17297 #define LPPHY_PAPD_EPS_TBL_SIZE 64
17299 wl_lpphy_papdepstbl(void *wl
, cmd_t
*cmd
, char **argv
)
17301 int32 eps_real
, eps_imag
;
17303 uint32 eps_tbl
[LPPHY_PAPD_EPS_TBL_SIZE
];
17306 UNUSED_PARAMETER(argv
);
17308 if ((err
= wlu_iovar_get(wl
, cmd
->name
, &eps_tbl
, sizeof(eps_tbl
))) < 0)
17311 printf("PAPD EPS TABLE:\n");
17312 for (i
= 0; i
< LPPHY_PAPD_EPS_TBL_SIZE
; i
++) {
17313 if ((eps_real
= (int32
)(eps_tbl
[i
] >> 12)) > 0x7ff)
17314 eps_real
-= 0x1000; /* Sign extend */
17315 if ((eps_imag
= (int32
)(eps_tbl
[i
] & 0xfff)) > 0x7ff)
17316 eps_imag
-= 0x1000; /* Sign extend */
17318 printf("%d+j%d\n", eps_real
, eps_imag
);
17320 printf("%d-j%d\n", eps_real
, -eps_imag
);
17327 wl_phy_txiqcc(void *wl
, cmd_t
*cmd
, char **argv
)
17331 int32 iqccValues
[2];
17337 if ((err
= wlu_iovar_get(wl
, cmd
->name
, iqccValues
, 2*sizeof(int32
))) < 0)
17339 a
= (int16
)iqccValues
[0];
17340 b
= (int16
)iqccValues
[1];
17341 /* sign extend a, b from 10 bit signed value to 32 bit signed value */
17342 a
= ((a
<< 22) >> 22);
17343 b
= ((b
<< 22) >> 22);
17344 printf("%d %d\n", a
, b
);
17348 for (i
= 0; i
< 2; i
++) {
17349 value
= strtol(*argv
++, &endptr
, 0);
17350 if (value
> 511 || value
< -512) {
17351 return BCME_BADARG
;
17353 iqccValues
[i
] = value
;
17356 if ((err
= wlu_var_setbuf(wl
, cmd
->name
, iqccValues
, 2*sizeof(int32
))) < 0)
17364 wl_phy_txlocc(void *wl
, cmd_t
*cmd
, char **argv
)
17368 int8 loccValues
[6];
17373 if ((err
= wlu_iovar_get(wl
, cmd
->name
, loccValues
, sizeof(loccValues
))) < 0)
17376 /* sign extend the loccValues */
17377 loccValues
[2] = (loccValues
[2] << 3) >> 3;
17378 loccValues
[3] = (loccValues
[3] << 3) >> 3;
17379 loccValues
[4] = (loccValues
[4] << 3) >> 3;
17380 loccValues
[5] = (loccValues
[5] << 3) >> 3;
17382 printf("%d %d %d %d %d %d\n", loccValues
[0],
17383 loccValues
[1], loccValues
[2], loccValues
[3], loccValues
[4], loccValues
[5]);
17387 for (i
= 0; i
< 6; i
++) {
17388 value
= strtol(*argv
++, &endptr
, 0);
17389 if (((i
< 2) && (value
> 63 || value
< -64)) ||
17390 ((i
>= 2) && (value
> 15 || value
< -15))) {
17391 return BCME_BADARG
;
17393 loccValues
[i
] = (int8
)value
;
17396 if ((err
= wlu_var_setbuf(wl
, "lpphy_txlocc", loccValues
, 6*sizeof(int8
))) < 0)
17405 wl_phytable(void *wl
, cmd_t
*cmd
, char **argv
)
17408 int32 tableInfo
[4];
17412 int32 tableId
, tableOffset
, tableWidth
, tableElement
;
17414 if (*++argv
!= NULL
)
17415 tableId
= strtol(*argv
, &endptr
, 0);
17417 return USAGE_ERROR
;
17419 if (*++argv
!= NULL
)
17420 tableOffset
= strtol(*argv
, &endptr
, 0);
17422 return USAGE_ERROR
;
17424 if (*++argv
!= NULL
)
17425 tableWidth
= strtol(*argv
, &endptr
, 0);
17427 return USAGE_ERROR
;
17429 if ((tableId
< 0) || (tableOffset
< 0))
17430 return BCME_BADARG
;
17432 if ((tableWidth
!= 8) && (tableWidth
!= 16) && (tableWidth
!= 32))
17433 return BCME_BADARG
;
17436 tableInfo
[0] = tableId
;
17437 tableInfo
[1] = tableOffset
;
17438 tableInfo
[2] = tableWidth
;
17440 if ((err
= wlu_var_getbuf(wl
, cmd
->name
, tableInfo
, 4*sizeof(int32
), &ptr
)) < 0)
17443 tableElement
= ((int32
*)ptr
)[0];
17445 printf("0x%x(%d)\n", tableElement
, tableElement
);
17449 value
= strtol(*argv
++, &endptr
, 0);
17450 tableElement
= value
;
17452 tableInfo
[0] = tableId
;
17453 tableInfo
[1] = tableOffset
;
17454 tableInfo
[2] = tableWidth
;
17455 tableInfo
[3] = tableElement
;
17457 if ((err
= wlu_var_setbuf(wl
, cmd
->name
, tableInfo
, 4*sizeof(int32
))) < 0)
17465 wl_phy_txpwrindex(void *wl
, cmd_t
*cmd
, char **argv
)
17469 uint32 txpwridx
[4] = { 0 };
17470 int8 idx
[4] = { 0 };
17475 for (argc
= 0; argv
[argc
]; argc
++);
17478 for (i
= 0; i
< 4; i
++) {
17480 txpwridx
[i
] = strtol(argv
[1 + i
], &endptr
, 0);
17481 if (*endptr
!= '\0') {
17489 if ((ret
= wlu_iovar_getint(wl
, cmd
->name
, (int*)&txpwridx
[0])) < 0) {
17492 txpwridx
[0] = dtoh32(txpwridx
[0]);
17493 idx
[0] = (int8
)(txpwridx
[0] & 0xff);
17494 idx
[1] = (int8
)((txpwridx
[0] >> 8) & 0xff);
17495 idx
[2] = (int8
)((txpwridx
[0] >> 16) & 0xff);
17496 idx
[3] = (int8
)((txpwridx
[0] >> 24) & 0xff);
17497 printf("txpwrindex for core{0...3}: %d %d %d %d\n", idx
[0], idx
[1],
17501 wlc_rev_info_t revinfo
;
17504 memset(&revinfo
, 0, sizeof(revinfo
));
17505 ret
= wlu_get(wl
, WLC_GET_REVINFO
, &revinfo
, sizeof(revinfo
));
17509 phytype
= dtoh32(revinfo
.phytype
);
17511 if (phytype
== WLC_PHY_TYPE_HT
) {
17513 printf("HTPHY must specify 3 core txpwrindex\n");
17514 return BCME_BADARG
;
17516 } else if (phytype
== WLC_PHY_TYPE_N
) {
17518 printf("NPHY must specify 2 core txpwrindex\n");
17519 return BCME_BADARG
;
17523 ret
= wlu_iovar_setbuf(wl
, cmd
->name
, txpwridx
, 4*sizeof(uint32
),
17524 buf
, WLC_IOCTL_MAXLEN
);
17531 wl_phy_pavars2(void *wl
, cmd_t
*cmd
, char **argv
)
17534 return CFE_ERR_UNSUPPORTED
;
17536 const pavars_t
*pav
= pavars
;
17537 wl_pavars2_t pavars2_data
, *ptr
= NULL
;
17538 uint16
*inpa
= pavars2_data
.inpa
;
17539 char *cpar
= NULL
, *p
= NULL
;
17540 char par
[256]; /* holds longest pavars->vars */
17541 char delimit
[2] = " \0";
17545 UNUSED_PARAMETER(cmd
);
17547 if (*++argv
) { /* set */
17548 while (pav
->phy_type
!= PHY_TYPE_NULL
) {
17549 bool found
= FALSE
;
17552 pavars2_data
.ver
= WL_PHY_PAVAR_VER
;
17553 pavars2_data
.len
= sizeof(wl_pavars2_t
);
17554 pavars2_data
.phy_type
= pav
->phy_type
;
17555 pavars2_data
.bandrange
= pav
->bandrange
;
17556 pavars2_data
.chain
= pav
->chain
;
17557 pavars2_data
.inuse
= 0;
17558 strcpy(par
, pav
->vars
);
17560 cpar
= strtok (par
, delimit
); /* current param */
17564 /* Find the parameter in the input argument list */
17565 if ((p
= find_pattern(argv
, cpar
, &val
))) {
17567 inpa
[i
] = (uint16
)val
;
17571 } while ((cpar
= strtok (NULL
, delimit
)));
17574 if ((err
= wlu_var_setbuf(wl
, "pavars2", &pavars2_data
,
17575 sizeof(wl_pavars2_t
))) < 0) {
17576 printf("wl_phy_pavars2: fail to set\n");
17583 while (pav
->phy_type
!= PHY_TYPE_NULL
) {
17587 pavars2_data
.ver
= WL_PHY_PAVAR_VER
;
17588 pavars2_data
.len
= sizeof(wl_pavars2_t
);
17589 pavars2_data
.phy_type
= pav
->phy_type
;
17590 pavars2_data
.bandrange
= pav
->bandrange
;
17591 pavars2_data
.chain
= pav
->chain
;
17592 pavars2_data
.inuse
= 0;
17593 strcpy(par
, pav
->vars
);
17595 if ((err
= wlu_var_getbuf_sm(wl
, "pavars2", &pavars2_data
,
17596 sizeof(wl_pavars2_t
), (void **)&ptr
)) < 0) {
17597 printf("phy %x band %x chain %d err %d\n", pav
->phy_type
,
17598 pav
->chain
, pav
->bandrange
, err
);
17602 outpa
= (uint16
*)(ptr
->inpa
);
17603 if (ptr
->phy_type
== PHY_TYPE_NULL
) {
17608 cpar
= strtok(par
, delimit
); /* current param */
17610 printf("%s=0x%x\n", cpar
, outpa
[i
++]);
17611 } while ((cpar
= strtok (NULL
, delimit
)));
17622 wl_phy_pavars(void *wl
, cmd_t
*cmd
, char **argv
)
17625 return CFE_ERR_UNSUPPORTED
;
17627 const pavars_t
*pav
= pavars
;
17628 uint16 inpa
[WL_PHY_PAVARS_LEN
];
17629 char *cpar
= NULL
, *p
= NULL
;
17630 char par
[256]; /* holds longest pavars->vars */
17631 char delimit
[2] = " \0";
17636 if (*++argv
) { /* set */
17637 while (pav
->phy_type
!= PHY_TYPE_NULL
) {
17638 bool found
= FALSE
;
17641 inpa
[i
++] = pav
->phy_type
;
17642 inpa
[i
++] = pav
->bandrange
;
17643 inpa
[i
++] = pav
->chain
;
17644 strcpy(par
, pav
->vars
);
17646 cpar
= strtok (par
, delimit
); /* current param */
17650 /* Find the parameter in the input argument list */
17651 if ((p
= find_pattern(argv
, cpar
, &val
))) {
17653 inpa
[i
] = (uint16
)val
;
17657 } while ((cpar
= strtok (NULL
, delimit
)));
17660 if ((err
= wlu_var_setbuf(wl
, cmd
->name
, inpa
,
17661 WL_PHY_PAVARS_LEN
* sizeof(uint16
))) < 0) {
17662 printf("wl_phy_pavars: fail to set\n");
17669 while (pav
->phy_type
!= PHY_TYPE_NULL
) {
17673 inpa
[i
++] = pav
->phy_type
;
17674 inpa
[i
++] = pav
->bandrange
;
17675 inpa
[i
++] = pav
->chain
;
17676 strcpy(par
, pav
->vars
);
17678 if ((err
= wlu_var_getbuf_sm(wl
, cmd
->name
, inpa
,
17679 WL_PHY_PAVARS_LEN
* sizeof(uint16
), &ptr
)) < 0) {
17680 printf("phy %x band %x chain %d err %d\n", pav
->phy_type
,
17681 pav
->chain
, pav
->bandrange
, err
);
17685 outpa
= (uint16
*)ptr
;
17686 if (outpa
[0] == PHY_TYPE_NULL
) {
17691 cpar
= strtok(par
, delimit
); /* current param */
17693 printf("%s=0x%x\n", cpar
, outpa
[i
++]);
17694 } while ((cpar
= strtok (NULL
, delimit
)));
17705 wl_phy_povars(void *wl
, cmd_t
*cmd
, char **argv
)
17708 return CFE_ERR_UNSUPPORTED
;
17710 const povars_t
*pov
= povars
;
17712 char *cpar
= NULL
, *p
= NULL
;
17713 char par
[256]; /* holds longest povars->vars */
17714 char delimit
[2] = " \0";
17719 if (*++argv
) { /* set */
17720 while (pov
->phy_type
!= PHY_TYPE_NULL
) {
17721 bool found
= FALSE
;
17724 inpo
.phy_type
= pov
->phy_type
;
17725 inpo
.band
= pov
->bandrange
;
17726 strcpy(par
, pov
->vars
);
17728 /* Take care of cck and ofdm before walking through povars->vars */
17729 if (pov
->bandrange
== WL_CHAN_FREQ_RANGE_2G
) {
17730 p
= find_pattern(argv
, "cck2gpo", &val
);
17731 if (p
) found
= TRUE
;
17732 inpo
.cckpo
= p
? (uint16
)val
: 0;
17734 p
= find_pattern(argv
, "ofdm2gpo", &val
);
17735 } else if (pov
->bandrange
== WL_CHAN_FREQ_RANGE_5GL
) {
17736 p
= find_pattern(argv
, "ofdm5glpo", &val
);
17737 } else if (pov
->bandrange
== WL_CHAN_FREQ_RANGE_5GM
) {
17738 p
= find_pattern(argv
, "ofdm5gpo", &val
);
17739 } else if (pov
->bandrange
== WL_CHAN_FREQ_RANGE_5GH
) {
17740 p
= find_pattern(argv
, "ofdm5ghpo", &val
);
17742 inpo
.ofdmpo
= p
? (uint32
)val
: 0;
17743 if (p
) found
= TRUE
;
17745 cpar
= strtok (par
, delimit
); /* current param */
17749 /* Find the parameter in the input argument list */
17750 p
= find_pattern(argv
, cpar
, &val
);
17751 if (p
) found
= TRUE
;
17752 inpo
.mcspo
[i
] = p
? (uint16
)val
: 0;
17754 } while ((cpar
= strtok (NULL
, delimit
)));
17757 if ((err
= wlu_var_setbuf(wl
, cmd
->name
, &inpo
,
17758 sizeof(wl_po_t
))) < 0) {
17759 printf("wl_phy_povars: fail to set\n");
17766 while (pov
->phy_type
!= PHY_TYPE_NULL
) {
17770 inpo
.phy_type
= pov
->phy_type
;
17771 inpo
.band
= pov
->bandrange
;
17772 strcpy(par
, pov
->vars
);
17774 if ((err
= wlu_var_getbuf(wl
, cmd
->name
, &inpo
, sizeof(povars_t
),
17776 printf("phy %x band %x err %d\n", pov
->phy_type
,
17777 pov
->bandrange
, err
);
17781 outpo
= (wl_po_t
*)ptr
;
17782 if (outpo
->phy_type
== PHY_TYPE_NULL
) {
17787 /* Take care of cck and ofdm before walking through povars->vars */
17788 if (outpo
->band
== WL_CHAN_FREQ_RANGE_2G
) {
17789 printf("cck2gpo=0x%x\n", outpo
->cckpo
);
17790 printf("ofdm2gpo=0x%x\n", outpo
->ofdmpo
);
17791 } else if (pov
->bandrange
== WL_CHAN_FREQ_RANGE_5GL
) {
17792 printf("ofdm5glpo=0x%x\n", outpo
->ofdmpo
);
17793 } else if (pov
->bandrange
== WL_CHAN_FREQ_RANGE_5GM
) {
17794 printf("ofdm5gpo=0x%x\n", outpo
->ofdmpo
);
17795 } else if (pov
->bandrange
== WL_CHAN_FREQ_RANGE_5GH
) {
17796 printf("ofdm5ghpo=0x%x\n", outpo
->ofdmpo
);
17799 cpar
= strtok(par
, delimit
); /* current param */
17801 printf("%s=0x%x\n", cpar
, outpo
->mcspo
[i
++]);
17802 } while ((cpar
= strtok (NULL
, delimit
)));
17813 wl_phy_fem(void *wl
, cmd_t
*cmd
, char **argv
)
17816 return CFE_ERR_UNSUPPORTED
;
17821 bool found
= FALSE
;
17825 UNUSED_PARAMETER(cmd
);
17827 if (*++argv
) { /* write fem */
17830 memset(&fem
, 0, sizeof(srom_fem_t
));
17832 if (find_pattern(argv
, "tssipos2g", &val
)) {
17837 if (find_pattern(argv
, "extpagain2g", &val
)) {
17839 fem
.extpagain
= val
;
17842 if (find_pattern(argv
, "pdetrange2g", &val
)) {
17844 fem
.pdetrange
= val
;
17847 if (find_pattern(argv
, "triso2g", &val
)) {
17852 if (find_pattern(argv
, "antswctl2g", &val
)) {
17854 fem
.antswctrllut
= val
;
17858 if ((err
= wlu_var_setbuf(wl
, "fem2g", &fem
, sizeof(srom_fem_t
)) < 0))
17859 printf("wl_phy_fem: fail to set fem2g\n");
17861 printf("fem2g set\n");
17866 memset(&fem
, 0, sizeof(srom_fem_t
));
17868 if (find_pattern(argv
, "tssipos5g", &val
)) {
17873 if (find_pattern(argv
, "extpagain5g", &val
)) {
17875 fem
.extpagain
= val
;
17878 if (find_pattern(argv
, "pdetrange5g", &val
)) {
17880 fem
.pdetrange
= val
;
17883 if (find_pattern(argv
, "triso5g", &val
)) {
17888 if (find_pattern(argv
, "antswctl5g", &val
)) {
17890 fem
.antswctrllut
= val
;
17894 if ((err
= wlu_var_setbuf(wl
, "fem5g", &fem
, sizeof(srom_fem_t
)) < 0))
17895 printf("wl_phy_fem: fail to set fem5g\n");
17897 printf("fem5g set\n");
17900 if ((err
= wlu_var_getbuf(wl
, "fem2g", NULL
, 0, (void**)&ptr
) < 0)) {
17901 printf("wl_phy_fem: fail to get fem2g\n");
17903 rfem
= (srom_fem_t
*)ptr
; /* skip the "fem2g" */
17904 printf("tssipos2g=0x%x extpagain2g=0x%x pdetrange2g=0x%x"
17905 " triso2g=0x%x antswctl2g=0x%x\n",
17906 rfem
->tssipos
, rfem
->extpagain
, rfem
->pdetrange
,
17907 rfem
->triso
, rfem
->antswctrllut
);
17910 if ((err
= wlu_var_getbuf(wl
, "fem5g", NULL
, 0, (void**)&ptr
) < 0)) {
17911 printf("wl_phy_fem: fail to get fem5g\n");
17913 rfem
= (srom_fem_t
*)ptr
; /* skip the "fem2g" */
17914 printf("tssipos5g=0x%x extpagain5g=0x%x pdetrange5g=0x%x"
17915 " triso5g=0x%x antswctl5g=0x%x\n",
17916 rfem
->tssipos
, rfem
->extpagain
, rfem
->pdetrange
,
17917 rfem
->triso
, rfem
->antswctrllut
);
17926 wl_phy_maxpower(void *wl
, cmd_t
*cmd
, char **argv
)
17929 return CFE_ERR_UNSUPPORTED
;
17937 UNUSED_PARAMETER(cmd
);
17939 if (*++argv
) { /* write maxpower */
17941 if (find_pattern(argv
, "maxp2ga0", &val
))
17944 printf("Missing maxp2ga0\n");
17946 if (find_pattern(argv
, "maxp2ga1", &val
))
17949 printf("Missing maxp2ga1\n");
17951 if (find_pattern(argv
, "maxp5ga0", &val
))
17954 printf("Missing maxp5ga0\n");
17956 if (find_pattern(argv
, "maxp5ga1", &val
))
17959 printf("Missing maxp5ga1\n");
17961 if (find_pattern(argv
, "maxp5gla0", &val
))
17964 printf("Missing maxp5gla0\n");
17966 if (find_pattern(argv
, "maxp5gla1", &val
))
17969 printf("Missing maxp5gla1\n");
17971 if (find_pattern(argv
, "maxp5gha0", &val
))
17974 printf("Missing maxp5gha0\n");
17976 if (find_pattern(argv
, "maxp5gha1", &val
))
17979 printf("Missing maxp5gha1\n");
17981 if ((err
= wlu_var_setbuf(wl
, "maxpower", &maxp
, 8 * sizeof(uint8
)) < 0)) {
17982 printf("wl_phy_maxpower: fail to set\n");
17986 if ((err
= wlu_var_getbuf(wl
, "maxpower", NULL
, 0, &ptr
) < 0)) {
17987 printf("wl_phy_maxpower: fail to get maxpower\n");
17990 rmaxp
= (uint8
*)ptr
;
17991 printf("maxp2ga0=%x\n", rmaxp
[0]);
17992 printf("maxp2ga1=%x\n", rmaxp
[1]);
17993 printf("maxp5ga0=%x\n", rmaxp
[2]);
17994 printf("maxp5ga1=%x\n", rmaxp
[3]);
17995 printf("maxp5gla0=%x\n", rmaxp
[4]);
17996 printf("maxp5gla1=%x\n", rmaxp
[5]);
17997 printf("maxp5gha0=%x\n", rmaxp
[6]);
17998 printf("maxp5gha1=%x\n", rmaxp
[7]);
18006 wl_antgain(void *wl
, cmd_t
*cmd
, char **argv
)
18009 return CFE_ERR_UNSUPPORTED
;
18017 UNUSED_PARAMETER(cmd
);
18019 if (*++argv
) { /* write maxpower */
18020 if (find_pattern(argv
, "ag0", &val
))
18021 ag
[0] = val
& 0xff;
18023 printf("Missing ag0\n");
18027 if (find_pattern(argv
, "ag1", &val
))
18028 ag
[1] = val
& 0xff;
18030 printf("Missing ag1\n");
18034 if ((err
= wlu_var_setbuf(wl
, "antgain", &ag
, 2 * sizeof(uint8
)) < 0)) {
18035 printf("wl_antgain: fail to set\n");
18039 if ((err
= wlu_var_getbuf(wl
, "antgain", NULL
, 0, &ptr
) < 0)) {
18040 printf("wl_antgain: fail to get antgain\n");
18044 printf("ag0=%x\n", rag
[0]);
18045 printf("ag1=%x\n", rag
[1]);
18053 wl_pkteng(void *wl
, cmd_t
*cmd
, char **argv
)
18055 wl_pkteng_t pkteng
;
18057 memset(&pkteng
, 0, sizeof(pkteng
));
18058 if (strcmp(cmd
->name
, "pkteng_stop") == 0) {
18061 if (strcmp(*argv
, "tx") == 0)
18062 pkteng
.flags
= WL_PKTENG_PER_TX_STOP
;
18063 else if (strcmp(*argv
, "rx") == 0)
18064 pkteng
.flags
= WL_PKTENG_PER_RX_STOP
;
18067 return (wlu_var_setbuf(wl
, "pkteng", &pkteng
, sizeof(pkteng
)));
18069 else if (strcmp(cmd
->name
, "pkteng_start") == 0) {
18072 if (!wl_ether_atoe(*argv
, (struct ether_addr
*)&pkteng
.dest
))
18076 if ((strcmp(*argv
, "tx") == 0) || (strcmp(*argv
, "txwithack") == 0)) {
18077 if (strcmp(*argv
, "tx") == 0)
18078 pkteng
.flags
= WL_PKTENG_PER_TX_START
;
18080 pkteng
.flags
= WL_PKTENG_PER_TX_WITH_ACK_START
;
18083 if (strcmp(*argv
, "async") == 0)
18084 pkteng
.flags
&= ~WL_PKTENG_SYNCHRONOUS
;
18085 else if (strcmp(*argv
, "sync") == 0)
18086 pkteng
.flags
|= WL_PKTENG_SYNCHRONOUS
;
18088 /* neither optional parameter [async|sync] */
18092 pkteng
.delay
= strtoul(*argv
, NULL
, 0);
18095 pkteng
.length
= strtoul(*argv
, NULL
, 0);
18098 pkteng
.nframes
= strtoul(*argv
, NULL
, 0);
18100 if (!wl_ether_atoe(*argv
, (struct ether_addr
*)&pkteng
.src
))
18103 else if ((strcmp(*argv
, "rx") == 0) || (strcmp(*argv
, "rxwithack") == 0)) {
18104 if ((strcmp(*argv
, "rx") == 0))
18105 pkteng
.flags
= WL_PKTENG_PER_RX_START
;
18107 pkteng
.flags
= WL_PKTENG_PER_RX_WITH_ACK_START
;
18110 if (strcmp(*argv
, "async") == 0)
18111 pkteng
.flags
&= ~WL_PKTENG_SYNCHRONOUS
;
18112 else if (strcmp(*argv
, "sync") == 0) {
18113 pkteng
.flags
|= WL_PKTENG_SYNCHRONOUS
;
18114 /* sync mode requires number of frames and timeout */
18117 pkteng
.nframes
= strtoul(*argv
, NULL
, 0);
18120 pkteng
.delay
= strtoul(*argv
, NULL
, 0);
18127 return (wlu_var_setbuf(wl
, "pkteng", &pkteng
, sizeof(pkteng
)));
18130 printf("Invalid command name %s\n", cmd
->name
);
18136 wl_rxiq(void *wl
, cmd_t
*cmd
, char **argv
)
18139 const char* fn_name
= "wl_rxiqest";
18140 int err
, argc
, opt_err
;
18142 uint8 resolution
= 0;
18144 uint8 gain_correct
= 0;
18147 for (argc
= 0; argv
[argc
]; argc
++);
18150 * gain_correct = 0 (disable gain correction),
18151 * lpf_hpc = 1 (sets lpf hpc to lowest value),
18152 * resolution = 0 (coarse),
18153 * samples = 1024 (2^10) and antenna = 3
18155 rxiq
= (gain_correct
<< 24) | (lpf_hpc
<< 20) | (resolution
<< 16) | (10 << 8) | 3;
18159 miniopt_init(&to
, fn_name
, NULL
, FALSE
);
18160 while ((opt_err
= miniopt(&to
, argv
)) != -1) {
18161 if (opt_err
== 1) {
18165 argv
+= to
.consumed
;
18167 if (to
.opt
== 'g') {
18168 if (!to
.good_int
) {
18170 "%s: could not parse \"%s\" as an int"
18171 " for gain-correction (0, 1)\n",
18172 fn_name
, to
.valstr
);
18177 if ((to
.val
< 0) || (to
.val
> 1)) {
18178 fprintf(stderr
, "%s: invalid gain-correction select %d"
18179 " (0,1)\n", fn_name
, to
.val
);
18183 gain_correct
= to
.val
& 0xf;
18184 rxiq
= ((gain_correct
<< 24) | (rxiq
& 0xffffff));
18186 if (to
.opt
== 'f') {
18187 if (!to
.good_int
) {
18189 "%s: could not parse \"%s\" as an int"
18190 " for lpf-hpc override select (0, 1)\n",
18191 fn_name
, to
.valstr
);
18195 if ((to
.val
< 0) || (to
.val
> 1)) {
18196 fprintf(stderr
, "%s: invalid lpf-hpc override select %d"
18197 " (0,1)\n", fn_name
, to
.val
);
18201 lpf_hpc
= to
.val
& 0xf;
18202 rxiq
= ((lpf_hpc
<< 20) | (rxiq
& 0xf0fffff));
18204 if (to
.opt
== 'r') {
18205 if (!to
.good_int
) {
18207 "%s: could not parse \"%s\" as an int"
18208 " for resolution (0, 1)\n", fn_name
, to
.valstr
);
18212 if ((to
.val
< 0) || (to
.val
> 1)) {
18213 fprintf(stderr
, "%s: invalid resolution select %d"
18214 " (0,1)\n", fn_name
, to
.val
);
18218 resolution
= to
.val
& 0xf;
18219 rxiq
= ((resolution
<< 16) | (rxiq
& 0xff0ffff));
18221 if (to
.opt
== 's') {
18222 if (!to
.good_int
) {
18224 "%s: could not parse \"%s\" as an int for"
18225 " the sample count\n", fn_name
, to
.valstr
);
18229 if (to
.val
< 0 || to
.val
> 16) {
18230 fprintf(stderr
, "%s: sample count too large %d"
18231 "(10 <= x <= 16)\n", fn_name
, to
.val
);
18235 rxiq
= (((to
.val
& 0xff) << 8) | (rxiq
& 0xfff00ff));
18237 if (to
.opt
== 'a') {
18238 if (!to
.good_int
) {
18240 "%s: could not parse \"%s\" as an int"
18241 " for antenna (0, 1, 3)\n", fn_name
, to
.valstr
);
18245 if ((to
.val
< 0) || (to
.val
> 3)) {
18246 fprintf(stderr
, "%s: invalid antenna select %d\n",
18251 rxiq
= ((rxiq
& 0xfffff00) | (to
.val
& 0xff));
18256 if ((err
= wlu_iovar_setint(wl
, cmd
->name
, (int)rxiq
)) < 0)
18258 if ((err
= wlu_iovar_getint(wl
, cmd
->name
, (int*)&rxiq
)) < 0)
18261 if (resolution
== 1) {
18262 /* fine resolution power reporting (0.25dB resolution) */
18264 /* Three chains: */
18267 for (core
= 0; core
< 3; core
++) {
18268 tmp
= (rxiq
>> (10*core
)) & 0x3ff;
18269 tmp
= ((int16
)(tmp
<< 6)) >> 6; /* sign extension */
18272 printf("-%d.%ddBm ", (tmp
>> 2), (tmp
& 0x3)*25);
18274 printf("%d.%ddBm ", (tmp
>> 2), (tmp
& 0x3)*25);
18281 printf("%ddBm %ddBm %ddBm\n", (int8
)(rxiq
& 0xff),
18282 (int8
)((rxiq
>> 8) & 0xff), (int8
)((rxiq
>> 16) & 0xff));
18283 else if (rxiq
>> 8)
18284 printf("%ddBm %ddBm\n", (int8
)(rxiq
& 0xff), (int8
)((rxiq
>> 8) & 0xff));
18286 printf("%ddBm\n", (int8
)(rxiq
& 0xff));
18292 /* Convert user's input in hex pattern to byte-size mask */
18294 wl_pattern_atoh(char *src
, char *dst
)
18297 if (strncmp(src
, "0x", 2) != 0 &&
18298 strncmp(src
, "0X", 2) != 0) {
18299 printf("Mask invalid format. Needs to start with 0x\n");
18302 src
= src
+ 2; /* Skip past 0x */
18303 if (strlen(src
) % 2 != 0) {
18304 printf("Mask invalid format. Needs to be of even length\n");
18307 for (i
= 0; *src
!= '\0'; i
++) {
18309 strncpy(num
, src
, 2);
18311 dst
[i
] = (uint8
)strtoul(num
, NULL
, 16);
18318 wl_wowl_status(void *wl
, cmd_t
*cmd
, char **argv
)
18320 int flags_prev
= 0;
18323 UNUSED_PARAMETER(cmd
);
18327 if ((err
= wlu_iovar_getint(wl
, "wowl_status", &flags_prev
)))
18330 printf("Status of last wakeup:\n");
18331 printf("\tflags:0x%x\n", flags_prev
);
18333 if (flags_prev
& WL_WOWL_BCN
)
18334 printf("\t\tWake-on-Loss-of-Beacons enabled\n");
18336 if (flags_prev
& WL_WOWL_MAGIC
)
18337 printf("\t\tWake-on-Magic frame enabled\n");
18338 if (flags_prev
& WL_WOWL_NET
)
18339 printf("\t\tWake-on-Net pattern enabled\n");
18340 if (flags_prev
& WL_WOWL_DIS
)
18341 printf("\t\tWake-on-Deauth enabled\n");
18343 if (flags_prev
& WL_WOWL_RETR
)
18344 printf("\t\tRetrograde TSF enabled\n");
18345 if (flags_prev
& WL_WOWL_TST
)
18346 printf("\t\tTest-mode enabled\n");
18354 wl_wowl_wakeind(void *wl
, cmd_t
*cmd
, char **argv
)
18356 wl_wowl_wakeind_t wake
= {0, 0};
18359 UNUSED_PARAMETER(cmd
);
18364 if (strcmp(*argv
, "clear"))
18366 err
= wlu_iovar_set(wl
, "wowl_wakeind", *argv
, strlen(*argv
));
18370 if ((err
= wlu_iovar_get(wl
, "wowl_wakeind", &wake
, sizeof(wl_wowl_wakeind_t
))) < 0)
18373 if (wake
.pci_wakeind
)
18374 printf("PCI Indication set\n");
18375 if (wake
.ucode_wakeind
!= 0) {
18376 printf("MAC Indication set\n");
18378 if ((wake
.ucode_wakeind
& WL_WOWL_MAGIC
) == WL_WOWL_MAGIC
)
18379 printf("\tMAGIC packet received\n");
18380 if ((wake
.ucode_wakeind
& WL_WOWL_NET
) == WL_WOWL_NET
)
18381 printf("\tPacket received with Netpattern\n");
18382 if ((wake
.ucode_wakeind
& WL_WOWL_DIS
) == WL_WOWL_DIS
)
18383 printf("\tDisassociation/Deauth received\n");
18384 if ((wake
.ucode_wakeind
& WL_WOWL_RETR
) == WL_WOWL_RETR
)
18385 printf("\tRetrograde TSF detected\n");
18386 if ((wake
.ucode_wakeind
& WL_WOWL_BCN
) == WL_WOWL_BCN
)
18387 printf("\tBeacons Lost\n");
18388 if ((wake
.ucode_wakeind
& WL_WOWL_TST
) == WL_WOWL_TST
)
18389 printf("\tTest Mode\n");
18390 if ((wake
.ucode_wakeind
& (WL_WOWL_NET
| WL_WOWL_MAGIC
))) {
18391 if ((wake
.ucode_wakeind
& WL_WOWL_BCAST
) == WL_WOWL_BCAST
)
18392 printf("\t\tBroadcast/Mcast frame received\n");
18394 printf("\t\tUnicast frame received\n");
18398 if (!wake
.pci_wakeind
&& wake
.ucode_wakeind
== 0)
18399 printf("No wakeup indication set\n");
18404 /* Send a wakeup frame to sta in WAKE mode */
18406 wl_wowl_pkt(void *wl
, cmd_t
*cmd
, char **argv
)
18412 uint16 type
, pkt_len
;
18413 int dst_ea
= 0; /* 0 == manual, 1 == bcast, 2 == ucast */
18414 char *ea
[ETHER_ADDR_LEN
];
18418 UNUSED_PARAMETER(cmd
);
18421 strncpy(arg
, str
, strlen(str
));
18422 arg
[strlen(str
)] = '\0';
18423 dst
= arg
+ strlen(str
) + 1;
18424 tot
+= strlen(str
) + 1;
18426 pkt_len
= (uint16
)htod32(strtoul(*argv
, NULL
, 0));
18428 *((uint16
*)dst
) = pkt_len
;
18430 dst
+= sizeof(pkt_len
);
18431 tot
+= sizeof(pkt_len
);
18434 printf("Dest of the packet needs to be provided\n");
18438 /* Dest of the frame */
18439 if (!strcmp(*argv
, "bcast")) {
18441 if (!wl_ether_atoe("ff:ff:ff:ff:ff:ff", (struct ether_addr
*)dst
))
18443 } else if (!strcmp(*argv
, "ucast")) {
18446 printf("EA of ucast dest of the packet needs to be provided\n");
18449 if (!wl_ether_atoe(*argv
, (struct ether_addr
*)dst
))
18452 memcpy(ea
, dst
, ETHER_ADDR_LEN
);
18453 } else if (!wl_ether_atoe(*argv
, (struct ether_addr
*)dst
))
18456 dst
+= ETHER_ADDR_LEN
;
18457 tot
+= ETHER_ADDR_LEN
;
18460 printf("type - magic/net needs to be provided\n");
18464 if (strncmp(*argv
, "magic", strlen("magic")) == 0)
18465 type
= WL_WOWL_MAGIC
;
18466 else if (strncmp(*argv
, "net", strlen("net")) == 0)
18467 type
= WL_WOWL_NET
;
18471 *((uint16
*)dst
) = type
;
18472 dst
+= sizeof(type
);
18473 tot
+= sizeof(type
);
18475 if (type
== WL_WOWL_MAGIC
) {
18476 if (pkt_len
< MAGIC_PKT_MINLEN
)
18480 memcpy(dst
, ea
, ETHER_ADDR_LEN
);
18485 if (!wl_ether_atoe(*argv
, (struct ether_addr
*)dst
))
18488 tot
+= ETHER_ADDR_LEN
;
18490 wl_wowl_pattern_t
*wl_pattern
;
18491 wl_pattern
= (wl_wowl_pattern_t
*)dst
;
18494 printf("Starting offset not provided\n");
18498 wl_pattern
->offset
= (uint
)htod32(strtoul(*argv
, NULL
, 0));
18500 wl_pattern
->masksize
= 0;
18502 wl_pattern
->patternoffset
= (uint
)htod32(sizeof(wl_wowl_pattern_t
));
18504 dst
+= sizeof(wl_wowl_pattern_t
);
18507 printf("pattern not provided\n");
18511 wl_pattern
->patternsize
=
18512 (uint
)htod32(wl_pattern_atoh((char *)(uintptr
)*argv
, dst
));
18514 tot
+= sizeof(wl_wowl_pattern_t
) + wl_pattern
->patternsize
;
18517 return (wlu_set(wl
, WLC_SET_VAR
, arg
, tot
));
18521 wl_wowl_pattern(void *wl
, cmd_t
*cmd
, char **argv
)
18526 wl_wowl_pattern_t
*wl_pattern
;
18528 UNUSED_PARAMETER(cmd
);
18536 if (strcmp(*argv
, "add") != 0 && strcmp(*argv
, "del") != 0 &&
18537 strcmp(*argv
, "clr") != 0) {
18541 str
= "wowl_pattern";
18542 strncpy(arg
, str
, strlen(str
));
18543 arg
[strlen(str
)] = '\0';
18544 dst
= arg
+ strlen(str
) + 1;
18545 tot
+= strlen(str
) + 1;
18548 strncpy(dst
, str
, strlen(str
));
18549 tot
+= strlen(str
) + 1;
18551 if (strcmp(str
, "clr") != 0) {
18552 wl_pattern
= (wl_wowl_pattern_t
*)(dst
+ strlen(str
) + 1);
18553 dst
= (char*)wl_pattern
+ sizeof(wl_wowl_pattern_t
);
18555 printf("Starting offset not provided\n");
18558 wl_pattern
->offset
= htod32(strtoul(*argv
, NULL
, 0));
18560 printf("Mask not provided\n");
18564 /* Parse the mask */
18566 wl_pattern
->masksize
= htod32(wl_pattern_atoh((char *)(uintptr
)str
, dst
));
18567 if (wl_pattern
->masksize
== (uint
)-1)
18570 dst
+= wl_pattern
->masksize
;
18571 wl_pattern
->patternoffset
= htod32((sizeof(wl_wowl_pattern_t
) +
18572 wl_pattern
->masksize
));
18575 printf("Pattern value not provided\n");
18579 /* Parse the value */
18581 wl_pattern
->patternsize
=
18582 htod32(wl_pattern_atoh((char *)(uintptr
)str
, dst
));
18583 if (wl_pattern
->patternsize
== (uint
)-1)
18585 tot
+= sizeof(wl_wowl_pattern_t
) + wl_pattern
->patternsize
+
18586 wl_pattern
->masksize
;
18589 return (wlu_set(wl
, WLC_SET_VAR
, arg
, tot
));
18591 wl_wowl_pattern_list_t
*list
;
18592 if ((err
= wlu_iovar_get(wl
, "wowl_pattern", buf
, WLC_IOCTL_MAXLEN
)) < 0)
18594 list
= (wl_wowl_pattern_list_t
*)buf
;
18595 printf("#of patterns :%d\n", list
->count
);
18596 ptr
= (uint8
*)list
->pattern
;
18597 for (i
= 0; i
< list
->count
; i
++) {
18600 wl_pattern
= (wl_wowl_pattern_t
*)ptr
;
18601 printf("Pattern %d:\n", i
+1);
18602 printf("Offset :%d\n"
18605 wl_pattern
->offset
, wl_pattern
->masksize
);
18606 pattern
= ((uint8
*)wl_pattern
+ sizeof(wl_wowl_pattern_t
));
18607 for (j
= 0; j
< wl_pattern
->masksize
; j
++)
18608 printf("%02x", pattern
[j
]);
18611 "Pattern :0x", wl_pattern
->patternsize
);
18612 /* Go to end to find pattern */
18613 pattern
= ((uint8
*)wl_pattern
+ wl_pattern
->patternoffset
);
18614 for (j
= 0; j
< wl_pattern
->patternsize
; j
++)
18615 printf("%02x", pattern
[j
]);
18617 ptr
+= (wl_pattern
->masksize
+ wl_pattern
->patternsize
+
18618 sizeof(wl_wowl_pattern_t
));
18626 wl_rifs(void *wl
, cmd_t
*cmd
, char **argv
)
18632 UNUSED_PARAMETER(cmd
);
18635 val_name
= *argv
++;
18638 if ((err
= wlu_iovar_getint(wl
, val_name
, (int*)&rifs
)) < 0)
18641 printf("%s\n", ((rifs
& 0xff) ? "On" : "Off"));
18645 val
= rifs
= (atoi(*argv
) ? 1 : 0);
18646 if (rifs
!= 0 && rifs
!= 1)
18647 return USAGE_ERROR
;
18649 if ((err
= wlu_set(wl
, WLC_SET_FAKEFRAG
, &val
, sizeof(int))) < 0) {
18650 printf("Set frameburst error %d\n", err
);
18653 if ((err
= wlu_iovar_setint(wl
, val_name
, (int)rifs
)) < 0)
18654 printf("Set rifs error %d\n", err
);
18660 wl_rifs_advert(void *wl
, cmd_t
*cmd
, char **argv
)
18666 BCM_REFERENCE(cmd
);
18669 val_name
= *argv
++;
18672 if ((err
= wlu_iovar_getint(wl
, val_name
, (int*)&rifs_advert
)) < 0)
18675 printf("%s\n", ((rifs_advert
& 0xff) ? "On" : "Off"));
18679 if (strcmp(*argv
, "-1") && strcmp(*argv
, "0"))
18680 return USAGE_ERROR
;
18682 rifs_advert
= atoi(*argv
);
18684 if ((err
= wlu_iovar_setint(wl
, val_name
, (int)rifs_advert
)) < 0)
18685 printf("Set rifs mode advertisement error %d\n", err
);
18691 clean_up_cmd_list(void)
18693 wl_seq_cmd_pkt_t
*this_cmd
, *next_cmd
;
18695 this_cmd
= cmd_list
.head
;
18696 while (this_cmd
!= NULL
) {
18697 next_cmd
= this_cmd
->next
;
18698 if (this_cmd
->data
!= NULL
) {
18699 free(this_cmd
->data
);
18702 this_cmd
= next_cmd
;
18704 cmd_list
.head
= NULL
;
18705 cmd_list
.tail
= NULL
;
18706 cmd_pkt_list_num
= 0;
18710 add_one_batched_cmd(int cmd
, void *cmdbuf
, int len
)
18712 wl_seq_cmd_pkt_t
*new_cmd
;
18714 new_cmd
= malloc(sizeof(wl_seq_cmd_pkt_t
));
18716 if (new_cmd
== NULL
) {
18717 printf("malloc(%d) failed, free %d batched commands and exit batching mode\n",
18718 (int)sizeof(wl_seq_cmd_pkt_t
), cmd_pkt_list_num
);
18719 goto free_and_exit
;
18721 printf("batching %dth command %d\n", cmd_pkt_list_num
+1, cmd
);
18724 new_cmd
->cmd_header
.cmd
= cmd
;
18725 new_cmd
->cmd_header
.len
= len
;
18726 new_cmd
->next
= NULL
;
18728 new_cmd
->data
= malloc(len
);
18730 if (new_cmd
->data
== NULL
) {
18731 printf("malloc(%d) failed, free %d batched commands and exit batching mode\n",
18732 len
, cmd_pkt_list_num
);
18734 goto free_and_exit
;
18737 memcpy(new_cmd
->data
, cmdbuf
, len
);
18739 if (cmd_list
.tail
!= NULL
)
18740 cmd_list
.tail
->next
= new_cmd
;
18742 cmd_list
.head
= new_cmd
;
18744 cmd_list
.tail
= new_cmd
;
18746 cmd_pkt_list_num
++;
18751 clean_up_cmd_list();
18753 if (cmd_batching_mode
) {
18754 cmd_batching_mode
= FALSE
;
18757 printf("calling add_one_batched_cmd() at non-command-batching mode, weird\n");
18763 /* now IOCTL GET commands shall call wlu_get() instead of wl_get() so that the commands
18764 * can be batched when needed
18767 wlu_get(void *wl
, int cmd
, void *cmdbuf
, int len
)
18769 if (cmd_batching_mode
) {
18770 if (!WL_SEQ_CMDS_GET_IOCTL_FILTER(cmd
)) {
18771 printf("IOCTL GET command %d is not supported in batching mode\n", cmd
);
18772 return IOCTL_ERROR
;
18776 return wl_get(wl
, cmd
, cmdbuf
, len
);
18779 /* now IOCTL SET commands shall call wlu_set() instead of wl_set() so that the commands
18780 * can be batched when needed
18783 wlu_set(void *wl
, int cmd
, void *cmdbuf
, int len
)
18785 if (cmd_batching_mode
) {
18786 return add_one_batched_cmd(cmd
, cmdbuf
, len
);
18789 return wl_set(wl
, cmd
, cmdbuf
, len
);
18793 /* this is the batched command packet size. now for remoteWL, we set it to 512 bytes */
18794 #define MEMBLOCK (512 - 32) /* allow 32 bytes for overhead (header, alignment, etc) */
18796 int wl_seq_batch_in_client(bool enable
)
18798 batch_in_client
= enable
;
18803 wl_seq_start(void *wl
, cmd_t
*cmd
, char **argv
)
18805 UNUSED_PARAMETER(cmd
);
18806 UNUSED_PARAMETER(argv
);
18808 if (!batch_in_client
) {
18809 return wlu_iovar_setbuf(wl
, "seq_start", NULL
, 0, buf
, WLC_IOCTL_MAXLEN
);
18812 if (cmd_batching_mode
) {
18813 printf("calling seq_start() when it's already in batching mode\n");
18814 clean_up_cmd_list();
18815 cmd_batching_mode
= FALSE
;
18816 return USAGE_ERROR
;
18819 cmd_batching_mode
= TRUE
;
18820 cmd_pkt_list_num
= 0;
18822 cmd_list
.head
= NULL
;
18823 cmd_list
.tail
= NULL
;
18831 wl_seq_stop(void *wl
, cmd_t
*cmd
, char **argv
)
18837 wl_seq_cmd_pkt_t
*next_cmd
;
18839 UNUSED_PARAMETER(cmd
);
18840 UNUSED_PARAMETER(argv
);
18842 if (!batch_in_client
) {
18843 return wlu_iovar_setbuf(wl
, "seq_stop", NULL
, 0, buf
, WLC_IOCTL_MAXLEN
);
18846 if (!cmd_batching_mode
) {
18847 printf("calling seq_stop when it's already out of batching mode\n");
18848 return IOCTL_ERROR
;
18850 cmd_batching_mode
= FALSE
;
18852 next_cmd
= cmd_list
.head
;
18854 /* dump batched commands to the DUT */
18856 if (next_cmd
== NULL
) {
18857 printf("no command batched\n");
18861 ret
= wlu_iovar_setbuf(wl
, "seq_start", NULL
, 0, buf
, WLC_IOCTL_MAXLEN
);
18863 printf("failed to send seq_start\n");
18867 while (next_cmd
!= NULL
) {
18869 memset(bufp
, 0, WLC_IOCTL_MAXLEN
);
18871 strcpy(bufp
, "seq_list");
18872 bufp
+= (strlen("seq_list") + 1);
18873 bufp
= ALIGN_ADDR(bufp
, WL_SEQ_CMD_ALIGN_BYTES
);
18874 seq_list_len
= bufp
- buf
;
18876 while ((seq_list_len
< MEMBLOCK
) && (next_cmd
!= NULL
)) {
18877 len
= ROUNDUP(next_cmd
->cmd_header
.len
, WL_SEQ_CMD_ALIGN_BYTES
);
18878 len
+= (seq_list_len
+ sizeof(wl_seq_cmd_ioctl_t
));
18880 if (len
< MEMBLOCK
) {
18881 memcpy(bufp
, &(next_cmd
->cmd_header
),
18882 sizeof(wl_seq_cmd_ioctl_t
));
18883 bufp
+= sizeof(wl_seq_cmd_ioctl_t
);
18884 memcpy(bufp
, next_cmd
->data
, next_cmd
->cmd_header
.len
);
18885 bufp
+= next_cmd
->cmd_header
.len
;
18886 bufp
= ALIGN_ADDR(bufp
, WL_SEQ_CMD_ALIGN_BYTES
);
18887 seq_list_len
= len
;
18889 next_cmd
= next_cmd
->next
;
18895 ret
= wl_set(wl
, WLC_SET_VAR
, &buf
[0], seq_list_len
);
18898 printf("failed to send seq_list\n");
18903 ret
= wlu_iovar_setbuf(wl
, "seq_stop", NULL
, 0, buf
, WLC_IOCTL_MAXLEN
);
18905 printf("failed to send seq_stop\n");
18909 clean_up_cmd_list();
18915 wl_obss_scan_params_range_chk(wl_obss_scan_arg_t
*obss_scan_arg
)
18917 if (obss_scan_arg
->passive_dwell
< 0)
18918 obss_scan_arg
->passive_dwell
= WLC_OBSS_SCAN_PASSIVE_DWELL_DEFAULT
;
18919 else if (obss_scan_arg
->passive_dwell
< WLC_OBSS_SCAN_PASSIVE_DWELL_MIN
||
18920 obss_scan_arg
->passive_dwell
> WLC_OBSS_SCAN_PASSIVE_DWELL_MAX
) {
18921 printf("passive dwell not in range %d\n", obss_scan_arg
->passive_dwell
);
18925 if (obss_scan_arg
->active_dwell
< 0)
18926 obss_scan_arg
->active_dwell
= WLC_OBSS_SCAN_ACTIVE_DWELL_DEFAULT
;
18927 else if (obss_scan_arg
->active_dwell
< WLC_OBSS_SCAN_ACTIVE_DWELL_MIN
||
18928 obss_scan_arg
->active_dwell
> WLC_OBSS_SCAN_ACTIVE_DWELL_MAX
) {
18929 printf("active dwell not in range %d\n", obss_scan_arg
->active_dwell
);
18933 if (obss_scan_arg
->bss_widthscan_interval
< 0)
18934 obss_scan_arg
->bss_widthscan_interval
=
18935 WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_DEFAULT
;
18936 else if (obss_scan_arg
->bss_widthscan_interval
< WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_MIN
||
18937 obss_scan_arg
->bss_widthscan_interval
> WLC_OBSS_SCAN_WIDTHSCAN_INTERVAL_MAX
) {
18938 printf("Width Trigger Scan Interval not in range %d\n",
18939 obss_scan_arg
->bss_widthscan_interval
);
18943 if (obss_scan_arg
->chanwidth_transition_delay
< 0)
18944 obss_scan_arg
->chanwidth_transition_delay
=
18945 WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_DEFAULT
;
18946 else if ((obss_scan_arg
->chanwidth_transition_delay
<
18947 WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_MIN
) ||
18948 (obss_scan_arg
->chanwidth_transition_delay
>
18949 WLC_OBSS_SCAN_CHANWIDTH_TRANSITION_DLY_MAX
)) {
18950 printf("Width Channel Transition Delay Factor not in range %d\n",
18951 obss_scan_arg
->chanwidth_transition_delay
);
18955 if (obss_scan_arg
->passive_total
< 0)
18956 obss_scan_arg
->passive_total
= WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_DEFAULT
;
18957 else if (obss_scan_arg
->passive_total
< WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_MIN
||
18958 obss_scan_arg
->passive_total
> WLC_OBSS_SCAN_PASSIVE_TOTAL_PER_CHANNEL_MAX
) {
18959 printf("Passive Total per Channel not in range %d\n", obss_scan_arg
->passive_total
);
18963 if (obss_scan_arg
->active_total
< 0)
18964 obss_scan_arg
->active_total
= WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_DEFAULT
;
18965 if (obss_scan_arg
->active_total
< WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_MIN
||
18966 obss_scan_arg
->active_total
> WLC_OBSS_SCAN_ACTIVE_TOTAL_PER_CHANNEL_MAX
) {
18967 printf("Active Total per Channel not in range %d\n", obss_scan_arg
->active_total
);
18971 if (obss_scan_arg
->activity_threshold
< 0)
18972 obss_scan_arg
->activity_threshold
= WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_DEFAULT
;
18973 else if (obss_scan_arg
->activity_threshold
< WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_MIN
||
18974 obss_scan_arg
->activity_threshold
> WLC_OBSS_SCAN_ACTIVITY_THRESHOLD_MAX
) {
18975 printf("Activity Threshold not in range %d\n", obss_scan_arg
->activity_threshold
);
18981 /* Send a periodic keep-alive packet at the specificed interval. */
18983 wl_keep_alive(void *wl
, cmd_t
*cmd
, char **argv
)
18986 wl_keep_alive_pkt_t keep_alive_pkt
;
18987 wl_keep_alive_pkt_t
*keep_alive_pktp
;
18995 if (NULL
== *++argv
) {
18997 ** Get current keep-alive status.
18999 if ((rc
= wlu_var_getbuf(wl
, cmd
->name
, NULL
, 0, &ptr
)) < 0)
19002 keep_alive_pktp
= (wl_keep_alive_pkt_t
*) ptr
;
19004 printf("Period (msec) :%d\n"
19007 dtoh32(keep_alive_pktp
->period_msec
),
19008 dtoh16(keep_alive_pktp
->len_bytes
));
19010 for (i
= 0; i
< keep_alive_pktp
->len_bytes
; i
++)
19011 printf("%02x", keep_alive_pktp
->data
[i
]);
19017 ** Set keep-alive attributes.
19020 str
= "keep_alive";
19021 str_len
= strlen(str
);
19022 strncpy(buf
, str
, str_len
);
19023 buf
[ str_len
] = '\0';
19025 keep_alive_pktp
= (wl_keep_alive_pkt_t
*) (buf
+ str_len
+ 1);
19026 keep_alive_pkt
.period_msec
= htod32(strtoul(*argv
, NULL
, 0));
19027 buf_len
= str_len
+ 1;
19030 if (0 == keep_alive_pkt
.period_msec
) {
19031 keep_alive_pkt
.len_bytes
= 0;
19033 buf_len
+= sizeof(wl_keep_alive_pkt_t
);
19036 if (NULL
== *++argv
) {
19037 printf("Network packet not provided\n");
19042 keep_alive_pkt
.len_bytes
=
19043 htod16(wl_pattern_atoh(*argv
, (char *) keep_alive_pktp
->data
));
19045 buf_len
+= (WL_KEEP_ALIVE_FIXED_LEN
+ keep_alive_pkt
.len_bytes
);
19049 /* Keep-alive attributes are set in local variable (keep_alive_pkt), and
19050 * then memcpy'ed into buffer (keep_alive_pktp) since there is no
19051 * guarantee that the buffer is properly aligned.
19053 memcpy((char *)keep_alive_pktp
, &keep_alive_pkt
, WL_KEEP_ALIVE_FIXED_LEN
);
19067 /* Enable/disable installed packet filter. */
19069 wl_pkt_filter_enable(void *wl
, cmd_t
*cmd
, char **argv
)
19071 wl_pkt_filter_enable_t enable_parm
;
19074 if (NULL
== *++argv
) {
19075 printf("No args provided\n");
19079 /* Parse packet filter id. */
19080 enable_parm
.id
= htod32(strtoul(*argv
, NULL
, 0));
19082 if (NULL
== *++argv
) {
19083 printf("Enable/disable value not provided\n");
19087 /* Parse enable/disable value. */
19088 enable_parm
.enable
= htod32(strtoul(*argv
, NULL
, 0));
19091 /* Enable/disable the specified filter. */
19092 rc
= wlu_var_setbuf(wl
,
19095 sizeof(wl_pkt_filter_enable_t
));
19101 /* Install a new packet filter. */
19103 wl_pkt_filter_add(void *wl
, cmd_t
*cmd
, char **argv
)
19106 wl_pkt_filter_t pkt_filter
;
19107 wl_pkt_filter_t
*pkt_filterp
;
19112 uint32 pattern_size
;
19114 UNUSED_PARAMETER(cmd
);
19116 if (NULL
== *++argv
) {
19117 printf("No args provided\n");
19121 str
= "pkt_filter_add";
19122 str_len
= strlen(str
);
19123 strncpy(buf
, str
, str_len
);
19124 buf
[ str_len
] = '\0';
19125 buf_len
= str_len
+ 1;
19127 pkt_filterp
= (wl_pkt_filter_t
*) (buf
+ str_len
+ 1);
19129 /* Parse packet filter id. */
19130 pkt_filter
.id
= htod32(strtoul(*argv
, NULL
, 0));
19132 if (NULL
== *++argv
) {
19133 printf("Polarity not provided\n");
19137 /* Parse filter polarity. */
19138 pkt_filter
.negate_match
= htod32(strtoul(*argv
, NULL
, 0));
19140 if (NULL
== *++argv
) {
19141 printf("Filter type not provided\n");
19145 /* Parse filter type. */
19146 pkt_filter
.type
= htod32(strtoul(*argv
, NULL
, 0));
19148 if (NULL
== *++argv
) {
19149 printf("Offset not provided\n");
19153 /* Parse pattern filter offset. */
19154 pkt_filter
.u
.pattern
.offset
= htod32(strtoul(*argv
, NULL
, 0));
19156 if (NULL
== *++argv
) {
19157 printf("Bitmask not provided\n");
19161 /* Parse pattern filter mask. */
19163 htod32(wl_pattern_atoh(*argv
, (char *) pkt_filterp
->u
.pattern
.mask_and_pattern
));
19165 if (NULL
== *++argv
) {
19166 printf("Pattern not provided\n");
19170 /* Parse pattern filter pattern. */
19172 htod32(wl_pattern_atoh(*argv
,
19173 (char *) &pkt_filterp
->u
.pattern
.mask_and_pattern
[mask_size
]));
19175 if (mask_size
!= pattern_size
) {
19176 printf("Mask and pattern not the same size\n");
19181 pkt_filter
.u
.pattern
.size_bytes
= mask_size
;
19182 buf_len
+= WL_PKT_FILTER_FIXED_LEN
;
19183 buf_len
+= (WL_PKT_FILTER_PATTERN_FIXED_LEN
+ 2 * mask_size
);
19185 /* Keep-alive attributes are set in local variable (keep_alive_pkt), and
19186 ** then memcpy'ed into buffer (keep_alive_pktp) since there is no
19187 ** guarantee that the buffer is properly aligned.
19189 memcpy((char *)pkt_filterp
,
19191 WL_PKT_FILTER_FIXED_LEN
+ WL_PKT_FILTER_PATTERN_FIXED_LEN
);
19204 /* List installed packet filters. */
19206 wl_pkt_filter_list(void *wl
, cmd_t
*cmd
, char **argv
)
19208 wl_pkt_filter_list_t
*list
;
19209 wl_pkt_filter_t
*filterp
;
19214 unsigned int filter_len
;
19218 if (NULL
== *++argv
) {
19219 printf("No args provided\n");
19223 /* Parse filter list to retrieve (enabled/disabled). */
19224 enable
= htod32(strtoul(*argv
, NULL
, 0));
19226 ** Get list of installed packet filters.
19228 if ((rc
= wlu_var_getbuf(wl
, cmd
->name
, &enable
, sizeof(enable
), &ptr
)) < 0)
19231 list
= (wl_pkt_filter_list_t
*) ptr
;
19233 printf("Num filters: %d\n\n", list
->num
);
19235 filterp
= list
->filter
;
19236 for (i
= 0; i
< list
->num
; i
++)
19242 "Pattern len :%d\n"
19244 dtoh32(filterp
->id
),
19245 dtoh32(filterp
->negate_match
),
19246 dtoh32(filterp
->type
),
19247 dtoh32(filterp
->u
.pattern
.offset
),
19248 dtoh32(filterp
->u
.pattern
.size_bytes
));
19251 for (j
= 0; j
< filterp
->u
.pattern
.size_bytes
; j
++)
19252 printf("%02x", filterp
->u
.pattern
.mask_and_pattern
[j
]);
19254 printf("\nPattern :0x");
19256 for (; j
< 2 * filterp
->u
.pattern
.size_bytes
; j
++)
19257 printf("%02x", filterp
->u
.pattern
.mask_and_pattern
[j
]);
19262 filter_len
= WL_PKT_FILTER_FIXED_LEN
;
19263 filter_len
+= WL_PKT_FILTER_PATTERN_FIXED_LEN
+ 2 * filterp
->u
.pattern
.size_bytes
;
19264 filterp
= (wl_pkt_filter_t
*) ((uint8
*)filterp
+ filter_len
);
19265 filterp
= ALIGN_ADDR(filterp
, sizeof(uint32
));
19273 /* Get packet filter debug statistics. */
19275 wl_pkt_filter_stats(void *wl
, cmd_t
*cmd
, char **argv
)
19277 wl_pkt_filter_stats_t
*stats
;
19282 if (NULL
== *++argv
) {
19283 printf("No args provided\n");
19287 /* Parse filter id to retrieve. */
19288 id
= htod32(strtoul(*argv
, NULL
, 0));
19291 /* Get debug stats. */
19292 if ((rc
= wlu_var_getbuf(wl
, cmd
->name
, &id
, sizeof(id
), &ptr
)) < 0)
19295 stats
= (wl_pkt_filter_stats_t
*) ptr
;
19297 printf("Packets matched for filter '%d': %d\n"
19298 "Total packets discarded : %d\n"
19299 "Total packet forwarded : %d\n",
19301 dtoh32(stats
->num_pkts_matched
),
19302 dtoh32(stats
->num_pkts_discarded
),
19303 dtoh32(stats
->num_pkts_forwarded
));
19310 wl_obss_scan(void *wl
, cmd_t
*cmd
, char **argv
)
19313 wl_obss_scan_arg_t obss_scan_arg
;
19314 char *endptr
= NULL
;
19320 wl_obss_scan_arg_t
*obss_scan_param
;
19322 err
= wlu_var_getbuf(wl
, cmd
->name
, NULL
, 0, &ptr
);
19326 obss_scan_param
= (wl_obss_scan_arg_t
*)ptr
;
19327 printf("%d %d %d %d %d %d %d\n",
19328 dtoh16(obss_scan_param
->passive_dwell
),
19329 dtoh16(obss_scan_param
->active_dwell
),
19330 dtoh16(obss_scan_param
->bss_widthscan_interval
),
19331 dtoh16(obss_scan_param
->passive_total
),
19332 dtoh16(obss_scan_param
->active_total
),
19333 dtoh16(obss_scan_param
->chanwidth_transition_delay
),
19334 dtoh16(obss_scan_param
->activity_threshold
));
19342 buflen
= WL_OBSS_SCAN_PARAM_LEN
;
19343 memset((uint8
*)&obss_scan_arg
, 0, buflen
);
19345 /* required argments */
19346 if (argc
< WL_MIN_NUM_OBSS_SCAN_ARG
) {
19347 fprintf(stderr
, "Too few/many arguments (require %d, got %d)\n",
19348 WL_MIN_NUM_OBSS_SCAN_ARG
, argc
);
19352 obss_scan_arg
.passive_dwell
= htod16((int16
)strtol(*argv
++, &endptr
, 0));
19353 if (*endptr
!= '\0')
19356 obss_scan_arg
.active_dwell
= htod16((int16
)strtol(*argv
++, &endptr
, 0));
19357 if (*endptr
!= '\0')
19360 obss_scan_arg
.bss_widthscan_interval
= htod16((int16
)strtol(*argv
++, &endptr
, 0));
19361 if (*endptr
!= '\0')
19364 obss_scan_arg
.passive_total
= htod16((int16
)strtol(*argv
++, &endptr
, 0));
19365 if (*endptr
!= '\0')
19368 obss_scan_arg
.active_total
= htod16((int16
)strtol(*argv
++, &endptr
, 0));
19369 if (*endptr
!= '\0')
19372 obss_scan_arg
.chanwidth_transition_delay
= htod16((int16
)strtol(*argv
++, &endptr
, 0));
19373 if (*endptr
!= '\0')
19376 obss_scan_arg
.activity_threshold
= htod16((int16
)strtol(*argv
++, &endptr
, 0));
19377 if (*endptr
!= '\0')
19380 if (wl_obss_scan_params_range_chk(&obss_scan_arg
))
19383 err
= wlu_var_setbuf(wl
, cmd
->name
, &obss_scan_arg
, buflen
);
19390 /* Function added to support RWL_WIFI Transport
19391 * Used to find the remote server with proper mac address given by
19392 * the user,this cmd is specific to RWL_WIFIi protocol
19394 static int wl_wifiserver(void *wl
, cmd_t
*cmd
, char **argv
)
19398 if ((ret
= wlu_iovar_set(wl
, cmd
->name
, *argv
, strlen(*argv
))) < 0) {
19399 printf("Error finding the remote server %s\n", argv
[0]);
19406 wl_obss_coex_action(void *wl
, cmd_t
*cmd
, char **argv
)
19410 wl_action_obss_coex_req_t
*req
= (wl_action_obss_coex_req_t
*)var
;
19416 memset(&var
, 0, sizeof(wl_action_obss_coex_req_t
));
19418 if (!strncmp(*argv
, "-i", 2) && ((options
& 0x1) != 0x1)) {
19423 if ((val
!= 0) && (val
!= 1))
19425 req
->info
|= val
? WL_COEX_40MHZ_INTOLERANT
: 0;
19428 else if (!strncmp(*argv
, "-w", 2) && ((options
& 0x2) != 0x2)) {
19433 if ((val
!= 0) && (val
!= 1))
19435 req
->info
|= val
? WL_COEX_WIDTH20
: 0;
19438 else if (!strncmp(*argv
, "-c", 2) && ((options
& 0x4) != 0x4)) {
19441 if (isdigit((const unsigned char)(**argv
))) {
19442 val
= htod32(strtoul(*argv
, NULL
, 0));
19443 if ((val
== 0) || (val
> 14)) {
19444 printf("Invalid channel %d\n", val
);
19447 req
->ch_list
[num
] = (uint8
)val
;
19451 printf("Too many channels (max 14)\n");
19458 printf("With option '-c' specified, a channel list is required\n");
19471 err
= wlu_var_setbuf(wl
, cmd
->name
, &var
, (sizeof(wl_action_obss_coex_req_t
) +
19472 (req
->num
? (req
->num
- 1) * sizeof(uint8
) : 0)));
19477 wl_srchmem(void *wl
, cmd_t
*cmd
, char **argv
)
19484 uint8 ssid
[DOT11_MAX_SSID_LEN
];
19486 struct args
*pargs
;
19491 UNUSED_PARAMETER(cmd
);
19493 memset(&x
, 0, sizeof(x
));
19495 /* save command name */
19500 for (argc
= 0; argv
[argc
]; argc
++)
19503 /* required arg: reg offset */
19507 x
.reg
= strtol(argv
[0], &endptr
, 0);
19508 if (*endptr
!= '\0' || x
.reg
> 15)
19517 len
= strlen(argv
[1]);
19518 if (len
> sizeof(x
.ssid
)) {
19519 printf("ssid too long\n");
19522 memcpy(x
.ssid
, argv
[1], len
);
19526 /* issue the get or set ioctl */
19528 x
.band
= htod32(x
.band
);
19529 x
.reg
= htod32(x
.reg
);
19531 ret
= wlu_iovar_getbuf(wl
, iovar
, &x
, sizeof(x
), buf
, WLC_IOCTL_SMLEN
);
19533 printf("get returned error 0x%x\n", ret
);
19536 pargs
= (struct args
*)(buf
+ strlen(iovar
) + 1 + 2*sizeof(int));
19538 wl_hexdump((uchar
*)pargs
, sizeof(pargs
->ssidlen
) + sizeof(pargs
->ssid
));
19541 x
.band
= htod32(x
.band
);
19542 x
.reg
= htod32(x
.reg
);
19543 x
.ssidlen
= htod32(x
.ssidlen
);
19545 ret
= wlu_iovar_setbuf(wl
, iovar
, &x
, sizeof(x
), buf
, WLC_IOCTL_MAXLEN
);
19547 printf("set returned error 0x%x\n", ret
);
19555 cntry_name_t cntry_names
[] = {
19557 {"AFGHANISTAN", "AF"},
19560 {"AMERICAN SAMOA", "AS"},
19563 {"ANGUILLA", "AI"},
19564 {"ANTARCTICA", "AQ"},
19565 {"ANTIGUA AND BARBUDA", "AG"},
19566 {"ARGENTINA", "AR"},
19569 {"ASCENSION ISLAND", "AC"},
19570 {"AUSTRALIA", "AU"},
19572 {"AZERBAIJAN", "AZ"},
19575 {"BANGLADESH", "BD"},
19576 {"BARBADOS", "BB"},
19584 {"BOSNIA AND HERZEGOVINA", "BA"},
19585 {"BOTSWANA", "BW"},
19586 {"BOUVET ISLAND", "BV"},
19588 {"BRITISH INDIAN OCEAN TERRITORY", "IO"},
19589 {"BRUNEI DARUSSALAM", "BN"},
19590 {"BULGARIA", "BG"},
19591 {"BURKINA FASO", "BF"},
19593 {"CAMBODIA", "KH"},
19594 {"CAMEROON", "CM"},
19596 {"CAPE VERDE", "CV"},
19597 {"CAYMAN ISLANDS", "KY"},
19598 {"CENTRAL AFRICAN REPUBLIC", "CF"},
19602 {"CHRISTMAS ISLAND", "CX"},
19603 {"CLIPPERTON ISLAND", "CP"},
19604 {"COCOS (KEELING) ISLANDS", "CC"},
19605 {"COLOMBIA", "CO"},
19608 {"CONGO, THE DEMOCRATIC REPUBLIC OF THE", "CD"},
19609 {"COOK ISLANDS", "CK"},
19610 {"COSTA RICA", "CR"},
19611 {"COTE D'IVOIRE", "CI"},
19615 {"CZECH REPUBLIC", "CZ"},
19617 {"DJIBOUTI", "DJ"},
19618 {"DOMINICA", "DM"},
19619 {"DOMINICAN REPUBLIC", "DO"},
19622 {"EL SALVADOR", "SV"},
19623 {"EQUATORIAL GUINEA", "GQ"},
19626 {"ETHIOPIA", "ET"},
19627 {"EUROPEAN UNION", "EU"},
19628 {"FALKLAND ISLANDS (MALVINAS)", "FK"},
19629 {"FAROE ISLANDS", "FO"},
19633 {"FRENCH GUIANA", "GF"},
19634 {"FRENCH POLYNESIA", "PF"},
19635 {"FRENCH SOUTHERN TERRITORIES", "TF"},
19641 {"GIBRALTAR", "GI"},
19643 {"GREENLAND", "GL"},
19645 {"GUADELOUPE", "GP"},
19647 {"GUATEMALA", "GT"},
19648 {"GUERNSEY", "GG"},
19650 {"GUINEA-BISSAU", "GW"},
19653 {"HEARD ISLAND AND MCDONALD ISLANDS", "HM"},
19654 {"HOLY SEE (VATICAN CITY STATE)", "VA"},
19655 {"HONDURAS", "HN"},
19656 {"HONG KONG", "HK"},
19660 {"INDONESIA", "ID"},
19661 {"IRAN, ISLAMIC REPUBLIC OF", "IR"},
19670 {"KAZAKHSTAN", "KZ"},
19672 {"KIRIBATI", "KI"},
19673 {"KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF", "KP"},
19674 {"KOREA, REPUBLIC OF", "KR"},
19676 {"KYRGYZSTAN", "KG"},
19677 {"LAO PEOPLE'S DEMOCRATIC REPUBLIC", "LA"},
19682 {"LIBYAN ARAB JAMAHIRIYA", "LY"},
19683 {"LIECHTENSTEIN", "LI"},
19684 {"LITHUANIA", "LT"},
19685 {"LUXEMBOURG", "LU"},
19687 {"MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF", "MK"},
19688 {"MADAGASCAR", "MG"},
19690 {"MALAYSIA", "MY"},
19691 {"MALDIVES", "MV"},
19694 {"MAN, ISLE OF", "IM"},
19695 {"MARSHALL ISLANDS", "MH"},
19696 {"MARTINIQUE", "MQ"},
19697 {"MAURITANIA", "MR"},
19698 {"MAURITIUS", "MU"},
19701 {"MICRONESIA, FEDERATED STATES OF", "FM"},
19702 {"MOLDOVA, REPUBLIC OF", "MD"},
19704 {"MONGOLIA", "MN"},
19705 {"MONTENEGRO", "ME"},
19706 {"MONTSERRAT", "MS"},
19708 {"MOZAMBIQUE", "MZ"},
19713 {"NETHERLANDS", "NL"},
19714 {"NETHERLANDS ANTILLES", "AN"},
19715 {"NEW CALEDONIA", "NC"},
19716 {"NEW ZEALAND", "NZ"},
19717 {"NICARAGUA", "NI"},
19721 {"NORFOLK ISLAND", "NF"},
19722 {"NORTHERN MARIANA ISLANDS", "MP"},
19725 {"PAKISTAN", "PK"},
19727 {"PALESTINIAN TERRITORY, OCCUPIED", "PS"},
19729 {"PAPUA NEW GUINEA", "PG"},
19730 {"PARAGUAY", "PY"},
19732 {"PHILIPPINES", "PH"},
19733 {"PITCAIRN", "PN"},
19735 {"PORTUGAL", "PT"},
19736 {"PUERTO RICO", "PR"},
19740 {"RUSSIAN FEDERATION", "RU"},
19742 {"SAINT HELENA", "SH"},
19743 {"SAINT KITTS AND NEVIS", "KN"},
19744 {"SAINT LUCIA", "LC"},
19745 {"SAINT PIERRE AND MIQUELON", "PM"},
19746 {"SAINT VINCENT AND THE GRENADINES", "VC"},
19748 {"SAN MARINO", "SM"},
19749 {"SAO TOME AND PRINCIPE", "ST"},
19750 {"SAUDI ARABIA", "SA"},
19753 {"SEYCHELLES", "SC"},
19754 {"SIERRA LEONE", "SL"},
19755 {"SINGAPORE", "SG"},
19756 {"SLOVAKIA", "SK"},
19757 {"SLOVENIA", "SI"},
19758 {"SOLOMON ISLANDS", "SB"},
19760 {"SOUTH AFRICA", "ZA"},
19761 {"SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS", "GS"},
19763 {"SRI LANKA", "LK"},
19765 {"SURINAME", "SR"},
19766 {"SVALBARD AND JAN MAYEN", "SJ"},
19767 {"SWAZILAND", "SZ"},
19769 {"SWITZERLAND", "CH"},
19770 {"SYRIAN ARAB REPUBLIC", "SY"},
19771 {"TAIWAN, PROVINCE OF CHINA", "TW"},
19772 {"TAJIKISTAN", "TJ"},
19773 {"TANZANIA, UNITED REPUBLIC OF", "TZ"},
19774 {"THAILAND", "TH"},
19775 {"TIMOR-LESTE (EAST TIMOR)", "TL"},
19779 {"TRINIDAD AND TOBAGO", "TT"},
19780 {"TRISTAN DA CUNHA", "TA"},
19783 {"TURKMENISTAN", "TM"},
19784 {"TURKS AND CAICOS ISLANDS", "TC"},
19788 {"UNITED ARAB EMIRATES", "AE"},
19789 {"UNITED KINGDOM", "GB"},
19790 {"UNITED STATES", "US"},
19791 {"UNITED STATES MINOR OUTLYING ISLANDS", "UM"},
19793 {"UZBEKISTAN", "UZ"},
19795 {"VENEZUELA", "VE"},
19796 {"VIET NAM", "VN"},
19797 {"VIRGIN ISLANDS, BRITISH", "VG"},
19798 {"VIRGIN ISLANDS, U.S.", "VI"},
19799 {"WALLIS AND FUTUNA", "WF"},
19800 {"WESTERN SAHARA", "EH"},
19802 {"YUGOSLAVIA", "YU"},
19804 {"ZIMBABWE", "ZW"},
19805 {"RADAR CHANNELS", "RDR"},
19806 {"ALL CHANNELS", "ALL"},
19811 wl_print_mcsset(char *mcsset
)
19815 printf("MCS SET : [ ");
19816 for (i
= 0; i
< (MCSSET_LEN
* 8); i
++)
19817 if (isset(mcsset
, i
))
19823 wl_txmcsset(void *wl
, cmd_t
*cmd
, char **argv
)
19827 if ((err
= wl_var_get(wl
, cmd
, argv
)) < 0)
19829 wl_print_mcsset(buf
);
19835 wl_rxmcsset(void *wl
, cmd_t
*cmd
, char **argv
)
19839 if ((err
= wl_var_get(wl
, cmd
, argv
)) < 0)
19842 wl_print_mcsset(buf
);
19848 wl_mimo_stf(void *wl
, cmd_t
*cmd
, char **argv
)
19864 /* toss the command name */
19870 memcpy(&var
[len
], (char *)&int_val
, sizeof(int_val
));
19871 len
+= sizeof(int_val
);
19874 if (isdigit((const unsigned char)(**argv
))) {
19876 int_val
= htod32(strtoul(*argv
, &endptr
, 0));
19877 if ((int_val
!= 0) && (int_val
!= 1)) {
19878 fprintf(stderr
, "wl mimo_ss_stf: bad stf mode.\n");
19881 memcpy(var
, (char *)&int_val
, sizeof(int_val
));
19882 len
+= sizeof(int_val
);
19889 memcpy(&var
[len
], (char *)&int_val
, sizeof(int_val
));
19890 len
+= sizeof(int_val
);
19892 else if (!strncmp(*argv
, "-b", 2)) {
19898 if (!strcmp(*argv
, "a"))
19900 else if (!strcmp(*argv
, "b"))
19904 "wl mimo_ss_stf: wrong -b option, \"-b a\" or \"-b b\"\n");
19910 memcpy(&var
[len
], (char *)&int_val
, sizeof(int_val
));
19911 len
+= sizeof(int_val
);
19916 if (wlu_var_getbuf(wl
, cmd
->name
, var
, sizeof(var
), &ptr
) < 0)
19919 printf("0x%x\n", dtoh32(*(int *)ptr
));
19922 wlu_var_setbuf(wl
, cmd
->name
, &var
, sizeof(var
));
19928 wl_extlog(void *wl
, cmd_t
*cmd
, char **argv
)
19935 char *log_p
= NULL
;
19936 wlc_extlog_req_t r_args
;
19937 wlc_extlog_results_t
*results
;
19941 for (argc
= 0; argv
[argc
]; argc
++)
19950 from_last
= htod32(strtoul(argv
[1], &endptr
, 0));
19951 if ((from_last
!= 0) && (from_last
!= 1))
19955 r_args
.from_last
= from_last
;
19957 r_args
.num
= htod32(strtoul(argv
[2], &endptr
, 0));
19961 if ((err
= wlu_var_getbuf(wl
, cmd
->name
, &r_args
, sizeof(wlc_extlog_req_t
), &ptr
)) < 0)
19964 results
= (wlc_extlog_results_t
*)buf
;
19966 printf("get external log records: %d\n", results
->num
);
19970 if (results
->version
!= EXTLOG_CUR_VER
) {
19971 printf("version mismatch: version = 0x%x, expected 0x%0x\n",
19972 results
->version
, EXTLOG_CUR_VER
);
19976 log_p
= (char *)&results
->logs
[0];
19978 printf("Seq:\tTime(ms) Log\n");
19979 for (i
= 0; i
< (int)results
->num
; i
++) {
19980 printf("%d:\t%d\t ", ((log_record_t
*)log_p
)->seq_num
,
19981 ((log_record_t
*)log_p
)->time
);
19982 for (j
= 0; j
< FMTSTR_MAX_ID
; j
++)
19983 if (((log_record_t
*)log_p
)->id
== extlog_fmt_str
[j
].id
)
19985 if (j
== FMTSTR_MAX_ID
) {
19986 printf("fmt string not found for id %d\n", ((log_record_t
*)log_p
)->id
);
19987 log_p
+= results
->record_len
;
19991 switch (extlog_fmt_str
[j
].arg_type
) {
19992 case LOG_ARGTYPE_NULL
:
19993 printf("%s", extlog_fmt_str
[j
].fmt_str
);
19996 case LOG_ARGTYPE_STR
:
19997 printf(extlog_fmt_str
[j
].fmt_str
, ((log_record_t
*)log_p
)->str
);
20000 case LOG_ARGTYPE_INT
:
20001 printf(extlog_fmt_str
[j
].fmt_str
, ((log_record_t
*)log_p
)->arg
);
20004 case LOG_ARGTYPE_INT_STR
:
20005 printf(extlog_fmt_str
[j
].fmt_str
, ((log_record_t
*)log_p
)->arg
,
20006 ((log_record_t
*)log_p
)->str
);
20009 case LOG_ARGTYPE_STR_INT
:
20010 printf(extlog_fmt_str
[j
].fmt_str
, ((log_record_t
*)log_p
)->str
,
20011 ((log_record_t
*)log_p
)->arg
);
20014 log_p
+= results
->record_len
;
20022 wl_extlog_cfg(void *wl
, cmd_t
*cmd
, char **argv
)
20027 wlc_extlog_cfg_t
*r_cfg
;
20028 wlc_extlog_cfg_t w_cfg
;
20031 for (argc
= 0; argv
[argc
]; argc
++)
20035 err
= wl_var_get(wl
, cmd
, argv
);
20038 r_cfg
= (wlc_extlog_cfg_t
*)buf
;
20039 printf("max_number=%d, module=%x, level=%d, flag=%d, version=0x%04x\n",
20040 r_cfg
->max_number
, r_cfg
->module
, r_cfg
->level
,
20041 r_cfg
->flag
, r_cfg
->version
);
20043 else if (argc
== 4) {
20044 w_cfg
.module
= htod16((uint16
)(strtoul(argv
[1], &endptr
, 0)));
20045 w_cfg
.level
= (uint8
)strtoul(argv
[2], &endptr
, 0);
20046 w_cfg
.flag
= (uint8
)strtoul(argv
[3], &endptr
, 0);
20047 wlu_var_setbuf(wl
, cmd
->name
, &w_cfg
, sizeof(wlc_extlog_cfg_t
));
20050 fprintf(stderr
, "illegal command!\n");
20056 #endif /* WLEXTLOG */
20059 wl_assertlog(void *wl
, cmd_t
*cmd
, char **argv
)
20064 char *log_p
= NULL
;
20065 assertlog_results_t
*results
;
20069 for (argc
= 0; argv
[argc
]; argc
++)
20075 if ((err
= wlu_var_getbuf(wl
, cmd
->name
, NULL
, 0, &ptr
)) < 0)
20078 results
= (assertlog_results_t
*)buf
;
20080 printf("get external assert logs: %d\n", results
->num
);
20084 if (results
->version
!= ASSERTLOG_CUR_VER
) {
20085 printf("Version mismatch: version = 0x%x, expected 0x%x\n",
20086 results
->version
, ASSERTLOG_CUR_VER
);
20090 log_p
= (char *)&results
->logs
[0];
20092 printf("id: \ttime(ms) \tstring\n");
20093 for (i
= 0; i
< (int)results
->num
; i
++) {
20094 printf("%d: \t%d \t%s", i
, ((assert_record_t
*)log_p
)->time
,
20095 ((assert_record_t
*)log_p
)->str
);
20096 log_p
+= results
->record_len
;
20102 extern cca_congest_channel_req_t
*
20103 cca_per_chan_summary(cca_congest_channel_req_t
*input
,
20104 cca_congest_channel_req_t
*avg
, bool percent
);
20107 cca_analyze(cca_congest_channel_req_t
*input
[], int num_chans
, uint flags
, chanspec_t
*answer
);
20109 static const char *
20110 cca_level(int score
, int med
, int hi
)
20114 if (score
>= med
&& score
< hi
)
20121 static const char *cca_errors
[] = {
20124 "Dwell Duration too low",
20126 "Interference too high",
20127 "Only 1 channel inoput"
20131 wl_cca_get_stats(void *wl
, cmd_t
*cmd
, char **argv
)
20133 cca_congest_channel_req_t
*results
;
20134 cca_congest_channel_req_t req
;
20135 cca_congest_t
*chptr
;
20136 cca_congest_channel_req_t
*avg
[MAX_CCA_CHANNELS
]; /* Max num of channels */
20138 char *param
, *val_p
;
20139 int base
, limit
, i
, channel
, err
= 0;
20140 int ibss_per
, obss_per
, inter_per
, val
;
20141 const char *ibss_lvl
= NULL
;
20142 const char *obss_lvl
= NULL
;
20143 const char *inter_lvl
= NULL
;
20145 chanspec_t new_chanspec
, cur_chanspec
;
20146 bool do_average
= TRUE
;
20147 bool do_individ
= FALSE
;
20148 bool do_analyze
= TRUE
;
20149 bool curband
= FALSE
;
20150 bool do_csa
= FALSE
;
20151 int avg_chan_idx
= 0;
20156 tmp_channel
= 0xff;
20161 while ((param
= *argv
++) != NULL
) {
20162 if (stricmp(param
, "-a") == 0) {
20166 if (stricmp(param
, "-i") == 0) {
20170 if (stricmp(param
, "-csa") == 0) {
20174 if (stricmp(param
, "-curband") == 0) {
20179 if ((val_p
= *argv
++) == NULL
) {
20180 printf("Need value following %s\n", param
);
20181 return USAGE_ERROR
;
20183 if (stricmp(param
, "-c") == 0) {
20184 tmp_channel
= (int)strtoul(val_p
, NULL
, 0);
20187 if (stricmp(param
, "-cs") == 0) {
20188 if ((new_chanspec
= wf_chspec_aton(val_p
)))
20189 tmp_channel
= wf_chspec_ctlchan(new_chanspec
);
20192 if (stricmp(param
, "-s") == 0) {
20193 req
.num_secs
= (int)strtoul(val_p
, NULL
, 0);
20194 if (req
.num_secs
== 0 || req
.num_secs
> MAX_CCA_SECS
) {
20195 printf("%d: Num of seconds must be <= %d\n",
20196 req
.num_secs
, MAX_CCA_SECS
);
20197 return USAGE_ERROR
;
20201 if (!do_average
&& !do_individ
) {
20202 printf("Must pick at least one of averages or individual secs\n");
20203 return USAGE_ERROR
;
20206 if (tmp_channel
== 0) {
20207 /* do all channels */
20208 base
= 1; limit
= 255;
20210 /* Use current channel as default if none specified */
20211 if (tmp_channel
== 0xff) {
20212 if ((err
= wlu_iovar_getint(wl
, "chanspec", (int*)&val
)) < 0) {
20213 printf("CCA: Can't get currrent chanspec\n");
20216 cur_chanspec
= (chanspec_t
)val
;
20217 tmp_channel
= wf_chspec_ctlchan(cur_chanspec
);
20218 printf("Using channel %d\n", tmp_channel
);
20220 base
= limit
= tmp_channel
;
20224 for (channel
= base
; channel
<= limit
; channel
++) {
20226 /* Get stats for each channel */
20227 req
.chanspec
= CH20MHZ_CHSPEC(channel
);
20228 if ((err
= wlu_var_getbuf(wl
, cmd
->name
, &req
, sizeof(req
), &ptr
)) < 0)
20231 results
= (cca_congest_channel_req_t
*)ptr
;
20232 if (results
->chanspec
== 0 || results
->num_secs
== 0)
20235 if (results
->num_secs
> MAX_CCA_SECS
) {
20236 printf("Bogus num of seconds returned %d\n", results
->num_secs
);
20240 /* Summarize and save summary for this channel */
20242 avg
[avg_chan_idx
] = (cca_congest_channel_req_t
*)
20243 malloc(sizeof(cca_congest_channel_req_t
));
20244 cca_per_chan_summary(results
, avg
[avg_chan_idx
], 1);
20245 if (avg
[avg_chan_idx
]->num_secs
)
20249 /* printf stats for each second of each channel */
20251 if (channel
== base
)
20252 printf("chan dur ibss obss"
20254 for (i
= 0; i
< results
->num_secs
; i
++) {
20255 chptr
= &results
->secs
[i
];
20256 if (chptr
->duration
) {
20258 ibss_per
= chptr
->congest_ibss
* 100 /chptr
->duration
;
20259 obss_per
= chptr
->congest_obss
* 100 /chptr
->duration
;
20260 inter_per
= chptr
->interference
* 100 /chptr
->duration
;
20262 ibss_lvl
= cca_level(ibss_per
, IBSS_MED
, IBSS_HI
);
20263 obss_lvl
= cca_level(obss_per
, OBSS_MED
, OBSS_HI
);
20264 inter_lvl
= cca_level(inter_per
, INTERFER_MED
, INTERFER_HI
);
20266 printf("%-3u %4d %4u %2d%% %-6s %4u %2d%% %-6s %4u %2d%% %-6s %d\n",
20267 CHSPEC_CHANNEL(results
->chanspec
),
20269 chptr
->congest_ibss
, ibss_per
, ibss_lvl
,
20270 chptr
->congest_obss
, obss_per
, obss_lvl
,
20271 chptr
->interference
, inter_per
, inter_lvl
,
20278 /* Print summary stats of each channel */
20281 printf("Summaries:\n");
20282 printf("chan dur ibss obss interf num seconds\n");
20283 for (j
= 0; j
< avg_chan_idx
; j
++) {
20285 ibss_per
= avg
[j
]->secs
[0].congest_ibss
;
20286 obss_per
= avg
[j
]->secs
[0].congest_obss
;
20287 inter_per
= avg
[j
]->secs
[0].interference
;
20289 ibss_lvl
= cca_level(ibss_per
, IBSS_MED
, IBSS_HI
);
20290 obss_lvl
= cca_level(obss_per
, OBSS_MED
, OBSS_HI
);
20291 inter_lvl
= cca_level(inter_per
, INTERFER_MED
, INTERFER_HI
);
20293 if (avg
[j
]->num_secs
) {
20294 printf("%-3u %4d %4s %2d%% %-6s %4s %2d%% %-6s %4s %2d%% %-6s %d\n",
20295 CHSPEC_CHANNEL(avg
[j
]->chanspec
),
20296 avg
[j
]->secs
[0].duration
,
20297 "", avg
[j
]->secs
[0].congest_ibss
, ibss_lvl
,
20298 "", avg
[j
]->secs
[0].congest_obss
, obss_lvl
,
20299 "", avg
[j
]->secs
[0].interference
, inter_lvl
,
20308 if ((err
= wlu_iovar_getint(wl
, "chanspec", (int *)&val
)) < 0) {
20309 printf("CCA: Can't get currrent chanspec\n");
20312 cur_chanspec
= (chanspec_t
)val
;
20315 if (CHSPEC_IS5G(cur_chanspec
))
20316 flags
|= CCA_FLAG_5G_ONLY
;
20317 if (CHSPEC_IS2G(cur_chanspec
))
20318 flags
|= CCA_FLAG_2G_ONLY
;
20321 if ((err
= cca_analyze(avg
, avg_chan_idx
, flags
, &new_chanspec
)) != 0) {
20322 printf("Cannot find a good channel due to: %s\n", cca_errors
[err
]);
20325 printf("Recommended channel: %d\n", wf_chspec_ctlchan(new_chanspec
));
20331 wl_itfr_get_stats(void *wl
, cmd_t
*cmd
, char **argv
)
20334 interference_source_rep_t
*iftr_stats
= NULL
;
20335 const char *iftr_source
[] = {"none", "wireless phone", "wireless video camera",
20336 "microwave oven", "wireless baby monitor", "bluetooth device",
20337 "wireless video camera or baby monitor", "bluetooth or baby monitor",
20338 "video camera or phone", "unidentified"}; /* sync with interference_source_t */
20340 UNUSED_PARAMETER(argv
);
20342 if ((err
= wlu_var_getbuf(wl
, cmd
->name
, NULL
, 0, (void*)&iftr_stats
)) < 0)
20345 if (iftr_stats
->flags
& ITFR_NOISY_ENVIRONMENT
)
20346 printf("Feature is stopped due to noisy environment\n");
20348 printf("Interference %s detected. last interference at timestamp %d: "
20349 "source is %s on %s channel\n",
20350 (iftr_stats
->flags
& ITFR_INTERFERENCED
) ? "is" : "is not",
20351 iftr_stats
->timestamp
, iftr_source
[iftr_stats
->source
],
20352 (iftr_stats
->flags
& ITFR_HOME_CHANNEL
) ? "home" : "non-home");
20358 wl_chanim_acs_record(void *wl
, cmd_t
*cmd
, char **argv
)
20362 wl_acs_record_t
*result
;
20364 /* need to add to this str if new acs trigger type is added */
20365 const char *trig_str
[] = {"None", "IOCTL", "CHANIM", "TIMER", "BTA"};
20367 UNUSED_PARAMETER(argv
);
20369 if ((err
= wlu_var_getbuf(wl
, cmd
->name
, NULL
, 0, &ptr
)) < 0)
20372 result
= (wl_acs_record_t
*) ptr
;
20374 if (!result
->count
) {
20375 printf("There is no ACS recorded\n");
20379 printf("current timestamp: %u (ms)\n", result
->timestamp
);
20381 printf("Timestamp(ms) ACS Trigger Selected Channel Glitch Count CCA Count\n");
20382 for (i
= 0; i
< result
->count
; i
++) {
20383 uint8 idx
= CHANIM_ACS_RECORD
- result
->count
+ i
;
20384 chanim_acs_record_t
* record
= &result
->acs_record
[idx
];
20386 printf("%10u \t%s \t%10d \t%12d \t%8d\n", record
->timestamp
,
20387 trig_str
[record
->trigger
], wf_chspec_ctlchan(record
->selected_chspc
),
20388 record
->glitch_cnt
, record
->ccastats
);
20394 ARGCNT(char **argv
)
20398 for (i
= 0; argv
[i
] != NULL
; i
++)
20405 wl_p2p_state(void *wl
, cmd_t
*cmd
, char **argv
)
20407 wl_p2p_disc_st_t st
;
20413 count
= ARGCNT(argv
);
20417 st
.state
= (uint8
) strtol(argv
[0], &endptr
, 0);
20418 if (st
.state
== WL_P2P_DISC_ST_LISTEN
) {
20421 if (wl_parse_chanspec_list(argv
[1], &st
.chspec
, 1) == -1) {
20422 fprintf(stderr
, "error parsing chanspec list arg\n");
20423 return BCME_BADARG
;
20425 st
.dwell
= (uint16
) strtol(argv
[2], &endptr
, 0);
20428 return wlu_var_setbuf(wl
, cmd
->name
, &st
, sizeof(st
));
20432 wl_p2p_scan(void *wl
, cmd_t
*cmd
, char **argv
)
20434 wl_p2p_scan_t
*params
= NULL
;
20435 int params_size
= 0;
20436 int malloc_size
= 0;
20437 int sparams_size
= 0;
20440 if (*(argv
+ 1) != NULL
) {
20441 malloc_size
= sizeof(wl_p2p_scan_t
);
20442 switch (toupper(**(argv
+ 1))) {
20444 malloc_size
+= WL_SCAN_PARAMS_FIXED_SIZE
+ WL_NUMCHANNELS
* sizeof(uint16
);
20447 malloc_size
+= OFFSETOF(wl_escan_params_t
, params
) +
20448 WL_SCAN_PARAMS_FIXED_SIZE
+ WL_NUMCHANNELS
* sizeof(uint16
);
20452 if (malloc_size
== 0) {
20453 fprintf(stderr
, "wrong syntax, need 'S' or 'E'\n");
20457 malloc_size
+= WL_SCAN_PARAMS_SSID_MAX
* sizeof(wlc_ssid_t
);
20458 params
= (wl_p2p_scan_t
*)malloc(malloc_size
);
20459 if (params
== NULL
) {
20460 fprintf(stderr
, "Error allocating %d bytes for scan params\n", malloc_size
);
20463 memset(params
, 0, malloc_size
);
20465 switch (toupper(**(argv
+ 1))) {
20467 wl_scan_params_t
*sparams
= (wl_scan_params_t
*)(params
+1);
20468 sparams_size
= malloc_size
- sizeof(wl_p2p_scan_t
);
20470 params
->type
= 'S';
20472 err
= wl_scan_prep(wl
, cmd
, argv
+ 1, sparams
, &sparams_size
);
20473 params_size
= sizeof(wl_p2p_scan_t
) + sparams_size
;
20478 wl_escan_params_t
*eparams
= (wl_escan_params_t
*)(params
+1);
20479 sparams_size
= malloc_size
- sizeof(wl_p2p_scan_t
) - sizeof(wl_escan_params_t
);
20481 params
->type
= 'E';
20483 eparams
->version
= htod32(ESCAN_REQ_VERSION
);
20484 eparams
->action
= htod16(WL_SCAN_ACTION_START
);
20487 srand((unsigned)time(NULL
));
20488 eparams
->sync_id
= htod16(rand() & 0xffff);
20490 eparams
->sync_id
= htod16(4321);
20491 #endif /* #if defined(linux) */
20493 err
= wl_scan_prep(wl
, cmd
, argv
+ 1, &eparams
->params
, &sparams_size
);
20494 params_size
= sizeof(wl_p2p_scan_t
) + sizeof(wl_escan_params_t
) + sparams_size
;
20500 err
= wlu_iovar_setbuf(wl
, cmd
->name
, params
, params_size
, buf
, WLC_IOCTL_MAXLEN
);
20507 wl_p2p_ifadd(void *wl
, cmd_t
*cmd
, char **argv
)
20514 count
= ARGCNT(argv
);
20518 if (!wl_ether_atoe(argv
[0], &ifreq
.addr
))
20521 if (stricmp(argv
[1], "go") == 0)
20522 ifreq
.type
= WL_P2P_IF_GO
;
20523 else if (stricmp(argv
[1], "client") == 0)
20524 ifreq
.type
= WL_P2P_IF_CLIENT
;
20525 else if (stricmp(argv
[1], "dyngo") == 0)
20526 ifreq
.type
= WL_P2P_IF_DYNBCN_GO
;
20530 if (ifreq
.type
== WL_P2P_IF_GO
|| ifreq
.type
== WL_P2P_IF_DYNBCN_GO
) {
20532 if (wl_parse_chanspec_list(argv
[2], &ifreq
.chspec
, 1) == -1) {
20533 fprintf(stderr
, "error parsing chanspec list arg\n");
20534 return BCME_BADARG
;
20541 return wlu_var_setbuf(wl
, cmd
->name
, &ifreq
, sizeof(ifreq
));
20545 wl_p2p_ifdel(void *wl
, cmd_t
*cmd
, char **argv
)
20547 struct ether_addr addr
;
20552 count
= ARGCNT(argv
);
20556 if (!wl_ether_atoe(argv
[0], &addr
))
20559 return wlu_var_setbuf(wl
, cmd
->name
, &addr
, sizeof(addr
));
20563 wl_p2p_ifupd(void *wl
, cmd_t
*cmd
, char **argv
)
20568 int bsscfg_idx
= 0;
20573 /* parse a bsscfg_idx option if present */
20574 if ((ret
= wl_cfg_option(argv
, cmd
->name
, &bsscfg_idx
, &consumed
)) != 0)
20580 count
= ARGCNT(argv
);
20584 if (!wl_ether_atoe(argv
[0], &ifreq
.addr
))
20587 if (stricmp(argv
[1], "go") == 0)
20588 ifreq
.type
= WL_P2P_IF_GO
;
20589 else if (stricmp(argv
[1], "client") == 0)
20590 ifreq
.type
= WL_P2P_IF_CLIENT
;
20596 if (bsscfg_idx
== -1)
20597 return wlu_var_setbuf(wl
, cmd
->name
, &ifreq
, sizeof(ifreq
));
20598 return wl_bssiovar_setbuf(wl
, cmd
->name
, bsscfg_idx
,
20599 &ifreq
, sizeof(ifreq
),
20600 buf
, WLC_IOCTL_MAXLEN
);
20604 wl_p2p_if(void *wl
, cmd_t
*cmd
, char **argv
)
20606 struct ether_addr addr
;
20613 count
= ARGCNT(argv
);
20617 if (!wl_ether_atoe(argv
[0], &addr
))
20620 err
= wlu_var_getbuf(wl
, cmd
->name
, &addr
, sizeof(addr
), (void*)&ptr
);
20622 printf("%u %s\n", dtoh32(ptr
->bsscfgidx
), (ptr
->ifname
));
20628 wl_p2p_ops(void *wl
, cmd_t
*cmd
, char **argv
)
20636 count
= ARGCNT(argv
);
20641 err
= wlu_var_getbuf(wl
, cmd
->name
, NULL
, 0, (void *)&ops
);
20642 if (err
!= BCME_OK
) {
20643 fprintf(stderr
, "%s: error %d\n", cmd
->name
, err
);
20647 printf("ops: %u ctw: %u\n", ops
->ops
, ops
->ctw
);
20652 ops
.ops
= (uint8
) strtol(argv
[0], &endptr
, 0);
20653 if (ops
.ops
!= 0) {
20656 ops
.ctw
= (uint8
) strtol(argv
[1], &endptr
, 0);
20661 return wlu_var_setbuf(wl
, cmd
->name
, &ops
, sizeof(ops
));
20665 wl_p2p_noa(void *wl
, cmd_t
*cmd
, char **argv
)
20668 wl_p2p_sched_t
*noa
;
20675 strcpy(buf
, cmd
->name
);
20677 count
= ARGCNT(argv
);
20679 int err
= wlu_get(wl
, WLC_GET_VAR
, buf
, WLC_IOCTL_MAXLEN
);
20680 wl_p2p_sched_t
*sched
;
20683 if (err
!= BCME_OK
) {
20684 fprintf(stderr
, "%s: error %d\n", cmd
->name
, err
);
20688 sched
= (wl_p2p_sched_t
*)buf
;
20689 for (i
= 0; i
< 16; i
++) {
20690 if (sched
->desc
[i
].count
== 0)
20692 printf("start: %u interval: %u duration: %u count: %u\n",
20693 sched
->desc
[i
].start
, sched
->desc
[i
].interval
,
20694 sched
->desc
[i
].duration
, sched
->desc
[i
].count
);
20702 noa
= (wl_p2p_sched_t
*)&buf
[len
+ 1];
20705 noa
->type
= (uint8
)strtol(argv
[0], &endptr
, 0);
20706 len
+= sizeof(noa
->type
);
20707 noa
->action
= (uint8
)strtol(argv
[1], &endptr
, 0);
20708 len
+= sizeof(noa
->action
);
20713 /* action == -1 is to cancel the current schedule */
20714 if (noa
->action
== WL_P2P_SCHED_ACTION_RESET
) {
20715 /* the fixed portion of wl_p2p_sched_t with action == WL_P2P_SCHED_ACTION_RESET
20716 * is required to cancel the curret schedule.
20718 len
+= (char *)&noa
->desc
[0] - ((char *)buf
+ len
);
20720 /* Take care of any special cases only and let all other cases fall through
20721 * as normal 'start/interval/duration/count' descriptions.
20722 * All cases start with 'type' 'action' 'option'.
20723 * Any count value greater than 255 is to repeat unlimited.
20726 switch (noa
->type
) {
20727 case WL_P2P_SCHED_TYPE_ABS
:
20728 case WL_P2P_SCHED_TYPE_REQ_ABS
:
20731 noa
->option
= (uint8
)strtol(argv
[0], &endptr
, 0);
20732 len
+= sizeof(noa
->option
);
20738 /* add any paddings before desc field */
20739 len
+= (char *)&noa
->desc
[0] - ((char *)buf
+ len
);
20741 switch (noa
->type
) {
20742 case WL_P2P_SCHED_TYPE_ABS
:
20743 switch (noa
->option
) {
20744 case WL_P2P_SCHED_OPTION_BCNPCT
:
20746 noa
->desc
[0].duration
= htod32(strtol(argv
[0], &endptr
, 0));
20747 noa
->desc
[0].start
= 100 - noa
->desc
[0].duration
;
20749 else if (count
== 2) {
20750 noa
->desc
[0].start
= htod32(strtol(argv
[0], &endptr
, 0));
20751 noa
->desc
[0].duration
= htod32(strtol(argv
[1], &endptr
, 0));
20754 fprintf(stderr
, "Usage: wl p2p_noa 0 %d 1 "
20755 "<start-pct> <duration-pct>\n",
20759 len
+= sizeof(wl_p2p_sched_desc_t
);
20763 if (count
< 4 || (count
% 4) != 0) {
20764 fprintf(stderr
, "Usage: wl p2p_noa 0 %d 0 "
20765 "<start> <interval> <duration> <count> ...\n",
20775 fprintf(stderr
, "Usage: wl p2p_noa 1 %d "
20776 "<start> <interval> <duration> <count> ...\n",
20780 /* fall through... */
20782 for (i
= 0; i
< count
; i
+= 4) {
20783 noa
->desc
[i
/ 4].start
= htod32(strtoul(argv
[i
], &endptr
, 0));
20784 noa
->desc
[i
/ 4].interval
= htod32(strtol(argv
[i
+ 1], &endptr
, 0));
20785 noa
->desc
[i
/ 4].duration
= htod32(strtol(argv
[i
+ 2], &endptr
, 0));
20786 noa
->desc
[i
/ 4].count
= htod32(strtol(argv
[i
+ 3], &endptr
, 0));
20787 len
+= sizeof(wl_p2p_sched_desc_t
);
20793 return wlu_set(wl
, WLC_SET_VAR
, buf
, len
);
20798 wl_rpmt(void *wl
, cmd_t
*cmd
, char **argv
)
20807 count
= ARGCNT(argv
);
20812 strcpy(buf
, cmd
->name
);
20813 len
= strlen(buf
) + 1;
20815 val
= htod32(strtoul(argv
[0], &endptr
, 0));
20816 memcpy(&buf
[len
], &val
, sizeof(uint32
));
20817 len
+= sizeof(uint32
);
20818 val
= htod32(strtoul(argv
[1], &endptr
, 0));
20819 memcpy(&buf
[len
], &val
, sizeof(uint32
));
20820 len
+= sizeof(uint32
);
20822 return wlu_set(wl
, WLC_SET_VAR
, buf
, len
);
20826 wl_ledbh(void *wl
, cmd_t
*cmd
, char **argv
)
20832 memset(&led
, 0, sizeof(wl_led_info_t
));
20833 if (*++argv
== NULL
) {
20834 printf("Usage: ledbh [led#] [behavior#]\n");
20837 led
.index
= (int)strtoul(*argv
, NULL
, 10);
20839 if (led
.index
> 3) {
20840 printf("only 4 led supported\n");
20844 if (*++argv
) { /* set */
20845 /* Read the original back so we don't toggle the activehi */
20846 if ((err
= wlu_var_getbuf(wl
, cmd
->name
, (void*)&led
,
20847 sizeof(wl_led_info_t
), &ptr
)) < 0) {
20848 printf("wl_ledbh: fail to get. code %x\n", err
);
20850 led
.behavior
= (int)strtoul(*argv
, NULL
, 10);
20851 led
.activehi
= ((wl_led_info_t
*)ptr
)->activehi
;
20853 if ((err
= wlu_var_setbuf(wl
, cmd
->name
, (void*)&led
,
20854 sizeof(wl_led_info_t
))) < 0) {
20855 printf("wl_ledbh: fail to set\n");
20858 wl_led_info_t
*ledo
;
20860 if ((err
= wlu_var_getbuf(wl
, cmd
->name
, (void*)&led
,
20861 sizeof(wl_led_info_t
), &ptr
)) < 0) {
20862 printf("wl_ledbh: fail to get\n");
20864 ledo
= (wl_led_info_t
*)ptr
;
20866 printf("led %d behavior %d\n", ledo
->index
, ledo
->behavior
);
20873 wl_led_blink_sync(void *wl
, cmd_t
*cmd
, char **argv
)
20882 for (argc
= 0; argv
[argc
]; argc
++)
20885 if (argc
> 3 || argc
< 2)
20888 in_arg
[0] = htod32((uint32
)(strtoul(argv
[1], &endptr
, 0)));
20890 if (in_arg
[0] > 3) {
20891 printf("only 4 led supported\n");
20896 err
= wlu_var_getbuf(wl
, cmd
->name
, (void*)in_arg
, sizeof(int), &ptr
);
20899 printf("led%d, blink_sync is %s\n", in_arg
[0],
20900 (dtoh32(*(int*)ptr
) != 0) ? "TRUE" : "FALSE");
20902 else if (argc
== 3) {
20903 in_arg
[1] = htod32((uint32
)(strtoul(argv
[2], &endptr
, 0)));
20904 wlu_var_setbuf(wl
, cmd
->name
, in_arg
, sizeof(in_arg
));
20907 fprintf(stderr
, "illegal command!\n");
20915 wl_rrm_nbr_req(void *wl
, cmd_t
*cmd
, char **argv
)
20920 UNUSED_PARAMETER(cmd
);
20922 strcpy(buf
, "rrm_nbr_req");
20923 buflen
= strlen("rrm_nbr_req") + 1;
20928 len
= strlen(*argv
);
20929 if (len
> DOT11_MAX_SSID_LEN
) {
20930 printf("ssid too long\n");
20933 memset(&ssid
, 0, sizeof(wlc_ssid_t
));
20934 memcpy(ssid
.SSID
, *argv
, len
);
20935 ssid
.SSID_len
= len
;
20936 memcpy(&buf
[buflen
], &ssid
, sizeof(wlc_ssid_t
));
20937 buflen
+= sizeof(wlc_ssid_t
);
20940 err
= wlu_set(wl
, WLC_SET_VAR
, buf
, buflen
);
20946 wl_dngl_wd(void *wl
, cmd_t
*cmd
, char **argv
)
20948 const char *cmdname
= "dngl_wd";
20951 uint32 dngl_wd_exptime
;
20956 UNUSED_PARAMETER(cmd
);
20958 /* toss the command name */
20961 if (*argv
== NULL
) {
20963 err
= wlu_iovar_get(wl
, cmdname
, &dngl_wd_buf
, sizeof(dngl_wd_buf
));
20966 if (htod32(dngl_wd_buf
.dngl_wd
))
20967 printf("wd: on exptime: %dsec\n",
20968 htod32(dngl_wd_buf
.dngl_wd_exptime
));
20970 printf("wd: off\n");
20972 if (!stricmp(*argv
, "on")) {
20973 dngl_wd_buf
.dngl_wd
= 1;
20974 if (argv
[1] == NULL
)
20975 dngl_wd_buf
.dngl_wd_exptime
= 0;
20978 dngl_wd_buf
.dngl_wd_exptime
= (uint32
)strtoul(*argv
, &endptr
, 0);
20980 } else if (!stricmp(*argv
, "off")) {
20981 dngl_wd_buf
.dngl_wd
= 0;
20982 dngl_wd_buf
.dngl_wd_exptime
= 0;
20984 return USAGE_ERROR
;
20986 dngl_wd_buf
.dngl_wd
= dtoh32(dngl_wd_buf
.dngl_wd
);
20987 dngl_wd_buf
.dngl_wd_exptime
= dtoh32(dngl_wd_buf
.dngl_wd_exptime
);
20988 err
= wlu_iovar_set(wl
, cmdname
, &dngl_wd_buf
, sizeof(dngl_wd_buf
));
20995 wl_wnm_bsstq(void *wl
, cmd_t
*cmd
, char **argv
)
21000 UNUSED_PARAMETER(cmd
);
21002 strcpy(buf
, "wnm_bsstq");
21003 buflen
= strlen("wnm_bsstq") + 1;
21008 len
= strlen(*argv
);
21009 if (len
> DOT11_MAX_SSID_LEN
) {
21010 printf("ssid too long\n");
21013 memset(&ssid
, 0, sizeof(wlc_ssid_t
));
21014 memcpy(ssid
.SSID
, *argv
, len
);
21015 ssid
.SSID_len
= len
;
21016 memcpy(&buf
[buflen
], &ssid
, sizeof(wlc_ssid_t
));
21017 buflen
+= sizeof(wlc_ssid_t
);
21020 err
= wlu_set(wl
, WLC_SET_VAR
, buf
, buflen
);
21027 wl_tsf(void *wl
, cmd_t
*cmd
, char **argv
)
21029 const char *cmdname
= "tsf";
21037 UNUSED_PARAMETER(cmd
);
21039 /* toss the command name */
21042 if (*argv
== NULL
) {
21044 err
= wlu_iovar_get(wl
, cmdname
, &tsf_buf
, sizeof(tsf_buf
));
21047 printf("0x%08X 0x%08X\n", htod32(tsf_buf
.high
), htod32(tsf_buf
.low
));
21050 if (argv
[1] == NULL
)
21051 return USAGE_ERROR
;
21053 tsf_buf
.high
= (uint32
)strtoul(*argv
, &endptr
, 0);
21054 if (*endptr
!= '\0') {
21055 fprintf(stderr
, "%s: %s: error parsing \"%s\" as an integer\n",
21056 wlu_av0
, cmdname
, *argv
);
21057 return USAGE_ERROR
;
21061 tsf_buf
.low
= (uint32
)strtoul(*argv
, &endptr
, 0);
21062 if (*endptr
!= '\0') {
21063 fprintf(stderr
, "%s: %s: error parsing \"%s\" as an integer\n",
21064 wlu_av0
, cmdname
, *argv
);
21065 return USAGE_ERROR
;
21068 tsf_buf
.low
= dtoh32(tsf_buf
.low
);
21069 tsf_buf
.high
= dtoh32(tsf_buf
.high
);
21071 err
= wlu_iovar_set(wl
, cmdname
, &tsf_buf
, sizeof(tsf_buf
));
21080 wl_mfp_config(void *wl
, cmd_t
*cmd
, char **argv
)
21085 const char *cmdname
= "mfp";
21087 UNUSED_PARAMETER(cmd
);
21090 for (argc
= 0; argv
[argc
]; argc
++)
21093 if (argc
> 1 && argv
[1]) {
21094 flag
= htod32(atoi(argv
[1]));
21095 *(int *)buf
= flag
;
21098 err
= wlu_iovar_set(wl
, cmdname
, buf
, 256);
21105 wl_mfp_sha256(void *wl
, cmd_t
*cmd
, char **argv
)
21110 const char *cmdname
= "mfp_sha256";
21112 UNUSED_PARAMETER(cmd
);
21115 for (argc
= 0; argv
[argc
]; argc
++)
21118 if (argc
> 1 && argv
[1]) {
21119 flag
= htod32(atoi(argv
[1]));
21120 *(int *)buf
= flag
;
21123 err
= wlu_iovar_set(wl
, cmdname
, buf
, 256);
21131 wl_mfp_sa_query(void *wl
, cmd_t
*cmd
, char **argv
)
21133 wl_sa_query_t
* query
;
21137 UNUSED_PARAMETER(cmd
);
21140 for (argc
= 0; argv
[argc
]; argc
++)
21143 if ((query
= (wl_sa_query_t
*) malloc(sizeof(wl_sa_query_t
))) == NULL
) {
21144 printf("unable to allocate frame \n");
21147 memset(query
, 0, sizeof(wl_sa_query_t
));
21150 if (argc
> 1 && argv
[1]) {
21151 query
->flag
= htod32(atoi(argv
[1]));
21154 /* add the action */
21155 if (argc
> 2 && argv
[2]) {
21156 query
->action
= htod32(atoi(argv
[2]));
21160 if (argc
> 3 && argv
[3]) {
21161 query
->id
= htod32(atoi(argv
[3]));
21164 err
= wlu_var_setbuf(wl
, "mfp_sa_query", query
, sizeof(wl_sa_query_t
));
21173 wl_mfp_disassoc(void *wl
, cmd_t
*cmd
, char **argv
)
21175 const char *cmdname
= "mfp_disassoc";
21181 UNUSED_PARAMETER(cmd
);
21182 memset(buf
, 0, 256);
21185 for (argc
= 0; argv
[argc
]; argc
++)
21188 /* add the action */
21189 if (argc
> 1 && argv
[1]) {
21190 flag
= htod32(atoi(argv
[1]));
21191 *(int *)buf
= flag
;
21193 if (argc
> 2 && argv
[2]) {
21194 flag
= htod32(atoi(argv
[2]));
21195 *(int *)(buf
+ sizeof(flag
)) = flag
;
21198 err
= wlu_iovar_set(wl
, cmdname
, buf
, 256);
21206 wl_mfp_deauth(void *wl
, cmd_t
*cmd
, char **argv
)
21208 const char *cmdname
= "mfp_deauth";
21214 UNUSED_PARAMETER(cmd
);
21216 memset(buf
, 0, 256);
21219 for (argc
= 0; argv
[argc
]; argc
++)
21222 /* add the action */
21223 if (argc
> 1 && argv
[1]) {
21224 flag
= htod32(atoi(argv
[1]));
21225 *(int *)buf
= flag
;
21227 if (argc
> 2 && argv
[2]) {
21228 flag
= htod32(atoi(argv
[2]));
21229 *(int *)(buf
+ sizeof(flag
)) = flag
;
21232 err
= wlu_iovar_set(wl
, cmdname
, buf
, 256);
21240 wl_mfp_assoc(void *wl
, cmd_t
*cmd
, char **argv
)
21242 const char *cmdname
= "mfp_assoc";
21248 UNUSED_PARAMETER(cmd
);
21249 memset(buf
, 0, 256);
21252 for (argc
= 0; argv
[argc
]; argc
++)
21255 /* add the action */
21256 if (argc
> 1 && argv
[1]) {
21257 flag
= htod32(atoi(argv
[1]));
21258 *(int *)buf
= flag
;
21260 if (argc
> 2 && argv
[2]) {
21261 flag
= htod32(atoi(argv
[2]));
21262 *(int *)(buf
+ sizeof(int)) = flag
;
21265 err
= wlu_iovar_set(wl
, cmdname
, buf
, 256);
21273 wl_mfp_auth(void *wl
, cmd_t
*cmd
, char **argv
)
21275 const char *cmdname
= "mfp_auth";
21281 UNUSED_PARAMETER(cmd
);
21282 memset(buf
, 0, 256);
21285 for (argc
= 0; argv
[argc
]; argc
++)
21288 /* add the action */
21289 if (argc
> 1 && argv
[1]) {
21290 flag
= htod32(atoi(argv
[1]));
21291 *(int *)buf
= flag
;
21293 if (argc
> 2 && argv
[2]) {
21294 flag
= htod32(atoi(argv
[2]));
21295 *(int *)(buf
+ sizeof(int)) = flag
;
21298 err
= wlu_iovar_set(wl
, cmdname
, buf
, 256);
21307 wl_mfp_reassoc(void *wl
, cmd_t
*cmd
, char **argv
)
21309 const char *cmdname
= "mfp_reassoc";
21315 UNUSED_PARAMETER(cmd
);
21316 memset(buf
, 0, 256);
21319 for (argc
= 0; argv
[argc
]; argc
++)
21322 /* add the action */
21323 if (argc
> 1 && argv
[1]) {
21324 flag
= htod32(atoi(argv
[1]));
21325 *(int *)buf
= flag
;
21327 if (argc
> 2 && argv
[2]) {
21328 flag
= htod32(atoi(argv
[2]));
21329 *(int *)(buf
+ sizeof(int)) = flag
;
21332 err
= wlu_iovar_set(wl
, cmdname
, buf
, 256);
21341 wl_scb_probe(void *wl
, cmd_t
*cmd
, char **argv
)
21343 const char *cmdname
= "scb_probe";
21344 wl_scb_probe_t buff
;
21347 UNUSED_PARAMETER(cmd
);
21349 /* toss the command name */
21352 if (*argv
== NULL
) {
21354 err
= wlu_iovar_get(wl
, cmdname
, &buff
, sizeof(wl_scb_probe_t
));
21358 printf("timeout:%d sec, activity_time:%d sec, nprobes:%d\n",
21359 buff
.scb_timeout
, buff
.scb_activity_time
, buff
.scb_max_probe
);
21362 for (argc
= 0; argv
[argc
]; argc
++)
21369 buff
.scb_timeout
= htod32(atoi(argv
[0]));
21370 buff
.scb_activity_time
= htod32(atoi(argv
[1]));
21371 buff
.scb_max_probe
= htod32(atoi(argv
[2]));
21372 err
= wlu_iovar_set(wl
, cmdname
, &buff
, sizeof(wl_scb_probe_t
));
21378 wl_spatial_policy(void *wl
, cmd_t
*cmd
, char **argv
)
21381 int err
, i
, *reply
;
21382 int mode
[SPATIAL_MODE_MAX_IDX
] = {-1, -1, -1, -1, -1};
21384 /* Order is 2G, 5G-LOW, 5G-MID, 5G-HIGH, 5G-UPPER
21385 * if only one argument given, than all band or sub-band take the
21389 bool all_same
= TRUE
;
21390 if ((err
= wlu_var_getbuf(wl
, cmd
->name
, &mode
, sizeof(mode
), &ptr
)) < 0)
21392 reply
= (int *)ptr
;
21393 for (i
= 1; i
< SPATIAL_MODE_MAX_IDX
; i
++) {
21394 /* check if return values for each band/sub-band is same or not */
21395 if (reply
[i
-1] != reply
[i
])
21399 printf("%2d\n", reply
[0]);
21401 printf("2.4GHz : %2d\n", reply
[SPATIAL_MODE_2G_IDX
]);
21402 printf("5GHz (lower) : %2d\n", reply
[SPATIAL_MODE_5G_LOW_IDX
]);
21403 printf("5GHz (middle): %2d\n", reply
[SPATIAL_MODE_5G_MID_IDX
]);
21404 printf("5GHz (high) : %2d\n", reply
[SPATIAL_MODE_5G_HIGH_IDX
]);
21405 printf("5GHz (upper) : %2d\n", reply
[SPATIAL_MODE_5G_UPPER_IDX
]);
21409 mode
[0] = atoi(*argv
);
21411 for (i
= 1; i
< SPATIAL_MODE_MAX_IDX
; i
++)
21414 for (i
= 1; i
< SPATIAL_MODE_MAX_IDX
; i
++) {
21415 mode
[i
] = atoi(*argv
);
21416 if (!*++argv
&& i
< (SPATIAL_MODE_MAX_IDX
- 1)) {
21417 printf("error: missing arguments\n");
21422 err
= wlu_var_setbuf(wl
, cmd
->name
, &mode
, sizeof(mode
));
21427 wl_ratetbl_ppr(void *wl
, cmd_t
*cmd
, char **argv
)
21430 int err
, i
, *reply
;
21433 /* Order is 2G, 5G-LOW, 5G-MID, 5G-HIGH, 5G-UPPER
21434 * if only one argument given, than all band or sub-band take the
21437 memset(&val
, 0, sizeof(val
));
21439 if ((err
= wlu_var_getbuf(wl
, cmd
->name
, &val
, sizeof(val
), &ptr
)) < 0)
21441 reply
= (int *)ptr
;
21442 for (i
= 0; i
< 12; i
++)
21443 printf("%s: %2d\n", (reply
[i
] & 0x80) ? "OFDM" : "CCK ", (reply
[i
] & 0x7f));
21446 val
[0] = atoi(*argv
++);
21447 val
[1] = atoi(*argv
++);
21448 err
= wlu_var_setbuf(wl
, cmd
->name
, &val
, sizeof(val
));
21453 wl_ie(void *wl
, cmd_t
*cmd
, char **argv
)
21458 int bsscfg_idx
= 0;
21462 ie_setbuf_t
*ie_setbuf
;
21464 uchar datalen
, type
, count
, col
;
21466 /* parse a bsscfg_idx option if present */
21467 if ((err
= wl_cfg_option(argv
+ 1, argv
[0], &bsscfg_idx
, &consumed
)) != 0)
21470 argv
= argv
+ consumed
;
21475 fprintf(stderr
, "missing parameter type\n");
21479 type
= (uchar
)atoi(argv
[0]);
21481 /* use VNDR_IE_CUSTOM_FLAG flags for none vendor IE */
21482 pktflag
= htod32(VNDR_IE_CUSTOM_FLAG
);
21485 memcpy((void *)¶m
.pktflag
, &pktflag
, sizeof(uint32
));
21488 if (bsscfg_idx
== -1)
21489 err
= wlu_var_getbuf(wl
, cmd
->name
, ¶m
, sizeof(param
), &ptr
);
21491 err
= wl_bssiovar_getbuf(wl
, cmd
->name
, bsscfg_idx
, ¶m
, sizeof(param
),
21492 buf
, WLC_IOCTL_MAXLEN
);
21494 data
= (uchar
*)ptr
;
21495 datalen
= data
[1]+2;
21496 printf("%s len %d\n", cmd
->name
, datalen
);
21497 printf("%s Data:\n", cmd
->name
);
21498 for (count
= 0; (count
< datalen
);) {
21499 for (col
= 0; (col
< MAX_DATA_COLS
) &&
21500 (count
< datalen
); col
++, count
++) {
21501 printf("%02x", *data
++);
21507 fprintf(stderr
, "Error %d getting IOVar\n", err
);
21512 /* get IE length */
21513 datalen
= (uchar
)atoi(argv
[0]);
21517 fprintf(stderr
, "Data bytes should be specified for IE of length %d\n",
21522 /* Ensure each data byte is 2 characters long */
21523 if ((int)strlen (argv
[1]) < (datalen
* 2)) {
21524 fprintf(stderr
, "Please specify all the data bytes for this IE\n");
21530 if ((datalen
== 0) && (argv
[1] != NULL
))
21531 fprintf(stderr
, "Ignoring data bytes for IE of length %d\n", datalen
);
21533 count
= sizeof(ie_setbuf_t
) + datalen
- 1;
21534 data
= malloc(count
);
21535 if (data
== NULL
) {
21536 fprintf(stderr
, "memory alloc failure\n");
21540 ie_setbuf
= (ie_setbuf_t
*) data
;
21541 /* Copy the ie SET command ("add") to the buffer */
21542 strncpy(ie_setbuf
->cmd
, "add", VNDR_IE_CMD_LEN
- 1);
21543 ie_setbuf
->cmd
[VNDR_IE_CMD_LEN
- 1] = '\0';
21545 /* Buffer contains only 1 IE */
21546 iecount
= htod32(1);
21547 memcpy((void *)&ie_setbuf
->ie_buffer
.iecount
, &iecount
, sizeof(int));
21549 memcpy((void *)&ie_setbuf
->ie_buffer
.pktflag
, &pktflag
, sizeof(uint32
));
21551 /* Now, add the IE to the buffer */
21552 ie_setbuf
->ie_buffer
.ie_list
[0].id
= type
;
21553 ie_setbuf
->ie_buffer
.ie_list
[0].len
= datalen
;
21556 if ((err
= get_ie_data ((uchar
*)argv
[1],
21557 &ie_setbuf
->ie_buffer
.ie_list
[0].data
[0],
21560 fprintf(stderr
, "Error parsing data arg\n");
21565 if (bsscfg_idx
== -1)
21566 err
= wlu_var_setbuf(wl
, cmd
->name
, data
, count
);
21568 err
= wl_bssiovar_setbuf(wl
, cmd
->name
, bsscfg_idx
,
21569 data
, count
, buf
, WLC_IOCTL_MAXLEN
);
21575 /* Restore the ignored warnings status */
21577 #pragma warning(pop)