prepare to upload
[debian/uaputl] / uapcmd.c
1 /** @file  uapcmd.c
2  *
3  *  @brief This file contains the handling of command.
4   * 
5   * Copyright (C) 2008-2009, Marvell International Ltd. 
6   *
7   * This software file (the "File") is distributed by Marvell International 
8   * Ltd. under the terms of the GNU General Public License Version 2, June 1991 
9   * (the "License").  You may use, redistribute and/or modify this File in 
10   * accordance with the terms and conditions of the License, a copy of which 
11   * is available along with the File in the gpl.txt file or by writing to 
12   * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 
13   * 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
14   *
15   * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE 
16   * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE 
17   * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about 
18   * this warranty disclaimer.
19   *
20   */
21 /****************************************************************************
22 Change log:
23     03/01/08: Initial creation
24 ****************************************************************************/
25
26 /****************************************************************************
27         Header files
28 ****************************************************************************/
29 #include <sys/types.h>
30 #include <unistd.h>
31 #include <sys/socket.h>
32 #include <sys/select.h>
33 #include <stdio.h>
34 #include <getopt.h>
35 #include <netinet/in.h>
36 #include <errno.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <ctype.h>
40 #include <sys/ioctl.h>
41 #include <errno.h>
42 #include "uaputl.h"
43 #include "uapcmd.h"
44
45 extern struct option cmd_options[];
46
47 /****************************************************************************
48         Local functions
49 ****************************************************************************/
50 /**
51  *  @brief Show usage information for the sys_cfg_ap_mac_address
52  *   command
53  *
54  *  $return         N/A
55  */
56 void
57 print_sys_cfg_ap_mac_address_usage(void)
58 {
59     printf("\nUsage : sys_cfg_ap_mac_address [AP_MAC_ADDRESS]\n");
60     printf
61         ("\nIf AP_MAC_ADDRESS is provided, a 'set' is performed, else a 'get' is performed.\n");
62     return;
63 }
64
65 /**
66  *  @brief Show usage information for the sys_cfg_ssid command
67  *
68  *  $return         N/A
69  */
70 void
71 print_sys_cfg_ssid_usage(void)
72 {
73     printf("\nUsage : sys_cfg_ssid [SSID]\n");
74     printf
75         ("\nIf SSID is provided, a 'set' is performed, else a 'get' is performed.\n");
76     return;
77 }
78
79 /**
80  *  @brief Show usage information for the sys_cfg_beacon_period
81  *   command
82  *
83  *  $return         N/A
84  */
85 void
86 print_sys_cfg_beacon_period_usage(void)
87 {
88     printf("\nUsage : sys_cfg_beacon_period [BEACON_PERIOD]\n");
89     printf
90         ("\nIf BEACON_PERIOD is provided, a 'set' is performed, else a 'get' is performed.\n");
91     return;
92 }
93
94 /**
95  *  @brief Show usage information for the sys_cfg_dtim_period
96  *   command
97  *
98  *  $return         N/A
99  */
100 void
101 print_sys_cfg_dtim_period_usage(void)
102 {
103     printf("\nUsage : sys_cfg_dtim_period [DTIM_PERIOD]\n");
104     printf
105         ("\nIf DTIM_PERIOD is provided, a 'set' is performed, else a 'get' is performed.\n");
106     return;
107 }
108
109 /**
110  *  @brief Show usage information for the sys_cfg_channel
111  *   command
112  *
113  *  $return         N/A
114  */
115 void
116 print_sys_cfg_channel_usage(void)
117 {
118     printf("\nUsage : sys_cfg_channel [CHANNEL] [MODE]\n");
119     printf
120         ("\nIf CHANNEL is provided, a 'set' is performed, else a 'get' is performed.");
121     printf("\nIf MODE is provided, 0 for manual channel selection,");
122     printf("\nelse ACS (automatic channel selection) is performed\n");
123     return;
124 }
125
126 /**
127  *  @brief Show usage information for the sys_cfg_scan_channels
128  *   command
129  *
130  *  $return         N/A
131  */
132 void
133 print_sys_cfg_scan_channels_usage(void)
134 {
135     printf("\nUsage : sys_cfg_scan_channels [CHANNELS]\n");
136     printf
137         ("\nIf CHANNELS are provided, a 'set' is performed, else a 'get' is performed.\n");
138     return;
139 }
140
141 /**
142  *  @brief Show usage information for the sys_cfg_rates_ext command
143  *
144  *  $return         N/A
145  */
146 void
147 print_sys_cfg_rates_ext_usage(void)
148 {
149     printf
150         ("\nUsage : sys_cfg_rates_ext [rates RATES] [mbrate RATE] [urate RATE]\n");
151     printf
152         ("\nIf 'Rate' provided, a 'set' is performed else a 'get' is performed");
153     printf
154         ("\nRATES is provided as a set of data rates, in unit of 500 kilobits");
155     printf("\nA rate with MSB bit is basic rate, i.e 0x82 is basic rate.\n");
156     printf("\nFollowing is the list of supported rates in units of 500 Kbps:");
157     printf("\nDecimal: (2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108)");
158     printf
159         ("\nHex: (0x02, 0x04, 0x0b, 0x16, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c)");
160     printf
161         ("\nBasic rates: (0x82, 0x84, 0x8b, 0x96, 0x8C, 0x92, 0x98, 0xA4, 0xB0, 0xC8, 0xE0, 0xEc)\n");
162     printf
163         ("\nRates 2, 4, 11 and 22 (in units of 500 Kbps) must be present in either of basic or");
164     printf
165         ("\nnon-basic rates. If OFDM rates are enabled then 12, 24 and 48 (in units of 500 Kbps)");
166     printf("\nmust be present in either basic or non-basic rates");
167     printf("\nEach rate must be separated by a space.");
168     printf("\nrates followed by RATES for setting operational rates.");
169     printf
170         ("\nmbrate followed by RATE for setting multicast and broadcast rate.");
171     printf("\nurate followed by RATE for setting unicast rate.\n");
172     return;
173 }
174
175 /**
176  *  @brief Show usage information for the sys_cfg_rates command
177  *
178  *  $return         N/A
179  */
180 void
181 print_sys_cfg_rates_usage(void)
182 {
183     printf("\nUsage : sys_cfg_rates [RATES]\n");
184     printf
185         ("\n[RATES] is set of data rates in unit of 500 kbps and each rate can be");
186     printf
187         ("\nentered in hexadecimal or decimal format. Rates must be separated by");
188     printf("\nspace. Duplicate Rate  fields are not allowed");
189     printf("\nA rate with MSB bit is basic rate, i.e 0x82 is basic rate.");
190     printf("\nFollowing is the list of supported rates in units of 500 Kbps:");
191     printf("\nDecimal: (2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108)");
192     printf
193         ("\nHex: (0x02, 0x04, 0x0b, 0x16, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c)");
194     printf
195         ("\nBasic rates: (0x82, 0x84, 0x8b, 0x96, 0x8C, 0x92, 0x98, 0xA4, 0xB0, 0xC8, 0xE0, 0xEc)\n");
196     return;
197 }
198
199 /**
200  *   @brief Show usage information for the sys_cfg_tx_power
201  *    command
202  *
203  *  $return         N/A
204  */
205 void
206 print_sys_cfg_tx_power_usage(void)
207 {
208     printf("\nUsage : sys_cfg_tx_power [TX_POWER]\n");
209     printf
210         ("\nIf TX_POWER is provided, a 'set' is performed, else a 'get' is performed.");
211     printf("\nTX_POWER is represented in dBm.\n");
212     return;
213 }
214
215 /**
216  *  @brief Show usage information for the sys_cfg_bcast_ssid_ctl
217  *   command
218  *
219  *  $return         N/A
220  */
221 void
222 print_sys_cfg_bcast_ssid_ctl_usage(void)
223 {
224     printf("\nUsage : sys_cfg_bcast_ssid_ctl [0|1]\n");
225     printf("\nOptions: 0     - Disable SSID broadcast");
226     printf("\n         1     - Enable SSID broadcast");
227     printf("\n         empty - Get current SSID broadcast setting\n");
228     return;
229 }
230
231 /**
232  *  @brief Show usage information for the sys_cfg_rsn_replay_prot
233  *   command
234  *
235  *  $return         N/A
236  */
237 void
238 print_sys_cfg_rsn_replay_prot_usage(void)
239 {
240     printf("\nUsage : sys_cfg_rsn_replay_prot [0|1]\n");
241     printf("\nOptions: 0     - Disable RSN replay protection");
242     printf("\n         1     - Enable  RSN replay protection");
243     printf("\n         empty - Get current RSN replay protection setting\n");
244     return;
245 }
246
247 /**
248  *  @brief Show usage information for the sys_cfg_preamble_ctl
249  *   command
250  *
251  *  $return         N/A
252  */
253 void
254 print_sys_cfg_preamble_ctl_usage(void)
255 {
256     printf("\nUsage : sys_cfg_preamble_ctl\n");
257     return;
258 }
259
260 /**
261  *  @brief Show usage information for the sys_cfg_antenna_ctl
262  *   command
263  *
264  *  $return         N/A
265  */
266 void
267 print_sys_cfg_antenna_ctl_usage(void)
268 {
269     printf("\nUsage : sys_cfg_antenna_ctl <ANTENNA> [MODE]\n");
270     printf("\nOptions: ANTENNA : 0 - Rx antenna");
271     printf("\n                   1 - Tx antenna");
272     printf("\n         MODE    : 0       - Antenna A");
273     printf("\n                   1       - Antenna B");
274     printf("\n                   empty   - Get current antenna settings\n");
275     return;
276 }
277
278 /**
279  *  @brief Show usage information for the sys_cfg_rts_threshold
280  *   command
281  *
282  *  $return         N/A
283  */
284 void
285 print_sys_cfg_rts_threshold_usage(void)
286 {
287     printf("\nUsage : sys_cfg_rts_threshold [RTS_THRESHOLD]\n");
288     printf
289         ("\nIf RTS_THRESHOLD is provided, a 'set' is performed, else a 'get' is performed.\n");
290     return;
291 }
292
293 /**
294  *  @brief Show usage information for the sys_cfg_frag_threshold
295  *   command
296  *
297  *  $return         N/A
298  */
299 void
300 print_sys_cfg_frag_threshold_usage(void)
301 {
302     printf("\nUsage : sys_cfg_frag_threshold [FRAG_THRESHOLD]\n");
303     printf
304         ("\nIf FRAG_THRESHOLD is provided, a 'set' is performed, else a 'get' is performed.");
305     printf("\nFragment threshold should between 256 and 2346.\n");
306     return;
307 }
308
309 /**
310  *  @brief Show usage information for the sys_cfg_radio_ctl
311  *   command
312  *
313  *  $return         N/A
314  */
315 void
316 print_sys_cfg_radio_ctl_usage(void)
317 {
318     printf("\nUsage : sys_cfg_radio_ctl [0|1]\n");
319     printf("\nOptions: 0     - Turn radio on");
320     printf("\n         1     - Turn radio off");
321     printf("\n         empty - Get current radio setting\n");
322     return;
323 }
324
325 /**
326  *  @brief Show usage information for the sys_cfg_tx_data_rate
327  *   command
328  *
329  *  $return         N/A
330  */
331 void
332 print_sys_cfg_tx_data_rates_usage(void)
333 {
334     printf("\nUsage : sys_cfg_tx_data_rate [TX_DATA_RATE]\n");
335     printf("\nOptions: 0     - Auto rate");
336     printf("\n         >0    - Set specified data rate");
337     printf("\n         empty - Get current data rate");
338     printf("\nFollowing is the list of supported rates in units of 500 Kbps");
339     printf("\nDecimal: (2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108)");
340     printf
341         ("\nHex: (0x02, 0x04, 0x0b, 0x16, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c)");
342     printf("\nOnly zero or rates currently configured are allowed.\n");
343     return;
344 }
345
346 /**
347  *  @brief Show usage information for the sys_cfg_mcbc_data_rate
348  *   command
349  *
350  *  $return         N/A
351  */
352 void
353 print_sys_cfg_mcbc_data_rates_usage(void)
354 {
355     printf("\nUsage : sys_cfg_mcbc_data_rate [MCBC_DATA_RATE]\n");
356     printf("\nOptions: 0     - Auto rate");
357     printf("\n         >0    - Set specified MCBC data rate");
358     printf("\n         empty - Get current MCBC data rate");
359     printf("\nFollowing is the list of supported rates in units of 500 Kbps");
360     printf("\nDecimal: (2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108)");
361     printf
362         ("\nHex: (0x02, 0x04, 0x0b, 0x16, 0x0C, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c)");
363     printf
364         ("\nOnly zero or one of the basic rates currently configured are allowed.\n");
365     return;
366 }
367
368 /**
369  *  @brief Show usage information for the sys_cfg_auth command
370  *
371  *  $return         N/A
372  */
373 void
374 print_sys_cfg_auth_usage(void)
375 {
376     printf("\nUsage : sys_cfg_auth [AUTHMODE]\n");
377     printf("\nOptions: AUTHMODE :     0 - Open authentication");
378     printf("\n                        1 - Shared key authentication");
379     printf("\n         empty - Get current authenticaton mode\n");
380     return;
381 }
382
383 /**
384  *  @brief Show usage information for the sys_cfg_pkt_fwd_ctl command
385  *
386  *  $return         N/A
387  */
388 void
389 print_sys_cfg_pkt_fwd_ctl_usage(void)
390 {
391     printf("\nUsage : sys_cfg_pkt_fwd_ctl [0|1]\n");
392     printf("\nOptions: 0     - Forward all packets to the host");
393     printf("\n         1     - Firmware handles intra-BSS packets");
394     printf("\n         empty - Get current packet forwarding setting\n");
395     return;
396 }
397
398 /**
399  *  @brief Show usage information for the sys_cfg_sta_ageout_timer
400  *   command
401  *
402  *  $return         N/A
403  */
404 void
405 print_sys_cfg_sta_ageout_timer_usage(void)
406 {
407     printf("\nUsage : sys_cfg_sta_ageout_timer [STA_AGEOUT_TIMER]\n");
408     printf
409         ("\nIf STA_AGEOUT_TIMER is provided, a 'set' is performed, else a 'get' is performed.");
410     printf("\nSTA_AGEOUT_TIMER is represented in units of 100 ms.");
411     printf("\nValue of 0 will mean that stations will never be aged out.");
412     printf("\nThe value should between 300 and 864000.\n");
413     return;
414 }
415
416 /**
417  *  @brief Show usage information for the sys_cfg_protocol command
418  *
419  *  $return         N/A
420  */
421 void
422 print_sys_cfg_protocol_usage(void)
423 {
424     printf("\nUsage : sys_cfg_protocol [PROTOCOL]\n");
425     printf("\nOptions: PROTOCOL:                1 - No RSN");
426     printf("\n                          2 - WEP Static");
427     printf("\n                          8 - WPA");
428     printf("\n                          32 - WPA2");
429     printf("\n                          40 - WPA2 Mixed");
430     printf("\n                          empty - Get current protocol\n");
431     return;
432 }
433
434 /**
435  *  @brief Show usage information for the sys_cfg_wep_key
436  *   command
437  *
438  *  $return         N/A
439  */
440 void
441 print_sys_cfg_wep_key_usage(void)
442 {
443     printf("\nUsage : sys_cfg_wep_key ");
444     printf
445         ("[INDEX_0 IS_DEFAULT KEY_0] [INDEX_1 IS_DEFAULT KEY_1] [INDEX_2 IS_DEFAULT KEY_2] [INDEX_3 IS_DEFAULT KEY_3]\n");
446     printf("[Index_0] [Index_1] [Index_2] [Index_3]\n");
447     printf("\nOptions: INDEX_* :      0 - KeyIndex is 0");
448     printf("\n                        1 - KeyIndex is 1");
449     printf("\n                        2 - KeyIndex is 2");
450     printf("\n                        3 - KeyIndex is 3");
451     printf("\n         IS_DEFAULT :   0 - KeyIndex is not the default");
452     printf
453         ("\n                        1 - KeyIndex is the default transmit key");
454     printf("\n         KEY_* :        Key value");
455     printf("\n         Index_*:       0 - Get key 0 setting");
456     printf("\n                        1 - Get key 1 setting");
457     printf("\n                        2 - Get key 2 setting");
458     printf("\n                        3 - Get key 3 setting");
459     printf("\n         empty - Get current WEP key settings\n");
460     return;
461 }
462
463 /**
464  *  @brief Show usage information for the sys_cfg_custom_ie
465  *   command
466  *
467  *  $return         N/A
468  */
469 void
470 print_sys_cfg_custom_ie_usage(void)
471 {
472     printf("\nUsage : sys_cfg_custom_ie [INDEX] [MASK] [IEBuffer]");
473     printf("\n         empty - Get all IE settings\n");
474     printf("\n         INDEX:  0 - Get/Set IE index 0 setting");
475     printf("\n                 1 - Get/Set IE index 1 setting");
476     printf("\n                 2 - Get/Set IE index 2 setting");
477     printf("\n                 3 - Get/Set IE index 3 setting");
478     printf
479         ("\n         MASK :  Management subtype mask value as per bit defintions");
480     printf("\n              :  Bit 0 - Association request.");
481     printf("\n              :  Bit 1 - Association response.");
482     printf("\n              :  Bit 2 - Reassociation request.");
483     printf("\n              :  Bit 3 - Reassociation response.");
484     printf("\n              :  Bit 4 - Probe request.");
485     printf("\n              :  Bit 5 - Probe response.");
486     printf("\n              :  Bit 8 - Beacon.");
487     printf("\n         MASK :  MASK = 0 to clear the mask and the IE buffer");
488     printf("\n         IEBuffer :  IE Buffer in hex (max 256 bytes)\n\n");
489     return;
490 }
491
492  /* @brief Show usage information for the sys_cfg_cipher * command * * $return
493     N/A */
494 void
495 print_sys_cfg_cipher_usage(void)
496 {
497     printf("\nUsage : sys_cfg_cipher [PAIRWISE_CIPHER GROUP_CIPHER]\n");
498     printf("\nOptions: PAIRWISE_CIPHER:  0 - NONE");
499     printf("\n                           4 - TKIP");
500     printf("\n                           8 - AES CCMP");
501     printf("\n                           12 - AES CCMP + TKIP");
502     printf("\n         GROUP_CIPHER :    0 - NONE");
503     printf("\n                           4 - TKIP");
504     printf("\n                           8 - AES CCMP");
505     printf("\n         empty - Get current cipher settings\n");
506     return;
507 }
508
509 /**
510  *  @brief Show usage information for the sys_cfg_group_rekey_timer command
511  *
512  *  $return         N/A
513  */
514 void
515 print_sys_cfg_group_rekey_timer_usage(void)
516 {
517     printf("\nUsage : sys_cfg_group_rekey_timer [GROUP_REKEY_TIMER]\n");
518     printf("\nOptions: GROUP_REKEY_TIME is represented in seconds");
519     printf("\n         empty - Get current group re-key time\n");
520     return;
521 }
522
523 /**
524  *  @brief Show usage information for the sys_cfg_wpa_passphrase
525  *   command
526  *
527  *  $return         N/A
528  */
529 void
530 print_sys_cfg_wpa_passphrase_usage(void)
531 {
532     printf("\nUsage : sys_cfg_wpa_passphrase [PASSPHRASE]\n");
533     printf
534         ("\nIf PASSPHRASE is provided, a 'set' is performed, else a 'get' is performed.\n");
535     return;
536 }
537
538 /**
539  *  @brief Show usage information for the sta_filter_table command
540  *
541  *  $return         N/A
542  */
543 void
544 print_sta_filter_table_usage(void)
545 {
546     printf("\nUsage : sta_filter_table <FILTERMODE> <MACADDRESS_LIST>\n");
547     printf("\nOptions: FILTERMODE : 0 - Disable filter table");
548     printf
549         ("\n                      1 - allow MAC addresses specified in the allowed list");
550     printf
551         ("\n                      2 - block MAC addresses specified in the banned list");
552     printf
553         ("\n         MACADDRESS_LIST is the list of MAC addresses to be acted upon. Each");
554     printf
555         ("\n                      MAC address must be separated with a space. Maximum of");
556     printf("\n                      16 MAC addresses are supported.");
557     printf("\n         empty - Get current mac filter settings\n");
558     return;
559 }
560
561 /**
562  *  @brief Show usage information for the sys_cfg_max_sta_num command
563  *
564  *  $return         N/A
565  */
566 void
567 print_sys_cfg_max_sta_num_usage(void)
568 {
569     printf("\nUsage : sys_cfg_max_sta_num [STA_NUM]\n");
570     printf
571         ("\nIf STA_NUM is provided, a 'set' is performed, else a 'get' is performed.");
572     printf("\nSTA_NUM should not bigger than 8.\n");
573     return;
574 }
575
576 /**
577  *  @brief Show usage information for the sys_cfg_retry_limit command
578  *
579  *  $return         N/A
580  */
581 void
582 print_sys_cfg_retry_limit_usage(void)
583 {
584     printf("\nUsage : sys_cfg_retry_limit [RETRY_LIMIT]\n");
585     printf
586         ("\nIf RETRY_LIMIT is provided, a 'set' is performed, else a 'get' is performed.");
587     printf("\nRETRY_LIMIT should not bigger than 14.\n");
588     return;
589 }
590
591 /**
592  *  @brief Show usage information for the sys_cfg_retry_limit command
593  *
594  *  $return         N/A
595  */
596 void
597 print_cfg_data_usage(void)
598 {
599     printf("\nUsage : cfg_data <type> [*.conf]\n");
600     printf("\n        type : 2 -- cal data");
601     printf("\n        *.conf : file contain configuration data");
602     printf("\n                 empty - get current configuration data\n");
603     return;
604 }
605
606 /** 
607  *  @brief  get configured operational rates.
608  *
609  *  @param  rates   Operational rates allowed are
610  *                  stored at this pointer
611  *  @return         number of basic rates allowed.
612  *                  -1 if a failure 
613  */
614 int
615 get_sys_cfg_rates(u8 * rates)
616 {
617     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
618     TLVBUF_RATES *tlv = NULL;
619     u8 *buffer = NULL;
620     u16 cmd_len;
621     int ret = UAP_FAILURE;
622     int i = 0;
623     int rate_cnt = 0;
624     /* Initialize the command length */
625     cmd_len =
626         sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_RATES) + MAX_DATA_RATES;
627     /* Initialize the command buffer */
628     buffer = (u8 *) malloc(cmd_len);
629     if (!buffer) {
630         printf("ERR:Cannot allocate buffer for command!\n");
631         return -1;
632     }
633     bzero((char *) buffer, cmd_len);
634
635     /* Locate headers */
636     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
637     tlv = (TLVBUF_RATES *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
638
639     /* Fill the command buffer */
640     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
641     cmd_buf->Size = cmd_len;
642     cmd_buf->SeqNum = 0;
643     cmd_buf->Result = 0;
644     tlv->Tag = MRVL_RATES_TLV_ID;
645     cmd_buf->Action = ACTION_GET;
646     tlv->Length = MAX_DATA_RATES;
647
648     endian_convert_tlv_header_out(tlv);
649     /* Send the command */
650     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
651     endian_convert_tlv_header_in(tlv);
652     /* Process response */
653     if (ret == UAP_SUCCESS) {
654         /* Verify response */
655         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
656             (tlv->Tag != MRVL_RATES_TLV_ID)) {
657             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
658                    cmd_buf->CmdCode, tlv->Tag);
659             free(buffer);
660             return -1;
661         }
662
663         /* copy response */
664         if (cmd_buf->Result == CMD_SUCCESS) {
665             for (i = 0; i < tlv->Length; i++) {
666                 if (tlv->OperationalRates[i] != 0) {
667                     rates[rate_cnt++] = tlv->OperationalRates[i];
668                 }
669             }
670         } else {
671             printf("ERR:Could not get operational rates!\n");
672         }
673     } else {
674         printf("ERR:Command sending failed!\n");
675     }
676     if (buffer)
677         free(buffer);
678     return rate_cnt;
679 }
680
681 /** 
682  *  @brief check rate is valid or not.
683  *
684  *  @param  rate   rate for check
685  *
686  *  @return         UAP_SUCCESS or UAP_FAILURE
687  */
688 int
689 is_tx_rate_valid(u8 rate)
690 {
691     int rate_cnt = 0;
692     int i;
693     u8 rates[MAX_DATA_RATES];
694
695     rate_cnt = get_sys_cfg_rates((u8 *) & rates);
696     if (rate_cnt > 0) {
697         for (i = 0; i < rate_cnt; i++) {
698             if (rate == (rates[i] & ~BASIC_RATE_SET_BIT)) {
699                 return UAP_SUCCESS;
700             }
701         }
702     }
703     return UAP_FAILURE;
704 }
705
706 /** 
707  *  @brief check mcbc rate is valid or not.
708  *
709  *  @param  rate   rate for check
710  *
711  *  @return         UAP_SUCCESS or UAP_FAILURE
712  */
713 int
714 is_mcbc_rate_valid(u8 rate)
715 {
716     int rate_cnt = 0;
717     int i;
718     u8 rates[MAX_DATA_RATES];
719
720     rate_cnt = get_sys_cfg_rates((u8 *) & rates);
721     if (rate_cnt > 0) {
722         for (i = 0; i < rate_cnt; i++) {
723             if (rates[i] & BASIC_RATE_SET_BIT) {
724                 if (rate == (rates[i] & ~BASIC_RATE_SET_BIT)) {
725                     return UAP_SUCCESS;
726                 }
727             }
728         }
729     }
730     return UAP_FAILURE;
731 }
732
733 /****************************************************************************
734         Global functions
735 ****************************************************************************/
736 /** 
737  *  @brief Creates a sys_cfg request for AP MAC address
738  *   and sends to the driver
739  *
740  *  Usage: "sys_cfg_ap_mac_address [AP_MAC_ADDRESS]"
741  *          if AP_MAC_ADDRESS is provided, a 'set' is performed,
742  *          else a 'get' is performed.
743  *
744  *  @param argc     Number of arguments
745  *  @param argv     Pointer to the arguments
746  *  @return         N/A
747  */
748 void
749 apcmd_sys_cfg_ap_mac_address(int argc, char *argv[])
750 {
751     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
752     TLVBUF_AP_MAC_ADDRESS *tlv = NULL;
753     u8 *buffer = NULL;
754     u16 cmd_len;
755     int ret = UAP_FAILURE;
756     int opt;
757
758     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
759         switch (opt) {
760         default:
761             print_sys_cfg_ap_mac_address_usage();
762             return;
763         }
764     }
765     argc -= optind;
766     argv += optind;
767
768     /* Check arguments */
769     if (argc > 1) {
770         printf("ERR:Too many arguments.\n");
771         print_sys_cfg_ap_mac_address_usage();
772         return;
773     }
774
775     /* Initialize the command length */
776     cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_AP_MAC_ADDRESS);
777
778     /* Initialize the command buffer */
779     buffer = (u8 *) malloc(cmd_len);
780
781     if (!buffer) {
782         printf("ERR:Cannot allocate buffer for command!\n");
783         return;
784     }
785     bzero((char *) buffer, cmd_len);
786
787     /* Locate headers */
788     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
789     tlv = (TLVBUF_AP_MAC_ADDRESS *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
790
791     /* Fill the command buffer */
792     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
793     cmd_buf->Size = cmd_len;
794     cmd_buf->SeqNum = 0;
795     cmd_buf->Result = 0;
796     tlv->Tag = MRVL_AP_MAC_ADDRESS_TLV_ID;
797     tlv->Length = ETH_ALEN;
798     if (argc == 0) {
799         cmd_buf->Action = ACTION_GET;
800     } else {
801         cmd_buf->Action = ACTION_SET;
802         if ((ret = mac2raw(argv[0], tlv->ApMacAddr)) != UAP_SUCCESS) {
803             printf("ERR: %s Address \n", ret == UAP_FAILURE ? "Invalid MAC" :
804                    ret == UAP_RET_MAC_BROADCAST ? "Broadcast" : "Multicast");
805             free(buffer);
806             return;
807         }
808     }
809     endian_convert_tlv_header_out(tlv);
810
811     /* Send the command */
812     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
813     endian_convert_tlv_header_in(tlv);
814     /* Process response */
815     if (ret == UAP_SUCCESS) {
816         /* Verify response */
817         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
818             (tlv->Tag != MRVL_AP_MAC_ADDRESS_TLV_ID)) {
819             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
820                    cmd_buf->CmdCode, tlv->Tag);
821             free(buffer);
822             return;
823         }
824
825         /* Print response */
826         if (cmd_buf->Result == CMD_SUCCESS) {
827             if (argc == 0) {
828                 printf("AP MAC address = ");
829                 print_mac(tlv->ApMacAddr);
830                 printf("\n");
831             } else {
832                 printf("AP MAC address setting successful\n");
833             }
834         } else {
835             if (argc == 0) {
836                 printf("ERR:Could not get AP MAC address!\n");
837             } else {
838                 printf("ERR:Could not set AP MAC address!\n");
839             }
840         }
841     } else {
842         printf("ERR:Command sending failed!\n");
843     }
844
845     if (buffer)
846         free(buffer);
847     return;
848 }
849
850 /** 
851  *  @brief Creates a sys_cfg request for SSID
852  *   and sends to the driver
853  *
854  *  Usage: "sys_cfg_ssid [SSID]"
855  *          if SSID is provided, a 'set' is performed
856  *          else a 'get' is performed 
857  *
858  *  @param argc     Number of arguments
859  *  @param argv     Pointer to the arguments
860  *  @return         N/A
861  */
862 void
863 apcmd_sys_cfg_ssid(int argc, char *argv[])
864 {
865     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
866     TLVBUF_SSID *tlv = NULL;
867     u8 *buffer = NULL;
868     u16 cmd_len;
869     int ret = UAP_FAILURE;
870     int opt;
871     u8 ssid[33];
872
873     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
874         switch (opt) {
875         default:
876             print_sys_cfg_ssid_usage();
877             return;
878         }
879     }
880     argc -= optind;
881     argv += optind;
882
883     /* Check arguments */
884     if (argc > 1) {
885         printf("ERR:Too many arguments.\n");
886         print_sys_cfg_ssid_usage();
887         return;
888     }
889
890     if (argc == 0) {
891         /* Initialize the command length */
892         cmd_len =
893             sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_SSID) +
894             MAX_SSID_LENGTH;
895     } else {
896         if (strlen(argv[0]) > MAX_SSID_LENGTH) {
897             printf("ERR:SSID too long.\n");
898             return;
899         }
900         /* Initialize the command length */
901         if (argv[0][1] == '"') {
902             argv[0]++;
903         }
904         if (argv[0][strlen(argv[0])] == '"') {
905             argv[0][strlen(argv[0])] = '\0';
906         }
907         if (!strlen(argv[0])) {
908             printf("ERR:NULL SSID not allowed.\n");
909             return;
910         }
911         cmd_len =
912             sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_SSID) +
913             strlen(argv[0]);
914     }
915
916     /* Initialize the command buffer */
917     buffer = (u8 *) malloc(cmd_len);
918
919     if (!buffer) {
920         printf("ERR:Cannot allocate buffer for command!\n");
921         return;
922     }
923     bzero((char *) buffer, cmd_len);
924
925     /* Locate headers */
926     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
927     tlv = (TLVBUF_SSID *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
928
929     /* Fill the command buffer */
930     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
931     cmd_buf->Size = cmd_len;
932     cmd_buf->SeqNum = 0;
933     cmd_buf->Result = 0;
934     tlv->Tag = MRVL_SSID_TLV_ID;
935     if (argc == 0) {
936         cmd_buf->Action = ACTION_GET;
937         tlv->Length = MAX_SSID_LENGTH;
938     } else {
939         cmd_buf->Action = ACTION_SET;
940         tlv->Length = strlen(argv[0]);
941         memcpy(tlv->Ssid, argv[0], tlv->Length);
942     }
943
944     endian_convert_tlv_header_out(tlv);
945
946     /* Send the command */
947     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
948
949     endian_convert_tlv_header_in(tlv);
950
951     /* Process response */
952     if (ret == UAP_SUCCESS) {
953         /* Verify response */
954         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
955             (tlv->Tag != MRVL_SSID_TLV_ID)) {
956             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
957                    cmd_buf->CmdCode, tlv->Tag);
958             free(buffer);
959             return;
960         }
961
962         /* Print response */
963         if (cmd_buf->Result == CMD_SUCCESS) {
964             if (argc == 0) {
965                 memset(ssid, 0, sizeof(ssid));
966                 memcpy(ssid, tlv->Ssid, tlv->Length);
967                 printf("SSID = %s\n", ssid);
968             } else {
969                 printf("SSID setting successful\n");
970             }
971         } else {
972             if (argc == 0) {
973                 printf("ERR:Could not get SSID!\n");
974             } else {
975                 printf("ERR:Could not set SSID!\n");
976             }
977         }
978     } else {
979         printf("ERR:Command sending failed!\n");
980     }
981
982     if (buffer)
983         free(buffer);
984     return;
985 }
986
987 /** 
988  *  @brief Creates a sys_cfg request for beacon period
989  *   and sends to the driver
990  *
991  *   Usage: "sys_cfg_beacon_period [BEACON_PERIOD]"
992  *           if BEACON_PERIOD is provided, a 'set' is performed
993  *           else a 'get' is performed.
994  *
995  *           BEACON_PERIOD is represented in ms
996  *
997  *  @param argc     Number of arguments
998  *  @param argv     Pointer to the arguments
999  *  @return         N/A
1000  */
1001 void
1002 apcmd_sys_cfg_beacon_period(int argc, char *argv[])
1003 {
1004     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
1005     TLVBUF_BEACON_PERIOD *tlv = NULL;
1006     u8 *buffer = NULL;
1007     u16 cmd_len;
1008     int ret = UAP_FAILURE;
1009     int opt;
1010
1011     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
1012         switch (opt) {
1013         default:
1014             print_sys_cfg_beacon_period_usage();
1015             return;
1016         }
1017     }
1018     argc -= optind;
1019     argv += optind;
1020
1021     /* Check arguments */
1022     if (argc && is_input_valid(BEACONPERIOD, argc, argv) != UAP_SUCCESS) {
1023         print_sys_cfg_beacon_period_usage();
1024         return;
1025     }
1026     /* Initialize the command length */
1027     cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_BEACON_PERIOD);
1028
1029     /* Initialize the command buffer */
1030     buffer = (u8 *) malloc(cmd_len);
1031
1032     if (!buffer) {
1033         printf("ERR:Cannot allocate buffer for command!\n");
1034         return;
1035     }
1036     bzero((char *) buffer, cmd_len);
1037
1038     /* Locate headers */
1039     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
1040     tlv = (TLVBUF_BEACON_PERIOD *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
1041
1042     /* Fill the command buffer */
1043     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
1044     cmd_buf->Size = cmd_len;
1045     cmd_buf->SeqNum = 0;
1046     cmd_buf->Result = 0;
1047     tlv->Tag = MRVL_BEACON_PERIOD_TLV_ID;
1048     tlv->Length = 2;
1049     if (argc == 0) {
1050         cmd_buf->Action = ACTION_GET;
1051     } else {
1052         cmd_buf->Action = ACTION_SET;
1053         tlv->BeaconPeriod_ms = (u16) atoi(argv[0]);
1054     }
1055     endian_convert_tlv_header_out(tlv);
1056     tlv->BeaconPeriod_ms = uap_cpu_to_le16(tlv->BeaconPeriod_ms);
1057
1058     /* Send the command */
1059     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
1060     endian_convert_tlv_header_in(tlv);
1061     tlv->BeaconPeriod_ms = uap_le16_to_cpu(tlv->BeaconPeriod_ms);
1062     /* Process response */
1063     if (ret == UAP_SUCCESS) {
1064         /* Verify response */
1065         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
1066             (tlv->Tag != MRVL_BEACON_PERIOD_TLV_ID)) {
1067             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
1068                    cmd_buf->CmdCode, tlv->Tag);
1069             free(buffer);
1070             return;
1071         }
1072         /* Print response */
1073         if (cmd_buf->Result == CMD_SUCCESS) {
1074             if (argc == 0) {
1075                 printf("Beacon period = %d\n", tlv->BeaconPeriod_ms);
1076             } else {
1077                 printf("Beacon period setting successful\n");
1078             }
1079         } else {
1080             if (argc == 0) {
1081                 printf("ERR:Could not get beacon period!\n");
1082             } else {
1083                 printf("ERR:Could not set beacon period!\n");
1084             }
1085         }
1086     } else {
1087         printf("ERR:Command sending failed!\n");
1088     }
1089     if (buffer)
1090         free(buffer);
1091     return;
1092 }
1093
1094 /** 
1095  *  @brief Creates a sys_cfg request for DTIM period
1096  *   and sends to the driver
1097  *
1098  *   Usage: "sys_cfg_dtim_period [DTIM_PERIOD]"
1099  *           if DTIM_PERIOD is provided, a 'set' is performed
1100  *           else a 'get' is performed
1101  *
1102  *  @param argc     Number of arguments
1103  *  @param argv     Pointer to the arguments
1104  *  @return         N/A
1105  */
1106 void
1107 apcmd_sys_cfg_dtim_period(int argc, char *argv[])
1108 {
1109     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
1110     TLVBUF_DTIM_PERIOD *tlv = NULL;
1111     u8 *buffer = NULL;
1112     u16 cmd_len;
1113     int ret = UAP_FAILURE;
1114     int opt;
1115     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
1116         switch (opt) {
1117         default:
1118             print_sys_cfg_dtim_period_usage();
1119             return;
1120         }
1121     }
1122     argc -= optind;
1123     argv += optind;
1124     /* Check arguments */
1125     if (argc && (is_input_valid(DTIMPERIOD, argc, argv) != UAP_SUCCESS)) {
1126         print_sys_cfg_dtim_period_usage();
1127         return;
1128     }
1129
1130     /* Initialize the command length */
1131     cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_DTIM_PERIOD);
1132
1133     /* Initialize the command buffer */
1134     buffer = (u8 *) malloc(cmd_len);
1135
1136     if (!buffer) {
1137         printf("ERR:Cannot allocate buffer for command!\n");
1138         return;
1139     }
1140     bzero((char *) buffer, cmd_len);
1141
1142     /* Locate headers */
1143     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
1144     tlv = (TLVBUF_DTIM_PERIOD *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
1145
1146     /* Fill the command buffer */
1147     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
1148     cmd_buf->Size = cmd_len;
1149     cmd_buf->SeqNum = 0;
1150     cmd_buf->Result = 0;
1151     tlv->Tag = MRVL_DTIM_PERIOD_TLV_ID;
1152     tlv->Length = 1;
1153     if (argc == 0) {
1154         cmd_buf->Action = ACTION_GET;
1155     } else {
1156         cmd_buf->Action = ACTION_SET;
1157         tlv->DtimPeriod = (u8) atoi(argv[0]);
1158     }
1159     endian_convert_tlv_header_out(tlv);
1160     /* Send the command */
1161     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
1162     endian_convert_tlv_header_in(tlv);
1163
1164     /* Process response */
1165     if (ret == UAP_SUCCESS) {
1166         /* Verify response */
1167         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
1168             (tlv->Tag != MRVL_DTIM_PERIOD_TLV_ID)) {
1169             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
1170                    cmd_buf->CmdCode, tlv->Tag);
1171             free(buffer);
1172             return;
1173         }
1174         /* Print response */
1175         if (cmd_buf->Result == CMD_SUCCESS) {
1176             if (argc == 0) {
1177                 printf("DTIM period = %d\n", tlv->DtimPeriod);
1178             } else {
1179                 printf("DTIM period setting successful\n");
1180             }
1181         } else {
1182             if (argc == 0) {
1183                 printf("ERR:Could not get DTIM period!\n");
1184             } else {
1185                 printf("ERR:Could not set DTIM period!\n");
1186             }
1187         }
1188     } else {
1189         printf("ERR:Command sending failed!\n");
1190     }
1191     if (buffer)
1192         free(buffer);
1193     return;
1194 }
1195
1196 /** 
1197  *  @brief Creates a sys_cfg request for channel
1198  *   and sends to the driver
1199  *
1200  *   Usage: "sys_cfg_channel [CHANNEL] [MODE]"
1201  *           if CHANNEL is provided, a 'set' is performed
1202  *           else a 'get' is performed
1203  *           if MODE is provided, a 'set' is performed with
1204  *           0 as manual channel selection
1205  *           1 as automatic channel selection.
1206  *
1207  *  @param argc     Number of arguments
1208  *  @param argv     Pointer to the arguments
1209  *  @return         N/A
1210  */
1211 void
1212 apcmd_sys_cfg_channel(int argc, char *argv[])
1213 {
1214     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
1215     TLVBUF_CHANNEL_CONFIG *tlv = NULL;
1216     u8 *buffer = NULL;
1217     u16 cmd_len;
1218     int ret = UAP_FAILURE;
1219     int opt;
1220     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
1221         switch (opt) {
1222         default:
1223             print_sys_cfg_channel_usage();
1224             return;
1225         }
1226     }
1227     argc -= optind;
1228     argv += optind;
1229
1230     /* Check arguments */
1231     if (argc && is_input_valid(CHANNEL, argc, argv) != UAP_SUCCESS) {
1232         print_sys_cfg_channel_usage();
1233         return;
1234     }
1235
1236     /* Initialize the command length */
1237     cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_CHANNEL_CONFIG);
1238
1239     /* Initialize the command buffer */
1240     buffer = (u8 *) malloc(cmd_len);
1241
1242     if (!buffer) {
1243         printf("ERR:Cannot allocate buffer for command!\n");
1244         return;
1245     }
1246     bzero((char *) buffer, cmd_len);
1247
1248     /* Locate headers */
1249     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
1250     tlv = (TLVBUF_CHANNEL_CONFIG *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
1251
1252     /* Fill the command buffer */
1253     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
1254     cmd_buf->Size = cmd_len;
1255     cmd_buf->SeqNum = 0;
1256     cmd_buf->Result = 0;
1257     tlv->Tag = MRVL_CHANNELCONFIG_TLV_ID;
1258     tlv->Length = 2;
1259     if (argc == 0) {
1260         cmd_buf->Action = ACTION_GET;
1261     } else {
1262         cmd_buf->Action = ACTION_SET;
1263         if (argc == 1) {
1264             tlv->ChanNumber = (u8) atoi(argv[0]);
1265             tlv->BandConfigType = 0;
1266         } else {
1267             tlv->BandConfigType = atoi(argv[1]) ? BAND_CONFIG_ACS_MODE : 0;
1268             tlv->ChanNumber = (u8) atoi(argv[0]);
1269         }
1270     }
1271     endian_convert_tlv_header_out(tlv);
1272     /* Send the command */
1273     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
1274     endian_convert_tlv_header_in(tlv);
1275     /* Process response */
1276     if (ret == UAP_SUCCESS) {
1277         /* Verify response */
1278         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
1279             (tlv->Tag != MRVL_CHANNELCONFIG_TLV_ID)) {
1280             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
1281                    cmd_buf->CmdCode, tlv->Tag);
1282             free(buffer);
1283             return;
1284         }
1285         /* Print response */
1286         if (cmd_buf->Result == CMD_SUCCESS) {
1287             if (argc == 0) {
1288                 printf("Mode    = %s\n",
1289                        (tlv->BandConfigType == 0) ? "Manual" : "ACS");
1290                 printf("Channel = %d\n", tlv->ChanNumber);
1291             } else {
1292                 printf("Channel setting successful\n");
1293             }
1294         } else {
1295             if (argc == 0) {
1296                 printf("ERR:Could not get channel!\n");
1297             } else {
1298                 printf("ERR:Could not set channel!\n");
1299             }
1300         }
1301     } else {
1302         printf("ERR:Command sending failed!\n");
1303     }
1304     if (buffer)
1305         free(buffer);
1306     return;
1307 }
1308
1309 /** 
1310  *  @brief Creates a sys_cfg request for channel list
1311  *   and sends to the driver
1312  *
1313  *   Usage: "sys_cfg_scan_channels [CHANNELS]"
1314  *           if CHANNELS are provided, a 'set' is performed
1315  *           else a 'get' is performed
1316  *
1317  *  @param argc     Number of arguments
1318  *  @param argv     Pointer to the arguments
1319  *  @return         N/A
1320  */
1321 void
1322 apcmd_sys_cfg_scan_channels(int argc, char *argv[])
1323 {
1324     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
1325     TLVBUF_CHANNEL_LIST *tlv = NULL;
1326     CHANNEL_LIST *pChanList = NULL;
1327     u8 *buffer = NULL;
1328     u16 cmd_len;
1329     int ret = UAP_FAILURE;
1330     int opt;
1331     int i;
1332     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
1333         switch (opt) {
1334         default:
1335             print_sys_cfg_scan_channels_usage();
1336             return;
1337         }
1338     }
1339     argc -= optind;
1340     argv += optind;
1341
1342     /* Check arguments */
1343     if (argc && is_input_valid(SCANCHANNELS, argc, argv) != UAP_SUCCESS) {
1344         print_sys_cfg_scan_channels_usage();
1345         return;
1346     }
1347
1348     /* Initialize the command length */
1349     if (argc == 0)
1350         cmd_len =
1351             sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_CHANNEL_LIST) +
1352             sizeof(CHANNEL_LIST) * MAX_CHANNELS;
1353     else
1354         cmd_len =
1355             sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_CHANNEL_LIST) +
1356             sizeof(CHANNEL_LIST) * argc;
1357
1358     /* Initialize the command buffer */
1359     buffer = (u8 *) malloc(cmd_len);
1360
1361     if (!buffer) {
1362         printf("ERR:Can not allocate buffer for command!\n");
1363         return;
1364     }
1365     bzero((char *) buffer, cmd_len);
1366
1367     /* LOCATE HEADERS */
1368     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
1369     tlv = (TLVBUF_CHANNEL_LIST *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
1370
1371     /* Fill the command buffer */
1372     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
1373     cmd_buf->Size = cmd_len;
1374     cmd_buf->SeqNum = 0;
1375     cmd_buf->Result = 0;
1376     tlv->Tag = MRVL_CHANNELLIST_TLV_ID;
1377     if (argc == 0) {
1378         cmd_buf->Action = ACTION_GET;
1379         tlv->Length = sizeof(CHANNEL_LIST) * MAX_CHANNELS;
1380     } else {
1381         cmd_buf->Action = ACTION_SET;
1382         tlv->Length = sizeof(CHANNEL_LIST) * argc;
1383         pChanList = tlv->ChanList;
1384         for (i = 0; i < argc; i++) {
1385             pChanList->ChanNumber = (u8) atoi(argv[i]);
1386             pChanList->BandConfigType = 0;
1387             pChanList++;
1388         }
1389     }
1390     endian_convert_tlv_header_out(tlv);
1391     /* Send the command */
1392     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
1393     endian_convert_tlv_header_in(tlv);
1394     /* Process response */
1395     if (ret == UAP_SUCCESS) {
1396         /* Verify response */
1397         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
1398             (tlv->Tag != MRVL_CHANNELLIST_TLV_ID)) {
1399             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
1400                    cmd_buf->CmdCode, tlv->Tag);
1401             free(buffer);
1402             return;
1403         }
1404         /* Print response */
1405         if (cmd_buf->Result == CMD_SUCCESS) {
1406             if (argc == 0) {
1407                 printf("Channels List = ");
1408                 if (tlv->Length % sizeof(CHANNEL_LIST)) {
1409                     printf("Error: Length mismatch\n");
1410                     free(buffer);
1411                     return;
1412                 }
1413                 pChanList = tlv->ChanList;
1414                 for (i = 0; i < (tlv->Length / sizeof(CHANNEL_LIST)); i++) {
1415                     printf("%d ", pChanList->ChanNumber);
1416                     pChanList++;
1417                 }
1418                 printf("\n");
1419             } else {
1420                 printf("Scan Channel List setting successful\n");
1421             }
1422         } else {
1423             printf("ERR:Could not %s scan channel list!\n",
1424                    argc ? "SET" : "GET");
1425         }
1426     } else {
1427         printf("ERR:Command sending failed!\n");
1428     }
1429     if (buffer)
1430         free(buffer);
1431     return;
1432 }
1433
1434 /**
1435  *  @brief parser for sys_cfg_rates_ext input 
1436  *
1437  *  @param argc     Number of arguments
1438  *  @param argv     Pointer to the arguments
1439  *  @param output   stores indexes for "rates, mbrate and urate"
1440  *                  arguments
1441  *
1442  *                  e.g., 
1443  *
1444  *                  "rates 0x82 4 16 22 0x30 mbrate 2 urate 16"
1445  *                  
1446  *                  will have output array as
1447  *
1448  *                          start_index end_index
1449  *                  rates       0           5
1450  *                  mbrate      6           7
1451  *                  urate       8           9
1452  *
1453  *  @return         NA
1454  *
1455  */
1456 void
1457 parse_input(int argc, char **argv, int output[3][2])
1458 {
1459     int i, j, k = 0;
1460     char *keywords[3] = { "rates", "mbrate", "urate" };
1461
1462     for (i = 0; i < 3; i++)
1463         output[i][0] = -1;
1464
1465     for (i = 0; i < argc; i++) {
1466         for (j = 0; j < 3; j++) {
1467             if (strcmp(argv[i], keywords[j]) == 0) {
1468                 output[j][1] = output[j][0] = i;
1469                 k = j;
1470                 break;
1471             }
1472         }
1473         output[k][1] += 1;
1474     }
1475 }
1476
1477 /**
1478  *  @brief Creates a sys_cfg request for setting data_rates, MCBC and
1479  *   TX data rates.
1480  *
1481  *   Usage: "sys_cfg_rates_ext  [RATES]" 
1482  *  
1483  *  @param argc     Number of arguments
1484  *  @param argv     Pointer to the arguments
1485  *  @return         N/A
1486  */
1487 void
1488 apcmd_sys_cfg_rates_ext(int argc, char *argv[])
1489 {
1490     int i, j = 0;
1491     int opt;
1492     int rflag = 0, mflag = 0, uflag = 0;
1493     char *argv_rate[14];
1494     int argc_rate = 0;
1495     char *argv_mrate[1];
1496     char *argv_urate[1];
1497     int mrate_found = UAP_FAILURE;
1498     int urate_found = UAP_FAILURE;
1499     u8 *tlv_buf = NULL;
1500     TLVBUF_TX_DATA_RATE *tlv_urate = NULL;
1501     TLVBUF_MCBC_DATA_RATE *tlv_mrate = NULL;
1502     TLVBUF_RATES *tlv_rate = NULL;
1503     u8 *buffer = NULL;
1504     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
1505     int ret = UAP_FAILURE;
1506     u16 cmd_len;
1507     int output[3][2];
1508
1509     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
1510         switch (opt) {
1511         default:
1512             print_sys_cfg_rates_ext_usage();
1513             return;
1514         }
1515     }
1516     argc -= optind;
1517     argv += optind;
1518
1519     if (argc) {
1520         /* 
1521          * SET
1522          */
1523         parse_input(argc, argv, output);
1524
1525         /* 
1526          * Rate
1527          */
1528         if ((output[0][0] != -1) && (output[0][1] > output[0][0])) {
1529             rflag = 1;
1530             i = 0;
1531             for (j = (output[0][0] + 1); j < output[0][1]; j++) {
1532                 argv_rate[i] =
1533                     (char *) malloc(sizeof(char) * (strlen(argv[j]) + 1));
1534                 strcpy(argv_rate[i], argv[j]);
1535                 argc_rate = ++i;
1536             }
1537         }
1538
1539         /* 
1540          * mrate
1541          */
1542
1543         if ((output[1][0] != -1) && (output[1][1] > output[1][0])) {
1544             if ((output[1][1] - output[1][0]) != 2) {
1545                 printf("\nERR: Invalid mrate input");
1546                 print_sys_cfg_rates_ext_usage();
1547                 goto done;
1548             }
1549             mflag = 1;
1550             argv_mrate[0] =
1551                 (char *) malloc(sizeof(char) * (strlen(argv[j]) + 1));
1552             strcpy(argv_mrate[0], argv[output[1][0] + 1]);
1553         }
1554
1555         /* 
1556          * urate
1557          */
1558         if ((output[2][0] != -1) && (output[2][1] > output[2][0])) {
1559             if ((output[2][1] - output[2][0]) != 2) {
1560                 printf("\nERR: Invalid urate input");
1561                 print_sys_cfg_rates_ext_usage();
1562                 goto done;
1563             }
1564             uflag = 1;
1565             argv_urate[0] =
1566                 (char *) malloc(sizeof(char) * (strlen(argv[j]) + 1));
1567             strcpy(argv_urate[0], argv[output[2][0] + 1]);
1568         }
1569
1570         if (!rflag && !mflag & !uflag) {
1571             printf("ERR: Invalid input\n");
1572             print_sys_cfg_rates_ext_usage();
1573             goto done;
1574         }
1575
1576         if (rflag && is_input_valid(RATE, argc_rate, argv_rate) != UAP_SUCCESS) {
1577             printf("ERR: Invalid RATE\n");
1578             print_sys_cfg_rates_ext_usage();
1579             goto done;
1580         }
1581
1582         if (mflag && is_input_valid(MCBCDATARATE, 1, argv_mrate) != UAP_SUCCESS) {
1583             printf("ERR: Invalid MCBC RATE\n");
1584             print_sys_cfg_rates_ext_usage();
1585             goto done;
1586         }
1587
1588         if (uflag && is_input_valid(TXDATARATE, 1, argv_urate) != UAP_SUCCESS) {
1589             printf("ERR: Invalid TX RATE\n");
1590             print_sys_cfg_rates_ext_usage();
1591             goto done;
1592         }
1593
1594         if (!rflag && (mflag || uflag)) {
1595             /* 
1596              * Check mrate and urate wrt old Rates
1597              */
1598             if (mflag && A2HEXDECIMAL(argv_mrate[0]) &&
1599                 is_mcbc_rate_valid(A2HEXDECIMAL(argv_mrate[0])) !=
1600                 UAP_SUCCESS) {
1601                 printf("ERR: invalid MCBC data rate.");
1602                 print_sys_cfg_rates_ext_usage();
1603                 goto done;
1604             }
1605             if (uflag && A2HEXDECIMAL(argv_urate[0]) &&
1606                 is_tx_rate_valid(A2HEXDECIMAL(argv_urate[0])) != UAP_SUCCESS) {
1607                 printf("ERR: invalid tx data rate.");
1608                 print_sys_cfg_rates_ext_usage();
1609                 goto done;
1610             }
1611         } else if (rflag && (mflag || uflag)) {
1612             /* 
1613              * Check mrate and urate wrt new Rates
1614              */
1615             for (i = 0; i < argc_rate; i++) {
1616                 /* 
1617                  * MCBC rate must be from Basic rates
1618                  */
1619                 if (mflag && !mrate_found &&
1620                     A2HEXDECIMAL(argv_rate[i]) & BASIC_RATE_SET_BIT) {
1621                     if (A2HEXDECIMAL(argv_mrate[0]) ==
1622                         (A2HEXDECIMAL(argv_rate[i]) & ~BASIC_RATE_SET_BIT)) {
1623                         mrate_found = UAP_SUCCESS;
1624                     }
1625                 }
1626                 if (uflag && !urate_found && (A2HEXDECIMAL(argv_urate[0]) ==
1627                                               ((A2HEXDECIMAL(argv_rate[i]) &
1628                                                 ~BASIC_RATE_SET_BIT)))) {
1629                     urate_found = UAP_SUCCESS;
1630                 }
1631             }
1632
1633             if (mflag && A2HEXDECIMAL(argv_mrate[0]) &&
1634                 !(mrate_found == UAP_SUCCESS)) {
1635                 printf("ERR: mrate not valid\n");
1636                 goto done;
1637             }
1638
1639             if (uflag && A2HEXDECIMAL(argv_urate[0]) &&
1640                 !(urate_found == UAP_SUCCESS)) {
1641                 printf("ERR: urate not valid\n");
1642                 goto done;
1643             }
1644         }
1645         /* post-parsing */
1646         cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE);
1647         if (rflag) {
1648             cmd_len += sizeof(TLVBUF_RATES) + argc_rate;
1649             cmd_len += sizeof(TLVBUF_MCBC_DATA_RATE);
1650             cmd_len += sizeof(TLVBUF_TX_DATA_RATE);
1651         } else {
1652             if (mflag)
1653                 cmd_len += sizeof(TLVBUF_MCBC_DATA_RATE);
1654             if (uflag)
1655                 cmd_len += sizeof(TLVBUF_TX_DATA_RATE);
1656         }
1657     } else {
1658         /* GET */
1659         cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE)
1660             + sizeof(TLVBUF_RATES) + MAX_RATES + sizeof(TLVBUF_MCBC_DATA_RATE)
1661             + sizeof(TLVBUF_TX_DATA_RATE);
1662     }
1663
1664     buffer = (u8 *) malloc(cmd_len);
1665     if (!buffer) {
1666         printf("ERR:Cannot allocate buffer for command!\n");
1667         goto done;
1668     }
1669     bzero((char *) buffer, cmd_len);
1670
1671     /* Fill the command buffer */
1672     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
1673     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
1674     cmd_buf->Size = cmd_len;
1675     cmd_buf->SeqNum = 0;
1676     cmd_buf->Result = 0;
1677     cmd_buf->Action = argc ? ACTION_SET : ACTION_GET;
1678     tlv_buf = buffer + sizeof(APCMDBUF_SYS_CONFIGURE);
1679     /* Locate headers */
1680     if (rflag || (!argc)) {
1681         tlv_rate = (TLVBUF_RATES *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
1682         tlv_rate->Tag = MRVL_RATES_TLV_ID;
1683         tlv_rate->Length = argc ? argc_rate : MAX_RATES;
1684         for (i = 0; i < argc_rate; i++) {
1685             tlv_rate->OperationalRates[i] = (u8) A2HEXDECIMAL(argv_rate[i]);
1686         }
1687         tlv_buf += tlv_rate->Length + sizeof(TLVBUF_RATES);
1688         endian_convert_tlv_header_out(tlv_rate);
1689     }
1690     if (rflag || mflag || (!argc)) {
1691         tlv_mrate = (TLVBUF_MCBC_DATA_RATE *) tlv_buf;
1692         tlv_mrate->Tag = MRVL_MCBC_DATA_RATE_TLV_ID;
1693         tlv_mrate->Length = 2;
1694         tlv_mrate->MCBCdatarate = 0;
1695         if (mflag) {
1696             tlv_mrate->MCBCdatarate = (u16) A2HEXDECIMAL(argv_mrate[0])
1697                 & ~BASIC_RATE_SET_BIT;
1698             tlv_mrate->MCBCdatarate = uap_cpu_to_le16(tlv_mrate->MCBCdatarate);
1699         }
1700         tlv_buf += sizeof(TLVBUF_MCBC_DATA_RATE);
1701         endian_convert_tlv_header_out(tlv_mrate);
1702     }
1703     if (rflag || uflag || (!argc)) {
1704         tlv_urate = (TLVBUF_TX_DATA_RATE *) tlv_buf;
1705         tlv_urate->Tag = MRVL_TX_DATA_RATE_TLV_ID;
1706         tlv_urate->Length = 2;
1707         tlv_urate->TxDataRate = 0;
1708         if (uflag) {
1709             tlv_urate->TxDataRate = (u16) A2HEXDECIMAL(argv_urate[0])
1710                 & ~BASIC_RATE_SET_BIT;
1711             tlv_urate->TxDataRate = uap_cpu_to_le16(tlv_urate->TxDataRate);
1712         }
1713         endian_convert_tlv_header_out(tlv_urate);
1714     }
1715
1716     /* Send the command */
1717     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
1718
1719     tlv_buf = buffer + sizeof(APCMDBUF_SYS_CONFIGURE);
1720
1721     if (ret == UAP_SUCCESS) {
1722         /* Verify response */
1723         if (cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) {
1724             printf("ERR:Corrupted response! CmdCode=%x\n", cmd_buf->CmdCode);
1725             goto done;
1726         }
1727         /* Print response */
1728         if (cmd_buf->Result == CMD_SUCCESS) {
1729             if (argc) {
1730                 printf("Rates setting successful\n");
1731             } else {
1732                 print_tlv((u8 *) tlv_buf,
1733                           cmd_buf->Size - sizeof(APCMDBUF_SYS_CONFIGURE) +
1734                           BUF_HEADER_SIZE);
1735             }
1736         } else {
1737             printf("ERR:Could not %s operational rates!\n",
1738                    argc ? "set" : "get");
1739             if (argc)
1740                 printf
1741                     ("operational rates only allow to set before bss start.\n");
1742         }
1743     } else {
1744         printf("ERR:Command sending failed!\n");
1745     }
1746   done:
1747     if (rflag) {
1748         for (i = 0; i < argc_rate; i++) {
1749             free(argv_rate[i]);
1750         }
1751     }
1752     if (mflag)
1753         free(argv_mrate[0]);
1754     if (uflag)
1755         free(argv_urate[0]);
1756     if (buffer)
1757         free(buffer);
1758     return;
1759 }
1760
1761 /** 
1762  *  @brief Creates a sys_cfg request for data rates
1763  *   and sends to the driver
1764  *
1765  *   Usage: "sys_cfg_rates  [RATES]"
1766  *
1767  *           RATES is provided as a set of data rates, in
1768  *           unit of 500 kilobits/s. 
1769  *           Maximum 12 rates can be provided.
1770  *
1771  *           if no RATE is provided, then it gets configured rates
1772  *
1773  *           Each rate must be separated by a space
1774  *
1775  *  @param argc     Number of arguments
1776  *  @param argv     Pointer to the arguments
1777  *  @return         N/A
1778  */
1779 void
1780 apcmd_sys_cfg_rates(int argc, char *argv[])
1781 {
1782     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
1783     TLVBUF_RATES *tlv = NULL;
1784     u8 *buffer = NULL;
1785     u16 cmd_len;
1786     int ret = UAP_FAILURE;
1787     int i = 0;
1788     int opt;
1789     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
1790         switch (opt) {
1791         default:
1792             print_sys_cfg_rates_usage();
1793             return;
1794         }
1795     }
1796     argc -= optind;
1797     argv += optind;
1798
1799     /* Check arguments */
1800     if (argc && is_input_valid(RATE, argc, argv) != UAP_SUCCESS) {
1801         print_sys_cfg_rates_usage();
1802         return;
1803     }
1804     if (argc == 0) {
1805         /* Initialize the command length */
1806         cmd_len =
1807             sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_RATES) + MAX_RATES;
1808     } else {
1809         /* Initialize the command length */
1810         cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_RATES) + argc;
1811     }
1812     /* Initialize the command buffer */
1813     buffer = (u8 *) malloc(cmd_len);
1814     if (!buffer) {
1815         printf("ERR:Cannot allocate buffer for command!\n");
1816         return;
1817     }
1818     bzero((char *) buffer, cmd_len);
1819
1820     /* Locate headers */
1821     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
1822     tlv = (TLVBUF_RATES *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
1823
1824     /* Fill the command buffer */
1825     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
1826     cmd_buf->Size = cmd_len;
1827     cmd_buf->SeqNum = 0;
1828     cmd_buf->Result = 0;
1829     tlv->Tag = MRVL_RATES_TLV_ID;
1830     if (argc == 0) {
1831         cmd_buf->Action = ACTION_GET;
1832         tlv->Length = MAX_RATES;
1833     } else {
1834         cmd_buf->Action = ACTION_SET;
1835         tlv->Length = argc;
1836         for (i = 0; i < tlv->Length; i++) {
1837             tlv->OperationalRates[i] = (u8) A2HEXDECIMAL(argv[i]);
1838         }
1839     }
1840
1841     endian_convert_tlv_header_out(tlv);
1842     /* Send the command */
1843     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
1844     endian_convert_tlv_header_in(tlv);
1845     /* Process response */
1846     if (ret == UAP_SUCCESS) {
1847         /* Verify response */
1848         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
1849             (tlv->Tag != MRVL_RATES_TLV_ID)) {
1850             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
1851                    cmd_buf->CmdCode, tlv->Tag);
1852             free(buffer);
1853             return;
1854         }
1855
1856         /* Print response */
1857         if (cmd_buf->Result == CMD_SUCCESS) {
1858             if (argc == 0) {
1859                 print_rate(tlv);
1860             } else {
1861                 printf("Rates setting successful\n");
1862             }
1863         } else {
1864             if (argc == 0) {
1865                 printf("ERR:Could not get operational rates!\n");
1866             } else {
1867                 printf("ERR:Could not set operational rates!\n");
1868             }
1869         }
1870     } else {
1871         printf("ERR:Command sending failed!\n");
1872     }
1873     if (buffer)
1874         free(buffer);
1875     return;
1876 }
1877
1878 /** 
1879  *  @brief Creates a sys_cfg request for Tx power
1880  *   and sends to the driver
1881  *
1882  *   Usage: "sys_cfg_tx_power [TX_POWER]"
1883  *           if TX_POWER is provided, a 'set' is performed
1884  *           else a 'get' is performed.
1885  *
1886  *           TX_POWER is represented in dBm
1887  *
1888  *  @param argc     Number of arguments
1889  *  @param argv     Pointer to the arguments
1890  *  @return         N/A
1891  */
1892 void
1893 apcmd_sys_cfg_tx_power(int argc, char *argv[])
1894 {
1895     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
1896     TLVBUF_TX_POWER *tlv = NULL;
1897     u8 *buffer = NULL;
1898     u16 cmd_len;
1899     int ret = UAP_FAILURE;
1900     int opt;
1901     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
1902         switch (opt) {
1903         default:
1904             print_sys_cfg_tx_power_usage();
1905             return;
1906         }
1907     }
1908     argc -= optind;
1909     argv += optind;
1910     /* Check arguments */
1911     if (argc && is_input_valid(TXPOWER, argc, argv) != UAP_SUCCESS) {
1912         print_sys_cfg_tx_power_usage();
1913         return;
1914     }
1915
1916     /* Initialize the command length */
1917     cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_TX_POWER);
1918
1919     /* Initialize the command buffer */
1920     buffer = (u8 *) malloc(cmd_len);
1921
1922     if (!buffer) {
1923         printf("ERR:Cannot allocate buffer for command!\n");
1924         return;
1925     }
1926     bzero((char *) buffer, cmd_len);
1927
1928     /* Locate headers */
1929     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
1930     tlv = (TLVBUF_TX_POWER *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
1931
1932     /* Fill the command buffer */
1933     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
1934     cmd_buf->Size = cmd_len;
1935     cmd_buf->SeqNum = 0;
1936     cmd_buf->Result = 0;
1937     tlv->Tag = MRVL_TX_POWER_TLV_ID;
1938     tlv->Length = 1;
1939     if (argc == 0) {
1940         cmd_buf->Action = ACTION_GET;
1941     } else {
1942         printf("Please check power calibration for board to see if this power\n"
1943                "setting is within calibrated range. Firmware may over-ride\n "
1944                "this setting if it is not within calibrated range, which can\n"
1945                "vary from board to board.\n");
1946         cmd_buf->Action = ACTION_SET;
1947         tlv->TxPower_dBm = (u8) atoi(argv[0]);
1948     }
1949     endian_convert_tlv_header_out(tlv);
1950     /* Send the command */
1951     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
1952     endian_convert_tlv_header_in(tlv);
1953     /* Process response */
1954     if (ret == UAP_SUCCESS) {
1955         /* Verify response */
1956         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
1957             (tlv->Tag != MRVL_TX_POWER_TLV_ID)) {
1958             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
1959                    cmd_buf->CmdCode, tlv->Tag);
1960             free(buffer);
1961             return;
1962         }
1963         /* Print response */
1964         if (cmd_buf->Result == CMD_SUCCESS) {
1965             if (argc == 0) {
1966                 printf("Tx power = %d dBm\n", tlv->TxPower_dBm);
1967             } else {
1968                 printf("Tx power setting successful\n");
1969             }
1970         } else {
1971             if (argc == 0) {
1972                 printf("ERR:Could not get tx power!\n");
1973             } else {
1974                 printf("ERR:Could not set tx power!\n");
1975             }
1976         }
1977     } else {
1978         printf("ERR:Command sending failed!\n");
1979     }
1980     if (buffer)
1981         free(buffer);
1982     return;
1983 }
1984
1985 /** 
1986  *  @brief Creates a sys_cfg request for SSID broadcast
1987  *   and sends to the driver
1988  *
1989  *   Usage: "sys_cfg_bcast_ssid_ctl [0|1]"
1990  *
1991  *   Options: 0     - Disable SSID broadcast
1992  *            1     - Enable SSID broadcast
1993  *            empty - Get current SSID broadcast setting
1994  *
1995  *  @param argc     Number of arguments
1996  *  @param argv     Pointer to the arguments
1997  *  @return         N/A
1998  */
1999 void
2000 apcmd_sys_cfg_bcast_ssid_ctl(int argc, char *argv[])
2001 {
2002     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
2003     TLVBUF_BCAST_SSID_CTL *tlv = NULL;
2004     u8 *buffer = NULL;
2005     u16 cmd_len;
2006     int ret = UAP_FAILURE;
2007     int opt;
2008
2009     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
2010         switch (opt) {
2011         default:
2012             print_sys_cfg_bcast_ssid_ctl_usage();
2013             return;
2014         }
2015     }
2016     argc -= optind;
2017     argv += optind;
2018     /* Check arguments */
2019     if (argc && is_input_valid(BROADCASTSSID, argc, argv) != UAP_SUCCESS) {
2020         print_sys_cfg_bcast_ssid_ctl_usage();
2021         return;
2022     }
2023     /* Initialize the command length */
2024     cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_BCAST_SSID_CTL);
2025
2026     /* Initialize the command buffer */
2027     buffer = (u8 *) malloc(cmd_len);
2028     if (!buffer) {
2029         printf("ERR:Cannot allocate buffer for command!\n");
2030         return;
2031     }
2032     bzero((char *) buffer, cmd_len);
2033
2034     /* Locate headers */
2035     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2036     tlv = (TLVBUF_BCAST_SSID_CTL *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
2037
2038     /* Fill the command buffer */
2039     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
2040     cmd_buf->Size = cmd_len;
2041     cmd_buf->SeqNum = 0;
2042     cmd_buf->Result = 0;
2043     tlv->Tag = MRVL_BCAST_SSID_CTL_TLV_ID;
2044     tlv->Length = 1;
2045     if (argc == 0) {
2046         cmd_buf->Action = ACTION_GET;
2047     } else {
2048         cmd_buf->Action = ACTION_SET;
2049         tlv->BcastSsidCtl = (u8) atoi(argv[0]);
2050     }
2051     endian_convert_tlv_header_out(tlv);
2052     /* Send the command */
2053     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
2054     endian_convert_tlv_header_in(tlv);
2055     /* Process response */
2056     if (ret == UAP_SUCCESS) {
2057         /* Verify response */
2058         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
2059             (tlv->Tag != MRVL_BCAST_SSID_CTL_TLV_ID)) {
2060             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
2061                    cmd_buf->CmdCode, tlv->Tag);
2062             free(buffer);
2063             return;
2064         }
2065         /* Print response */
2066         if (cmd_buf->Result == CMD_SUCCESS) {
2067             if (argc == 0) {
2068                 printf("SSID broadcast is %s\n",
2069                        (tlv->BcastSsidCtl == 1) ? "enabled" : "disabled");
2070             } else {
2071                 printf("SSID broadcast setting successful\n");
2072             }
2073         } else {
2074             if (argc == 0) {
2075                 printf("ERR:Could not get SSID broadcast!\n");
2076             } else {
2077                 printf("ERR:Could not set SSID broadcast!\n");
2078             }
2079         }
2080     } else {
2081         printf("ERR:Command sending failed!\n");
2082     }
2083     if (buffer)
2084         free(buffer);
2085     return;
2086 }
2087
2088 /** 
2089  *  @brief Creates a sys_cfg request for preamble settings
2090  *   and sends to the driver
2091  *
2092  *   Usage: "sys_cfg_preamble_ctl"
2093  *
2094  *  @param argc     Number of arguments
2095  *  @param argv     Pointer to the arguments
2096  *  @return         N/A
2097  */
2098 void
2099 apcmd_sys_cfg_preamble_ctl(int argc, char *argv[])
2100 {
2101     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
2102     TLVBUF_PREAMBLE_CTL *tlv = NULL;
2103     u8 *buffer = NULL;
2104     u16 cmd_len;
2105     int ret = UAP_FAILURE;
2106     int opt;
2107     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
2108         switch (opt) {
2109         default:
2110             print_sys_cfg_preamble_ctl_usage();
2111             return;
2112         }
2113     }
2114     argc -= optind;
2115     argv += optind;
2116
2117     /* Check arguments */
2118     if (argc != 0) {
2119         printf("ERR:Too many arguments.\n");
2120         print_sys_cfg_preamble_ctl_usage();
2121         return;
2122     }
2123     /* Initialize the command length */
2124     cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_PREAMBLE_CTL);
2125
2126     /* Initialize the command buffer */
2127     buffer = (u8 *) malloc(cmd_len);
2128
2129     if (!buffer) {
2130         printf("ERR:Cannot allocate buffer for command!\n");
2131         return;
2132     }
2133     bzero((char *) buffer, cmd_len);
2134
2135     /* Locate headers */
2136     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2137     tlv = (TLVBUF_PREAMBLE_CTL *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
2138
2139     /* Fill the command buffer */
2140     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
2141     cmd_buf->Size = cmd_len;
2142     cmd_buf->SeqNum = 0;
2143     cmd_buf->Result = 0;
2144     tlv->Tag = MRVL_PREAMBLE_CTL_TLV_ID;
2145     tlv->Length = 1;
2146     cmd_buf->Action = ACTION_GET;
2147     endian_convert_tlv_header_out(tlv);
2148     /* Send the command */
2149     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
2150     endian_convert_tlv_header_in(tlv);
2151     /* Process response */
2152     if (ret == UAP_SUCCESS) {
2153         /* Verify response */
2154         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
2155             (tlv->Tag != MRVL_PREAMBLE_CTL_TLV_ID)) {
2156             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
2157                    cmd_buf->CmdCode, tlv->Tag);
2158             free(buffer);
2159             return;
2160         }
2161         /* Print response */
2162         if (cmd_buf->Result == CMD_SUCCESS)
2163             printf("Preamble type is %s\n", (tlv->PreambleType == 0) ?
2164                    "auto" : ((tlv->PreambleType == 1) ? "short" : "long"));
2165         else
2166             printf("ERR:Could not get preamble type!\n");
2167
2168     } else {
2169         printf("ERR:Command sending failed!\n");
2170     }
2171     if (buffer)
2172         free(buffer);
2173     return;
2174 }
2175
2176 /** 
2177  *  @brief Creates a sys_cfg request for antenna configuration
2178  *   and sends to the driver
2179  *
2180  *   Usage: "sys_cfg_antenna_ctl <ANTENNA> [MODE]"
2181  *
2182  *   Options: ANTENNA : 0 - Rx antenna
2183  *                      1 - Tx antenna
2184  *            MODE    : 0       - Antenna A
2185  *                      1       - Antenna B
2186  *                      empty   - Get current antenna settings
2187  *
2188  *  @param argc     Number of arguments
2189  *  @param argv     Pointer to the arguments
2190  *  @return         N/A
2191  */
2192 void
2193 apcmd_sys_cfg_antenna_ctl(int argc, char *argv[])
2194 {
2195     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
2196     TLVBUF_ANTENNA_CTL *tlv = NULL;
2197     u8 *buffer = NULL;
2198     u16 cmd_len;
2199     int ret = UAP_FAILURE;
2200     int opt;
2201     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
2202         switch (opt) {
2203         default:
2204             print_sys_cfg_antenna_ctl_usage();
2205             return;
2206         }
2207     }
2208     argc -= optind;
2209     argv += optind;
2210     /* Check arguments */
2211     if ((argc == 0) || (argc > 2)) {
2212         printf("ERR:wrong arguments.\n");
2213         print_sys_cfg_antenna_ctl_usage();
2214         return;
2215     } else if (argc == 1) {
2216         if ((ISDIGIT(argv[0]) == 0) || (atoi(argv[0]) < 0) ||
2217             (atoi(argv[0]) > 1)) {
2218             printf
2219                 ("ERR:Illegal ANTENNA parameter %s. Must be either '0' or '1'.\n",
2220                  argv[0]);
2221             print_sys_cfg_antenna_ctl_usage();
2222             return;
2223         }
2224     } else {
2225         if ((ISDIGIT(argv[0]) == 0) || (atoi(argv[0]) < 0) ||
2226             (atoi(argv[0]) > 1)) {
2227             printf
2228                 ("ERR:Illegal ANTENNA parameter %s. Must be either '0' or '1'.\n",
2229                  argv[0]);
2230             print_sys_cfg_antenna_ctl_usage();
2231             return;
2232         }
2233         if ((ISDIGIT(argv[1]) == 0) || (atoi(argv[1]) < 0) ||
2234             (atoi(argv[1]) > 1)) {
2235             printf
2236                 ("ERR:Illegal MODE parameter %s. Must be either '0' or '1'.\n",
2237                  argv[1]);
2238             print_sys_cfg_antenna_ctl_usage();
2239             return;
2240         }
2241     }
2242
2243     /* Initialize the command length */
2244     cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_ANTENNA_CTL);
2245
2246     /* Initialize the command buffer */
2247     buffer = (u8 *) malloc(cmd_len);
2248
2249     if (!buffer) {
2250         printf("ERR:Cannot allocate buffer for command!\n");
2251         return;
2252     }
2253     bzero((char *) buffer, cmd_len);
2254     /* Locate headers */
2255     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2256     tlv = (TLVBUF_ANTENNA_CTL *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
2257
2258     /* Fill the command buffer */
2259     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
2260     cmd_buf->Size = cmd_len;
2261     cmd_buf->SeqNum = 0;
2262     cmd_buf->Result = 0;
2263     tlv->Tag = MRVL_ANTENNA_CTL_TLV_ID;
2264     tlv->Length = 2;
2265     tlv->WhichAntenna = (u8) atoi(argv[0]);
2266     if (argc == 1) {
2267         cmd_buf->Action = ACTION_GET;
2268     } else {
2269         cmd_buf->Action = ACTION_SET;
2270         tlv->AntennaMode = (u8) atoi(argv[1]);
2271     }
2272     endian_convert_tlv_header_out(tlv);
2273     /* Send the command */
2274     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
2275     endian_convert_tlv_header_in(tlv);
2276     /* Process response */
2277     if (ret == UAP_SUCCESS) {
2278         /* Verify response */
2279         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
2280             (tlv->Tag != MRVL_ANTENNA_CTL_TLV_ID)) {
2281             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
2282                    cmd_buf->CmdCode, tlv->Tag);
2283             free(buffer);
2284             return;
2285         }
2286         /* Print response */
2287         if (cmd_buf->Result == CMD_SUCCESS) {
2288             if (argc == 1) {
2289                 printf("%s antenna: %s\n", (tlv->WhichAntenna == 0) ?
2290                        "Rx" : "Tx", (tlv->AntennaMode == 0) ? "A" : "B");
2291             } else {
2292                 printf("Antenna setting successful\n");
2293             }
2294         } else {
2295             if (argc == 1) {
2296                 printf("ERR:Could not get antenna!\n");
2297             } else {
2298                 printf("ERR:Could not set antenna!\n");
2299             }
2300         }
2301     } else {
2302         printf("ERR:Command sending failed!\n");
2303     }
2304     if (buffer)
2305         free(buffer);
2306     return;
2307 }
2308
2309 /** 
2310  *  @brief Creates a sys_cfg request for RTS threshold
2311  *   and sends to the driver
2312  *
2313  *   Usage: "sys_cfg_rts_threshold [RTS_THRESHOLD]"
2314  *           if RTS_THRESHOLD is provided, a 'set' is performed
2315  *           else a 'get' is performed
2316  *
2317  *  @param argc     Number of arguments
2318  *  @param argv     Pointer to the arguments
2319  *  @return         N/A
2320  */
2321 void
2322 apcmd_sys_cfg_rts_threshold(int argc, char *argv[])
2323 {
2324     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
2325     TLVBUF_RTS_THRESHOLD *tlv = NULL;
2326     u8 *buffer = NULL;
2327     u16 cmd_len;
2328     int ret = UAP_FAILURE;
2329     int opt;
2330     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
2331         switch (opt) {
2332         default:
2333             print_sys_cfg_rts_threshold_usage();
2334             return;
2335         }
2336     }
2337     argc -= optind;
2338     argv += optind;
2339     /* Check arguments */
2340     if (argc && (is_input_valid(RTSTHRESH, argc, argv) != UAP_SUCCESS)) {
2341         print_sys_cfg_rts_threshold_usage();
2342         return;
2343     }
2344     /* Initialize the command length */
2345     cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_RTS_THRESHOLD);
2346
2347     /* Initialize the command buffer */
2348     buffer = (u8 *) malloc(cmd_len);
2349
2350     if (!buffer) {
2351         printf("ERR:Cannot allocate buffer for command!\n");
2352         return;
2353     }
2354     bzero((char *) buffer, cmd_len);
2355
2356     /* Locate headers */
2357     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2358     tlv = (TLVBUF_RTS_THRESHOLD *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
2359
2360     /* Fill the command buffer */
2361     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
2362     cmd_buf->Size = cmd_len;
2363     cmd_buf->SeqNum = 0;
2364     cmd_buf->Result = 0;
2365     tlv->Tag = MRVL_RTS_THRESHOLD_TLV_ID;
2366     tlv->Length = 2;
2367     if (argc == 0) {
2368         cmd_buf->Action = ACTION_GET;
2369     } else {
2370         cmd_buf->Action = ACTION_SET;
2371         tlv->RtsThreshold = (u16) atoi(argv[0]);
2372     }
2373     endian_convert_tlv_header_out(tlv);
2374     tlv->RtsThreshold = uap_cpu_to_le16(tlv->RtsThreshold);
2375     /* Send the command */
2376     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
2377     endian_convert_tlv_header_in(tlv);
2378     tlv->RtsThreshold = uap_le16_to_cpu(tlv->RtsThreshold);
2379     /* Process response */
2380     if (ret == UAP_SUCCESS) {
2381         /* Verify response */
2382         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
2383             (tlv->Tag != MRVL_RTS_THRESHOLD_TLV_ID)) {
2384             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
2385                    cmd_buf->CmdCode, tlv->Tag);
2386             free(buffer);
2387             return;
2388         }
2389         /* Print response */
2390         if (cmd_buf->Result == CMD_SUCCESS) {
2391             if (argc == 0) {
2392                 printf("RTS threshold = %d\n", tlv->RtsThreshold);
2393             } else {
2394                 printf("RTS threshold setting successful\n");
2395             }
2396         } else {
2397             if (argc == 0) {
2398                 printf("ERR:Could not get RTS threshold!\n");
2399             } else {
2400                 printf("ERR:Could not set RTS threshold!\n");
2401             }
2402         }
2403     } else {
2404         printf("ERR:Command sending failed!\n");
2405     }
2406     if (buffer)
2407         free(buffer);
2408     return;
2409 }
2410
2411 /** 
2412  *  @brief Creates a sys_cfg request for Fragmentation threshold
2413  *   and sends to the driver
2414  *
2415  *   Usage: "sys_cfg_frag_threshold [FRAG_THRESHOLD]"
2416  *           if FRAG_THRESHOLD is provided, a 'set' is performed
2417  *           else a 'get' is performed
2418  *
2419  *  @param argc     Number of arguments
2420  *  @param argv     Pointer to the arguments
2421  *  @return         N/A
2422  */
2423 void
2424 apcmd_sys_cfg_frag_threshold(int argc, char *argv[])
2425 {
2426     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
2427     TLVBUF_FRAG_THRESHOLD *tlv = NULL;
2428     u8 *buffer = NULL;
2429     u16 cmd_len;
2430     int ret = UAP_FAILURE;
2431     int opt;
2432     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
2433         switch (opt) {
2434         default:
2435             print_sys_cfg_frag_threshold_usage();
2436             return;
2437         }
2438     }
2439     argc -= optind;
2440     argv += optind;
2441     /* Check arguments */
2442     if (argc && (is_input_valid(FRAGTHRESH, argc, argv) != UAP_SUCCESS)) {
2443         print_sys_cfg_frag_threshold_usage();
2444         return;
2445     }
2446     /* Initialize the command length */
2447     cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_FRAG_THRESHOLD);
2448
2449     /* Initialize the command buffer */
2450     buffer = (u8 *) malloc(cmd_len);
2451
2452     if (!buffer) {
2453         printf("ERR:Cannot allocate buffer for command!\n");
2454         return;
2455     }
2456     bzero((char *) buffer, cmd_len);
2457
2458     /* Locate headers */
2459     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2460     tlv = (TLVBUF_FRAG_THRESHOLD *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
2461
2462     /* Fill the command buffer */
2463     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
2464     cmd_buf->Size = cmd_len;
2465     cmd_buf->SeqNum = 0;
2466     cmd_buf->Result = 0;
2467     tlv->Tag = MRVL_FRAG_THRESHOLD_TLV_ID;
2468     tlv->Length = 2;
2469     if (argc == 0) {
2470         cmd_buf->Action = ACTION_GET;
2471     } else {
2472         cmd_buf->Action = ACTION_SET;
2473         tlv->FragThreshold = (u16) atoi(argv[0]);
2474     }
2475     endian_convert_tlv_header_out(tlv);
2476     tlv->FragThreshold = uap_cpu_to_le16(tlv->FragThreshold);
2477     /* Send the command */
2478     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
2479     endian_convert_tlv_header_in(tlv);
2480     tlv->FragThreshold = uap_le16_to_cpu(tlv->FragThreshold);
2481
2482     /* Process response */
2483     if (ret == UAP_SUCCESS) {
2484         /* Verify response */
2485         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
2486             (tlv->Tag != MRVL_FRAG_THRESHOLD_TLV_ID)) {
2487             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
2488                    cmd_buf->CmdCode, tlv->Tag);
2489             free(buffer);
2490             return;
2491         }
2492         /* Print response */
2493         if (cmd_buf->Result == CMD_SUCCESS) {
2494             if (argc == 0) {
2495                 printf("Fragmentation threshold = %d\n", tlv->FragThreshold);
2496             } else {
2497                 printf("Fragmentation threshold setting successful\n");
2498             }
2499         } else {
2500             if (argc == 1) {
2501                 printf("ERR:Could not get Fragmentation threshold!\n");
2502             } else {
2503                 printf("ERR:Could not set Fragmentation threshold!\n");
2504             }
2505         }
2506     } else {
2507         printf("ERR:Command sending failed!\n");
2508     }
2509     if (buffer)
2510         free(buffer);
2511     return;
2512 }
2513
2514 /** 
2515  *  @brief Creates a sys_cfg request for radio settings
2516  *   and sends to the driver
2517  *
2518  *   Usage: "sys_cfg_radio_ctl [0|1]"
2519  *
2520  *   Options: 0     - Turn radio on
2521  *            1     - Turn radio off
2522  *            empty - Get current radio setting
2523  *
2524  *  @param argc     Number of arguments
2525  *  @param argv     Pointer to the arguments
2526  *  @return         N/A
2527  */
2528 void
2529 apcmd_sys_cfg_radio_ctl(int argc, char *argv[])
2530 {
2531     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
2532     TLVBUF_RADIO_CTL *tlv = NULL;
2533     u8 *buffer = NULL;
2534     u16 cmd_len;
2535     int ret = UAP_FAILURE;
2536     int opt;
2537     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
2538         switch (opt) {
2539         default:
2540             print_sys_cfg_radio_ctl_usage();
2541             return;
2542         }
2543     }
2544     argc -= optind;
2545     argv += optind;
2546     /* Check arguments */
2547     if (argc && (is_input_valid(RADIOCONTROL, argc, argv) != UAP_SUCCESS)) {
2548         print_sys_cfg_radio_ctl_usage();
2549         return;
2550     }
2551     /* Initialize the command length */
2552     cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_RADIO_CTL);
2553
2554     /* Initialize the command buffer */
2555     buffer = (u8 *) malloc(cmd_len);
2556     if (!buffer) {
2557         printf("ERR:Cannot allocate buffer for command!\n");
2558         return;
2559     }
2560     bzero((char *) buffer, cmd_len);
2561
2562     /* Locate headers */
2563     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2564     tlv = (TLVBUF_RADIO_CTL *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
2565
2566     /* Fill the command buffer */
2567     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
2568     cmd_buf->Size = cmd_len;
2569     cmd_buf->SeqNum = 0;
2570     cmd_buf->Result = 0;
2571     tlv->Tag = MRVL_RADIO_CTL_TLV_ID;
2572     tlv->Length = 1;
2573     if (argc == 0) {
2574         cmd_buf->Action = ACTION_GET;
2575     } else {
2576         cmd_buf->Action = ACTION_SET;
2577         tlv->RadioCtl = (u8) atoi(argv[0]);
2578     }
2579     endian_convert_tlv_header_out(tlv);
2580     /* Send the command */
2581     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
2582     endian_convert_tlv_header_in(tlv);
2583     /* Process response */
2584     if (ret == UAP_SUCCESS) {
2585         /* Verify response */
2586         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
2587             (tlv->Tag != MRVL_RADIO_CTL_TLV_ID)) {
2588             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
2589                    cmd_buf->CmdCode, tlv->Tag);
2590             free(buffer);
2591             return;
2592         }
2593         /* Print response */
2594         if (cmd_buf->Result == CMD_SUCCESS) {
2595             if (argc == 0) {
2596                 printf("Radio is %s\n", (tlv->RadioCtl == 0) ? "on" : "off");
2597             } else {
2598                 printf("Radio setting successful\n");
2599             }
2600         } else {
2601             if (argc == 0) {
2602                 printf("ERR:Could not get radio status!\n");
2603             } else {
2604                 printf("ERR:Could not set radio status!\n");
2605             }
2606         }
2607     } else {
2608         printf("ERR:Command sending failed!\n");
2609     }
2610     if (buffer)
2611         free(buffer);
2612     return;
2613 }
2614
2615 /** 
2616  *  @brief Creates a sys_cfg request for RSN replay protection
2617  *   and sends to the driver
2618  *
2619  *   Usage: "sys_cfg_rsn_replay_prot [0|1]"
2620  *
2621  *   Options: 0     - Disable RSN replay protection
2622  *            1     - Enable  RSN replay protection
2623  *            empty - Get current RSN replay protection setting
2624  *
2625  *  @param argc     Number of arguments
2626  *  @param argv     Pointer to the arguments
2627  *  @return         N/A
2628  */
2629 void
2630 apcmd_sys_cfg_rsn_replay_prot(int argc, char *argv[])
2631 {
2632     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
2633     tlvbuf_rsn_replay_prot *tlv = NULL;
2634     u8 *buffer = NULL;
2635     u16 cmd_len;
2636     int ret = UAP_FAILURE;
2637     int opt;
2638
2639     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
2640         switch (opt) {
2641         default:
2642             print_sys_cfg_rsn_replay_prot_usage();
2643             return;
2644         }
2645     }
2646     argc -= optind;
2647     argv += optind;
2648     /* Check arguments */
2649     if (argc && is_input_valid(RSNREPLAYPROT, argc, argv) != UAP_SUCCESS) {
2650         print_sys_cfg_rsn_replay_prot_usage();
2651         return;
2652     }
2653     /* Initialize the command length */
2654     cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(tlvbuf_rsn_replay_prot);
2655
2656     /* Initialize the command buffer */
2657     buffer = (u8 *) malloc(cmd_len);
2658     if (!buffer) {
2659         printf("ERR:Cannot allocate buffer for command!\n");
2660         return;
2661     }
2662     bzero((char *) buffer, cmd_len);
2663
2664     /* Locate headers */
2665     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2666     tlv = (tlvbuf_rsn_replay_prot *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
2667
2668     /* Fill the command buffer */
2669     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
2670     cmd_buf->Size = cmd_len;
2671     cmd_buf->SeqNum = 0;
2672     cmd_buf->Result = 0;
2673     tlv->Tag = MRVL_RSN_REPLAY_PROT_TLV_ID;
2674     tlv->Length = 1;
2675     if (argc == 0) {
2676         cmd_buf->Action = ACTION_GET;
2677     } else {
2678         cmd_buf->Action = ACTION_SET;
2679         tlv->rsn_replay_prot = (u8) atoi(argv[0]);
2680     }
2681     endian_convert_tlv_header_out(tlv);
2682     /* Send the command */
2683     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
2684     endian_convert_tlv_header_in(tlv);
2685     /* Process response */
2686     if (ret == UAP_SUCCESS) {
2687         /* Verify response */
2688         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
2689             (tlv->Tag != MRVL_RSN_REPLAY_PROT_TLV_ID)) {
2690             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
2691                    cmd_buf->CmdCode, tlv->Tag);
2692             free(buffer);
2693             return;
2694         }
2695         /* Print response */
2696         if (cmd_buf->Result == CMD_SUCCESS) {
2697             if (argc == 0) {
2698                 printf("RSN replay protection is %s\n",
2699                        (tlv->rsn_replay_prot == 1) ? "enabled" : "disabled");
2700             } else {
2701                 printf("RSN replay protection setting successful\n");
2702             }
2703         } else {
2704             if (argc == 0) {
2705                 printf("ERR:Could not get RSN replay protection !\n");
2706             } else {
2707                 printf("ERR:Could not set RSN replay protection !\n");
2708             }
2709         }
2710     } else {
2711         printf("ERR:Command sending failed!\n");
2712     }
2713     if (buffer)
2714         free(buffer);
2715     return;
2716 }
2717
2718 /** 
2719  *  @brief Creates a sys_cfg request for MCBC data rates
2720  *   and sends to the driver
2721  *
2722  *   Usage: "sys_cfg_mcbc_data_rate [MCBC_DATA_RATE]"
2723  *
2724  *   Options: 0     - Auto rate
2725  *            >0    - Set specified MCBC data rate
2726  *            empty - Get current MCBC data rate
2727  *
2728  *           MCBC_DATA_RATE is represented in units of 500 kbps
2729  *
2730  *  @param argc     Number of arguments
2731  *  @param argv     Pointer to the arguments
2732  *  @return         N/A
2733  */
2734 void
2735 apcmd_sys_cfg_mcbc_data_rate(int argc, char *argv[])
2736 {
2737     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
2738     TLVBUF_MCBC_DATA_RATE *tlv = NULL;
2739     u8 *buffer = NULL;
2740     u16 cmd_len;
2741     int ret = UAP_FAILURE;
2742     int opt;
2743     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
2744         switch (opt) {
2745         default:
2746             print_sys_cfg_mcbc_data_rates_usage();
2747             return;
2748         }
2749     }
2750     argc -= optind;
2751     argv += optind;
2752
2753     /* Check arguments */
2754     if (argc) {
2755         if (is_input_valid(MCBCDATARATE, argc, argv) != UAP_SUCCESS) {
2756             printf("ERR: Invalid input\n");
2757             print_sys_cfg_mcbc_data_rates_usage();
2758             return;
2759         }
2760         if ((A2HEXDECIMAL(argv[0]) != 0) &&
2761             (is_mcbc_rate_valid(A2HEXDECIMAL(argv[0])) != UAP_SUCCESS)) {
2762             printf("ERR: invalid MCBC data rate.");
2763             print_sys_cfg_mcbc_data_rates_usage();
2764             return;
2765         }
2766     }
2767
2768     /* Initialize the command length */
2769     cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_MCBC_DATA_RATE);
2770
2771     /* Initialize the command buffer */
2772     buffer = (u8 *) malloc(cmd_len);
2773
2774     if (!buffer) {
2775         printf("ERR:Cannot allocate buffer for command!\n");
2776         return;
2777     }
2778     bzero((char *) buffer, cmd_len);
2779
2780     /* Locate headers */
2781     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2782     tlv = (TLVBUF_MCBC_DATA_RATE *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
2783
2784     /* Fill the command buffer */
2785     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
2786     cmd_buf->Size = cmd_len;
2787     cmd_buf->SeqNum = 0;
2788     cmd_buf->Result = 0;
2789     tlv->Tag = MRVL_MCBC_DATA_RATE_TLV_ID;
2790     tlv->Length = 2;
2791     if (argc == 0) {
2792         cmd_buf->Action = ACTION_GET;
2793     } else {
2794         cmd_buf->Action = ACTION_SET;
2795         tlv->MCBCdatarate = (u16) A2HEXDECIMAL(argv[0]);
2796     }
2797     endian_convert_tlv_header_out(tlv);
2798     tlv->MCBCdatarate = uap_cpu_to_le16(tlv->MCBCdatarate);
2799
2800     /* Send the command */
2801     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
2802     endian_convert_tlv_header_in(tlv);
2803     tlv->MCBCdatarate = uap_le16_to_cpu(tlv->MCBCdatarate);
2804
2805     /* Process response */
2806     if (ret == UAP_SUCCESS) {
2807         /* Verify response */
2808         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
2809             (tlv->Tag != MRVL_MCBC_DATA_RATE_TLV_ID)) {
2810             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
2811                    cmd_buf->CmdCode, tlv->Tag);
2812             free(buffer);
2813             return;
2814         }
2815         /* Print response */
2816         if (cmd_buf->Result == CMD_SUCCESS) {
2817             if (argc == 0) {
2818                 if (tlv->MCBCdatarate == 0) {
2819                     printf("MCBC data rate is auto\n");
2820                 } else {
2821                     printf("MCBC data rate = 0x%x\n", tlv->MCBCdatarate);
2822                 }
2823             } else {
2824                 printf("MCBC data rate setting successful\n");
2825             }
2826         } else {
2827             if (argc == 0) {
2828                 printf("ERR:Could not get MCBC data rate!\n");
2829             } else {
2830                 printf("ERR:Could not set MCBC data rate!\n");
2831             }
2832         }
2833     } else {
2834         printf("ERR:Command sending failed!\n");
2835     }
2836     if (buffer)
2837         free(buffer);
2838     return;
2839 }
2840
2841 /** 
2842  *  @brief Creates a sys_cfg request for Tx data rates
2843  *   and sends to the driver
2844  *
2845  *   Usage: "sys_cfg_tx_data_rate [TX_DATA_RATE]"
2846  *
2847  *   Options: 0     - Auto rate
2848  *            >0    - Set specified data rate
2849  *            empty - Get current data rate
2850  *
2851  *           TX_DATA_RATE is represented in units of 500 kbps
2852  *
2853  *  @param argc     Number of arguments
2854  *  @param argv     Pointer to the arguments
2855  *  @return         N/A
2856  */
2857 void
2858 apcmd_sys_cfg_tx_data_rate(int argc, char *argv[])
2859 {
2860     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
2861     TLVBUF_TX_DATA_RATE *tlv = NULL;
2862     u8 *buffer = NULL;
2863     u16 cmd_len;
2864     int ret = UAP_FAILURE;
2865     int opt;
2866     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
2867         switch (opt) {
2868         default:
2869             print_sys_cfg_tx_data_rates_usage();
2870             return;
2871         }
2872     }
2873     argc -= optind;
2874     argv += optind;
2875
2876     /* Check arguments */
2877     if (argc) {
2878         if (is_input_valid(TXDATARATE, argc, argv) != UAP_SUCCESS) {
2879             printf("ERR: Invalid input\n");
2880             print_sys_cfg_tx_data_rates_usage();
2881             return;
2882         } else if ((A2HEXDECIMAL(argv[0]) != 0) &&
2883                    (is_tx_rate_valid(A2HEXDECIMAL(argv[0])) != UAP_SUCCESS)) {
2884             printf("ERR: invalid tx data rate.");
2885             print_sys_cfg_tx_data_rates_usage();
2886             return;
2887         }
2888     }
2889
2890     /* Initialize the command length */
2891     cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_TX_DATA_RATE);
2892
2893     /* Initialize the command buffer */
2894     buffer = (u8 *) malloc(cmd_len);
2895
2896     if (!buffer) {
2897         printf("ERR:Cannot allocate buffer for command!\n");
2898         return;
2899     }
2900     bzero((char *) buffer, cmd_len);
2901
2902     /* Locate headers */
2903     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
2904     tlv = (TLVBUF_TX_DATA_RATE *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
2905
2906     /* Fill the command buffer */
2907     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
2908     cmd_buf->Size = cmd_len;
2909     cmd_buf->SeqNum = 0;
2910     cmd_buf->Result = 0;
2911     tlv->Tag = MRVL_TX_DATA_RATE_TLV_ID;
2912     tlv->Length = 2;
2913     if (argc == 0) {
2914         cmd_buf->Action = ACTION_GET;
2915     } else {
2916         cmd_buf->Action = ACTION_SET;
2917         tlv->TxDataRate = (u16) A2HEXDECIMAL(argv[0]);
2918     }
2919     endian_convert_tlv_header_out(tlv);
2920     tlv->TxDataRate = uap_cpu_to_le16(tlv->TxDataRate);
2921
2922     /* Send the command */
2923     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
2924     endian_convert_tlv_header_in(tlv);
2925     tlv->TxDataRate = uap_le16_to_cpu(tlv->TxDataRate);
2926
2927     /* Process response */
2928     if (ret == UAP_SUCCESS) {
2929         /* Verify response */
2930         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
2931             (tlv->Tag != MRVL_TX_DATA_RATE_TLV_ID)) {
2932             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
2933                    cmd_buf->CmdCode, tlv->Tag);
2934             free(buffer);
2935             return;
2936         }
2937         /* Print response */
2938         if (cmd_buf->Result == CMD_SUCCESS) {
2939             if (argc == 0) {
2940                 if (tlv->TxDataRate == 0) {
2941                     printf("Tx data rate is auto\n");
2942                 } else {
2943                     printf("Tx data rate = 0x%x\n", tlv->TxDataRate);
2944                 }
2945             } else {
2946                 printf("Tx data rate setting successful\n");
2947             }
2948         } else {
2949             if (argc == 0) {
2950                 printf("ERR:Could not get tx data rate!\n");
2951             } else {
2952                 printf("ERR:Could not set tx data rate!\n");
2953             }
2954         }
2955     } else {
2956         printf("ERR:Command sending failed!\n");
2957     }
2958     if (buffer)
2959         free(buffer);
2960     return;
2961 }
2962
2963 /** 
2964  *  @brief Creates a sys_cfg request for packet forwarding
2965  *   and sends to the driver
2966  *
2967  *   Usage: "sys_cfg_pkt_fwd_ctl [0|1]"
2968  *
2969  *   Options: 0     - Forward all packets to the host
2970  *            1     - Firmware handles intra-BSS packets
2971  *            empty - Get current packet forwarding setting
2972  *
2973  *  @param argc     Number of arguments
2974  *  @param argv     Pointer to the arguments
2975  *  @return         N/A
2976  */
2977 void
2978 apcmd_sys_cfg_pkt_fwd_ctl(int argc, char *argv[])
2979 {
2980     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
2981     TLVBUF_PKT_FWD_CTL *tlv = NULL;
2982     u8 *buffer = NULL;
2983     u16 cmd_len;
2984     int ret = UAP_FAILURE;
2985     int opt;
2986     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
2987         switch (opt) {
2988         default:
2989             print_sys_cfg_pkt_fwd_ctl_usage();
2990             return;
2991         }
2992     }
2993     argc -= optind;
2994     argv += optind;
2995     /* Check arguments */
2996     if (argc && (is_input_valid(PKTFWD, argc, argv) != UAP_SUCCESS)) {
2997         print_sys_cfg_pkt_fwd_ctl_usage();
2998         return;
2999     }
3000     /* Initialize the command length */
3001     cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_PKT_FWD_CTL);
3002     /* Initialize the command buffer */
3003     buffer = (u8 *) malloc(cmd_len);
3004
3005     if (!buffer) {
3006         printf("ERR:Cannot allocate buffer for command!\n");
3007         return;
3008     }
3009     bzero((char *) buffer, cmd_len);
3010
3011     /* Locate headers */
3012     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
3013     tlv = (TLVBUF_PKT_FWD_CTL *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
3014
3015     /* Fill the command buffer */
3016     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
3017     cmd_buf->Size = cmd_len;
3018     cmd_buf->SeqNum = 0;
3019     cmd_buf->Result = 0;
3020     tlv->Tag = MRVL_PKT_FWD_CTL_TLV_ID;
3021     tlv->Length = 1;
3022     if (argc == 0) {
3023         cmd_buf->Action = ACTION_GET;
3024     } else {
3025         cmd_buf->Action = ACTION_SET;
3026         tlv->PktFwdCtl = (u8) atoi(argv[0]);
3027     }
3028     endian_convert_tlv_header_out(tlv);
3029     /* Send the command */
3030     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
3031     endian_convert_tlv_header_in(tlv);
3032     /* Process response */
3033     if (ret == UAP_SUCCESS) {
3034         /* Verify response */
3035         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
3036             (tlv->Tag != MRVL_PKT_FWD_CTL_TLV_ID)) {
3037             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
3038                    cmd_buf->CmdCode, tlv->Tag);
3039             free(buffer);
3040             return;
3041         }
3042         /* Print response */
3043         if (cmd_buf->Result == CMD_SUCCESS) {
3044             if (argc == 0) {
3045                 printf("Firmware %s\n", (tlv->PktFwdCtl == 0) ?
3046                        "forwards all packets to the host" :
3047                        "handles intra-BSS packets");
3048             } else {
3049                 printf("Packet control logic setting successful\n");
3050             }
3051         } else {
3052             if (argc == 0) {
3053                 printf("ERR:Could not get packet control logic!\n");
3054             } else {
3055                 printf("ERR:Could not set packet control logic!\n");
3056             }
3057         }
3058     } else {
3059         printf("ERR:Command sending failed!\n");
3060     }
3061     if (buffer)
3062         free(buffer);
3063     return;
3064 }
3065
3066 /** 
3067  *  @brief Creates a sys_cfg request for STA ageout timer
3068  *   and sends to the driver
3069  *
3070  *   Usage: "sys_cfg_sta_ageout_timer [STA_AGEOUT_TIMER]"
3071  *           if STA_AGEOUT_TIMER is provided, a 'set' is performed
3072  *           else a 'get' is performed.
3073  *           The value should between 300 and 864000
3074  *
3075  *           STA_AGEOUT_TIMER is represented in units of 100 ms
3076  *
3077  *  @param argc     Number of arguments
3078  *  @param argv     Pointer to the arguments
3079  *  @return         N/A
3080  */
3081 void
3082 apcmd_sys_cfg_sta_ageout_timer(int argc, char *argv[])
3083 {
3084     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
3085     TLVBUF_STA_AGEOUT_TIMER *tlv = NULL;
3086     u8 *buffer = NULL;
3087     u16 cmd_len;
3088     int ret = UAP_FAILURE;
3089     int opt;
3090     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
3091         switch (opt) {
3092         default:
3093             print_sys_cfg_sta_ageout_timer_usage();
3094             return;
3095         }
3096     }
3097     argc -= optind;
3098     argv += optind;
3099     /* Check arguments */
3100     if (argc && (is_input_valid(STAAGEOUTTIMER, argc, argv) != UAP_SUCCESS)) {
3101         print_sys_cfg_sta_ageout_timer_usage();
3102         return;
3103     }
3104     /* Initialize the command length */
3105     cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_STA_AGEOUT_TIMER);
3106
3107     /* Initialize the command buffer */
3108     buffer = (u8 *) malloc(cmd_len);
3109
3110     if (!buffer) {
3111         printf("ERR:Cannot allocate buffer for command!\n");
3112         return;
3113     }
3114     bzero((char *) buffer, cmd_len);
3115
3116     /* Locate headers */
3117     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
3118     tlv = (TLVBUF_STA_AGEOUT_TIMER *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
3119
3120     /* Fill the command buffer */
3121     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
3122     cmd_buf->Size = cmd_len;
3123     cmd_buf->SeqNum = 0;
3124     cmd_buf->Result = 0;
3125     tlv->Tag = MRVL_STA_AGEOUT_TIMER_TLV_ID;
3126     tlv->Length = 4;
3127     if (argc == 0) {
3128         cmd_buf->Action = ACTION_GET;
3129     } else {
3130         cmd_buf->Action = ACTION_SET;
3131         tlv->StaAgeoutTimer_ms = (u32) atoi(argv[0]);
3132     }
3133     endian_convert_tlv_header_out(tlv);
3134     tlv->StaAgeoutTimer_ms = uap_cpu_to_le32(tlv->StaAgeoutTimer_ms);
3135     /* Send the command */
3136     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
3137     endian_convert_tlv_header_in(tlv);
3138     tlv->StaAgeoutTimer_ms = uap_le32_to_cpu(tlv->StaAgeoutTimer_ms);
3139     /* Process response */
3140     if (ret == UAP_SUCCESS) {
3141         /* Verify response */
3142         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
3143             (tlv->Tag != MRVL_STA_AGEOUT_TIMER_TLV_ID)) {
3144             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
3145                    cmd_buf->CmdCode, tlv->Tag);
3146             free(buffer);
3147             return;
3148         }
3149         /* Print response */
3150         if (cmd_buf->Result == CMD_SUCCESS) {
3151             if (argc == 0) {
3152                 printf("STA ageout timer value = %d\n",
3153                        (int) tlv->StaAgeoutTimer_ms);
3154             } else {
3155                 printf("STA ageout timer setting successful\n");
3156             }
3157         } else {
3158             if (argc == 0) {
3159                 printf("ERR:Could not get STA ageout timer!\n");
3160             } else {
3161                 printf("ERR:Could not set STA ageout timer!\n");
3162             }
3163         }
3164     } else {
3165         printf("ERR:Command sending failed!\n");
3166     }
3167     if (buffer)
3168         free(buffer);
3169     return;
3170 }
3171
3172 /** 
3173  *  @brief Creates a sys_cfg request for authentication mode
3174  *   and sends to the driver
3175  *
3176  *   Usage: "Usage : sys_cfg_auth [AUTHMODE]"
3177  *
3178  *   Options: AUTHMODE :     0 - Open authentication
3179  *                           1 - Shared key authentication
3180  *            empty - Get current authentication mode                         
3181  *
3182  *  @param argc     Number of arguments
3183  *  @param argv     Pointer to the arguments
3184  *  @return         N/A
3185  */
3186 void
3187 apcmd_sys_cfg_auth(int argc, char *argv[])
3188 {
3189     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
3190     TLVBUF_AUTH_MODE *tlv = NULL;
3191     u8 *buffer = NULL;
3192     u16 cmd_len;
3193     int ret = UAP_FAILURE;
3194     int opt;
3195     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
3196         switch (opt) {
3197         default:
3198             print_sys_cfg_auth_usage();
3199             return;
3200         }
3201     }
3202     argc -= optind;
3203     argv += optind;
3204     /* Check arguments */
3205     if (argc && (is_input_valid(AUTHMODE, argc, argv) != UAP_SUCCESS)) {
3206         print_sys_cfg_auth_usage();
3207         return;
3208     }
3209     /* Initialize the command length */
3210     cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_AUTH_MODE);
3211
3212     /* Initialize the command buffer */
3213     buffer = (u8 *) malloc(cmd_len);
3214
3215     if (!buffer) {
3216         printf("ERR:Cannot allocate buffer for command!\n");
3217         return;
3218     }
3219     bzero((char *) buffer, cmd_len);
3220
3221     /* Locate headers */
3222     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
3223     tlv = (TLVBUF_AUTH_MODE *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
3224
3225     /* Fill the command buffer */
3226     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
3227     cmd_buf->Size = cmd_len;
3228     cmd_buf->SeqNum = 0;
3229     cmd_buf->Result = 0;
3230     tlv->Tag = MRVL_AUTH_TLV_ID;
3231     tlv->Length = 1;
3232     if (argc == 0) {
3233         cmd_buf->Action = ACTION_GET;
3234     } else {
3235         cmd_buf->Action = ACTION_SET;
3236         tlv->AuthMode = (u8) atoi(argv[0]);
3237     }
3238     endian_convert_tlv_header_out(tlv);
3239     /* Send the command */
3240     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
3241     endian_convert_tlv_header_in(tlv);
3242
3243     /* Process response */
3244     if (ret == UAP_SUCCESS) {
3245         /* Verify response */
3246         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
3247             (tlv->Tag != MRVL_AUTH_TLV_ID)) {
3248             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
3249                    cmd_buf->CmdCode, tlv->Tag);
3250             free(buffer);
3251             return;
3252         }
3253         /* Print response */
3254         if (cmd_buf->Result == CMD_SUCCESS) {
3255             if (argc == 0) {
3256                 print_auth(tlv);
3257             } else {
3258                 printf("authentication mode setting successful\n");
3259             }
3260         } else {
3261             if (argc == 0) {
3262                 printf("ERR:Could not get authentication mode!\n");
3263             } else {
3264                 printf("ERR:Could not set authentication mode!\n");
3265             }
3266         }
3267     } else {
3268         printf("ERR:Command sending failed!\n");
3269     }
3270     if (buffer)
3271         free(buffer);
3272     return;
3273 }
3274
3275 /** 
3276  *  @brief Creates a sys_cfg request for encryption protocol
3277  *   and sends to the driver
3278  *
3279  *   Usage: "Usage : sys_cfg_protocol [PROTOCOL]"
3280  *
3281  *   Options: PROTOCOL               Bit 0 - No RSN
3282  *                                   Bit 1 - WEP Static
3283  *                                   Bit 3 - WPA
3284  *                                   Bit 3 - WPA2
3285  *            empty - Get current protocol                         
3286  *           
3287  *  @param argc     Number of arguments
3288  *  @param argv     Pointer to the arguments
3289  *  @return         N/A
3290  */
3291 void
3292 apcmd_sys_cfg_protocol(int argc, char *argv[])
3293 {
3294     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
3295     TLVBUF_PROTOCOL *tlv = NULL;
3296     TLVBUF_AKMP *akmp_tlv = NULL;
3297     u8 *buffer = NULL;
3298     u16 cmd_len;
3299     int ret = UAP_FAILURE;
3300     int opt;
3301     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
3302         switch (opt) {
3303         default:
3304             print_sys_cfg_protocol_usage();
3305             return;
3306         }
3307     }
3308     argc -= optind;
3309     argv += optind;
3310     /* Check arguments */
3311     if (argc && is_input_valid(PROTOCOL, argc, argv) != UAP_SUCCESS) {
3312         print_sys_cfg_protocol_usage();
3313         return;
3314     }
3315     /* Initialize the command length */
3316     if ((argc == 1) &&
3317         ((atoi(argv[0]) == PROTOCOL_NO_SECURITY) ||
3318          (atoi(argv[0]) == PROTOCOL_STATIC_WEP))) {
3319         cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_PROTOCOL);
3320     } else
3321         cmd_len =
3322             sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_PROTOCOL) +
3323             sizeof(TLVBUF_AKMP);
3324     /* Initialize the command buffer */
3325     buffer = (u8 *) malloc(cmd_len);
3326     if (!buffer) {
3327         printf("ERR:Cannot allocate buffer for command!\n");
3328         return;
3329     }
3330     bzero((char *) buffer, cmd_len);
3331     /* Locate headers */
3332     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
3333     tlv = (TLVBUF_PROTOCOL *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
3334     akmp_tlv =
3335         (TLVBUF_AKMP *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE) +
3336                          sizeof(TLVBUF_PROTOCOL));
3337     /* Fill the command buffer */
3338     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
3339     cmd_buf->Size = cmd_len;
3340     cmd_buf->SeqNum = 0;
3341     cmd_buf->Result = 0;
3342     tlv->Tag = MRVL_PROTOCOL_TLV_ID;
3343     tlv->Length = 2;
3344     if (argc == 0) {
3345         cmd_buf->Action = ACTION_GET;
3346         akmp_tlv->Tag = MRVL_AKMP_TLV_ID;
3347         akmp_tlv->Length = 2;
3348     } else {
3349         cmd_buf->Action = ACTION_SET;
3350         tlv->Protocol = (u16) atoi(argv[0]);
3351         if (tlv->Protocol & (PROTOCOL_WPA | PROTOCOL_WPA2)) {
3352             akmp_tlv->Tag = MRVL_AKMP_TLV_ID;
3353             akmp_tlv->Length = 2;
3354             akmp_tlv->KeyMgmt = KEY_MGMT_PSK;
3355             akmp_tlv->KeyMgmt = uap_cpu_to_le16(akmp_tlv->KeyMgmt);
3356         }
3357     }
3358     endian_convert_tlv_header_out(tlv);
3359     if (cmd_len ==
3360         (sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_PROTOCOL) +
3361          sizeof(TLVBUF_AKMP)))
3362         endian_convert_tlv_header_out(akmp_tlv);
3363     tlv->Protocol = uap_cpu_to_le16(tlv->Protocol);
3364     /* Send the command */
3365     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
3366     endian_convert_tlv_header_in(tlv);
3367     if (cmd_len ==
3368         (sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_PROTOCOL) +
3369          sizeof(TLVBUF_AKMP)))
3370         endian_convert_tlv_header_in(akmp_tlv);
3371
3372     /* Process response */
3373     if (ret == UAP_SUCCESS) {
3374         /* Verify response */
3375         if (cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) {
3376             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
3377                    cmd_buf->CmdCode, tlv->Tag);
3378             free(buffer);
3379             return;
3380         }
3381         /* Print response */
3382         if (cmd_buf->Result == CMD_SUCCESS) {
3383             if (argc == 0) {
3384                 print_tlv((u8 *) tlv,
3385                           cmd_buf->Size - sizeof(APCMDBUF_SYS_CONFIGURE) +
3386                           BUF_HEADER_SIZE);
3387             } else {
3388                 printf("protocol setting successful\n");
3389             }
3390         } else {
3391             if (argc == 0) {
3392                 printf("ERR:Could not get protocol!\n");
3393             } else {
3394                 printf("ERR:Could not set protocol!\n");
3395             }
3396         }
3397     } else {
3398         printf("ERR:Command sending failed!\n");
3399     }
3400     if (buffer)
3401         free(buffer);
3402     return;
3403 }
3404
3405 /** 
3406  *  @brief Creates a sys_cfg request for WEP keys settings
3407  *   and sends to the driver
3408  *
3409  *   Usage: "sys_cfg_wep_key [INDEX_0 IS_DEFAULT KEY_0] [INDEX_1 IS_DEFAULT KEY_1] [INDEX_2 IS_DEFAULT KEY_2] [INDEX_3 IS_DEFAULT KEY_3]"
3410  *
3411  *   Options: INDEX_* :      0 - KeyIndex is 0
3412  *                           1 - KeyIndex is 1
3413  *                           2 - KeyIndex is 2
3414  *                           3 - KeyIndex is 3
3415  *            IS_DEFAUL :    0 - KeyIndex is not the default
3416  *                           1 - KeyIndex is the default transmit key
3417  *            KEY_* :        Key value
3418  *            empty - Get current WEP key settings
3419  *
3420  *  @param argc     Number of arguments
3421  *  @param argv     Pointer to the arguments
3422  *  @return         N/A
3423  */
3424 void
3425 apcmd_sys_cfg_wep_key(int argc, char *argv[])
3426 {
3427     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
3428     TLVBUF_WEP_KEY *tlv = NULL;
3429     u8 *buffer = NULL;
3430     u16 cmd_len;
3431     u16 buf_len;
3432     int ret = UAP_FAILURE;
3433     int key_len = -1;
3434     int length = 0;
3435     int number_of_keys = 0;
3436     int i = 0;
3437     int keyindex = -1;
3438     int is_default = -1;
3439     char *key = NULL;
3440     int opt;
3441     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
3442         switch (opt) {
3443         default:
3444             print_sys_cfg_wep_key_usage();
3445             return;
3446         }
3447     }
3448     argc -= optind;
3449     argv += optind;
3450
3451     /* Check arguments */
3452     if (argc > 12) {
3453         printf("ERR:Too many arguments.\n");
3454         print_sys_cfg_wep_key_usage();
3455         return;
3456     } else if ((argc > 1) && ((argc % 3) != 0)) {
3457         printf("ERR:Illegal number of parameters.\n");
3458         print_sys_cfg_wep_key_usage();
3459         return;
3460     } else if (argc > 1) {
3461         /* Find number of keys provided */
3462         number_of_keys = argc / 3;
3463         for (i = 0; i < number_of_keys; i++) {
3464             if ((ISDIGIT(argv[(3 * i)]) == 0) || (atoi(argv[(3 * i)]) < 0) ||
3465                 (atoi(argv[(3 * i)]) > 3)) {
3466                 printf
3467                     ("ERR:Illegal INDEX %s. Must be either '0', '1', '2', or '3'.\n",
3468                      argv[(3 * i)]);
3469                 print_sys_cfg_wep_key_usage();
3470                 return;
3471             }
3472             if ((ISDIGIT(argv[(3 * i) + 1]) == 0) ||
3473                 (atoi(argv[(3 * i) + 1]) < 0) ||
3474                 (atoi(argv[(3 * i) + 1]) > 1)) {
3475                 printf
3476                     ("ERR:Illegal IS_DEFAULT %s. Must be either '0', or '1'.\n",
3477                      argv[(3 * i) + 1]);
3478                 print_sys_cfg_wep_key_usage();
3479                 return;
3480             }
3481             if ((strlen(argv[(3 * i) + 2]) != 5) &&
3482                 (strlen(argv[(3 * i) + 2]) != 10)
3483                 && (strlen(argv[(3 * i) + 2]) != 13) &&
3484                 (strlen(argv[(3 * i) + 2]) != 26)) {
3485                 printf("ERR:Incorrect KEY_%d length %d\n", atoi(argv[(3 * i)]),
3486                        strlen(argv[(3 * i) + 2]));
3487                 print_sys_cfg_wep_key_usage();
3488                 return;
3489             }
3490             if ((strlen(argv[(3 * i) + 2]) == 10) ||
3491                 (strlen(argv[(3 * i) + 2]) == 26)) {
3492                 if (UAP_FAILURE == ishexstring(argv[(3 * i) + 2])) {
3493                     printf
3494                         ("ERR:Only hex digits are allowed when key length is 10 or 26\n");
3495                     print_sys_cfg_wep_key_usage();
3496                     return;
3497                 }
3498             }
3499         }
3500     } else if (argc == 1) {
3501         if ((ISDIGIT(argv[0]) == 0) || (atoi(argv[0]) < 0) ||
3502             (atoi(argv[0]) > 3)) {
3503             printf
3504                 ("ERR:Illegal INDEX %s. Must be either '0', '1', '2', or '3'.\n",
3505                  argv[0]);
3506             print_sys_cfg_wep_key_usage();
3507             return;
3508         }
3509     }
3510
3511     /* Initialize the command length */
3512     if (argc == 0 || argc == 1) {
3513         if (argc == 0)
3514             cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_HEADER);
3515         else
3516             cmd_len =
3517                 sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_WEP_KEY) - 1;
3518         buf_len = MRVDRV_SIZE_OF_CMD_BUFFER;
3519     } else {
3520         buf_len = cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE);
3521     }
3522     /* Initialize the command buffer */
3523     buffer = (u8 *) malloc(buf_len);
3524     if (!buffer) {
3525         printf("ERR:Cannot allocate buffer for command!\n");
3526         return;
3527     }
3528     bzero((char *) buffer, buf_len);
3529     /* Locate headers */
3530     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
3531
3532     /* Fill the command buffer */
3533     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
3534     cmd_buf->SeqNum = 0;
3535     cmd_buf->Result = 0;
3536     if (argc == 0 || argc == 1) {
3537         cmd_buf->Action = ACTION_GET;
3538         tlv = (TLVBUF_WEP_KEY *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
3539         tlv->Tag = MRVL_WEP_KEY_TLV_ID;
3540         if (argc == 0)
3541             tlv->Length = 0;
3542         else {
3543             tlv->Length = 1;
3544             tlv->KeyIndex = atoi(argv[0]);
3545         }
3546         endian_convert_tlv_header_out(tlv);
3547     } else {
3548         cmd_buf->Action = ACTION_SET;
3549     }
3550     /* Add key TLVs */
3551     for (i = 0; i < number_of_keys; i++) {
3552         keyindex = atoi(argv[(3 * i)]);
3553         is_default = atoi(argv[(3 * i) + 1]);
3554         key = argv[(3 * i) + 2];
3555         length = strlen(key);
3556         switch (length) {
3557         case 5:
3558         case 10:
3559             key_len = 5;
3560             break;
3561         case 13:
3562         case 26:
3563             key_len = 13;
3564             break;
3565         default:
3566             key_len = 0;
3567             break;
3568         }
3569         /* Adjust command buffer */
3570         buffer = realloc(buffer, (cmd_len + sizeof(TLVBUF_WEP_KEY) + key_len));
3571         if (!buffer) {
3572             printf("ERR:Cannot append WEP key configurations TLV!\n");
3573             return;
3574         }
3575         /* Locate headers */
3576         cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
3577         tlv = (TLVBUF_WEP_KEY *) (buffer + cmd_len);
3578         /* Adjust command length */
3579         cmd_len += (sizeof(TLVBUF_WEP_KEY) + key_len);
3580         /* Set TLV fields */
3581         tlv->Tag = MRVL_WEP_KEY_TLV_ID;
3582         tlv->Length = 2 + key_len;
3583         tlv->KeyIndex = (u8) keyindex;
3584         tlv->IsDefault = (u8) is_default;
3585         /* Check if string or raw */
3586         switch (length) {
3587         case 5:
3588         case 13:
3589             memcpy(tlv->Key, key, length);
3590             break;
3591         case 10:
3592         case 26:
3593             string2raw(key, tlv->Key);
3594             break;
3595         default:
3596             break;
3597         }
3598         endian_convert_tlv_header_out(tlv);
3599     }
3600
3601     /* Update command length */
3602     cmd_buf->Size = cmd_len;
3603     if ((argc != 0) && (argc != 1))
3604         buf_len = cmd_len;
3605
3606     /* Send the command */
3607     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, buf_len);
3608     /* Process response */
3609     if (ret == UAP_SUCCESS) {
3610         /* Verify response */
3611         if (cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) {
3612             printf("ERR:Corrupted response!\n");
3613             free(buffer);
3614             return;
3615         }
3616         /* Print response */
3617         if (cmd_buf->Result == CMD_SUCCESS) {
3618             if ((argc != 0) && (argc != 1)) {
3619                 printf("WEP key setting successful\n");
3620             } else {
3621                 printf("query WEP key setting successful\n");
3622                 tlv =
3623                     (TLVBUF_WEP_KEY *) (buffer +
3624                                         sizeof(APCMDBUF_SYS_CONFIGURE));
3625                 print_tlv((u8 *) tlv,
3626                           cmd_buf->Size - sizeof(APCMDBUF_SYS_CONFIGURE) +
3627                           BUF_HEADER_SIZE);
3628             }
3629         } else {
3630             if ((argc != 0) && (argc != 1))
3631                 printf("ERR:Could not set WEP keys!\n");
3632             else
3633                 printf("ERR:Could not get WEP keys!\n");
3634         }
3635     } else {
3636         printf("ERR:Command sending failed!\n");
3637     }
3638     if (buffer)
3639         free(buffer);
3640     return;
3641 }
3642
3643 /**
3644  *  @brief Creates a sys_cfg request for custom IE settings
3645  *   and sends to the driver
3646  *
3647  *   Usage: "sys_cfg_custom_ie [INDEX] [MASK] [IEBuffer]"
3648  *
3649  *   Options: INDEX :      0 - Get/Set IE index 0 setting
3650  *                         1 - Get/Set IE index 1 setting
3651  *                         2 - Get/Set IE index 2 setting
3652  *                         3 - Get/Set IE index 3 setting
3653  *            MASK  :      Management subtype mask value
3654  *            IEBuffer:      IE Buffer in hex
3655  *            empty - Get all IE settings
3656  *
3657  *  @param argc     Number of arguments
3658  *  @param argv     Pointer to the arguments
3659  *  @return         N/A
3660  */
3661 void
3662 apcmd_sys_cfg_custom_ie(int argc, char *argv[])
3663 {
3664     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
3665     tlvbuf_custom_ie *tlv = NULL;
3666     custom_ie *ie_ptr = NULL;
3667     u8 *buffer = NULL;
3668     u16 cmd_len;
3669     u16 buf_len;
3670     u16 mgmt_subtype_mask = 0;
3671     int ret = UAP_FAILURE;
3672     int ie_buf_len = 0, ie_len = 0;
3673     int opt;
3674     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
3675         switch (opt) {
3676         default:
3677             print_sys_cfg_custom_ie_usage();
3678             return;
3679         }
3680     }
3681     argc -= optind;
3682     argv += optind;
3683
3684     /* Check arguments */
3685     if (argc > 3) {
3686         printf("ERR:Too many arguments.\n");
3687         print_sys_cfg_custom_ie_usage();
3688         return;
3689     }
3690
3691     /* Error checks and initialize the command length */
3692     if (argc >= 1) {
3693         if ((ISDIGIT(argv[0]) == 0) || (atoi(argv[0]) < 0) ||
3694             (atoi(argv[0]) > 3)) {
3695             printf
3696                 ("ERR:Illegal index %s. Must be either '0', '1', '2', or '3'.\n",
3697                  argv[0]);
3698             print_sys_cfg_custom_ie_usage();
3699             return;
3700         }
3701     }
3702     switch (argc) {
3703     case 0:
3704         cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(tlvbuf_custom_ie);
3705         buf_len = MRVDRV_SIZE_OF_CMD_BUFFER;
3706         break;
3707     case 1:
3708         /* TLV header + ie_index */
3709         cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(tlvbuf_custom_ie) +
3710             sizeof(u16);
3711         buf_len = MRVDRV_SIZE_OF_CMD_BUFFER;
3712         break;
3713     case 2:
3714         if (UAP_FAILURE == ishexstring(argv[1]) || A2HEXDECIMAL(argv[1]) != 0) {
3715             printf("ERR: Mask value should be 0 to clear IEBuffers.\n");
3716             print_sys_cfg_custom_ie_usage();
3717             return;
3718         }
3719         buf_len = cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) +
3720             sizeof(tlvbuf_custom_ie) + sizeof(custom_ie);
3721         break;
3722     case 3:
3723         if (UAP_FAILURE == ishexstring(argv[1]) || A2HEXDECIMAL(argv[1]) == 0) {
3724             printf("ERR: Mask value should not be 0 to set IEBuffers.\n");
3725             print_sys_cfg_custom_ie_usage();
3726             return;
3727         }
3728         if (UAP_FAILURE == ishexstring(argv[2])) {
3729             printf("ERR:Only hex digits are allowed\n");
3730             print_sys_cfg_custom_ie_usage();
3731             return;
3732         }
3733         ie_buf_len = strlen(argv[2]);
3734         if (!strncasecmp("0x", argv[2], 2)) {
3735             ie_len = (ie_buf_len - 2 + 1) / 2;
3736             argv[2] += 2;
3737         } else
3738             ie_len = (ie_buf_len + 1) / 2;
3739         if (ie_len > MAX_IE_BUFFER_LEN) {
3740             printf("ERR:Incorrect IE length %d\n", ie_buf_len);
3741             print_sys_cfg_custom_ie_usage();
3742             return;
3743         }
3744         mgmt_subtype_mask = (u16) A2HEXDECIMAL(argv[1]);
3745         buf_len = cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) +
3746             sizeof(tlvbuf_custom_ie) + sizeof(custom_ie) + ie_len;
3747         break;
3748     }
3749
3750     /* Initialize the command buffer */
3751     buffer = (u8 *) malloc(buf_len);
3752     if (!buffer) {
3753         printf("ERR:Cannot allocate buffer for command!\n");
3754         return;
3755     }
3756     memset(buffer, 0, buf_len);
3757     /* Locate headers */
3758     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
3759
3760     /* Fill the command buffer */
3761     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
3762     cmd_buf->SeqNum = 0;
3763     cmd_buf->Result = 0;
3764     cmd_buf->Size = cmd_len;
3765
3766     if (argc == 0 || argc == 1) {
3767         cmd_buf->Action = ACTION_GET;
3768         tlv = (tlvbuf_custom_ie *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
3769         tlv->Tag = MRVL_MGMT_IE_LIST_TLV_ID;
3770         if (argc == 0)
3771             tlv->Length = 0;
3772         else {
3773             tlv->Length = sizeof(u16);
3774             ie_ptr = (custom_ie *) (tlv->ie_data);
3775             ie_ptr->ie_index = (u16) uap_cpu_to_le16(atoi(argv[0]));
3776         }
3777         endian_convert_tlv_header_out(tlv);
3778     } else {
3779         cmd_buf->Action = ACTION_SET;
3780         /* Locate headers */
3781         tlv = (tlvbuf_custom_ie *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
3782         ie_ptr = (custom_ie *) (tlv->ie_data);
3783         /* Set TLV fields */
3784         tlv->Tag = MRVL_MGMT_IE_LIST_TLV_ID;
3785         tlv->Length = sizeof(custom_ie) + ie_len;
3786         ie_ptr->ie_index = uap_cpu_to_le16(atoi(argv[0]));
3787         ie_ptr->mgmt_subtype_mask = uap_cpu_to_le16(mgmt_subtype_mask);
3788         ie_ptr->ie_length = uap_cpu_to_le16(ie_len);
3789         if (argc == 3)
3790             string2raw(argv[2], ie_ptr->ie_buffer);
3791         endian_convert_tlv_header_out(tlv);
3792     }
3793
3794     /* Send the command */
3795     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, buf_len);
3796     /* Process response */
3797     if (ret == UAP_SUCCESS) {
3798         /* Verify response */
3799         if (cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) {
3800             printf("ERR:Corrupted response!\n");
3801             free(buffer);
3802             return;
3803         }
3804         /* Print response */
3805         if (cmd_buf->Result == CMD_SUCCESS) {
3806             if ((argc != 0) && (argc != 1)) {
3807                 printf("custom IE setting successful\n");
3808             } else {
3809                 printf("Querying custom IE successful\n");
3810                 tlv =
3811                     (tlvbuf_custom_ie *) (buffer +
3812                                           sizeof(APCMDBUF_SYS_CONFIGURE));
3813                 print_tlv((u8 *) tlv,
3814                           cmd_buf->Size - sizeof(APCMDBUF_SYS_CONFIGURE) +
3815                           BUF_HEADER_SIZE);
3816             }
3817         } else {
3818             if ((argc != 0) && (argc != 1))
3819                 printf("ERR:Could not set custom IE elements!\n");
3820             else
3821                 printf("ERR:Could not get custom IE elements!\n");
3822         }
3823     } else {
3824         printf("ERR:Command sending failed!\n");
3825     }
3826     if (buffer)
3827         free(buffer);
3828     return;
3829 }
3830
3831 /** 
3832  *  @brief Creates a sys_cfg request for cipher configurations
3833  *   and sends to the driver
3834  *
3835  *   Usage: "sys_cfg_security_cfg [PAIRWISE_CIPHER GROUP_CIPHER]"
3836  *
3837  *   Options: PAIRWISE_CIPHER : Bit 2 - TKIP
3838  *                              Bit 3 - AES CCMP
3839  *            GROUP_CIPHER :    Bit 2 - TKIP
3840  *                              Bit 3 - AES CCMP
3841  *            empty - Get current cipher settings
3842  *
3843  *  @param argc     Number of arguments
3844  *  @param argv     Pointer to the arguments
3845  *  @return         N/A
3846  */
3847 void
3848 apcmd_sys_cfg_cipher(int argc, char *argv[])
3849 {
3850     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
3851     TLVBUF_CIPHER *tlv = NULL;
3852     u8 *buffer = NULL;
3853     u16 cmd_len;
3854     int ret = UAP_FAILURE;
3855     int opt;
3856     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
3857         switch (opt) {
3858         default:
3859             print_sys_cfg_cipher_usage();
3860             return;
3861         }
3862     }
3863     argc -= optind;
3864     argv += optind;
3865
3866     /* Check arguments */
3867     if ((argc != 0) && (argc != 2)) {
3868         printf("ERR:wrong arguments.\n");
3869         print_sys_cfg_cipher_usage();
3870         return;
3871     }
3872     if (argc == 2) {
3873         if ((ISDIGIT(argv[0]) == 0) || (ISDIGIT(argv[1]) == 0)) {
3874             print_sys_cfg_cipher_usage();
3875             return;
3876         }
3877         if (atoi(argv[0]) & ~CIPHER_BITMAP) {
3878             printf("ERR:Illegal PAIRWISE_CIPHER parameter %s.\n", argv[0]);
3879             print_sys_cfg_cipher_usage();
3880             return;
3881         }
3882         if (atoi(argv[1]) & ~CIPHER_BITMAP) {
3883             printf("ERR:Illegal GROUP_CIPHER parameter %s.\n", argv[1]);
3884             print_sys_cfg_cipher_usage();
3885             return;
3886         }
3887         if (is_cipher_valid(atoi(argv[0]), atoi(argv[1])) != UAP_SUCCESS) {
3888             printf("ERR:Wrong group and pair cipher combination!\n");
3889             print_sys_cfg_cipher_usage();
3890             return;
3891         }
3892     }
3893     /* Initialize the command length */
3894     cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_CIPHER);
3895
3896     /* Initialize the command buffer */
3897     buffer = (u8 *) malloc(cmd_len);
3898
3899     if (!buffer) {
3900         printf("ERR:Cannot allocate buffer for command!\n");
3901         return;
3902     }
3903     bzero((char *) buffer, cmd_len);
3904
3905     /* Locate headers */
3906     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
3907     tlv = (TLVBUF_CIPHER *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
3908     /* Fill the command buffer */
3909     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
3910     cmd_buf->Size = cmd_len;
3911     cmd_buf->SeqNum = 0;
3912     cmd_buf->Result = 0;
3913     tlv->Tag = MRVL_CIPHER_TLV_ID;
3914     tlv->Length = 2;
3915     if (argc == 0) {
3916         cmd_buf->Action = ACTION_GET;
3917     } else {
3918         cmd_buf->Action = ACTION_SET;
3919         tlv->PairwiseCipher = (u8) atoi(argv[0]);
3920         tlv->GroupCipher = (u8) atoi(argv[1]);
3921     }
3922     endian_convert_tlv_header_out(tlv);
3923     /* Send the command */
3924     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
3925     endian_convert_tlv_header_in(tlv);
3926     /* Process response */
3927     if (ret == UAP_SUCCESS) {
3928         /* Verify response */
3929         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
3930             (tlv->Tag != MRVL_CIPHER_TLV_ID)) {
3931             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
3932                    cmd_buf->CmdCode, tlv->Tag);
3933             free(buffer);
3934             return;
3935         }
3936         /* Print response */
3937         if (cmd_buf->Result == CMD_SUCCESS) {
3938             if (argc == 0) {
3939                 print_cipher(tlv);
3940             } else {
3941                 printf("cipher setting successful\n");
3942             }
3943         } else {
3944             if (argc == 0) {
3945                 printf("ERR:Could not get cipher parameters!\n");
3946             } else {
3947                 printf("ERR:Could not set cipher parameters!\n");
3948             }
3949         }
3950     } else {
3951         printf("ERR:Command sending failed!\n");
3952     }
3953     if (buffer)
3954         free(buffer);
3955     return;
3956 }
3957
3958 /** 
3959  *  @brief Creates a sys_cfg request for group re-key timer
3960  *   and sends to the driver
3961  *
3962  *   Usage: "Usage : sys_cfg_group_rekey_timer [GROUP_REKEY_TIMER]"
3963  *
3964  *   Options: GROUP_REKEY_TIME is represented in seconds
3965  *            Get current group re-key timer                         
3966  *
3967  *  @param argc     Number of arguments
3968  *  @param argv     Pointer to the arguments
3969  *  @return         N/A
3970  */
3971 void
3972 apcmd_sys_cfg_group_rekey_timer(int argc, char *argv[])
3973 {
3974     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
3975     TLVBUF_GROUP_REKEY_TIMER *tlv = NULL;
3976     u8 *buffer = NULL;
3977     u16 cmd_len;
3978     int ret = UAP_FAILURE;
3979     int opt;
3980     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
3981         switch (opt) {
3982         default:
3983             print_sys_cfg_group_rekey_timer_usage();
3984             return;
3985         }
3986     }
3987     argc -= optind;
3988     argv += optind;
3989     /* Check arguments */
3990     if (argc && (is_input_valid(GROUPREKEYTIMER, argc, argv) != UAP_SUCCESS)) {
3991         print_sys_cfg_group_rekey_timer_usage();
3992     }
3993
3994     /* Initialize the command length */
3995     cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_GROUP_REKEY_TIMER);
3996     /* Initialize the command buffer */
3997     buffer = (u8 *) malloc(cmd_len);
3998     if (!buffer) {
3999         printf("ERR:Cannot allocate buffer for command!\n");
4000         return;
4001     }
4002     bzero((char *) buffer, cmd_len);
4003     /* Locate headers */
4004     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
4005     tlv =
4006         (TLVBUF_GROUP_REKEY_TIMER *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
4007
4008     /* Fill the command buffer */
4009     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
4010     cmd_buf->Size = cmd_len;
4011     cmd_buf->SeqNum = 0;
4012     cmd_buf->Result = 0;
4013     tlv->Tag = MRVL_GRP_REKEY_TIME_TLV_ID;
4014     tlv->Length = 4;
4015     if (argc == 0) {
4016         cmd_buf->Action = ACTION_GET;
4017     } else {
4018         cmd_buf->Action = ACTION_SET;
4019         tlv->GroupRekeyTime_sec = (u32) atoi(argv[0]);
4020     }
4021     endian_convert_tlv_header_out(tlv);
4022     tlv->GroupRekeyTime_sec = uap_cpu_to_le32(tlv->GroupRekeyTime_sec);
4023     /* Send the command */
4024     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
4025     endian_convert_tlv_header_in(tlv);
4026     tlv->GroupRekeyTime_sec = uap_le32_to_cpu(tlv->GroupRekeyTime_sec);
4027     /* Process response */
4028     if (ret == UAP_SUCCESS) {
4029         /* Verify response */
4030         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
4031             (tlv->Tag != MRVL_GRP_REKEY_TIME_TLV_ID)) {
4032             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
4033                    cmd_buf->CmdCode, tlv->Tag);
4034             free(buffer);
4035             return;
4036         }
4037         /* Print response */
4038         if (cmd_buf->Result == CMD_SUCCESS) {
4039             if (argc == 0) {
4040                 if (tlv->GroupRekeyTime_sec > 0)
4041                     printf("Group rekey time is %ld s\n",
4042                            tlv->GroupRekeyTime_sec);
4043                 else
4044                     printf("Group rekey time is disabled\n");
4045             } else {
4046                 printf("group re-key time setting successful\n");
4047             }
4048         } else {
4049             if (argc == 0) {
4050                 printf("ERR:Could not get group re-key time!\n");
4051             } else {
4052                 printf("ERR:Could not set group re-key time!\n");
4053             }
4054         }
4055     } else {
4056         printf("ERR:Command sending failed!\n");
4057     }
4058     if (buffer)
4059         free(buffer);
4060     return;
4061 }
4062
4063 /** 
4064  *  @brief Creates a sys_cfg request for WPA passphrase
4065  *   and sends to the driver
4066  *
4067  *   Usage: "sys_cfg_wpa_passphrase [PASSPHRASE]"
4068  *           if PASSPHRASE is provided, a 'set' is performed
4069  *           else a 'get' is performed
4070  *
4071  *  @param argc     Number of arguments
4072  *  @param argv     Pointer to the arguments
4073  *  @return         N/A
4074  */
4075 void
4076 apcmd_sys_cfg_wpa_passphrase(int argc, char *argv[])
4077 {
4078     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
4079     TLVBUF_WPA_PASSPHRASE *tlv = NULL;
4080     u8 *buffer = NULL;
4081     u16 cmd_len;
4082     int ret = UAP_FAILURE;
4083     int opt;
4084     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
4085         switch (opt) {
4086         default:
4087             print_sys_cfg_wpa_passphrase_usage();
4088             return;
4089         }
4090     }
4091     argc -= optind;
4092     argv += optind;
4093     /* Check arguments */
4094     if (argc > 1) {
4095         printf("ERR:Too many arguments.\n");
4096         print_sys_cfg_wpa_passphrase_usage();
4097         return;
4098     }
4099     if ((argc == 1) && (strlen(argv[0]) > MAX_WPA_PASSPHRASE_LENGTH)) {
4100         printf("ERR:PASSPHRASE too long.\n");
4101         return;
4102     }
4103     if ((argc == 1) && (strlen(argv[0]) < MIN_WPA_PASSPHRASE_LENGTH)) {
4104         printf("ERR:PASSPHRASE too short.\n");
4105         return;
4106     }
4107     if ((argc == 1) && (strlen(argv[0]) == MAX_WPA_PASSPHRASE_LENGTH)) {
4108         if (UAP_FAILURE == ishexstring(argv[0])) {
4109             printf
4110                 ("ERR:Only hex digits are allowed when passphrase's length is 64\n");
4111             return;
4112         }
4113     }
4114     /* Initialize the command length */
4115     if (argc == 0)
4116         cmd_len =
4117             sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_WPA_PASSPHRASE) +
4118             MAX_WPA_PASSPHRASE_LENGTH;
4119     else
4120         cmd_len =
4121             sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_WPA_PASSPHRASE) +
4122             strlen(argv[0]);
4123     /* Initialize the command buffer */
4124     buffer = (u8 *) malloc(cmd_len);
4125     if (!buffer) {
4126         printf("ERR:Cannot allocate buffer for command!\n");
4127         return;
4128     }
4129     bzero((char *) buffer, cmd_len);
4130     /* Locate headers */
4131     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
4132     tlv = (TLVBUF_WPA_PASSPHRASE *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
4133     /* Fill the command buffer */
4134     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
4135     cmd_buf->Size = cmd_len;
4136     cmd_buf->SeqNum = 0;
4137     cmd_buf->Result = 0;
4138     tlv->Tag = MRVL_WPA_PASSPHRASE_TLV_ID;
4139     if (argc == 0) {
4140         cmd_buf->Action = ACTION_GET;
4141         tlv->Length = MAX_WPA_PASSPHRASE_LENGTH;
4142     } else {
4143         cmd_buf->Action = ACTION_SET;
4144         tlv->Length = strlen(argv[0]);
4145         memcpy(tlv->Passphrase, argv[0], tlv->Length);
4146     }
4147     endian_convert_tlv_header_out(tlv);
4148     /* Send the command */
4149     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
4150     endian_convert_tlv_header_in(tlv);
4151     /* Process response */
4152     if (ret == UAP_SUCCESS) {
4153         /* Verify response */
4154         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
4155             (tlv->Tag != MRVL_WPA_PASSPHRASE_TLV_ID)) {
4156             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
4157                    cmd_buf->CmdCode, tlv->Tag);
4158             free(buffer);
4159             return;
4160         }
4161         /* Print response */
4162         if (cmd_buf->Result == CMD_SUCCESS) {
4163             if (argc == 0) {
4164                 if (tlv->Length > 0)
4165                     printf("WPA passphrase = %s\n", tlv->Passphrase);
4166                 else
4167                     printf("WPA passphrase: None\n");
4168             } else {
4169                 printf("WPA passphrase setting successful\n");
4170             }
4171         } else {
4172             if (argc == 0) {
4173                 printf("ERR:Could not get WPA passphrase!\n");
4174             } else {
4175                 printf("ERR:Could not set WPA passphrase!\n");
4176             }
4177         }
4178     } else {
4179         printf("ERR:Command sending failed!\n");
4180     }
4181     if (buffer)
4182         free(buffer);
4183     return;
4184 }
4185
4186 /** 
4187  *  @brief Creates a STA filter request and sends to the driver
4188  *
4189  *   Usage: "sta_filter_table <FILTERMODE> <MACADDRESS_LIST>"
4190  *
4191  *   Options: FILTERMODE : 0 - Disable filter table
4192  *                         1 - Allow mac address specified in the allwed list
4193  *                         2 - Block MAC addresses specified in the  banned list
4194  *            MACADDRESS_LIST is the list of MAC addresses to be acted upon. Each
4195  *                         MAC address must be separated with a space. Maximum of
4196  *                         16 MAC addresses are supported.
4197  *
4198  *  @param argc     Number of arguments
4199  *  @param argv     Pointer to the arguments
4200  *  @return         N/A
4201  */
4202 void
4203 apcmd_sta_filter_table(int argc, char *argv[])
4204 {
4205     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
4206     TLVBUF_STA_MAC_ADDR_FILTER *tlv = NULL;
4207     u8 *buffer = NULL;
4208     u16 cmd_len;
4209     int ret = UAP_FAILURE;
4210     int i = 0;
4211     int opt;
4212     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
4213         switch (opt) {
4214         default:
4215             print_sta_filter_table_usage();
4216             return;
4217         }
4218     }
4219     argc -= optind;
4220     argv += optind;
4221     /* Check arguments */
4222     if (argc > (MAX_MAC_ONESHOT_FILTER + 1)) {
4223         printf("ERR:Too many arguments.\n");
4224         print_sta_filter_table_usage();
4225         return;
4226     }
4227     if (argc > 0) {
4228         if ((ISDIGIT(argv[0]) == 0) ||
4229             ((atoi(argv[0]) < 0) || (atoi(argv[0]) > 2))) {
4230             printf
4231                 ("ERR:Illegal FILTERMODE parameter %s. Must be either '0', '1', or '2'.\n",
4232                  argv[1]);
4233             print_sta_filter_table_usage();
4234             return;
4235         }
4236         if ((atoi(argv[0]) != 0) && (argc == 1)) {
4237             printf("ERR:At least one mac is required.\n");
4238             print_sta_filter_table_usage();
4239             return;
4240         }
4241     }
4242     /* Initialize the command length */
4243     if (argc == 0) {
4244         cmd_len =
4245             sizeof(APCMDBUF_SYS_CONFIGURE) +
4246             sizeof(TLVBUF_STA_MAC_ADDR_FILTER) +
4247             (MAX_MAC_ONESHOT_FILTER * ETH_ALEN);
4248     } else {
4249         cmd_len =
4250             sizeof(APCMDBUF_SYS_CONFIGURE) +
4251             sizeof(TLVBUF_STA_MAC_ADDR_FILTER) + (argc - 1) * ETH_ALEN;
4252     }
4253
4254     /* Initialize the command buffer */
4255     buffer = (u8 *) malloc(cmd_len);
4256
4257     if (!buffer) {
4258         printf("ERR:Cannot allocate buffer for command!\n");
4259         return;
4260     }
4261     bzero((char *) buffer, cmd_len);
4262     /* Locate headers */
4263     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
4264     tlv =
4265         (TLVBUF_STA_MAC_ADDR_FILTER *) (buffer +
4266                                         sizeof(APCMDBUF_SYS_CONFIGURE));
4267
4268     /* Fill the command buffer */
4269     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
4270     cmd_buf->Size = cmd_len;
4271     cmd_buf->SeqNum = 0;
4272     cmd_buf->Result = 0;
4273     tlv->Tag = MRVL_STA_MAC_ADDR_FILTER_TLV_ID;
4274     if (argc == 0) {
4275         cmd_buf->Action = ACTION_GET;
4276         tlv->Count = MAX_MAC_ONESHOT_FILTER;
4277     } else {
4278         cmd_buf->Action = ACTION_SET;
4279         tlv->FilterMode = atoi(argv[0]);
4280         tlv->Count = argc - 1;
4281         for (i = 0; i < tlv->Count; i++) {
4282             if ((ret =
4283                  mac2raw(argv[i + 1],
4284                          &tlv->MacAddress[i * ETH_ALEN])) != UAP_SUCCESS) {
4285                 printf("ERR: %s Address\n",
4286                        ret == UAP_FAILURE ? "Invalid MAC" : ret ==
4287                        UAP_RET_MAC_BROADCAST ? "Broadcast" : "Multicast");
4288                 print_sta_filter_table_usage();
4289                 free(buffer);
4290                 return;
4291             }
4292         }
4293     }
4294     tlv->Length = tlv->Count * ETH_ALEN + 2;
4295     endian_convert_tlv_header_out(tlv);
4296     /* Send the command */
4297     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
4298     endian_convert_tlv_header_in(tlv);
4299     /* Process response */
4300     if (ret == UAP_SUCCESS) {
4301         /* Verify response */
4302         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
4303             (tlv->Tag != MRVL_STA_MAC_ADDR_FILTER_TLV_ID)) {
4304             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
4305                    cmd_buf->CmdCode, tlv->Tag);
4306             free(buffer);
4307             return;
4308         }
4309         /* Print response */
4310         if (cmd_buf->Result == CMD_SUCCESS) {
4311             if (argc == 0) {
4312                 print_mac_filter(tlv);
4313             } else {
4314                 printf("MAC address filter table setting successful!\n");
4315             }
4316         } else {
4317             if (argc == 0) {
4318                 printf
4319                     ("ERR:Could not get MAC address filter table settings!\n");
4320             } else {
4321                 printf
4322                     ("ERR:Could not set MAC address filter table settings!\n");
4323             }
4324         }
4325     } else {
4326         printf("ERR:Command sending failed!\n");
4327     }
4328     if (buffer)
4329         free(buffer);
4330     return;
4331 }
4332
4333 /** 
4334  *  @brief Creates a sys_cfg request for max station number
4335  *   and sends to the driver
4336  *
4337  *   Usage: "sys_cfg_max_sta_num [STA_NUM]"
4338  *           if STA_NUM is provided, a 'set' is performed
4339  *           else a 'get' is performed.
4340  *
4341  *           STA_NUM should not bigger than 8
4342  *
4343  *  @param argc     Number of arguments
4344  *  @param argv     Pointer to the arguments
4345  *  @return         N/A
4346  */
4347 void
4348 apcmd_sys_cfg_max_sta_num(int argc, char *argv[])
4349 {
4350     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
4351     TLVBUF_MAX_STA_NUM *tlv = NULL;
4352     u8 *buffer = NULL;
4353     u16 cmd_len;
4354     int ret = UAP_FAILURE;
4355     int opt;
4356
4357     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
4358         switch (opt) {
4359         default:
4360             print_sys_cfg_max_sta_num_usage();
4361             return;
4362         }
4363     }
4364     argc -= optind;
4365     argv += optind;
4366
4367     /* Check arguments */
4368     if (argc && (is_input_valid(MAXSTANUM, argc, argv) != UAP_SUCCESS)) {
4369         print_sys_cfg_max_sta_num_usage();
4370         return;
4371     }
4372
4373     /* Initialize the command length */
4374     cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_MAX_STA_NUM);
4375
4376     /* Initialize the command buffer */
4377     buffer = (u8 *) malloc(cmd_len);
4378
4379     if (!buffer) {
4380         printf("ERR:Cannot allocate buffer for command!\n");
4381         return;
4382     }
4383     bzero((char *) buffer, cmd_len);
4384
4385     /* Locate headers */
4386     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
4387     tlv = (TLVBUF_MAX_STA_NUM *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
4388
4389     /* Fill the command buffer */
4390     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
4391     cmd_buf->Size = cmd_len;
4392     cmd_buf->SeqNum = 0;
4393     cmd_buf->Result = 0;
4394     tlv->Tag = MRVL_MAX_STA_CNT_TLV_ID;
4395     tlv->Length = 2;
4396     if (argc == 0) {
4397         cmd_buf->Action = ACTION_GET;
4398     } else {
4399         cmd_buf->Action = ACTION_SET;
4400         tlv->Max_sta_num = (u16) atoi(argv[0]);
4401     }
4402     endian_convert_tlv_header_out(tlv);
4403     tlv->Max_sta_num = uap_cpu_to_le16(tlv->Max_sta_num);
4404
4405     /* Send the command */
4406     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
4407     endian_convert_tlv_header_in(tlv);
4408     tlv->Max_sta_num = uap_le16_to_cpu(tlv->Max_sta_num);
4409     /* Process response */
4410     if (ret == UAP_SUCCESS) {
4411         /* Verify response */
4412         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
4413             (tlv->Tag != MRVL_MAX_STA_CNT_TLV_ID)) {
4414             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
4415                    cmd_buf->CmdCode, tlv->Tag);
4416             free(buffer);
4417             return;
4418         }
4419         /* Print response */
4420         if (cmd_buf->Result == CMD_SUCCESS) {
4421             if (argc == 0) {
4422                 printf("max station number = %d\n", tlv->Max_sta_num);
4423             } else {
4424                 printf("max station number setting successful\n");
4425             }
4426         } else {
4427             if (argc == 0) {
4428                 printf("ERR:Could not get max station number!\n");
4429             } else {
4430                 printf("ERR:Could not set max station number!\n");
4431             }
4432         }
4433     } else {
4434         printf("ERR:Command sending failed!\n");
4435     }
4436     if (buffer)
4437         free(buffer);
4438     return;
4439 }
4440
4441 /** 
4442  *  @brief Creates a sys_cfg request for retry limit
4443  *   and sends to the driver
4444  *
4445  *   Usage: "sys_cfg_retry_limit [RETRY_LIMIT]"
4446  *           if RETRY_LIMIT is provided, a 'set' is performed
4447  *           else a 'get' is performed.
4448  *
4449  *           RETRY_LIMIT should not bigger than 14
4450  *
4451  *  @param argc     Number of arguments
4452  *  @param argv     Pointer to the arguments
4453  *  @return         N/A
4454  */
4455 void
4456 apcmd_sys_cfg_retry_limit(int argc, char *argv[])
4457 {
4458     APCMDBUF_SYS_CONFIGURE *cmd_buf = NULL;
4459     TLVBUF_RETRY_LIMIT *tlv = NULL;
4460     u8 *buffer = NULL;
4461     u16 cmd_len;
4462     int ret = UAP_FAILURE;
4463     int opt;
4464
4465     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
4466         switch (opt) {
4467         default:
4468             print_sys_cfg_max_sta_num_usage();
4469             return;
4470         }
4471     }
4472     argc -= optind;
4473     argv += optind;
4474
4475     /* Check arguments */
4476     if (argc && (is_input_valid(RETRYLIMIT, argc, argv) != UAP_SUCCESS)) {
4477         print_sys_cfg_retry_limit_usage();
4478         return;
4479     }
4480
4481     /* Initialize the command length */
4482     cmd_len = sizeof(APCMDBUF_SYS_CONFIGURE) + sizeof(TLVBUF_RETRY_LIMIT);
4483
4484     /* Initialize the command buffer */
4485     buffer = (u8 *) malloc(cmd_len);
4486
4487     if (!buffer) {
4488         printf("ERR:Cannot allocate buffer for command!\n");
4489         return;
4490     }
4491     bzero((char *) buffer, cmd_len);
4492
4493     /* Locate headers */
4494     cmd_buf = (APCMDBUF_SYS_CONFIGURE *) buffer;
4495     tlv = (TLVBUF_RETRY_LIMIT *) (buffer + sizeof(APCMDBUF_SYS_CONFIGURE));
4496
4497     /* Fill the command buffer */
4498     cmd_buf->CmdCode = APCMD_SYS_CONFIGURE;
4499     cmd_buf->Size = cmd_len;
4500     cmd_buf->SeqNum = 0;
4501     cmd_buf->Result = 0;
4502     tlv->Tag = MRVL_RETRY_LIMIT_TLV_ID;
4503     tlv->Length = 1;
4504     if (argc == 0) {
4505         cmd_buf->Action = ACTION_GET;
4506     } else {
4507         cmd_buf->Action = ACTION_SET;
4508         tlv->retry_limit = (u8) atoi(argv[0]);
4509     }
4510     endian_convert_tlv_header_out(tlv);
4511
4512     /* Send the command */
4513     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, cmd_len);
4514     endian_convert_tlv_header_in(tlv);
4515
4516     /* Process response */
4517     if (ret == UAP_SUCCESS) {
4518         /* Verify response */
4519         if ((cmd_buf->CmdCode != (APCMD_SYS_CONFIGURE | APCMD_RESP_CHECK)) ||
4520             (tlv->Tag != MRVL_RETRY_LIMIT_TLV_ID)) {
4521             printf("ERR:Corrupted response! CmdCode=%x, Tlv->Tag=%x\n",
4522                    cmd_buf->CmdCode, tlv->Tag);
4523             free(buffer);
4524             return;
4525         }
4526         /* Print response */
4527         if (cmd_buf->Result == CMD_SUCCESS) {
4528             if (argc == 0) {
4529                 printf("retry limit = %d\n", tlv->retry_limit);
4530             } else {
4531                 printf("retry limit setting successful\n");
4532             }
4533         } else {
4534             if (argc == 0) {
4535                 printf("ERR:Could not get retry limit!\n");
4536             } else {
4537                 printf("ERR:Could not set retry limit!\n");
4538             }
4539         }
4540     } else {
4541         printf("ERR:Command sending failed!\n");
4542     }
4543     if (buffer)
4544         free(buffer);
4545     return;
4546 }
4547
4548 /** 
4549  *  @brief convert string to integer
4550  * 
4551  *  @param ptr          A pointer to data buffer
4552  *  @param chr          A pointer to return integer
4553  *  @return             A pointer to next data field
4554  */
4555 char *
4556 convert2hex(char *ptr, u8 * chr)
4557 {
4558     u8 val;
4559
4560     for (val = 0; *ptr && isxdigit(*ptr); ptr++) {
4561         val = (val * 16) + hexc2bin(*ptr);
4562     }
4563
4564     *chr = val;
4565
4566     return ptr;
4567 }
4568
4569 /** 
4570  *  @brief parse hex data
4571  *  @param fp           A pointer to FILE stream
4572  *  @param dst          A pointer to receive hex data
4573  *  @return             length of hex data
4574  */
4575 int
4576 fparse_for_hex(FILE * fp, u8 * dst)
4577 {
4578     char *ptr;
4579     u8 *dptr;
4580     char buf[256];
4581
4582     dptr = dst;
4583     while (fgets(buf, sizeof(buf), fp)) {
4584         ptr = buf;
4585
4586         while (*ptr) {
4587             /* skip leading spaces */
4588             while (*ptr && (isspace(*ptr) || *ptr == '\t'))
4589                 ptr++;
4590
4591             /* skip blank lines and lines beginning with '#' */
4592             if (*ptr == '\0' || *ptr == '#')
4593                 break;
4594
4595             if (isxdigit(*ptr)) {
4596                 ptr = convert2hex(ptr, dptr++);
4597             } else {
4598                 /* Invalid character on data line */
4599                 ptr++;
4600             }
4601         }
4602     }
4603
4604     return (dptr - dst);
4605 }
4606
4607 /** 
4608  *  @brief Creates a cfg_data request 
4609  *   and sends to the driver
4610  *
4611  *   Usage: "cfg_data <cfg_data.conf>"
4612  *
4613  *  @param argc     Number of arguments
4614  *  @param argv     Pointer to the arguments
4615  *  @return         N/A
4616  */
4617 void
4618 apcmd_cfg_data(int argc, char *argv[])
4619 {
4620     APCMDBUF_CFG_DATA *cmd_buf = NULL;
4621     u8 *buf = NULL;
4622     u16 cmd_len;
4623     u16 buf_len;
4624     int ret = UAP_FAILURE;
4625     int opt;
4626     FILE *fp = NULL;
4627     while ((opt = getopt_long(argc, argv, "+", cmd_options, NULL)) != -1) {
4628         switch (opt) {
4629         default:
4630             print_cfg_data_usage();
4631             return;
4632         }
4633     }
4634     argc -= optind;
4635     argv += optind;
4636
4637     /* Check arguments */
4638     if ((argc == 0) || (argc > 2)) {
4639         printf("ERR:wrong arguments.\n");
4640         print_cfg_data_usage();
4641         return;
4642     } else {
4643         if ((ISDIGIT(argv[0]) == 0) || (atoi(argv[0]) != 2)) {
4644             printf("ERR:Illegal type parameter %s. Must be '2'.\n", argv[0]);
4645             print_cfg_data_usage();
4646             return;
4647         }
4648     }
4649     buf_len = MRVDRV_SIZE_OF_CMD_BUFFER;
4650     buf = (u8 *) malloc(buf_len);
4651     memset(buf, 0, buf_len);
4652     cmd_buf = (APCMDBUF_CFG_DATA *) buf;
4653     if (buf == NULL) {
4654         printf("Error: allocate memory for hostcmd failed\n");
4655         return;
4656     }
4657     if (argc == 2) {
4658         /* Check if file exists */
4659         fp = fopen(argv[1], "r");
4660         if (fp == NULL) {
4661             printf("\nERR:Config file can not open %s.\n", argv[1]);
4662             free(buf);
4663             return;
4664         }
4665         cmd_buf->action = ACTION_SET;
4666         cmd_buf->data_len = fparse_for_hex(fp, cmd_buf->data);
4667         fclose(fp);
4668         if (cmd_buf->data_len > MAX_CFG_DATA_SIZE) {
4669             printf("ERR: Config file is too big %d\n", cmd_buf->data_len);
4670             free(buf);
4671             return;
4672         }
4673     } else {
4674         cmd_buf->action = ACTION_GET;
4675         cmd_buf->data_len = 0;
4676     }
4677
4678     cmd_buf->action = uap_cpu_to_le16(cmd_buf->action);
4679     cmd_buf->type = atoi(argv[0]);
4680     cmd_buf->type = uap_cpu_to_le16(cmd_buf->type);
4681     cmd_buf->data_len = uap_cpu_to_le16(cmd_buf->data_len);
4682
4683     /* Fill the command buffer */
4684     cmd_len = cmd_buf->data_len + sizeof(APCMDBUF_CFG_DATA);
4685     cmd_buf->CmdCode = HostCmd_CMD_CFG_DATA;
4686     cmd_buf->Size = cmd_len;
4687     cmd_buf->SeqNum = 0;
4688     cmd_buf->Result = 0;
4689
4690     /* Send the command */
4691     ret = uap_ioctl((u8 *) cmd_buf, &cmd_len, buf_len);
4692     /* Process response */
4693     if (ret == UAP_SUCCESS) {
4694         cmd_buf->action = uap_le16_to_cpu(cmd_buf->action);
4695         cmd_buf->data_len = uap_le16_to_cpu(cmd_buf->data_len);
4696         if (cmd_buf->action == ACTION_GET) {
4697             hexdump_data("cfg_data", cmd_buf->data, cmd_buf->data_len, ' ');
4698         } else
4699             printf("download cfg data successful\n");
4700     }
4701     if (buf)
4702         free(buf);
4703     return;
4704 }