1 /*******************************************************************************
3 * Wireless device driver for Linux (wlags49).
5 * Copyright (c) 1998-2003 Agere Systems Inc.
9 * Initially developed by TriplePoint, Inc.
10 * http://www.triplepoint.com
12 *------------------------------------------------------------------------------
14 * This file defines routines required to parse configuration parameters
15 * listed in a config file, if that config file exists.
17 *------------------------------------------------------------------------------
21 * This software is provided subject to the following terms and conditions,
22 * which you should read carefully before using the software. Using this
23 * software indicates your acceptance of these terms and conditions. If you do
24 * not agree with these terms and conditions, do not use the software.
26 * Copyright © 2003 Agere Systems Inc.
27 * All rights reserved.
29 * Redistribution and use in source or binary forms, with or without
30 * modifications, are permitted provided that the following conditions are met:
32 * . Redistributions of source code must retain the above copyright notice, this
33 * list of conditions and the following Disclaimer as comments in the code as
34 * well as in the documentation and/or other materials provided with the
37 * . Redistributions in binary form must reproduce the above copyright notice,
38 * this list of conditions and the following Disclaimer in the documentation
39 * and/or other materials provided with the distribution.
41 * . Neither the name of Agere Systems Inc. nor the names of the contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
47 * THIS SOFTWARE IS PROVIDED
\93AS IS
\94 AND ANY EXPRESS OR IMPLIED WARRANTIES,
48 * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
49 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY
50 * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
51 * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
52 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
53 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
54 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
55 * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
57 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
60 ******************************************************************************/
62 /* Only include this file if USE_PROFILE is defined */
68 /*******************************************************************************
69 * constant definitions
70 ******************************************************************************/
73 /* Allow support for calling system fcns to parse config file */
74 #define __KERNEL_SYSCALLS__
79 /*******************************************************************************
81 ******************************************************************************/
82 #include <wl_version.h>
84 #include <linux/netdevice.h>
85 #include <linux/etherdevice.h>
86 #include <linux/unistd.h>
87 #include <asm/uaccess.h>
94 /* #include <hcfdef.h> */
97 #include <wl_internal.h>
101 #include <wl_profile.h>
104 /*******************************************************************************
106 ******************************************************************************/
108 /* Definition needed to prevent unresolved external in unistd.h */
112 extern p_u32 DebugFlag;
113 extern dbg_info_t *DbgInfo;
116 int parse_yes_no(char *value);
119 int parse_yes_no(char *value)
121 int rc = 0; /* default to NO for invalid parameters */
123 if (strlen(value) == 1) {
124 if ((value[0] | ('Y'^'y')) == 'y')
127 /* this should not be debug time info, it is an enduser data entry error ;? */
128 /* DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MICROWAVE_ROBUSTNESS); */
134 /*******************************************************************************
136 *******************************************************************************
140 * This function opens the device's config file and parses the options from
141 * it, so that it can properly configure itself. If no configuration file
142 * or configuration is present, then continue to use the options already
143 * parsed from config.opts or wireless.opts.
147 * dev - a pointer to the device's net_device structure
153 ******************************************************************************/
154 void parse_config(struct net_device *dev)
161 char buffer[MAX_LINE_SIZE];
162 char filename[MAX_LINE_SIZE];
164 struct wl_private *wvlan_config = NULL;
165 ENCSTRCT sEncryption;
166 /*------------------------------------------------------------------------*/
170 /* Get the wavelan specific info for this device */
171 wvlan_config = dev->priv;
172 if (wvlan_config == NULL) {
173 DBG_ERROR(DbgInfo, "Wavelan specific info struct not present?\n");
177 /* setup the default encryption string */
178 strcpy(wvlan_config->szEncryption, DEF_CRYPT_STR);
180 /* Obtain a user-space process context, storing the original context */
184 /* Determine the filename for this device and attempt to open it */
185 sprintf(filename, "%s%s", ROOT_CONFIG_FILENAME, dev->name);
186 file_desc = open(filename, O_RDONLY, 0);
187 if (file_desc != -1) {
188 DBG_TRACE(DbgInfo, "Wireless config file found. Parsing options...\n");
190 /* Read out the options */
191 while (readline(file_desc, buffer))
192 translate_option(buffer, wvlan_config);
194 close(file_desc); /* ;?even if file_desc == -1 ??? */
196 DBG_TRACE(DbgInfo, "No iwconfig file found for this device; "
197 "config.opts or wireless.opts will be used\n");
199 /* Return to the original context */
202 /* convert the WEP keys, if read in as key1, key2, type of data */
203 if (wvlan_config->EnableEncryption) {
204 memset(&sEncryption, 0, sizeof(sEncryption));
206 wl_wep_decode(CRYPT_CODE, &sEncryption,
207 wvlan_config->szEncryption);
209 /* the Linux driver likes to use 1-4 for the key IDs, and then
210 convert to 0-3 when sending to the card. The Windows code
211 base used 0-3 in the API DLL, which was ported to Linux. For
212 the sake of the user experience, we decided to keep 0-3 as the
213 numbers used in the DLL; and will perform the +1 conversion here.
214 We could have converted the entire Linux driver, but this is
215 less obtrusive. This may be a "todo" to convert the whole driver */
216 sEncryption.wEnabled = wvlan_config->EnableEncryption;
217 sEncryption.wTxKeyID = wvlan_config->TransmitKeyID - 1;
219 memcpy(&sEncryption.EncStr, &wvlan_config->DefaultKeys,
220 sizeof(CFG_DEFAULT_KEYS_STRCT));
222 memset(wvlan_config->szEncryption, 0, sizeof(wvlan_config->szEncryption));
224 wl_wep_code(CRYPT_CODE, wvlan_config->szEncryption, &sEncryption,
225 sizeof(sEncryption));
228 /* decode the encryption string for the call to wl_commit() */
229 wl_wep_decode(CRYPT_CODE, &sEncryption, wvlan_config->szEncryption);
231 wvlan_config->TransmitKeyID = sEncryption.wTxKeyID + 1;
232 wvlan_config->EnableEncryption = sEncryption.wEnabled;
234 memcpy(&wvlan_config->DefaultKeys, &sEncryption.EncStr,
235 sizeof(CFG_DEFAULT_KEYS_STRCT));
238 /* Obtain a user-space process context, storing the original context */
242 /* ;?just to fake something */
243 strcpy(/*wvlan_config->fw_image_*/filename, "/etc/agere/fw.bin");
244 file_desc = open(/*wvlan_config->fw_image_*/filename, 0, 0);
245 if (file_desc == -1) {
246 DBG_ERROR(DbgInfo, "No image file found\n");
248 DBG_TRACE(DbgInfo, "F/W image file found\n");
249 #define DHF_ALLOC_SIZE 96000 /* just below 96K, let's hope it suffices for now and for the future */
250 cp = vmalloc(DHF_ALLOC_SIZE);
252 DBG_ERROR(DbgInfo, "error in vmalloc\n");
254 rc = read(file_desc, cp, DHF_ALLOC_SIZE);
255 if (rc == DHF_ALLOC_SIZE) {
256 DBG_ERROR(DbgInfo, "buffer too small, %d\n", DHF_ALLOC_SIZE);
258 DBG_TRACE(DbgInfo, "read O.K.: %d bytes %.12s\n", rc, cp);
259 rc = read(file_desc, &cp[rc], 1);
261 DBG_TRACE(DbgInfo, "no more to read\n");
264 DBG_ERROR(DbgInfo, "file not read in one swoop or other error"\
265 ", give up, too complicated, rc = %0X\n", rc);
271 set_fs(fs); /* Return to the original context */
278 /*******************************************************************************
280 *******************************************************************************
284 * This function reads in data from a given file one line at a time,
285 * converting the detected newline character '\n' to a null '\0'. Note that
286 * the file descriptor must be valid before calling this function.
290 * filedesc - the file descriptor for the open configuration file
291 * buffer - a buffer pointer, passed in by the caller, to which the
292 * line will be stored.
296 * the number of bytes read
299 ******************************************************************************/
300 int readline(int filedesc, char *buffer)
304 /*------------------------------------------------------------------------*/
306 /* Make sure the file descriptor is good */
307 if (filedesc != -1) {
308 /* Read in from the file byte by byte until a newline is reached */
309 while ((result = read(filedesc, &buffer[bytes_read], 1)) == 1) {
310 if (buffer[bytes_read] == '\n') {
311 buffer[bytes_read] = '\0';
319 /* Return the number of bytes read */
325 /*============================================================================*/
327 /*******************************************************************************
329 *******************************************************************************
333 * This function takes a line read in from the config file and parses out
334 * the key/value pairs. It then determines which key has been parsed and sets
335 * the card's configuration based on the value given.
339 * buffer - a buffer containing a line to translate
340 * config - a pointer to the device's private adapter structure
346 ******************************************************************************/
347 void translate_option(char *buffer, struct wl_private *lp)
349 unsigned int value_convert = 0;
350 int string_length = 0;
353 u_char mac_value[ETH_ALEN];
354 /*------------------------------------------------------------------------*/
356 if (buffer == NULL || lp == NULL) {
357 DBG_ERROR(DbgInfo, "Config file buffer and/or wavelan buffer ptr NULL\n");
361 ParseConfigLine(buffer, &key, &value);
363 if (key == NULL || value == NULL)
366 /* Determine which key it is and perform the appropriate action */
368 /* Configuration parameters used in all scenarios */
370 /* handle DebugFlag as early as possible so it starts its influence as early
373 if (strcmp(key, PARM_NAME_DEBUG_FLAG) == 0) {
374 if (DebugFlag == ~0) { /* if DebugFlag is not specified on the command line */
375 if (DbgInfo->DebugFlag == 0) { /* if pc_debug did not set DebugFlag (i.e.pc_debug is
376 * not specified or specified outside the 4-8 range
378 DbgInfo->DebugFlag |= DBG_DEFAULTS;
381 DbgInfo->DebugFlag = simple_strtoul(value, NULL, 0); /* ;?DebugFlag; */
383 DbgInfo->DebugFlag = simple_strtoul(value, NULL, 0); /* ;?Delete ASAP */
386 if (strcmp(key, PARM_NAME_AUTH_KEY_MGMT_SUITE) == 0) {
387 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_AUTH_KEY_MGMT_SUITE, value);
389 value_convert = simple_strtoul(value, NULL, 0);
390 if ((value_convert >= PARM_MIN_AUTH_KEY_MGMT_SUITE) || (value_convert <= PARM_MAX_AUTH_KEY_MGMT_SUITE))
391 lp->AuthKeyMgmtSuite = value_convert;
393 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_AUTH_KEY_MGMT_SUITE);
394 } else if (strcmp(key, PARM_NAME_BRSC_2GHZ) == 0) {
395 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_2GHZ, value);
397 value_convert = simple_strtoul(value, NULL, 0);
398 if ((value_convert >= PARM_MIN_BRSC) || (value_convert <= PARM_MAX_BRSC))
399 lp->brsc[0] = value_convert;
401 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_BRSC_2GHZ);
402 } else if (strcmp(key, PARM_NAME_BRSC_5GHZ) == 0) {
403 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_5GHZ, value);
405 value_convert = simple_strtoul(value, NULL, 0);
406 if ((value_convert >= PARM_MIN_BRSC) || (value_convert <= PARM_MAX_BRSC))
407 lp->brsc[1] = value_convert;
409 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_BRSC_5GHZ);
410 } else if ((strcmp(key, PARM_NAME_DESIRED_SSID) == 0) || (strcmp(key, PARM_NAME_OWN_SSID) == 0)) {
411 DBG_TRACE(DbgInfo, "SSID, value: %s\n", value);
413 memset(lp->NetworkName, 0, (PARM_MAX_NAME_LEN + 1));
415 /* Make sure the value isn't too long */
416 string_length = strlen(value);
417 if (string_length > PARM_MAX_NAME_LEN) {
418 DBG_WARNING(DbgInfo, "SSID too long; will be truncated\n");
419 string_length = PARM_MAX_NAME_LEN;
422 memcpy(lp->NetworkName, value, string_length);
425 else if (strcmp(key, PARM_NAME_DOWNLOAD_FIRMWARE) == 0) {
426 DBG_TRACE(DbgInfo, "DOWNLOAD_FIRMWARE, value: %s\n", value);
427 memset(lp->fw_image_filename, 0, (MAX_LINE_SIZE + 1));
428 /* Make sure the value isn't too long */
429 string_length = strlen(value);
430 if (string_length > MAX_LINE_SIZE)
431 DBG_WARNING(DbgInfo, "F/W image file name too long; will be ignored\n");
433 memcpy(lp->fw_image_filename, value, string_length);
436 else if (strcmp(key, PARM_NAME_ENABLE_ENCRYPTION) == 0) {
437 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_ENABLE_ENCRYPTION, value);
439 value_convert = simple_strtoul(value, NULL, 0);
440 if ((value_convert >= PARM_MIN_ENABLE_ENCRYPTION) && (value_convert <= PARM_MAX_ENABLE_ENCRYPTION))
441 lp->EnableEncryption = value_convert;
443 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_ENABLE_ENCRYPTION);
444 } else if (strcmp(key, PARM_NAME_ENCRYPTION) == 0) {
445 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_ENCRYPTION, value);
447 memset(lp->szEncryption, 0, sizeof(lp->szEncryption));
449 /* Make sure the value isn't too long */
450 string_length = strlen(value);
451 if (string_length > sizeof(lp->szEncryption)) {
452 DBG_WARNING(DbgInfo, "%s too long; will be truncated\n", PARM_NAME_ENCRYPTION);
453 string_length = sizeof(lp->szEncryption);
456 memcpy(lp->szEncryption, value, string_length);
457 } else if (strcmp(key, PARM_NAME_KEY1) == 0) {
458 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_KEY1, value);
460 if (is_valid_key_string(value)) {
461 memset(lp->DefaultKeys.key[0].key, 0, MAX_KEY_SIZE);
463 key_string2key(value, &lp->DefaultKeys.key[0]);
465 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY1);
467 } else if (strcmp(key, PARM_NAME_KEY2) == 0) {
468 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_KEY2, value);
470 if (is_valid_key_string(value)) {
471 memset(lp->DefaultKeys.key[1].key, 0, MAX_KEY_SIZE);
473 key_string2key(value, &lp->DefaultKeys.key[1]);
475 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY2);
477 } else if (strcmp(key, PARM_NAME_KEY3) == 0) {
478 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_KEY3, value);
480 if (is_valid_key_string(value)) {
481 memset(lp->DefaultKeys.key[2].key, 0, MAX_KEY_SIZE);
483 key_string2key(value, &lp->DefaultKeys.key[2]);
485 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY3);
487 } else if (strcmp(key, PARM_NAME_KEY4) == 0) {
488 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_KEY4, value);
490 if (is_valid_key_string(value)) {
491 memset(lp->DefaultKeys.key[3].key, 0, MAX_KEY_SIZE);
493 key_string2key(value, &lp->DefaultKeys.key[3]);
495 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY4);
498 /* New Parameters for WARP */
499 else if (strcmp(key, PARM_NAME_LOAD_BALANCING) == 0) {
500 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_LOAD_BALANCING, value);
501 lp->loadBalancing = parse_yes_no(value);
502 } else if (strcmp(key, PARM_NAME_MEDIUM_DISTRIBUTION) == 0) {
503 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MEDIUM_DISTRIBUTION, value);
504 lp->mediumDistribution = parse_yes_no(value);
505 } else if (strcmp(key, PARM_NAME_MICROWAVE_ROBUSTNESS) == 0) {
506 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MICROWAVE_ROBUSTNESS, value);
507 lp->MicrowaveRobustness = parse_yes_no(value);
508 } else if (strcmp(key, PARM_NAME_MULTICAST_RATE) == 0) {
509 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_RATE, value);
511 value_convert = simple_strtoul(value, NULL, 0);
513 if ((value_convert >= PARM_MIN_MULTICAST_RATE) && (value_convert <= PARM_MAX_MULTICAST_RATE))
514 lp->MulticastRate[0] = value_convert;
516 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MULTICAST_RATE);
517 } else if (strcmp(key, PARM_NAME_OWN_CHANNEL) == 0) {
518 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_CHANNEL, value);
520 value_convert = simple_strtoul(value, NULL, 0);
521 if (wl_is_a_valid_chan(value_convert)) {
522 if (value_convert > 14)
523 value_convert = value_convert | 0x100;
524 lp->Channel = value_convert;
526 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_CHANNEL);
528 } else if (strcmp(key, PARM_NAME_OWN_NAME) == 0) {
529 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_NAME, value);
531 memset(lp->StationName, 0, (PARM_MAX_NAME_LEN + 1));
533 /* Make sure the value isn't too long */
534 string_length = strlen(value);
535 if (string_length > PARM_MAX_NAME_LEN) {
536 DBG_WARNING(DbgInfo, "%s too long; will be truncated\n", PARM_NAME_OWN_NAME);
537 string_length = PARM_MAX_NAME_LEN;
540 memcpy(lp->StationName, value, string_length);
541 } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD) == 0) {
542 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD, value);
544 value_convert = simple_strtoul(value, NULL, 0);
545 if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD))
546 lp->RTSThreshold = value_convert;
548 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD);
549 } else if (strcmp(key, PARM_NAME_SRSC_2GHZ) == 0) {
550 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_2GHZ, value);
552 value_convert = simple_strtoul(value, NULL, 0);
553 if ((value_convert >= PARM_MIN_SRSC) || (value_convert <= PARM_MAX_SRSC))
554 lp->srsc[0] = value_convert;
556 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_SRSC_2GHZ);
557 } else if (strcmp(key, PARM_NAME_SRSC_5GHZ) == 0) {
558 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_5GHZ, value);
560 value_convert = simple_strtoul(value, NULL, 0);
561 if ((value_convert >= PARM_MIN_SRSC) || (value_convert <= PARM_MAX_SRSC))
562 lp->srsc[1] = value_convert;
564 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_SRSC_5GHZ);
565 } else if (strcmp(key, PARM_NAME_SYSTEM_SCALE) == 0) {
566 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_SYSTEM_SCALE, value);
568 value_convert = simple_strtoul(value, NULL, 0);
569 if ((value_convert >= PARM_MIN_SYSTEM_SCALE) && (value_convert <= PARM_MAX_SYSTEM_SCALE))
570 lp->DistanceBetweenAPs = value_convert;
572 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_SYSTEM_SCALE);
573 } else if (strcmp(key, PARM_NAME_TX_KEY) == 0) {
574 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_KEY, value);
576 value_convert = simple_strtoul(value, NULL, 0);
577 if ((value_convert >= PARM_MIN_TX_KEY) && (value_convert <= PARM_MAX_TX_KEY))
578 lp->TransmitKeyID = simple_strtoul(value, NULL, 0);
580 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_KEY);
581 } else if (strcmp(key, PARM_NAME_TX_RATE) == 0) {
582 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE, value);
584 value_convert = simple_strtoul(value, NULL, 0);
585 if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE))
586 lp->TxRateControl[0] = value_convert;
588 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE);
589 } else if (strcmp(key, PARM_NAME_TX_POW_LEVEL) == 0) {
590 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_POW_LEVEL, value);
592 value_convert = simple_strtoul(value, NULL, 0);
593 if ((value_convert >= PARM_MIN_TX_POW_LEVEL) || (value_convert <= PARM_MAX_TX_POW_LEVEL))
594 lp->txPowLevel = value_convert;
596 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_POW_LEVEL);
599 /* Need to add? : Country code, Short/Long retry */
601 /* Configuration parameters specific to STA mode */
602 #if 1 /* ;? (HCF_TYPE) & HCF_TYPE_STA */
603 /* ;?seems reasonable that even an AP-only driver could afford this small additional footprint */
604 if (CNV_INT_TO_LITTLE(lp->hcfCtx.IFB_FWIdentity.comp_id) == COMP_ID_FW_STA) {
605 /* ;?should we return an error status in AP mode */
606 if (strcmp(key, PARM_NAME_PORT_TYPE) == 0) {
607 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PORT_TYPE, value);
609 value_convert = simple_strtoul(value, NULL, 0);
610 if ((value_convert == PARM_MIN_PORT_TYPE) || (value_convert == PARM_MAX_PORT_TYPE))
611 lp->PortType = value_convert;
613 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_PORT_TYPE);
614 } else if (strcmp(key, PARM_NAME_PM_ENABLED) == 0) {
615 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PM_ENABLED, value);
616 value_convert = simple_strtoul(value, NULL, 0);
617 /* ;? how about wl_main.c containing
618 * VALID_PARAM(PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD ||
619 * (PARM_PM_ENABLED & 0x7FFF) <= WVLAN_PM_STATE_STANDARD);
621 if ((value_convert & 0x7FFF) <= PARM_MAX_PM_ENABLED) {
622 lp->PMEnabled = value_convert;
624 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_PM_ENABLED);
625 /* ;?this is a data entry error, hence not a DBG_WARNING */
627 } else if (strcmp(key, PARM_NAME_CREATE_IBSS) == 0) {
628 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_CREATE_IBSS, value);
629 lp->CreateIBSS = parse_yes_no(value);
630 } else if (strcmp(key, PARM_NAME_MULTICAST_RX) == 0) {
631 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_RX, value);
632 lp->MulticastReceive = parse_yes_no(value);
633 } else if (strcmp(key, PARM_NAME_MAX_SLEEP) == 0) {
634 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MAX_SLEEP, value);
636 value_convert = simple_strtoul(value, NULL, 0);
637 if ((value_convert >= 0) && (value_convert <= 65535))
638 lp->MaxSleepDuration = value_convert;
640 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MAX_SLEEP);
641 } else if (strcmp(key, PARM_NAME_NETWORK_ADDR) == 0) {
642 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_NETWORK_ADDR, value);
644 if (parse_mac_address(value, mac_value) == ETH_ALEN)
645 memcpy(lp->MACAddress, mac_value, ETH_ALEN);
647 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_NETWORK_ADDR);
648 } else if (strcmp(key, PARM_NAME_AUTHENTICATION) == 0) {
649 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_AUTHENTICATION, value);
651 value_convert = simple_strtoul(value, NULL, 0);
652 if ((value_convert >= PARM_MIN_AUTHENTICATION) && (value_convert <= PARM_MAX_AUTHENTICATION))
653 lp->authentication = value_convert;
655 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_AUTHENTICATION);
656 } else if (strcmp(key, PARM_NAME_OWN_ATIM_WINDOW) == 0) {
657 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_ATIM_WINDOW, value);
659 value_convert = simple_strtoul(value, NULL, 0);
660 if ((value_convert >= PARM_MIN_OWN_ATIM_WINDOW) && (value_convert <= PARM_MAX_OWN_ATIM_WINDOW))
661 lp->atimWindow = value_convert;
663 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_ATIM_WINDOW);
664 } else if (strcmp(key, PARM_NAME_PM_HOLDOVER_DURATION) == 0) {
665 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PM_HOLDOVER_DURATION, value);
667 value_convert = simple_strtoul(value, NULL, 0);
668 if ((value_convert >= PARM_MIN_PM_HOLDOVER_DURATION) && (value_convert <= PARM_MAX_PM_HOLDOVER_DURATION))
669 lp->holdoverDuration = value_convert;
671 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_PM_HOLDOVER_DURATION);
672 } else if (strcmp(key, PARM_NAME_PROMISCUOUS_MODE) == 0) {
673 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PROMISCUOUS_MODE, value);
674 lp->promiscuousMode = parse_yes_no(value);
675 } else if (strcmp(key, PARM_NAME_CONNECTION_CONTROL) == 0) {
676 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_CONNECTION_CONTROL, value);
678 value_convert = simple_strtoul(value, NULL, 0);
679 if ((value_convert >= PARM_MIN_CONNECTION_CONTROL) && (value_convert <= PARM_MAX_CONNECTION_CONTROL))
680 lp->connectionControl = value_convert;
682 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_CONNECTION_CONTROL);
685 /* Need to add? : Probe Data Rate */
687 #endif /* (HCF_TYPE) & HCF_TYPE_STA */
689 /* Configuration parameters specific to AP mode */
690 #if 1 /* ;? (HCF_TYPE) & HCF_TYPE_AP */
691 /* ;?should we restore this to allow smaller memory footprint */
692 if (CNV_INT_TO_LITTLE(lp->hcfCtx.IFB_FWIdentity.comp_id) == COMP_ID_FW_AP) {
693 if (strcmp(key, PARM_NAME_OWN_DTIM_PERIOD) == 0) {
694 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_DTIM_PERIOD, value);
696 value_convert = simple_strtoul(value, NULL, 0);
697 if (value_convert >= PARM_MIN_OWN_DTIM_PERIOD)
698 lp->DTIMPeriod = value_convert;
700 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_DTIM_PERIOD);
701 } else if (strcmp(key, PARM_NAME_REJECT_ANY) == 0) {
702 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_REJECT_ANY, value);
703 lp->RejectAny = parse_yes_no(value);
704 } else if (strcmp(key, PARM_NAME_EXCLUDE_UNENCRYPTED) == 0) {
705 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_EXCLUDE_UNENCRYPTED, value);
706 lp->ExcludeUnencrypted = parse_yes_no(value);
707 } else if (strcmp(key, PARM_NAME_MULTICAST_PM_BUFFERING) == 0) {
708 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_PM_BUFFERING, value);
709 lp->ExcludeUnencrypted = parse_yes_no(value);
710 } else if (strcmp(key, PARM_NAME_INTRA_BSS_RELAY) == 0) {
711 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_INTRA_BSS_RELAY, value);
712 lp->ExcludeUnencrypted = parse_yes_no(value);
713 } else if (strcmp(key, PARM_NAME_OWN_BEACON_INTERVAL) == 0) {
714 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_BEACON_INTERVAL, value);
716 value_convert = simple_strtoul(value, NULL, 0);
717 if (value_convert >= PARM_MIN_OWN_BEACON_INTERVAL)
718 lp->ownBeaconInterval = value_convert;
720 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_BEACON_INTERVAL);
721 } else if (strcmp(key, PARM_NAME_COEXISTENCE) == 0) {
722 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_COEXISTENCE, value);
724 value_convert = simple_strtoul(value, NULL, 0);
725 if (value_convert >= PARM_MIN_COEXISTENCE)
726 lp->coexistence = value_convert;
728 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_COEXISTENCE);
732 else if (strcmp(key, PARM_NAME_RTS_THRESHOLD1) == 0) {
733 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD1, value);
735 value_convert = simple_strtoul(value, NULL, 0);
736 if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD))
737 lp->wds_port[0].rtsThreshold = value_convert;
739 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD1);
740 } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD2) == 0) {
741 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD2, value);
743 value_convert = simple_strtoul(value, NULL, 0);
744 if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD))
745 lp->wds_port[1].rtsThreshold = value_convert;
747 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD2);
748 } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD3) == 0) {
749 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD3, value);
751 value_convert = simple_strtoul(value, NULL, 0);
752 if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD))
753 lp->wds_port[2].rtsThreshold = value_convert;
755 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD3);
756 } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD4) == 0) {
757 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD4, value);
759 value_convert = simple_strtoul(value, NULL, 0);
760 if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD))
761 lp->wds_port[3].rtsThreshold = value_convert;
763 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD4);
764 } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD5) == 0) {
765 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD5, value);
767 value_convert = simple_strtoul(value, NULL, 0);
768 if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD))
769 lp->wds_port[4].rtsThreshold = value_convert;
771 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD5);
772 } else if (strcmp(key, PARM_NAME_RTS_THRESHOLD6) == 0) {
773 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD6, value);
775 value_convert = simple_strtoul(value, NULL, 0);
776 if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD))
777 lp->wds_port[5].rtsThreshold = value_convert;
779 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD6);
780 } else if (strcmp(key, PARM_NAME_TX_RATE1) == 0) {
781 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE1, value);
783 value_convert = simple_strtoul(value, NULL, 0);
784 if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE))
785 lp->wds_port[0].txRateCntl = value_convert;
787 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE1);
788 } else if (strcmp(key, PARM_NAME_TX_RATE2) == 0) {
789 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE2, value);
791 value_convert = simple_strtoul(value, NULL, 0);
792 if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE))
793 lp->wds_port[1].txRateCntl = value_convert;
795 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE2);
796 } else if (strcmp(key, PARM_NAME_TX_RATE3) == 0) {
797 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE3, value);
799 value_convert = simple_strtoul(value, NULL, 0);
800 if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE))
801 lp->wds_port[2].txRateCntl = value_convert;
803 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE3);
804 } else if (strcmp(key, PARM_NAME_TX_RATE4) == 0) {
805 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE4, value);
807 value_convert = simple_strtoul(value, NULL, 0);
808 if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE))
809 lp->wds_port[3].txRateCntl = value_convert;
811 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE4);
812 } else if (strcmp(key, PARM_NAME_TX_RATE5) == 0) {
813 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE5, value);
815 value_convert = simple_strtoul(value, NULL, 0);
816 if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE))
817 lp->wds_port[4].txRateCntl = value_convert;
819 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE5);
820 } else if (strcmp(key, PARM_NAME_TX_RATE6) == 0) {
821 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE6, value);
823 value_convert = simple_strtoul(value, NULL, 0);
824 if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE))
825 lp->wds_port[5].txRateCntl = value_convert;
827 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE6);
828 } else if (strcmp(key, PARM_NAME_WDS_ADDRESS1) == 0) {
829 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS1, value);
831 if (parse_mac_address(value, mac_value) == ETH_ALEN)
832 memcpy(lp->wds_port[0].wdsAddress, mac_value, ETH_ALEN);
834 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS1);
835 } else if (strcmp(key, PARM_NAME_WDS_ADDRESS2) == 0) {
836 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS2, value);
838 if (parse_mac_address(value, mac_value) == ETH_ALEN)
839 memcpy(lp->wds_port[1].wdsAddress, mac_value, ETH_ALEN);
841 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS2);
842 } else if (strcmp(key, PARM_NAME_WDS_ADDRESS3) == 0) {
843 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS3, value);
845 if (parse_mac_address(value, mac_value) == ETH_ALEN)
846 memcpy(lp->wds_port[2].wdsAddress, mac_value, ETH_ALEN);
848 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS3);
849 } else if (strcmp(key, PARM_NAME_WDS_ADDRESS4) == 0) {
850 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS4, value);
852 if (parse_mac_address(value, mac_value) == ETH_ALEN)
853 memcpy(lp->wds_port[3].wdsAddress, mac_value, ETH_ALEN);
855 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS4);
856 } else if (strcmp(key, PARM_NAME_WDS_ADDRESS5) == 0) {
857 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS5, value);
859 if (parse_mac_address(value, mac_value) == ETH_ALEN)
860 memcpy(lp->wds_port[4].wdsAddress, mac_value, ETH_ALEN);
862 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS5);
863 } else if (strcmp(key, PARM_NAME_WDS_ADDRESS6) == 0) {
864 DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS6, value);
866 if (parse_mac_address(value, mac_value) == ETH_ALEN)
867 memcpy(lp->wds_port[5].wdsAddress, mac_value, ETH_ALEN);
869 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS6);
873 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
876 } /* translate_option */
877 /*============================================================================*/
879 /*******************************************************************************
880 * parse_mac_address()
881 *******************************************************************************
885 * This function will parse a mac address string and convert it to a byte
890 * value - the MAC address, represented as a string
891 * byte_array - the MAC address, represented as a byte array of length
896 * The number of bytes in the final MAC address, should equal to ETH_ALEN.
898 ******************************************************************************/
899 int parse_mac_address(char *value, u_char *byte_array)
901 int value_offset = 0;
902 int array_offset = 0;
903 int field_offset = 0;
905 /*------------------------------------------------------------------------*/
907 memset(byte_field, '\0', 3);
909 while (value[value_offset] != '\0') {
910 /* Skip over the colon chars separating the bytes, if they exist */
911 if (value[value_offset] == ':') {
916 byte_field[field_offset] = value[value_offset];
920 /* Once the byte_field is filled, convert it and store it */
921 if (field_offset == 2) {
922 byte_field[field_offset] = '\0';
923 byte_array[array_offset] = simple_strtoul(byte_field, NULL, 16);
929 /* Use the array_offset as a check; 6 bytes should be written to the
932 } /* parse_mac_address */
933 /*============================================================================*/
935 /*******************************************************************************
937 *******************************************************************************
941 * Parses a line from the configuration file into an L-val and an R-val,
942 * representing a key/value pair.
946 * pszLine - the line from the config file to parse
947 * ppszLVal - the resulting L-val (Key)
948 * ppszRVal - the resulting R-val (Value)
954 ******************************************************************************/
955 void ParseConfigLine(char *pszLine, char **ppszLVal, char **ppszRVal)
959 /*------------------------------------------------------------------------*/
963 /* get a snapshot of our string size */
964 size = strlen(pszLine);
968 if (pszLine[0] != '#' && /* skip the line if it is a comment */
969 pszLine[0] != '\n' && /* if it's an empty UNIX line, do nothing */
970 !(pszLine[0] == '\r' && pszLine[1] == '\n') /* if it's an empty MS-DOS line, do nothing */
972 /* advance past any whitespace, and assign the L-value */
973 for (i = 0; i < size; i++) {
974 if (pszLine[i] != ' ') {
975 *ppszLVal = &pszLine[i];
979 /* advance to the end of the l-value*/
980 for (i++; i < size; i++) {
981 if (pszLine[i] == ' ' || pszLine[i] == '=') {
986 /* make any whitespace and the equal sign a NULL character, and
987 advance to the R-Value */
988 for (i++; i < size; i++) {
989 if (pszLine[i] == ' ' || pszLine[i] == '=') {
993 *ppszRVal = &pszLine[i];
996 /* make the line ending character(s) a NULL */
997 for (i++; i < size; i++) {
998 if (pszLine[i] == '\n')
1000 if ((pszLine[i] == '\r') && (pszLine[i+1] == '\n'))
1005 } /* ParseConfigLine */
1006 /*============================================================================*/
1008 #endif /* USE_PROFILE */