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