• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/staging/wlags49_h2/
1/*******************************************************************************
2 * Agere Systems Inc.
3 * Wireless device driver for Linux (wlags49).
4 *
5 * Copyright (c) 1998-2003 Agere Systems Inc.
6 * All rights reserved.
7 *   http://www.agere.com
8 *
9 * Initially developed by TriplePoint, Inc.
10 *   http://www.triplepoint.com
11 *
12 *------------------------------------------------------------------------------
13 *
14 *   This file defines routines required to parse configuration parameters
15 *   listed in a config file, if that config file exists.
16 *
17 *------------------------------------------------------------------------------
18 *
19 * SOFTWARE LICENSE
20 *
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.
25 *
26 * Copyright � 2003 Agere Systems Inc.
27 * All rights reserved.
28 *
29 * Redistribution and use in source or binary forms, with or without
30 * modifications, are permitted provided that the following conditions are met:
31 *
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
35 *    distribution.
36 *
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.
40 *
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.
44 *
45 * Disclaimer
46 *
47 * THIS SOFTWARE IS PROVIDED �AS IS� 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
58 * DAMAGE.
59 *
60 ******************************************************************************/
61
62/* Only include this file if USE_PROFILE is defined */
63#ifdef USE_PROFILE
64
65
66
67
68/*******************************************************************************
69 *  constant definitions
70 ******************************************************************************/
71
72
73/* Allow support for calling system fcns to parse config file */
74#define __KERNEL_SYSCALLS__
75
76
77
78
79/*******************************************************************************
80 * include files
81 ******************************************************************************/
82#include <wl_version.h>
83
84#include <linux/netdevice.h>
85#include <linux/etherdevice.h>
86#include <linux/unistd.h>
87#include <asm/uaccess.h>
88#include <limits.h>
89
90#define BIN_DL 1
91
92#include <debug.h>
93#include <hcf.h>
94/* #include <hcfdef.h> */
95
96#include <wl_if.h>
97#include <wl_internal.h>
98#include <wl_util.h>
99#include <wl_enc.h>
100#include <wl_main.h>
101#include <wl_profile.h>
102
103
104/*******************************************************************************
105 * global variables
106 ******************************************************************************/
107
108/* Definition needed to prevent unresolved external in unistd.h */
109static int errno;
110
111#if DBG
112extern p_u32    DebugFlag;
113extern dbg_info_t *DbgInfo;
114#endif
115
116int parse_yes_no(char *value);
117
118
119int parse_yes_no(char *value)
120{
121int rc = 0;										/* default to NO for invalid parameters */
122
123	if (strlen(value) == 1) {
124		if ((value[0] | ('Y'^'y')) == 'y')
125			rc = 1;
126	/* } else { */
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); */
129	}
130	return rc;
131} /* parse_yes_no */
132
133
134/*******************************************************************************
135 *	parse_config()
136 *******************************************************************************
137 *
138 *  DESCRIPTION:
139 *
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.
144 *
145 *  PARAMETERS:
146 *
147 *      dev - a pointer to the device's net_device structure
148 *
149 *  RETURNS:
150 *
151 *      N/A
152 *
153 ******************************************************************************/
154void parse_config(struct net_device *dev)
155{
156	int				    file_desc;
157	char                buffer[MAX_LINE_SIZE];
158	char                filename[MAX_LINE_SIZE];
159	mm_segment_t	    fs;
160	struct wl_private   *wvlan_config = NULL;
161	ENCSTRCT            sEncryption;
162	/*------------------------------------------------------------------------*/
163
164	DBG_FUNC("parse_config");
165	DBG_ENTER(DbgInfo);
166
167	/* Get the wavelan specific info for this device */
168	wvlan_config = dev->priv;
169	if (wvlan_config == NULL) {
170		DBG_ERROR(DbgInfo, "Wavelan specific info struct not present?\n");
171		return;
172	}
173
174	/* setup the default encryption string */
175	strcpy(wvlan_config->szEncryption, DEF_CRYPT_STR);
176
177	/* Obtain a user-space process context, storing the original context */
178	fs = get_fs();
179	set_fs(get_ds());
180
181	/* Determine the filename for this device and attempt to open it */
182	sprintf(filename, "%s%s", ROOT_CONFIG_FILENAME, dev->name);
183	file_desc = open(filename, O_RDONLY, 0);
184	if (file_desc != -1) {
185		DBG_TRACE(DbgInfo, "Wireless config file found. Parsing options...\n");
186
187		/* Read out the options */
188		while (readline(file_desc, buffer))
189			translate_option(buffer, wvlan_config);
190		/* Close the file */
191		close(file_desc);	/* ;?even if file_desc == -1 ??? */
192	} else {
193		DBG_TRACE(DbgInfo, "No iwconfig file found for this device; "
194				   "config.opts or wireless.opts will be used\n");
195	}
196	/* Return to the original context */
197	set_fs(fs);
198
199	/* convert the WEP keys, if read in as key1, key2, type of data */
200	if (wvlan_config->EnableEncryption) {
201		memset(&sEncryption, 0, sizeof(sEncryption));
202
203		wl_wep_decode(CRYPT_CODE, &sEncryption,
204						   wvlan_config->szEncryption);
205
206		/* the Linux driver likes to use 1-4 for the key IDs, and then
207		   convert to 0-3 when sending to the card.  The Windows code
208		   base used 0-3 in the API DLL, which was ported to Linux.  For
209		   the sake of the user experience, we decided to keep 0-3 as the
210		   numbers used in the DLL; and will perform the +1 conversion here.
211		   We could have converted  the entire Linux driver, but this is
212		   less obtrusive.  This may be a "todo" to convert the whole driver */
213		sEncryption.wEnabled = wvlan_config->EnableEncryption;
214		sEncryption.wTxKeyID = wvlan_config->TransmitKeyID - 1;
215
216		memcpy(&sEncryption.EncStr, &wvlan_config->DefaultKeys,
217				sizeof(CFG_DEFAULT_KEYS_STRCT));
218
219		memset(wvlan_config->szEncryption, 0, sizeof(wvlan_config->szEncryption));
220
221		wl_wep_code(CRYPT_CODE, wvlan_config->szEncryption, &sEncryption,
222						 sizeof(sEncryption));
223	}
224
225	/* decode the encryption string for the call to wl_commit() */
226	wl_wep_decode(CRYPT_CODE, &sEncryption, wvlan_config->szEncryption);
227
228	wvlan_config->TransmitKeyID    = sEncryption.wTxKeyID + 1;
229	wvlan_config->EnableEncryption = sEncryption.wEnabled;
230
231	memcpy(&wvlan_config->DefaultKeys, &sEncryption.EncStr,
232			sizeof(CFG_DEFAULT_KEYS_STRCT));
233
234
235	DBG_LEAVE(DbgInfo);
236	return;
237} /* parse_config */
238
239/*******************************************************************************
240 *	readline()
241 *******************************************************************************
242 *
243 *  DESCRIPTION:
244 *
245 *      This function reads in data from a given file one line at a time,
246 *   converting the detected newline character '\n' to a null '\0'. Note that
247 *   the file descriptor must be valid before calling this function.
248 *
249 *  PARAMETERS:
250 *
251 *      filedesc    - the file descriptor for the open configuration file
252 *      buffer      - a buffer pointer, passed in by the caller, to which the
253 *                    line will be stored.
254 *
255 *  RETURNS:
256 *
257 *      the number of bytes read
258 *      -1 on error
259 *
260 ******************************************************************************/
261int readline(int filedesc, char *buffer)
262{
263	int result = -1;
264	int bytes_read = 0;
265	/*------------------------------------------------------------------------*/
266
267	/* Make sure the file descriptor is good */
268	if (filedesc != -1) {
269		/* Read in from the file byte by byte until a newline is reached */
270		while ((result = read(filedesc, &buffer[bytes_read], 1)) == 1) {
271			if (buffer[bytes_read] == '\n') {
272				buffer[bytes_read] = '\0';
273				bytes_read++;
274				break;
275			}
276			bytes_read++;
277		}
278	}
279
280	/* Return the number of bytes read */
281	if (result == -1)
282		return result;
283	else
284		return bytes_read;
285} /* readline */
286/*============================================================================*/
287
288/*******************************************************************************
289 *	translate_option()
290 *******************************************************************************
291 *
292 *  DESCRIPTION:
293 *
294 *      This function takes a line read in from the config file and parses out
295 *   the key/value pairs. It then determines which key has been parsed and sets
296 *   the card's configuration based on the value given.
297 *
298 *  PARAMETERS:
299 *
300 *      buffer - a buffer containing a line to translate
301 *      config - a pointer to the device's private adapter structure
302 *
303 *  RETURNS:
304 *
305 *      N/A
306 *
307 ******************************************************************************/
308void translate_option(char *buffer, struct wl_private *lp)
309{
310	unsigned int value_convert = 0;
311	int string_length = 0;
312	char *key = NULL;
313	char *value = NULL;
314	u_char mac_value[ETH_ALEN];
315	/*------------------------------------------------------------------------*/
316
317	DBG_FUNC("translate_option");
318
319	if (buffer == NULL || lp == NULL) {
320		DBG_ERROR(DbgInfo, "Config file buffer and/or wavelan buffer ptr NULL\n");
321		return;
322	}
323
324	ParseConfigLine(buffer, &key, &value);
325
326	if (key == NULL || value == NULL)
327		return;
328
329	/* Determine which key it is and perform the appropriate action */
330
331	/* Configuration parameters used in all scenarios */
332#if DBG
333	/* handle DebugFlag as early as possible so it starts its influence as early
334	 * as possible
335	 */
336	if (strcmp(key, PARM_NAME_DEBUG_FLAG) == 0) {
337		if (DebugFlag == ~0) {			/* if DebugFlag is not specified on the command line */
338			if (DbgInfo->DebugFlag == 0) {	/* if pc_debug did not set DebugFlag (i.e.pc_debug is
339											 * not specified or specified outside the 4-8 range
340											 */
341				DbgInfo->DebugFlag |= DBG_DEFAULTS;
342			}
343		} else {
344			DbgInfo->DebugFlag = simple_strtoul(value, NULL, 0); /* ;?DebugFlag; */
345		}
346		DbgInfo->DebugFlag = simple_strtoul(value, NULL, 0); /* ;?Delete ASAP */
347	}
348#endif /* DBG */
349	if (strcmp(key, PARM_NAME_AUTH_KEY_MGMT_SUITE) == 0) {
350		DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_AUTH_KEY_MGMT_SUITE, value);
351
352		value_convert = simple_strtoul(value, NULL, 0);
353		if ((value_convert >= PARM_MIN_AUTH_KEY_MGMT_SUITE) || (value_convert <= PARM_MAX_AUTH_KEY_MGMT_SUITE))
354			lp->AuthKeyMgmtSuite = value_convert;
355		else
356			DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_AUTH_KEY_MGMT_SUITE);
357	} else if (strcmp(key, PARM_NAME_BRSC_2GHZ) == 0) {
358		DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_2GHZ, value);
359
360		value_convert = simple_strtoul(value, NULL, 0);
361		if ((value_convert >= PARM_MIN_BRSC) || (value_convert <= PARM_MAX_BRSC))
362			lp->brsc[0] = value_convert;
363		else
364			DBG_WARNING(DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_BRSC_2GHZ);
365	} else if (strcmp(key, PARM_NAME_BRSC_5GHZ) == 0) {
366		DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_BRSC_5GHZ, value);
367
368		value_convert = simple_strtoul(value, NULL, 0);
369		if ((value_convert >= PARM_MIN_BRSC) || (value_convert <= PARM_MAX_BRSC))
370			lp->brsc[1] = value_convert;
371		else
372			DBG_WARNING(DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_BRSC_5GHZ);
373	} else if ((strcmp(key, PARM_NAME_DESIRED_SSID) == 0) || (strcmp(key, PARM_NAME_OWN_SSID) == 0)) {
374		DBG_TRACE(DbgInfo, "SSID, value: %s\n", value);
375
376		memset(lp->NetworkName, 0, (PARM_MAX_NAME_LEN + 1));
377
378		/* Make sure the value isn't too long */
379		string_length = strlen(value);
380		if (string_length > PARM_MAX_NAME_LEN) {
381			DBG_WARNING(DbgInfo, "SSID too long; will be truncated\n");
382			string_length = PARM_MAX_NAME_LEN;
383		}
384
385		memcpy(lp->NetworkName, value, string_length);
386	}
387	else if (strcmp(key, PARM_NAME_ENABLE_ENCRYPTION) == 0) {
388		DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_ENABLE_ENCRYPTION, value);
389
390		value_convert = simple_strtoul(value, NULL, 0);
391		if ((value_convert >= PARM_MIN_ENABLE_ENCRYPTION) && (value_convert <= PARM_MAX_ENABLE_ENCRYPTION))
392			lp->EnableEncryption = value_convert;
393		else
394			DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_ENABLE_ENCRYPTION);
395	} else if (strcmp(key, PARM_NAME_ENCRYPTION) == 0) {
396		DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_ENCRYPTION, value);
397
398		memset(lp->szEncryption, 0, sizeof(lp->szEncryption));
399
400		/* Make sure the value isn't too long */
401		string_length = strlen(value);
402		if (string_length > sizeof(lp->szEncryption)) {
403			DBG_WARNING(DbgInfo, "%s too long; will be truncated\n", PARM_NAME_ENCRYPTION);
404			string_length = sizeof(lp->szEncryption);
405		}
406
407		memcpy(lp->szEncryption, value, string_length);
408	} else if (strcmp(key, PARM_NAME_KEY1) == 0) {
409		DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_KEY1, value);
410
411		if (is_valid_key_string(value)) {
412			memset(lp->DefaultKeys.key[0].key, 0, MAX_KEY_SIZE);
413
414			key_string2key(value, &lp->DefaultKeys.key[0]);
415		} else {
416			 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY1);
417		}
418	} else if (strcmp(key, PARM_NAME_KEY2) == 0) {
419		DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_KEY2, value);
420
421		if (is_valid_key_string(value)) {
422			memset(lp->DefaultKeys.key[1].key, 0, MAX_KEY_SIZE);
423
424			key_string2key(value, &lp->DefaultKeys.key[1]);
425		} else {
426			 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY2);
427		}
428	} else if (strcmp(key, PARM_NAME_KEY3) == 0) {
429		DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_KEY3, value);
430
431		if (is_valid_key_string(value)) {
432			memset(lp->DefaultKeys.key[2].key, 0, MAX_KEY_SIZE);
433
434			key_string2key(value, &lp->DefaultKeys.key[2]);
435		} else {
436			 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY3);
437		}
438	} else if (strcmp(key, PARM_NAME_KEY4) == 0) {
439		DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_KEY4, value);
440
441		if (is_valid_key_string(value)) {
442			memset(lp->DefaultKeys.key[3].key, 0, MAX_KEY_SIZE);
443
444			key_string2key(value, &lp->DefaultKeys.key[3]);
445		} else {
446			 DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_KEY4);
447		}
448	}
449	/* New Parameters for WARP */
450	else if (strcmp(key, PARM_NAME_LOAD_BALANCING) == 0) {
451		DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_LOAD_BALANCING, value);
452		lp->loadBalancing = parse_yes_no(value);
453	} else if (strcmp(key, PARM_NAME_MEDIUM_DISTRIBUTION) == 0) {
454		DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MEDIUM_DISTRIBUTION, value);
455		lp->mediumDistribution = parse_yes_no(value);
456	} else if (strcmp(key, PARM_NAME_MICROWAVE_ROBUSTNESS) == 0) {
457		DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MICROWAVE_ROBUSTNESS, value);
458		lp->MicrowaveRobustness = parse_yes_no(value);
459	} else if (strcmp(key, PARM_NAME_MULTICAST_RATE) == 0) {
460		DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_RATE, value);
461
462		value_convert = simple_strtoul(value, NULL, 0);
463
464		if ((value_convert >= PARM_MIN_MULTICAST_RATE) && (value_convert <= PARM_MAX_MULTICAST_RATE))
465			lp->MulticastRate[0] = value_convert;
466		else
467			DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MULTICAST_RATE);
468	} else if (strcmp(key, PARM_NAME_OWN_CHANNEL) == 0) {
469		DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_CHANNEL, value);
470
471		value_convert = simple_strtoul(value, NULL, 0);
472		if (wl_is_a_valid_chan(value_convert)) {
473			if (value_convert > 14)
474				value_convert = value_convert | 0x100;
475			lp->Channel = value_convert;
476		} else {
477			DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_CHANNEL);
478		}
479	} else if (strcmp(key, PARM_NAME_OWN_NAME) == 0) {
480		DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_NAME, value);
481
482		memset(lp->StationName, 0, (PARM_MAX_NAME_LEN + 1));
483
484		/* Make sure the value isn't too long */
485		string_length = strlen(value);
486		if (string_length > PARM_MAX_NAME_LEN) {
487			DBG_WARNING(DbgInfo, "%s too long; will be truncated\n", PARM_NAME_OWN_NAME);
488			string_length = PARM_MAX_NAME_LEN;
489		}
490
491		memcpy(lp->StationName, value, string_length);
492	} else if (strcmp(key, PARM_NAME_RTS_THRESHOLD) == 0) {
493		DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD, value);
494
495		value_convert = simple_strtoul(value, NULL, 0);
496		if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD))
497			lp->RTSThreshold = value_convert;
498		else
499			DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD);
500	} else if (strcmp(key, PARM_NAME_SRSC_2GHZ) == 0) {
501		DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_2GHZ, value);
502
503		value_convert = simple_strtoul(value, NULL, 0);
504		if ((value_convert >= PARM_MIN_SRSC) || (value_convert <= PARM_MAX_SRSC))
505			lp->srsc[0] = value_convert;
506		else
507			DBG_WARNING(DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_SRSC_2GHZ);
508	} else if (strcmp(key, PARM_NAME_SRSC_5GHZ) == 0) {
509		DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_SRSC_5GHZ, value);
510
511		value_convert = simple_strtoul(value, NULL, 0);
512		if ((value_convert >= PARM_MIN_SRSC) || (value_convert <= PARM_MAX_SRSC))
513			lp->srsc[1] = value_convert;
514		else
515			DBG_WARNING(DbgInfo, "%s invaid; will be ignored\n", PARM_NAME_SRSC_5GHZ);
516	} else if (strcmp(key, PARM_NAME_SYSTEM_SCALE) == 0) {
517		DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_SYSTEM_SCALE, value);
518
519		value_convert = simple_strtoul(value, NULL, 0);
520		if ((value_convert >= PARM_MIN_SYSTEM_SCALE) && (value_convert <= PARM_MAX_SYSTEM_SCALE))
521			lp->DistanceBetweenAPs = value_convert;
522		else
523			DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_SYSTEM_SCALE);
524	} else if (strcmp(key, PARM_NAME_TX_KEY) == 0) {
525		DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_KEY, value);
526
527		value_convert = simple_strtoul(value, NULL, 0);
528		if ((value_convert >= PARM_MIN_TX_KEY) && (value_convert <= PARM_MAX_TX_KEY))
529			lp->TransmitKeyID = simple_strtoul(value, NULL, 0);
530		else
531			DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_KEY);
532	} else if (strcmp(key, PARM_NAME_TX_RATE) == 0) {
533		DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE, value);
534
535		value_convert = simple_strtoul(value, NULL, 0);
536		if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE))
537			lp->TxRateControl[0] = value_convert;
538		else
539			DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE);
540	} else if (strcmp(key, PARM_NAME_TX_POW_LEVEL) == 0) {
541		DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_POW_LEVEL, value);
542
543		value_convert = simple_strtoul(value, NULL, 0);
544		if ((value_convert >= PARM_MIN_TX_POW_LEVEL) || (value_convert <= PARM_MAX_TX_POW_LEVEL))
545			lp->txPowLevel = value_convert;
546		else
547			DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_POW_LEVEL);
548	}
549
550	/* Need to add? : Country code, Short/Long retry */
551
552	/* Configuration parameters specific to STA mode */
553/* ;?seems reasonable that even an AP-only driver could afford this small additional footprint */
554	if (CNV_INT_TO_LITTLE(lp->hcfCtx.IFB_FWIdentity.comp_id) == COMP_ID_FW_STA) {
555					/* ;?should we return an error status in AP mode */
556		if (strcmp(key, PARM_NAME_PORT_TYPE) == 0) {
557			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PORT_TYPE, value);
558
559			value_convert = simple_strtoul(value, NULL, 0);
560			if ((value_convert == PARM_MIN_PORT_TYPE) || (value_convert == PARM_MAX_PORT_TYPE))
561				lp->PortType = value_convert;
562			else
563				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_PORT_TYPE);
564		} else if (strcmp(key, PARM_NAME_PM_ENABLED) == 0) {
565			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PM_ENABLED, value);
566			value_convert = simple_strtoul(value, NULL, 0);
567	/* ;? how about wl_main.c containing
568	 * VALID_PARAM(PARM_PM_ENABLED <= WVLAN_PM_STATE_STANDARD ||
569	 *					 (PARM_PM_ENABLED & 0x7FFF) <= WVLAN_PM_STATE_STANDARD);
570	 */
571			if ((value_convert & 0x7FFF) <= PARM_MAX_PM_ENABLED) {
572				lp->PMEnabled = value_convert;
573			} else {
574				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_PM_ENABLED);
575				/* ;?this is a data entry error, hence not a DBG_WARNING */
576			}
577		} else if (strcmp(key, PARM_NAME_CREATE_IBSS) == 0) {
578			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_CREATE_IBSS, value);
579			lp->CreateIBSS = parse_yes_no(value);
580		} else if (strcmp(key, PARM_NAME_MULTICAST_RX) == 0) {
581			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_RX, value);
582			lp->MulticastReceive = parse_yes_no(value);
583		} else if (strcmp(key, PARM_NAME_MAX_SLEEP) == 0) {
584			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MAX_SLEEP, value);
585
586			value_convert = simple_strtoul(value, NULL, 0);
587			if ((value_convert >= 0) && (value_convert <= 65535))
588				lp->MaxSleepDuration = value_convert;
589			else
590				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_MAX_SLEEP);
591		} else if (strcmp(key, PARM_NAME_NETWORK_ADDR) == 0) {
592			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_NETWORK_ADDR, value);
593
594			if (parse_mac_address(value, mac_value) == ETH_ALEN)
595				memcpy(lp->MACAddress, mac_value, ETH_ALEN);
596			else
597				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_NETWORK_ADDR);
598		} else if (strcmp(key, PARM_NAME_AUTHENTICATION) == 0) {
599			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_AUTHENTICATION, value);
600
601			value_convert = simple_strtoul(value, NULL, 0);
602			if ((value_convert >= PARM_MIN_AUTHENTICATION) && (value_convert <= PARM_MAX_AUTHENTICATION))
603				lp->authentication = value_convert;
604			else
605				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_AUTHENTICATION);
606		} else if (strcmp(key, PARM_NAME_OWN_ATIM_WINDOW) == 0) {
607			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_ATIM_WINDOW, value);
608
609			value_convert = simple_strtoul(value, NULL, 0);
610			if ((value_convert >= PARM_MIN_OWN_ATIM_WINDOW) && (value_convert <= PARM_MAX_OWN_ATIM_WINDOW))
611				lp->atimWindow = value_convert;
612			else
613				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_ATIM_WINDOW);
614		} else if (strcmp(key, PARM_NAME_PM_HOLDOVER_DURATION) == 0) {
615			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PM_HOLDOVER_DURATION, value);
616
617			value_convert = simple_strtoul(value, NULL, 0);
618			if ((value_convert >= PARM_MIN_PM_HOLDOVER_DURATION) && (value_convert <= PARM_MAX_PM_HOLDOVER_DURATION))
619				lp->holdoverDuration = value_convert;
620			else
621				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_PM_HOLDOVER_DURATION);
622		} else if (strcmp(key, PARM_NAME_PROMISCUOUS_MODE) == 0) {
623			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_PROMISCUOUS_MODE, value);
624			lp->promiscuousMode = parse_yes_no(value);
625		} else if (strcmp(key, PARM_NAME_CONNECTION_CONTROL) == 0) {
626			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_CONNECTION_CONTROL, value);
627
628			value_convert = simple_strtoul(value, NULL, 0);
629			if ((value_convert >= PARM_MIN_CONNECTION_CONTROL) && (value_convert <= PARM_MAX_CONNECTION_CONTROL))
630				lp->connectionControl = value_convert;
631			else
632				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_CONNECTION_CONTROL);
633		}
634
635		/* Need to add? : Probe Data Rate */
636	}
637
638	/* Configuration parameters specific to AP mode */
639		/* ;?should we restore this to allow smaller memory footprint */
640	if (CNV_INT_TO_LITTLE(lp->hcfCtx.IFB_FWIdentity.comp_id) == COMP_ID_FW_AP) {
641		if (strcmp(key, PARM_NAME_OWN_DTIM_PERIOD) == 0) {
642			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_DTIM_PERIOD, value);
643
644			value_convert = simple_strtoul(value, NULL, 0);
645			if (value_convert >= PARM_MIN_OWN_DTIM_PERIOD)
646				lp->DTIMPeriod = value_convert;
647			else
648				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_DTIM_PERIOD);
649		} else if (strcmp(key, PARM_NAME_REJECT_ANY) == 0) {
650			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_REJECT_ANY, value);
651			lp->RejectAny = parse_yes_no(value);
652		} else if (strcmp(key, PARM_NAME_EXCLUDE_UNENCRYPTED) == 0) {
653			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_EXCLUDE_UNENCRYPTED, value);
654			lp->ExcludeUnencrypted = parse_yes_no(value);
655		} else if (strcmp(key, PARM_NAME_MULTICAST_PM_BUFFERING) == 0) {
656			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_MULTICAST_PM_BUFFERING, value);
657			lp->ExcludeUnencrypted = parse_yes_no(value);
658		} else if (strcmp(key, PARM_NAME_INTRA_BSS_RELAY) == 0) {
659			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_INTRA_BSS_RELAY, value);
660			lp->ExcludeUnencrypted = parse_yes_no(value);
661		} else if (strcmp(key, PARM_NAME_OWN_BEACON_INTERVAL) == 0) {
662			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_OWN_BEACON_INTERVAL, value);
663
664			value_convert = simple_strtoul(value, NULL, 0);
665			if (value_convert >= PARM_MIN_OWN_BEACON_INTERVAL)
666				lp->ownBeaconInterval = value_convert;
667			else
668				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_OWN_BEACON_INTERVAL);
669		} else if (strcmp(key, PARM_NAME_COEXISTENCE) == 0) {
670			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_COEXISTENCE, value);
671
672			value_convert = simple_strtoul(value, NULL, 0);
673			if (value_convert >= PARM_MIN_COEXISTENCE)
674				lp->coexistence = value_convert;
675			else
676				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_COEXISTENCE);
677		}
678
679#ifdef USE_WDS
680		else if (strcmp(key, PARM_NAME_RTS_THRESHOLD1) == 0) {
681			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD1, value);
682
683			value_convert = simple_strtoul(value, NULL, 0);
684			if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD))
685				lp->wds_port[0].rtsThreshold = value_convert;
686			else
687				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD1);
688		} else if (strcmp(key, PARM_NAME_RTS_THRESHOLD2) == 0) {
689			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD2, value);
690
691			value_convert = simple_strtoul(value, NULL, 0);
692			if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD))
693				lp->wds_port[1].rtsThreshold = value_convert;
694			else
695				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD2);
696		} else if (strcmp(key, PARM_NAME_RTS_THRESHOLD3) == 0) {
697			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD3, value);
698
699			value_convert = simple_strtoul(value, NULL, 0);
700			if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD))
701				lp->wds_port[2].rtsThreshold = value_convert;
702			else
703				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD3);
704		} else if (strcmp(key, PARM_NAME_RTS_THRESHOLD4) == 0) {
705			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD4, value);
706
707			value_convert = simple_strtoul(value, NULL, 0);
708			if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD))
709				lp->wds_port[3].rtsThreshold = value_convert;
710			else
711				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD4);
712		} else if (strcmp(key, PARM_NAME_RTS_THRESHOLD5) == 0) {
713			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD5, value);
714
715			value_convert = simple_strtoul(value, NULL, 0);
716			if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD))
717				lp->wds_port[4].rtsThreshold = value_convert;
718			else
719				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD5);
720		} else if (strcmp(key, PARM_NAME_RTS_THRESHOLD6) == 0) {
721			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_RTS_THRESHOLD6, value);
722
723			value_convert = simple_strtoul(value, NULL, 0);
724			if ((value_convert >= PARM_MIN_RTS_THRESHOLD) && (value_convert <= PARM_MAX_RTS_THRESHOLD))
725				lp->wds_port[5].rtsThreshold = value_convert;
726			else
727				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_RTS_THRESHOLD6);
728		} else if (strcmp(key, PARM_NAME_TX_RATE1) == 0) {
729			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE1, value);
730
731			value_convert = simple_strtoul(value, NULL, 0);
732			if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE))
733				lp->wds_port[0].txRateCntl = value_convert;
734			else
735				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE1);
736		} else if (strcmp(key, PARM_NAME_TX_RATE2) == 0) {
737			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE2, value);
738
739			value_convert = simple_strtoul(value, NULL, 0);
740			if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE))
741				lp->wds_port[1].txRateCntl = value_convert;
742			else
743				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE2);
744		} else if (strcmp(key, PARM_NAME_TX_RATE3) == 0) {
745			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE3, value);
746
747			value_convert = simple_strtoul(value, NULL, 0);
748			if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE))
749				lp->wds_port[2].txRateCntl = value_convert;
750			else
751				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE3);
752		} else if (strcmp(key, PARM_NAME_TX_RATE4) == 0) {
753			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE4, value);
754
755			value_convert = simple_strtoul(value, NULL, 0);
756			if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE))
757				lp->wds_port[3].txRateCntl = value_convert;
758			else
759				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE4);
760		} else if (strcmp(key, PARM_NAME_TX_RATE5) == 0) {
761			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE5, value);
762
763			value_convert = simple_strtoul(value, NULL, 0);
764			if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE))
765				lp->wds_port[4].txRateCntl = value_convert;
766			else
767				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE5);
768		} else if (strcmp(key, PARM_NAME_TX_RATE6) == 0) {
769			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_TX_RATE6, value);
770
771			value_convert = simple_strtoul(value, NULL, 0);
772			if ((value_convert >= PARM_MIN_TX_RATE) && (value_convert <= PARM_MAX_TX_RATE))
773				lp->wds_port[5].txRateCntl = value_convert;
774			else
775				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_TX_RATE6);
776		} else if (strcmp(key, PARM_NAME_WDS_ADDRESS1) == 0) {
777			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS1, value);
778
779			if (parse_mac_address(value, mac_value) == ETH_ALEN)
780				memcpy(lp->wds_port[0].wdsAddress, mac_value, ETH_ALEN);
781			else
782				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS1);
783		} else if (strcmp(key, PARM_NAME_WDS_ADDRESS2) == 0) {
784			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS2, value);
785
786			if (parse_mac_address(value, mac_value) == ETH_ALEN)
787				memcpy(lp->wds_port[1].wdsAddress, mac_value, ETH_ALEN);
788			else
789				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS2);
790		} else if (strcmp(key, PARM_NAME_WDS_ADDRESS3) == 0) {
791			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS3, value);
792
793			if (parse_mac_address(value, mac_value) == ETH_ALEN)
794				memcpy(lp->wds_port[2].wdsAddress, mac_value, ETH_ALEN);
795			else
796				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS3);
797		} else if (strcmp(key, PARM_NAME_WDS_ADDRESS4) == 0) {
798			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS4, value);
799
800			if (parse_mac_address(value, mac_value) == ETH_ALEN)
801				memcpy(lp->wds_port[3].wdsAddress, mac_value, ETH_ALEN);
802			else
803				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS4);
804		} else if (strcmp(key, PARM_NAME_WDS_ADDRESS5) == 0) {
805			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS5, value);
806
807			if (parse_mac_address(value, mac_value) == ETH_ALEN)
808				memcpy(lp->wds_port[4].wdsAddress, mac_value, ETH_ALEN);
809			else
810				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS5);
811		} else if (strcmp(key, PARM_NAME_WDS_ADDRESS6) == 0) {
812			DBG_TRACE(DbgInfo, "%s, value: %s\n", PARM_NAME_WDS_ADDRESS6, value);
813
814			if (parse_mac_address(value, mac_value) == ETH_ALEN)
815				memcpy(lp->wds_port[5].wdsAddress, mac_value, ETH_ALEN);
816			else
817				DBG_WARNING(DbgInfo, "%s invalid; will be ignored\n", PARM_NAME_WDS_ADDRESS6);
818		}
819#endif  /* USE_WDS */
820	}
821
822	return;
823} /* translate_option */
824/*============================================================================*/
825
826/*******************************************************************************
827 *	parse_mac_address()
828 *******************************************************************************
829 *
830 *  DESCRIPTION:
831 *
832 *      This function will parse a mac address string and convert it to a byte
833 *   array.
834 *
835 *  PARAMETERS:
836 *
837 *      value       - the MAC address, represented as a string
838 *      byte_array  - the MAC address, represented as a byte array of length
839 *                    ETH_ALEN
840 *
841 *  RETURNS:
842 *
843 *      The number of bytes in the final MAC address, should equal to ETH_ALEN.
844 *
845 ******************************************************************************/
846int parse_mac_address(char *value, u_char *byte_array)
847{
848	int     value_offset = 0;
849	int     array_offset = 0;
850	int     field_offset = 0;
851	char    byte_field[3];
852	/*------------------------------------------------------------------------*/
853
854	memset(byte_field, '\0', 3);
855
856	while (value[value_offset] != '\0') {
857		/* Skip over the colon chars seperating the bytes, if they exist */
858		if (value[value_offset] == ':') {
859			value_offset++;
860			continue;
861		}
862
863		byte_field[field_offset] = value[value_offset];
864		field_offset++;
865		value_offset++;
866
867		/* Once the byte_field is filled, convert it and store it */
868		if (field_offset == 2) {
869			byte_field[field_offset] = '\0';
870			byte_array[array_offset] = simple_strtoul(byte_field, NULL, 16);
871			field_offset = 0;
872			array_offset++;
873		}
874	}
875
876	/* Use the array_offset as a check; 6 bytes should be written to the
877	   byte_array */
878	return array_offset;
879} /* parse_mac_address */
880/*============================================================================*/
881
882/*******************************************************************************
883 *	ParseConfigLine()
884 *******************************************************************************
885 *
886 *  DESCRIPTION:
887 *
888 *      Parses a line from the configuration file into an L-val and an R-val,
889 *  representing a key/value pair.
890 *
891 *  PARAMETERS:
892 *
893 *      pszLine     - the line from the config file to parse
894 *      ppszLVal    - the resulting L-val (Key)
895 *      ppszRVal    - the resulting R-val (Value)
896 *
897 *  RETURNS:
898 *
899 *      N/A
900 *
901 ******************************************************************************/
902void ParseConfigLine(char *pszLine, char **ppszLVal, char **ppszRVal)
903{
904	int i;
905	int size;
906	/*------------------------------------------------------------------------*/
907
908	DBG_FUNC("ParseConfigLine");
909	DBG_ENTER(DbgInfo);
910
911	/* get a snapshot of our string size */
912	size      = strlen(pszLine);
913	*ppszLVal = NULL;
914	*ppszRVal = NULL;
915
916	if (pszLine[0] != '#' &&							/* skip the line if it is a comment */
917		 pszLine[0] != '\n' &&							/* if it's an empty UNIX line, do nothing */
918		 !(pszLine[0] == '\r' && pszLine[1] == '\n')	/* if it's an empty MS-DOS line, do nothing */
919	   ) {
920		/* advance past any whitespace, and assign the L-value */
921		for (i = 0; i < size; i++) {
922			if (pszLine[i] != ' ') {
923				*ppszLVal = &pszLine[i];
924				break;
925			}
926		}
927		/* advance to the end of the l-value*/
928		for (i++; i < size; i++) {
929			if (pszLine[i] == ' ' || pszLine[i] == '=') {
930				pszLine[i] = '\0';
931				break;
932			}
933		}
934		/* make any whitespace and the equal sign a NULL character, and
935		   advance to the R-Value */
936		for (i++; i < size; i++) {
937			if (pszLine[i] == ' ' || pszLine[i] == '=') {
938				pszLine[i] = '\0';
939				continue;
940			}
941			*ppszRVal = &pszLine[i];
942			break;
943		}
944		/* make the line ending character(s) a NULL */
945		for (i++; i < size; i++) {
946			if (pszLine[i] == '\n')
947				pszLine[i] = '\0';
948			if ((pszLine[i] == '\r') && (pszLine[i+1] == '\n'))
949				pszLine[i] = '\0';
950		}
951	}
952	DBG_LEAVE(DbgInfo);
953} /* ParseConfigLine */
954/*============================================================================*/
955
956#endif  /* USE_PROFILE */
957