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 /* Definition needed to prevent unresolved external in unistd.h */
108 extern p_u32 DebugFlag
;
111 int parse_yes_no(char *value
);
114 int parse_yes_no(char *value
)
116 int rc
= 0; /* default to NO for invalid parameters */
118 if (strlen(value
) == 1) {
119 if ((value
[0] | ('Y'^'y')) == 'y')
122 /* this should not be debug time info, it is an enduser data entry error ;? */
123 /* DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MICROWAVE_ROBUSTNESS); */
129 /*******************************************************************************
131 *******************************************************************************
135 * This function opens the device's config file and parses the options from
136 * it, so that it can properly configure itself. If no configuration file
137 * or configuration is present, then continue to use the options already
138 * parsed from config.opts or wireless.opts.
142 * dev - a pointer to the device's net_device structure
148 ******************************************************************************/
149 void parse_config(struct net_device
*dev
)
156 char buffer
[MAX_LINE_SIZE
];
157 char filename
[MAX_LINE_SIZE
];
159 struct wl_private
*wvlan_config
= NULL
;
160 ENCSTRCT sEncryption
;
162 /* Get the wavelan specific info for this device */
163 wvlan_config
= dev
->priv
;
164 if (wvlan_config
== NULL
) {
165 DBG_ERROR(DbgInfo
, "Wavelan specific info struct not present?\n");
169 /* setup the default encryption string */
170 strcpy(wvlan_config
->szEncryption
, DEF_CRYPT_STR
);
172 /* Obtain a user-space process context, storing the original context */
176 /* Determine the filename for this device and attempt to open it */
177 sprintf(filename
, "%s%s", ROOT_CONFIG_FILENAME
, dev
->name
);
178 file_desc
= open(filename
, O_RDONLY
, 0);
179 if (file_desc
!= -1) {
180 DBG_TRACE(DbgInfo
, "Wireless config file found. Parsing options...\n");
182 /* Read out the options */
183 while (readline(file_desc
, buffer
))
184 translate_option(buffer
, wvlan_config
);
186 close(file_desc
); /* ;?even if file_desc == -1 ??? */
188 DBG_TRACE(DbgInfo
, "No iwconfig file found for this device; "
189 "config.opts or wireless.opts will be used\n");
191 /* Return to the original context */
194 /* convert the WEP keys, if read in as key1, key2, type of data */
195 if (wvlan_config
->EnableEncryption
) {
196 memset(&sEncryption
, 0, sizeof(sEncryption
));
198 wl_wep_decode(CRYPT_CODE
, &sEncryption
,
199 wvlan_config
->szEncryption
);
201 /* the Linux driver likes to use 1-4 for the key IDs, and then
202 convert to 0-3 when sending to the card. The Windows code
203 base used 0-3 in the API DLL, which was ported to Linux. For
204 the sake of the user experience, we decided to keep 0-3 as the
205 numbers used in the DLL; and will perform the +1 conversion here.
206 We could have converted the entire Linux driver, but this is
207 less obtrusive. This may be a "todo" to convert the whole driver */
208 sEncryption
.wEnabled
= wvlan_config
->EnableEncryption
;
209 sEncryption
.wTxKeyID
= wvlan_config
->TransmitKeyID
- 1;
211 memcpy(&sEncryption
.EncStr
, &wvlan_config
->DefaultKeys
,
212 sizeof(CFG_DEFAULT_KEYS_STRCT
));
214 memset(wvlan_config
->szEncryption
, 0, sizeof(wvlan_config
->szEncryption
));
216 wl_wep_code(CRYPT_CODE
, wvlan_config
->szEncryption
, &sEncryption
,
217 sizeof(sEncryption
));
220 /* decode the encryption string for the call to wl_commit() */
221 wl_wep_decode(CRYPT_CODE
, &sEncryption
, wvlan_config
->szEncryption
);
223 wvlan_config
->TransmitKeyID
= sEncryption
.wTxKeyID
+ 1;
224 wvlan_config
->EnableEncryption
= sEncryption
.wEnabled
;
226 memcpy(&wvlan_config
->DefaultKeys
, &sEncryption
.EncStr
,
227 sizeof(CFG_DEFAULT_KEYS_STRCT
));
230 /* Obtain a user-space process context, storing the original context */
234 /* ;?just to fake something */
235 strcpy(/*wvlan_config->fw_image_*/filename
, "/etc/agere/fw.bin");
236 file_desc
= open(/*wvlan_config->fw_image_*/filename
, 0, 0);
237 if (file_desc
== -1) {
238 DBG_ERROR(DbgInfo
, "No image file found\n");
240 DBG_TRACE(DbgInfo
, "F/W image file found\n");
241 #define DHF_ALLOC_SIZE 96000 /* just below 96K, let's hope it suffices for now and for the future */
242 cp
= vmalloc(DHF_ALLOC_SIZE
);
244 DBG_ERROR(DbgInfo
, "error in vmalloc\n");
246 rc
= read(file_desc
, cp
, DHF_ALLOC_SIZE
);
247 if (rc
== DHF_ALLOC_SIZE
) {
248 DBG_ERROR(DbgInfo
, "buffer too small, %d\n", DHF_ALLOC_SIZE
);
250 DBG_TRACE(DbgInfo
, "read O.K.: %d bytes %.12s\n", rc
, cp
);
251 rc
= read(file_desc
, &cp
[rc
], 1);
253 DBG_TRACE(DbgInfo
, "no more to read\n");
256 DBG_ERROR(DbgInfo
, "file not read in one swoop or other error"\
257 ", give up, too complicated, rc = %0X\n", rc
);
263 set_fs(fs
); /* Return to the original context */
269 /*******************************************************************************
271 *******************************************************************************
275 * This function reads in data from a given file one line at a time,
276 * converting the detected newline character '\n' to a null '\0'. Note that
277 * the file descriptor must be valid before calling this function.
281 * filedesc - the file descriptor for the open configuration file
282 * buffer - a buffer pointer, passed in by the caller, to which the
283 * line will be stored.
287 * the number of bytes read
290 ******************************************************************************/
291 int readline(int filedesc
, char *buffer
)
295 /*------------------------------------------------------------------------*/
297 /* Make sure the file descriptor is good */
298 if (filedesc
!= -1) {
299 /* Read in from the file byte by byte until a newline is reached */
300 while ((result
= read(filedesc
, &buffer
[bytes_read
], 1)) == 1) {
301 if (buffer
[bytes_read
] == '\n') {
302 buffer
[bytes_read
] = '\0';
310 /* Return the number of bytes read */
316 /*============================================================================*/
318 /*******************************************************************************
320 *******************************************************************************
324 * This function takes a line read in from the config file and parses out
325 * the key/value pairs. It then determines which key has been parsed and sets
326 * the card's configuration based on the value given.
330 * buffer - a buffer containing a line to translate
331 * config - a pointer to the device's private adapter structure
337 ******************************************************************************/
338 void translate_option(char *buffer
, struct wl_private
*lp
)
340 unsigned int value_convert
= 0;
341 int string_length
= 0;
344 u_char mac_value
[ETH_ALEN
];
345 /*------------------------------------------------------------------------*/
347 if (buffer
== NULL
|| lp
== NULL
) {
348 DBG_ERROR(DbgInfo
, "Config file buffer and/or wavelan buffer ptr NULL\n");
352 ParseConfigLine(buffer
, &key
, &value
);
354 if (key
== NULL
|| value
== NULL
)
357 /* Determine which key it is and perform the appropriate action */
359 /* Configuration parameters used in all scenarios */
361 /* handle DebugFlag as early as possible so it starts its influence as early
364 if (strcmp(key
, PARM_NAME_DEBUG_FLAG
) == 0) {
365 if (DebugFlag
== ~0) { /* if DebugFlag is not specified on the command line */
366 if (DbgInfo
->DebugFlag
== 0) { /* if pc_debug did not set DebugFlag (i.e.pc_debug is
367 * not specified or specified outside the 4-8 range
369 DbgInfo
->DebugFlag
|= DBG_DEFAULTS
;
372 DbgInfo
->DebugFlag
= simple_strtoul(value
, NULL
, 0); /* ;?DebugFlag; */
374 DbgInfo
->DebugFlag
= simple_strtoul(value
, NULL
, 0); /* ;?Delete ASAP */
377 if (strcmp(key
, PARM_NAME_AUTH_KEY_MGMT_SUITE
) == 0) {
378 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_AUTH_KEY_MGMT_SUITE
, value
);
380 value_convert
= simple_strtoul(value
, NULL
, 0);
381 if ((value_convert
>= PARM_MIN_AUTH_KEY_MGMT_SUITE
) || (value_convert
<= PARM_MAX_AUTH_KEY_MGMT_SUITE
))
382 lp
->AuthKeyMgmtSuite
= value_convert
;
384 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_AUTH_KEY_MGMT_SUITE
);
385 } else if (strcmp(key
, PARM_NAME_BRSC_2GHZ
) == 0) {
386 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_BRSC_2GHZ
, value
);
388 value_convert
= simple_strtoul(value
, NULL
, 0);
389 if ((value_convert
>= PARM_MIN_BRSC
) || (value_convert
<= PARM_MAX_BRSC
))
390 lp
->brsc
[0] = value_convert
;
392 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_BRSC_2GHZ
);
393 } else if (strcmp(key
, PARM_NAME_BRSC_5GHZ
) == 0) {
394 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_BRSC_5GHZ
, value
);
396 value_convert
= simple_strtoul(value
, NULL
, 0);
397 if ((value_convert
>= PARM_MIN_BRSC
) || (value_convert
<= PARM_MAX_BRSC
))
398 lp
->brsc
[1] = value_convert
;
400 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_BRSC_5GHZ
);
401 } else if ((strcmp(key
, PARM_NAME_DESIRED_SSID
) == 0) || (strcmp(key
, PARM_NAME_OWN_SSID
) == 0)) {
402 DBG_TRACE(DbgInfo
, "SSID, value: %s\n", value
);
404 memset(lp
->NetworkName
, 0, (PARM_MAX_NAME_LEN
+ 1));
406 /* Make sure the value isn't too long */
407 string_length
= strlen(value
);
408 if (string_length
> PARM_MAX_NAME_LEN
) {
409 DBG_WARNING(DbgInfo
, "SSID too long; will be truncated\n");
410 string_length
= PARM_MAX_NAME_LEN
;
413 memcpy(lp
->NetworkName
, value
, string_length
);
416 else if (strcmp(key
, PARM_NAME_DOWNLOAD_FIRMWARE
) == 0) {
417 DBG_TRACE(DbgInfo
, "DOWNLOAD_FIRMWARE, value: %s\n", value
);
418 memset(lp
->fw_image_filename
, 0, (MAX_LINE_SIZE
+ 1));
419 /* Make sure the value isn't too long */
420 string_length
= strlen(value
);
421 if (string_length
> MAX_LINE_SIZE
)
422 DBG_WARNING(DbgInfo
, "F/W image file name too long; will be ignored\n");
424 memcpy(lp
->fw_image_filename
, value
, string_length
);
427 else if (strcmp(key
, PARM_NAME_ENABLE_ENCRYPTION
) == 0) {
428 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_ENABLE_ENCRYPTION
, value
);
430 value_convert
= simple_strtoul(value
, NULL
, 0);
431 if ((value_convert
>= PARM_MIN_ENABLE_ENCRYPTION
) && (value_convert
<= PARM_MAX_ENABLE_ENCRYPTION
))
432 lp
->EnableEncryption
= value_convert
;
434 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_ENABLE_ENCRYPTION
);
435 } else if (strcmp(key
, PARM_NAME_ENCRYPTION
) == 0) {
436 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_ENCRYPTION
, value
);
438 memset(lp
->szEncryption
, 0, sizeof(lp
->szEncryption
));
440 /* Make sure the value isn't too long */
441 string_length
= strlen(value
);
442 if (string_length
> sizeof(lp
->szEncryption
)) {
443 DBG_WARNING(DbgInfo
, "%s too long; will be truncated\n", PARM_NAME_ENCRYPTION
);
444 string_length
= sizeof(lp
->szEncryption
);
447 memcpy(lp
->szEncryption
, value
, string_length
);
448 } else if (strcmp(key
, PARM_NAME_KEY1
) == 0) {
449 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_KEY1
, value
);
451 if (is_valid_key_string(value
)) {
452 memset(lp
->DefaultKeys
.key
[0].key
, 0, MAX_KEY_SIZE
);
454 key_string2key(value
, &lp
->DefaultKeys
.key
[0]);
456 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_KEY1
);
458 } else if (strcmp(key
, PARM_NAME_KEY2
) == 0) {
459 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_KEY2
, value
);
461 if (is_valid_key_string(value
)) {
462 memset(lp
->DefaultKeys
.key
[1].key
, 0, MAX_KEY_SIZE
);
464 key_string2key(value
, &lp
->DefaultKeys
.key
[1]);
466 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_KEY2
);
468 } else if (strcmp(key
, PARM_NAME_KEY3
) == 0) {
469 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_KEY3
, value
);
471 if (is_valid_key_string(value
)) {
472 memset(lp
->DefaultKeys
.key
[2].key
, 0, MAX_KEY_SIZE
);
474 key_string2key(value
, &lp
->DefaultKeys
.key
[2]);
476 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_KEY3
);
478 } else if (strcmp(key
, PARM_NAME_KEY4
) == 0) {
479 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_KEY4
, value
);
481 if (is_valid_key_string(value
)) {
482 memset(lp
->DefaultKeys
.key
[3].key
, 0, MAX_KEY_SIZE
);
484 key_string2key(value
, &lp
->DefaultKeys
.key
[3]);
486 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_KEY4
);
489 /* New Parameters for WARP */
490 else if (strcmp(key
, PARM_NAME_LOAD_BALANCING
) == 0) {
491 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_LOAD_BALANCING
, value
);
492 lp
->loadBalancing
= parse_yes_no(value
);
493 } else if (strcmp(key
, PARM_NAME_MEDIUM_DISTRIBUTION
) == 0) {
494 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_MEDIUM_DISTRIBUTION
, value
);
495 lp
->mediumDistribution
= parse_yes_no(value
);
496 } else if (strcmp(key
, PARM_NAME_MICROWAVE_ROBUSTNESS
) == 0) {
497 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_MICROWAVE_ROBUSTNESS
, value
);
498 lp
->MicrowaveRobustness
= parse_yes_no(value
);
499 } else if (strcmp(key
, PARM_NAME_MULTICAST_RATE
) == 0) {
500 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_MULTICAST_RATE
, value
);
502 value_convert
= simple_strtoul(value
, NULL
, 0);
504 if ((value_convert
>= PARM_MIN_MULTICAST_RATE
) && (value_convert
<= PARM_MAX_MULTICAST_RATE
))
505 lp
->MulticastRate
[0] = value_convert
;
507 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_MULTICAST_RATE
);
508 } else if (strcmp(key
, PARM_NAME_OWN_CHANNEL
) == 0) {
509 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_OWN_CHANNEL
, value
);
511 value_convert
= simple_strtoul(value
, NULL
, 0);
512 if (wl_is_a_valid_chan(value_convert
)) {
513 if (value_convert
> 14)
514 value_convert
= value_convert
| 0x100;
515 lp
->Channel
= value_convert
;
517 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_OWN_CHANNEL
);
519 } else if (strcmp(key
, PARM_NAME_OWN_NAME
) == 0) {
520 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_OWN_NAME
, value
);
522 memset(lp
->StationName
, 0, (PARM_MAX_NAME_LEN
+ 1));
524 /* Make sure the value isn't too long */
525 string_length
= strlen(value
);
526 if (string_length
> PARM_MAX_NAME_LEN
) {
527 DBG_WARNING(DbgInfo
, "%s too long; will be truncated\n", PARM_NAME_OWN_NAME
);
528 string_length
= PARM_MAX_NAME_LEN
;
531 memcpy(lp
->StationName
, value
, string_length
);
532 } else if (strcmp(key
, PARM_NAME_RTS_THRESHOLD
) == 0) {
533 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD
, value
);
535 value_convert
= simple_strtoul(value
, NULL
, 0);
536 if ((value_convert
>= PARM_MIN_RTS_THRESHOLD
) && (value_convert
<= PARM_MAX_RTS_THRESHOLD
))
537 lp
->RTSThreshold
= value_convert
;
539 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD
);
540 } else if (strcmp(key
, PARM_NAME_SRSC_2GHZ
) == 0) {
541 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_SRSC_2GHZ
, value
);
543 value_convert
= simple_strtoul(value
, NULL
, 0);
544 if ((value_convert
>= PARM_MIN_SRSC
) || (value_convert
<= PARM_MAX_SRSC
))
545 lp
->srsc
[0] = value_convert
;
547 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_SRSC_2GHZ
);
548 } else if (strcmp(key
, PARM_NAME_SRSC_5GHZ
) == 0) {
549 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_SRSC_5GHZ
, value
);
551 value_convert
= simple_strtoul(value
, NULL
, 0);
552 if ((value_convert
>= PARM_MIN_SRSC
) || (value_convert
<= PARM_MAX_SRSC
))
553 lp
->srsc
[1] = value_convert
;
555 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_SRSC_5GHZ
);
556 } else if (strcmp(key
, PARM_NAME_SYSTEM_SCALE
) == 0) {
557 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_SYSTEM_SCALE
, value
);
559 value_convert
= simple_strtoul(value
, NULL
, 0);
560 if ((value_convert
>= PARM_MIN_SYSTEM_SCALE
) && (value_convert
<= PARM_MAX_SYSTEM_SCALE
))
561 lp
->DistanceBetweenAPs
= value_convert
;
563 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_SYSTEM_SCALE
);
564 } else if (strcmp(key
, PARM_NAME_TX_KEY
) == 0) {
565 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_TX_KEY
, value
);
567 value_convert
= simple_strtoul(value
, NULL
, 0);
568 if ((value_convert
>= PARM_MIN_TX_KEY
) && (value_convert
<= PARM_MAX_TX_KEY
))
569 lp
->TransmitKeyID
= simple_strtoul(value
, NULL
, 0);
571 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_TX_KEY
);
572 } else if (strcmp(key
, PARM_NAME_TX_RATE
) == 0) {
573 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_TX_RATE
, value
);
575 value_convert
= simple_strtoul(value
, NULL
, 0);
576 if ((value_convert
>= PARM_MIN_TX_RATE
) && (value_convert
<= PARM_MAX_TX_RATE
))
577 lp
->TxRateControl
[0] = value_convert
;
579 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE
);
580 } else if (strcmp(key
, PARM_NAME_TX_POW_LEVEL
) == 0) {
581 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_TX_POW_LEVEL
, value
);
583 value_convert
= simple_strtoul(value
, NULL
, 0);
584 if ((value_convert
>= PARM_MIN_TX_POW_LEVEL
) || (value_convert
<= PARM_MAX_TX_POW_LEVEL
))
585 lp
->txPowLevel
= value_convert
;
587 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_TX_POW_LEVEL
);
590 /* Need to add? : Country code, Short/Long retry */
592 /* Configuration parameters specific to STA mode */
593 #if 1 /* ;? (HCF_TYPE) & HCF_TYPE_STA */
594 /* ;?seems reasonable that even an AP-only driver could afford this small additional footprint */
595 if (CNV_INT_TO_LITTLE(lp
->hcfCtx
.IFB_FWIdentity
.comp_id
) == COMP_ID_FW_STA
) {
596 /* ;?should we return an error status in AP mode */
597 if (strcmp(key
, PARM_NAME_PORT_TYPE
) == 0) {
598 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_PORT_TYPE
, value
);
600 value_convert
= simple_strtoul(value
, NULL
, 0);
601 if ((value_convert
== PARM_MIN_PORT_TYPE
) || (value_convert
== PARM_MAX_PORT_TYPE
))
602 lp
->PortType
= value_convert
;
604 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_PORT_TYPE
);
605 } else if (strcmp(key
, PARM_NAME_PM_ENABLED
) == 0) {
606 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_PM_ENABLED
, value
);
607 value_convert
= simple_strtoul(value
, NULL
, 0);
608 /* ;? how about wl_main.c containing
609 * VALID_PARAM(PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD ||
610 * (PARM_PM_ENABLED & 0x7FFF) <= WVLAN_PM_STATE_STANDARD);
612 if ((value_convert
& 0x7FFF) <= PARM_MAX_PM_ENABLED
) {
613 lp
->PMEnabled
= value_convert
;
615 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_PM_ENABLED
);
616 /* ;?this is a data entry error, hence not a DBG_WARNING */
618 } else if (strcmp(key
, PARM_NAME_CREATE_IBSS
) == 0) {
619 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_CREATE_IBSS
, value
);
620 lp
->CreateIBSS
= parse_yes_no(value
);
621 } else if (strcmp(key
, PARM_NAME_MULTICAST_RX
) == 0) {
622 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_MULTICAST_RX
, value
);
623 lp
->MulticastReceive
= parse_yes_no(value
);
624 } else if (strcmp(key
, PARM_NAME_MAX_SLEEP
) == 0) {
625 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_MAX_SLEEP
, value
);
627 value_convert
= simple_strtoul(value
, NULL
, 0);
628 if ((value_convert
>= 0) && (value_convert
<= 65535))
629 lp
->MaxSleepDuration
= value_convert
;
631 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_MAX_SLEEP
);
632 } else if (strcmp(key
, PARM_NAME_NETWORK_ADDR
) == 0) {
633 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_NETWORK_ADDR
, value
);
635 if (parse_mac_address(value
, mac_value
) == ETH_ALEN
)
636 memcpy(lp
->MACAddress
, mac_value
, ETH_ALEN
);
638 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_NETWORK_ADDR
);
639 } else if (strcmp(key
, PARM_NAME_AUTHENTICATION
) == 0) {
640 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_AUTHENTICATION
, value
);
642 value_convert
= simple_strtoul(value
, NULL
, 0);
643 if ((value_convert
>= PARM_MIN_AUTHENTICATION
) && (value_convert
<= PARM_MAX_AUTHENTICATION
))
644 lp
->authentication
= value_convert
;
646 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_AUTHENTICATION
);
647 } else if (strcmp(key
, PARM_NAME_OWN_ATIM_WINDOW
) == 0) {
648 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_OWN_ATIM_WINDOW
, value
);
650 value_convert
= simple_strtoul(value
, NULL
, 0);
651 if ((value_convert
>= PARM_MIN_OWN_ATIM_WINDOW
) && (value_convert
<= PARM_MAX_OWN_ATIM_WINDOW
))
652 lp
->atimWindow
= value_convert
;
654 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_OWN_ATIM_WINDOW
);
655 } else if (strcmp(key
, PARM_NAME_PM_HOLDOVER_DURATION
) == 0) {
656 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_PM_HOLDOVER_DURATION
, value
);
658 value_convert
= simple_strtoul(value
, NULL
, 0);
659 if ((value_convert
>= PARM_MIN_PM_HOLDOVER_DURATION
) && (value_convert
<= PARM_MAX_PM_HOLDOVER_DURATION
))
660 lp
->holdoverDuration
= value_convert
;
662 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_PM_HOLDOVER_DURATION
);
663 } else if (strcmp(key
, PARM_NAME_PROMISCUOUS_MODE
) == 0) {
664 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_PROMISCUOUS_MODE
, value
);
665 lp
->promiscuousMode
= parse_yes_no(value
);
666 } else if (strcmp(key
, PARM_NAME_CONNECTION_CONTROL
) == 0) {
667 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_CONNECTION_CONTROL
, value
);
669 value_convert
= simple_strtoul(value
, NULL
, 0);
670 if ((value_convert
>= PARM_MIN_CONNECTION_CONTROL
) && (value_convert
<= PARM_MAX_CONNECTION_CONTROL
))
671 lp
->connectionControl
= value_convert
;
673 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_CONNECTION_CONTROL
);
676 /* Need to add? : Probe Data Rate */
678 #endif /* (HCF_TYPE) & HCF_TYPE_STA */
680 /* Configuration parameters specific to AP mode */
681 #if 1 /* ;? (HCF_TYPE) & HCF_TYPE_AP */
682 /* ;?should we restore this to allow smaller memory footprint */
683 if (CNV_INT_TO_LITTLE(lp
->hcfCtx
.IFB_FWIdentity
.comp_id
) == COMP_ID_FW_AP
) {
684 if (strcmp(key
, PARM_NAME_OWN_DTIM_PERIOD
) == 0) {
685 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_OWN_DTIM_PERIOD
, value
);
687 value_convert
= simple_strtoul(value
, NULL
, 0);
688 if (value_convert
>= PARM_MIN_OWN_DTIM_PERIOD
)
689 lp
->DTIMPeriod
= value_convert
;
691 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_OWN_DTIM_PERIOD
);
692 } else if (strcmp(key
, PARM_NAME_REJECT_ANY
) == 0) {
693 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_REJECT_ANY
, value
);
694 lp
->RejectAny
= parse_yes_no(value
);
695 } else if (strcmp(key
, PARM_NAME_EXCLUDE_UNENCRYPTED
) == 0) {
696 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_EXCLUDE_UNENCRYPTED
, value
);
697 lp
->ExcludeUnencrypted
= parse_yes_no(value
);
698 } else if (strcmp(key
, PARM_NAME_MULTICAST_PM_BUFFERING
) == 0) {
699 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_MULTICAST_PM_BUFFERING
, value
);
700 lp
->ExcludeUnencrypted
= parse_yes_no(value
);
701 } else if (strcmp(key
, PARM_NAME_INTRA_BSS_RELAY
) == 0) {
702 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_INTRA_BSS_RELAY
, value
);
703 lp
->ExcludeUnencrypted
= parse_yes_no(value
);
704 } else if (strcmp(key
, PARM_NAME_OWN_BEACON_INTERVAL
) == 0) {
705 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_OWN_BEACON_INTERVAL
, value
);
707 value_convert
= simple_strtoul(value
, NULL
, 0);
708 if (value_convert
>= PARM_MIN_OWN_BEACON_INTERVAL
)
709 lp
->ownBeaconInterval
= value_convert
;
711 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_OWN_BEACON_INTERVAL
);
712 } else if (strcmp(key
, PARM_NAME_COEXISTENCE
) == 0) {
713 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_COEXISTENCE
, value
);
715 value_convert
= simple_strtoul(value
, NULL
, 0);
716 if (value_convert
>= PARM_MIN_COEXISTENCE
)
717 lp
->coexistence
= value_convert
;
719 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_COEXISTENCE
);
723 else if (strcmp(key
, PARM_NAME_RTS_THRESHOLD1
) == 0) {
724 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD1
, value
);
726 value_convert
= simple_strtoul(value
, NULL
, 0);
727 if ((value_convert
>= PARM_MIN_RTS_THRESHOLD
) && (value_convert
<= PARM_MAX_RTS_THRESHOLD
))
728 lp
->wds_port
[0].rtsThreshold
= value_convert
;
730 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD1
);
731 } else if (strcmp(key
, PARM_NAME_RTS_THRESHOLD2
) == 0) {
732 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD2
, value
);
734 value_convert
= simple_strtoul(value
, NULL
, 0);
735 if ((value_convert
>= PARM_MIN_RTS_THRESHOLD
) && (value_convert
<= PARM_MAX_RTS_THRESHOLD
))
736 lp
->wds_port
[1].rtsThreshold
= value_convert
;
738 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD2
);
739 } else if (strcmp(key
, PARM_NAME_RTS_THRESHOLD3
) == 0) {
740 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD3
, value
);
742 value_convert
= simple_strtoul(value
, NULL
, 0);
743 if ((value_convert
>= PARM_MIN_RTS_THRESHOLD
) && (value_convert
<= PARM_MAX_RTS_THRESHOLD
))
744 lp
->wds_port
[2].rtsThreshold
= value_convert
;
746 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD3
);
747 } else if (strcmp(key
, PARM_NAME_RTS_THRESHOLD4
) == 0) {
748 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD4
, value
);
750 value_convert
= simple_strtoul(value
, NULL
, 0);
751 if ((value_convert
>= PARM_MIN_RTS_THRESHOLD
) && (value_convert
<= PARM_MAX_RTS_THRESHOLD
))
752 lp
->wds_port
[3].rtsThreshold
= value_convert
;
754 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD4
);
755 } else if (strcmp(key
, PARM_NAME_RTS_THRESHOLD5
) == 0) {
756 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD5
, value
);
758 value_convert
= simple_strtoul(value
, NULL
, 0);
759 if ((value_convert
>= PARM_MIN_RTS_THRESHOLD
) && (value_convert
<= PARM_MAX_RTS_THRESHOLD
))
760 lp
->wds_port
[4].rtsThreshold
= value_convert
;
762 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD5
);
763 } else if (strcmp(key
, PARM_NAME_RTS_THRESHOLD6
) == 0) {
764 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD6
, value
);
766 value_convert
= simple_strtoul(value
, NULL
, 0);
767 if ((value_convert
>= PARM_MIN_RTS_THRESHOLD
) && (value_convert
<= PARM_MAX_RTS_THRESHOLD
))
768 lp
->wds_port
[5].rtsThreshold
= value_convert
;
770 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD6
);
771 } else if (strcmp(key
, PARM_NAME_TX_RATE1
) == 0) {
772 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_TX_RATE1
, value
);
774 value_convert
= simple_strtoul(value
, NULL
, 0);
775 if ((value_convert
>= PARM_MIN_TX_RATE
) && (value_convert
<= PARM_MAX_TX_RATE
))
776 lp
->wds_port
[0].txRateCntl
= value_convert
;
778 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE1
);
779 } else if (strcmp(key
, PARM_NAME_TX_RATE2
) == 0) {
780 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_TX_RATE2
, value
);
782 value_convert
= simple_strtoul(value
, NULL
, 0);
783 if ((value_convert
>= PARM_MIN_TX_RATE
) && (value_convert
<= PARM_MAX_TX_RATE
))
784 lp
->wds_port
[1].txRateCntl
= value_convert
;
786 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE2
);
787 } else if (strcmp(key
, PARM_NAME_TX_RATE3
) == 0) {
788 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_TX_RATE3
, value
);
790 value_convert
= simple_strtoul(value
, NULL
, 0);
791 if ((value_convert
>= PARM_MIN_TX_RATE
) && (value_convert
<= PARM_MAX_TX_RATE
))
792 lp
->wds_port
[2].txRateCntl
= value_convert
;
794 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE3
);
795 } else if (strcmp(key
, PARM_NAME_TX_RATE4
) == 0) {
796 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_TX_RATE4
, value
);
798 value_convert
= simple_strtoul(value
, NULL
, 0);
799 if ((value_convert
>= PARM_MIN_TX_RATE
) && (value_convert
<= PARM_MAX_TX_RATE
))
800 lp
->wds_port
[3].txRateCntl
= value_convert
;
802 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE4
);
803 } else if (strcmp(key
, PARM_NAME_TX_RATE5
) == 0) {
804 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_TX_RATE5
, value
);
806 value_convert
= simple_strtoul(value
, NULL
, 0);
807 if ((value_convert
>= PARM_MIN_TX_RATE
) && (value_convert
<= PARM_MAX_TX_RATE
))
808 lp
->wds_port
[4].txRateCntl
= value_convert
;
810 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE5
);
811 } else if (strcmp(key
, PARM_NAME_TX_RATE6
) == 0) {
812 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_TX_RATE6
, value
);
814 value_convert
= simple_strtoul(value
, NULL
, 0);
815 if ((value_convert
>= PARM_MIN_TX_RATE
) && (value_convert
<= PARM_MAX_TX_RATE
))
816 lp
->wds_port
[5].txRateCntl
= value_convert
;
818 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE6
);
819 } else if (strcmp(key
, PARM_NAME_WDS_ADDRESS1
) == 0) {
820 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS1
, value
);
822 if (parse_mac_address(value
, mac_value
) == ETH_ALEN
)
823 memcpy(lp
->wds_port
[0].wdsAddress
, mac_value
, ETH_ALEN
);
825 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS1
);
826 } else if (strcmp(key
, PARM_NAME_WDS_ADDRESS2
) == 0) {
827 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS2
, value
);
829 if (parse_mac_address(value
, mac_value
) == ETH_ALEN
)
830 memcpy(lp
->wds_port
[1].wdsAddress
, mac_value
, ETH_ALEN
);
832 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS2
);
833 } else if (strcmp(key
, PARM_NAME_WDS_ADDRESS3
) == 0) {
834 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS3
, value
);
836 if (parse_mac_address(value
, mac_value
) == ETH_ALEN
)
837 memcpy(lp
->wds_port
[2].wdsAddress
, mac_value
, ETH_ALEN
);
839 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS3
);
840 } else if (strcmp(key
, PARM_NAME_WDS_ADDRESS4
) == 0) {
841 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS4
, value
);
843 if (parse_mac_address(value
, mac_value
) == ETH_ALEN
)
844 memcpy(lp
->wds_port
[3].wdsAddress
, mac_value
, ETH_ALEN
);
846 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS4
);
847 } else if (strcmp(key
, PARM_NAME_WDS_ADDRESS5
) == 0) {
848 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS5
, value
);
850 if (parse_mac_address(value
, mac_value
) == ETH_ALEN
)
851 memcpy(lp
->wds_port
[4].wdsAddress
, mac_value
, ETH_ALEN
);
853 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS5
);
854 } else if (strcmp(key
, PARM_NAME_WDS_ADDRESS6
) == 0) {
855 DBG_TRACE(DbgInfo
, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS6
, value
);
857 if (parse_mac_address(value
, mac_value
) == ETH_ALEN
)
858 memcpy(lp
->wds_port
[5].wdsAddress
, mac_value
, ETH_ALEN
);
860 DBG_WARNING(DbgInfo
, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS6
);
864 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
867 } /* translate_option */
868 /*============================================================================*/
870 /*******************************************************************************
871 * parse_mac_address()
872 *******************************************************************************
876 * This function will parse a mac address string and convert it to a byte
881 * value - the MAC address, represented as a string
882 * byte_array - the MAC address, represented as a byte array of length
887 * The number of bytes in the final MAC address, should equal to ETH_ALEN.
889 ******************************************************************************/
890 int parse_mac_address(char *value
, u_char
*byte_array
)
892 int value_offset
= 0;
893 int array_offset
= 0;
894 int field_offset
= 0;
896 /*------------------------------------------------------------------------*/
898 memset(byte_field
, '\0', 3);
900 while (value
[value_offset
] != '\0') {
901 /* Skip over the colon chars separating the bytes, if they exist */
902 if (value
[value_offset
] == ':') {
907 byte_field
[field_offset
] = value
[value_offset
];
911 /* Once the byte_field is filled, convert it and store it */
912 if (field_offset
== 2) {
913 byte_field
[field_offset
] = '\0';
914 byte_array
[array_offset
] = simple_strtoul(byte_field
, NULL
, 16);
920 /* Use the array_offset as a check; 6 bytes should be written to the
923 } /* parse_mac_address */
924 /*============================================================================*/
926 /*******************************************************************************
928 *******************************************************************************
932 * Parses a line from the configuration file into an L-val and an R-val,
933 * representing a key/value pair.
937 * pszLine - the line from the config file to parse
938 * ppszLVal - the resulting L-val (Key)
939 * ppszRVal - the resulting R-val (Value)
945 ******************************************************************************/
946 void ParseConfigLine(char *pszLine
, char **ppszLVal
, char **ppszRVal
)
951 /* get a snapshot of our string size */
952 size
= strlen(pszLine
);
956 if (pszLine
[0] != '#' && /* skip the line if it is a comment */
957 pszLine
[0] != '\n' && /* if it's an empty UNIX line, do nothing */
958 !(pszLine
[0] == '\r' && pszLine
[1] == '\n') /* if it's an empty MS-DOS line, do nothing */
960 /* advance past any whitespace, and assign the L-value */
961 for (i
= 0; i
< size
; i
++) {
962 if (pszLine
[i
] != ' ') {
963 *ppszLVal
= &pszLine
[i
];
967 /* advance to the end of the l-value*/
968 for (i
++; i
< size
; i
++) {
969 if (pszLine
[i
] == ' ' || pszLine
[i
] == '=') {
974 /* make any whitespace and the equal sign a NULL character, and
975 advance to the R-Value */
976 for (i
++; i
< size
; i
++) {
977 if (pszLine
[i
] == ' ' || pszLine
[i
] == '=') {
981 *ppszRVal
= &pszLine
[i
];
984 /* make the line ending character(s) a NULL */
985 for (i
++; i
< size
; i
++) {
986 if (pszLine
[i
] == '\n')
988 if ((pszLine
[i
] == '\r') && (pszLine
[i
+1] == '\n'))
992 } /* ParseConfigLine */
993 /*============================================================================*/
995 #endif /* USE_PROFILE */