• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
10  * This program is free software; you can redistribute it and/or modify  *
11  * it under the terms of the GNU General Public License as published by  *
12  * the Free Software Foundation; either version 2 of the License, or     *
13  * (at your option) any later version.                                   *
14  *                                                                       *
15  * This program is distributed in the hope that it will be useful,       *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  * GNU General Public License for more details.                          *
19  *                                                                       *
20  * You should have received a copy of the GNU General Public License     *
21  * along with this program; if not, write to the                         *
22  * Free Software Foundation, Inc.,                                       *
23  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24  *                                                                       *
25  *************************************************************************
26  */
27 
28 #include "rt_config.h"
29 
30 #ifdef DOT11_N_SUPPORT
31 static void HTParametersHook(
32 	IN	PRTMP_ADAPTER pAd,
33 	IN	CHAR		  *pValueStr,
34 	IN	CHAR		  *pInput);
35 #endif // DOT11_N_SUPPORT //
36 
37 #define ETH_MAC_ADDR_STR_LEN 17  // in format of xx:xx:xx:xx:xx:xx
38 
39 // We assume the s1 is a sting, s2 is a memory space with 6 bytes. and content of s1 will be changed.
rtstrmactohex(char * s1,char * s2)40 BOOLEAN rtstrmactohex(char *s1, char *s2)
41 {
42 	int i = 0;
43 	char *ptokS = s1, *ptokE = s1;
44 
45 	if (strlen(s1) != ETH_MAC_ADDR_STR_LEN)
46 		return FALSE;
47 
48 	while((*ptokS) != '\0')
49 	{
50 		if((ptokE = strchr(ptokS, ':')) != NULL)
51 			*ptokE++ = '\0';
52 		if ((strlen(ptokS) != 2) || (!isxdigit(*ptokS)) || (!isxdigit(*(ptokS+1))))
53 			break; // fail
54 		AtoH(ptokS, &s2[i++], 1);
55 		ptokS = ptokE;
56 		if (i == 6)
57 			break; // parsing finished
58 	}
59 
60 	return ( i == 6 ? TRUE : FALSE);
61 
62 }
63 
64 
65 // we assume the s1 and s2 both are strings.
rtstrcasecmp(char * s1,char * s2)66 BOOLEAN rtstrcasecmp(char *s1, char *s2)
67 {
68 	char *p1 = s1, *p2 = s2;
69 
70 	if (strlen(s1) != strlen(s2))
71 		return FALSE;
72 
73 	while(*p1 != '\0')
74 	{
75 		if((*p1 != *p2) && ((*p1 ^ *p2) != 0x20))
76 			return FALSE;
77 		p1++;
78 		p2++;
79 	}
80 
81 	return TRUE;
82 }
83 
84 // we assume the s1 (buffer) and s2 (key) both are strings.
rtstrstruncasecmp(char * s1,char * s2)85 char * rtstrstruncasecmp(char * s1, char * s2)
86 {
87 	INT l1, l2, i;
88 	char temp1, temp2;
89 
90 	l2 = strlen(s2);
91 	if (!l2)
92 		return (char *) s1;
93 
94 	l1 = strlen(s1);
95 
96 	while (l1 >= l2)
97 	{
98 		l1--;
99 
100 		for(i=0; i<l2; i++)
101 		{
102 			temp1 = *(s1+i);
103 			temp2 = *(s2+i);
104 
105 			if (('a' <= temp1) && (temp1 <= 'z'))
106 				temp1 = 'A'+(temp1-'a');
107 			if (('a' <= temp2) && (temp2 <= 'z'))
108 				temp2 = 'A'+(temp2-'a');
109 
110 			if (temp1 != temp2)
111 				break;
112 		}
113 
114 		if (i == l2)
115 			return (char *) s1;
116 
117 		s1++;
118 	}
119 
120 	return NULL; // not found
121 }
122 
123 //add by kathy
124 
125  /**
126   * strstr - Find the first substring in a %NUL terminated string
127   * @s1: The string to be searched
128   * @s2: The string to search for
129   */
rtstrstr(const char * s1,const char * s2)130 char * rtstrstr(const char * s1,const char * s2)
131 {
132 	INT l1, l2;
133 
134 	l2 = strlen(s2);
135 	if (!l2)
136 		return (char *) s1;
137 
138 	l1 = strlen(s1);
139 
140 	while (l1 >= l2)
141 	{
142 		l1--;
143 		if (!memcmp(s1,s2,l2))
144 			return (char *) s1;
145 		s1++;
146 	}
147 
148 	return NULL;
149 }
150 
151 /**
152  * rstrtok - Split a string into tokens
153  * @s: The string to be searched
154  * @ct: The characters to search for
155  * * WARNING: strtok is deprecated, use strsep instead. However strsep is not compatible with old architecture.
156  */
157 char * __rstrtok;
rstrtok(char * s,const char * ct)158 char * rstrtok(char * s,const char * ct)
159 {
160 	char *sbegin, *send;
161 
162 	sbegin  = s ? s : __rstrtok;
163 	if (!sbegin)
164 	{
165 		return NULL;
166 	}
167 
168 	sbegin += strspn(sbegin,ct);
169 	if (*sbegin == '\0')
170 	{
171 		__rstrtok = NULL;
172 		return( NULL );
173 	}
174 
175 	send = strpbrk( sbegin, ct);
176 	if (send && *send != '\0')
177 		*send++ = '\0';
178 
179 	__rstrtok = send;
180 
181 	return (sbegin);
182 }
183 
184 /**
185  * delimitcnt - return the count of a given delimiter in a given string.
186  * @s: The string to be searched.
187  * @ct: The delimiter to search for.
188  * Notice : We suppose the delimiter is a single-char string(for example : ";").
189  */
delimitcnt(char * s,const char * ct)190 INT delimitcnt(char * s,const char * ct)
191 {
192 	INT count = 0;
193 	/* point to the beginning of the line */
194 	const char *token = s;
195 
196 	for ( ;; )
197 	{
198 		token = strpbrk(token, ct); /* search for delimiters */
199 
200         if ( token == NULL )
201 		{
202 			/* advanced to the terminating null character */
203 			break;
204 		}
205 		/* skip the delimiter */
206 	    ++token;
207 
208 		/*
209 		 * Print the found text: use len with %.*s to specify field width.
210 		 */
211 
212 		/* accumulate delimiter count */
213 	    ++count;
214 	}
215     return count;
216 }
217 
218 /*
219   * converts the Internet host address from the standard numbers-and-dots notation
220   * into binary data.
221   * returns nonzero if the address is valid, zero if not.
222   */
rtinet_aton(const char * cp,unsigned int * addr)223 int rtinet_aton(const char *cp, unsigned int *addr)
224 {
225 	unsigned int 	val;
226 	int         	base, n;
227 	char        	c;
228 	unsigned int    parts[4];
229 	unsigned int    *pp = parts;
230 
231 	for (;;)
232     {
233          /*
234           * Collect number up to ``.''.
235           * Values are specified as for C:
236           *	0x=hex, 0=octal, other=decimal.
237           */
238          val = 0;
239          base = 10;
240          if (*cp == '0')
241          {
242              if (*++cp == 'x' || *cp == 'X')
243                  base = 16, cp++;
244              else
245                  base = 8;
246          }
247          while ((c = *cp) != '\0')
248          {
249              if (isdigit((unsigned char) c))
250              {
251                  val = (val * base) + (c - '0');
252                  cp++;
253                  continue;
254              }
255              if (base == 16 && isxdigit((unsigned char) c))
256              {
257                  val = (val << 4) +
258                      (c + 10 - (islower((unsigned char) c) ? 'a' : 'A'));
259                  cp++;
260                  continue;
261              }
262              break;
263          }
264          if (*cp == '.')
265          {
266              /*
267               * Internet format: a.b.c.d a.b.c   (with c treated as 16-bits)
268               * a.b     (with b treated as 24 bits)
269               */
270              if (pp >= parts + 3 || val > 0xff)
271                  return 0;
272              *pp++ = val, cp++;
273          }
274          else
275              break;
276      }
277 
278      /*
279       * Check for trailing junk.
280       */
281      while (*cp)
282          if (!isspace((unsigned char) *cp++))
283              return 0;
284 
285      /*
286       * Concoct the address according to the number of parts specified.
287       */
288      n = pp - parts + 1;
289      switch (n)
290      {
291 
292          case 1:         /* a -- 32 bits */
293              break;
294 
295          case 2:         /* a.b -- 8.24 bits */
296              if (val > 0xffffff)
297                  return 0;
298              val |= parts[0] << 24;
299              break;
300 
301          case 3:         /* a.b.c -- 8.8.16 bits */
302              if (val > 0xffff)
303                  return 0;
304              val |= (parts[0] << 24) | (parts[1] << 16);
305              break;
306 
307          case 4:         /* a.b.c.d -- 8.8.8.8 bits */
308              if (val > 0xff)
309                  return 0;
310              val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
311              break;
312      }
313 
314      *addr = htonl(val);
315      return 1;
316 
317 }
318 
319 /*
320     ========================================================================
321 
322     Routine Description:
323         Find key section for Get key parameter.
324 
325     Arguments:
326         buffer                      Pointer to the buffer to start find the key section
327         section                     the key of the secion to be find
328 
329     Return Value:
330         NULL                        Fail
331         Others                      Success
332     ========================================================================
333 */
RTMPFindSection(IN PCHAR buffer)334 PUCHAR  RTMPFindSection(
335     IN  PCHAR   buffer)
336 {
337     CHAR temp_buf[32];
338     PUCHAR  ptr;
339 
340     strcpy(temp_buf, "Default");
341 
342     if((ptr = rtstrstr(buffer, temp_buf)) != NULL)
343             return (ptr+strlen("\n"));
344         else
345             return NULL;
346 }
347 
348 /*
349     ========================================================================
350 
351     Routine Description:
352         Get key parameter.
353 
354     Arguments:
355         key                         Pointer to key string
356         dest                        Pointer to destination
357         destsize                    The datasize of the destination
358         buffer                      Pointer to the buffer to start find the key
359 
360     Return Value:
361         TRUE                        Success
362         FALSE                       Fail
363 
364     Note:
365         This routine get the value with the matched key (case case-sensitive)
366     ========================================================================
367 */
RTMPGetKeyParameter(IN PCHAR key,OUT PCHAR dest,IN INT destsize,IN PCHAR buffer)368 INT RTMPGetKeyParameter(
369     IN  PCHAR   key,
370     OUT PCHAR   dest,
371     IN  INT     destsize,
372     IN  PCHAR   buffer)
373 {
374     UCHAR *temp_buf1 = NULL;
375     UCHAR *temp_buf2 = NULL;
376     CHAR *start_ptr;
377     CHAR *end_ptr;
378     CHAR *ptr;
379     CHAR *offset = 0;
380     INT  len;
381 
382 	//temp_buf1 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
383 	os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE);
384 
385 	if(temp_buf1 == NULL)
386         return (FALSE);
387 
388 	//temp_buf2 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
389 	os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE);
390 	if(temp_buf2 == NULL)
391 	{
392 		os_free_mem(NULL, temp_buf1);
393         return (FALSE);
394 	}
395 
396     //find section
397     if((offset = RTMPFindSection(buffer)) == NULL)
398     {
399     	os_free_mem(NULL, temp_buf1);
400     	os_free_mem(NULL, temp_buf2);
401         return (FALSE);
402     }
403 
404     strcpy(temp_buf1, "\n");
405     strcat(temp_buf1, key);
406     strcat(temp_buf1, "=");
407 
408     //search key
409     if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
410     {
411 		os_free_mem(NULL, temp_buf1);
412     	os_free_mem(NULL, temp_buf2);
413         return (FALSE);
414     }
415 
416     start_ptr+=strlen("\n");
417     if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
418        end_ptr=start_ptr+strlen(start_ptr);
419 
420     if (end_ptr<start_ptr)
421     {
422 		os_free_mem(NULL, temp_buf1);
423     	os_free_mem(NULL, temp_buf2);
424         return (FALSE);
425     }
426 
427     NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
428     temp_buf2[end_ptr-start_ptr]='\0';
429     len = strlen(temp_buf2);
430     strcpy(temp_buf1, temp_buf2);
431     if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
432     {
433 		os_free_mem(NULL, temp_buf1);
434     	os_free_mem(NULL, temp_buf2);
435         return (FALSE);
436     }
437 
438     strcpy(temp_buf2, start_ptr+1);
439     ptr = temp_buf2;
440     //trim space or tab
441     while(*ptr != 0x00)
442     {
443         if( (*ptr == ' ') || (*ptr == '\t') )
444             ptr++;
445         else
446            break;
447     }
448 
449     len = strlen(ptr);
450     memset(dest, 0x00, destsize);
451     strncpy(dest, ptr, len >= destsize ?  destsize: len);
452 
453 	os_free_mem(NULL, temp_buf1);
454     os_free_mem(NULL, temp_buf2);
455     return TRUE;
456 }
457 
458 /*
459     ========================================================================
460 
461     Routine Description:
462         Get key parameter.
463 
464     Arguments:
465         key                         Pointer to key string
466         dest                        Pointer to destination
467         destsize                    The datasize of the destination
468         buffer                      Pointer to the buffer to start find the key
469 
470     Return Value:
471         TRUE                        Success
472         FALSE                       Fail
473 
474     Note:
475         This routine get the value with the matched key (case case-sensitive).
476         It is called for parsing SSID and any key string.
477     ========================================================================
478 */
RTMPGetCriticalParameter(IN PCHAR key,OUT PCHAR dest,IN INT destsize,IN PCHAR buffer)479 INT RTMPGetCriticalParameter(
480     IN  PCHAR   key,
481     OUT PCHAR   dest,
482     IN  INT     destsize,
483     IN  PCHAR   buffer)
484 {
485     UCHAR *temp_buf1 = NULL;
486     UCHAR *temp_buf2 = NULL;
487     CHAR *start_ptr;
488     CHAR *end_ptr;
489     CHAR *ptr;
490     CHAR *offset = 0;
491     INT  len;
492 
493 	//temp_buf1 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
494 	os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE);
495 
496 	if(temp_buf1 == NULL)
497         return (FALSE);
498 
499 	//temp_buf2 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
500 	os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE);
501 	if(temp_buf2 == NULL)
502 	{
503 		os_free_mem(NULL, temp_buf1);
504         return (FALSE);
505 	}
506 
507     //find section
508     if((offset = RTMPFindSection(buffer)) == NULL)
509     {
510     	os_free_mem(NULL, temp_buf1);
511     	os_free_mem(NULL, temp_buf2);
512         return (FALSE);
513     }
514 
515     strcpy(temp_buf1, "\n");
516     strcat(temp_buf1, key);
517     strcat(temp_buf1, "=");
518 
519     //search key
520     if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
521     {
522 		os_free_mem(NULL, temp_buf1);
523     	os_free_mem(NULL, temp_buf2);
524         return (FALSE);
525     }
526 
527     start_ptr+=strlen("\n");
528     if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
529        end_ptr=start_ptr+strlen(start_ptr);
530 
531     if (end_ptr<start_ptr)
532     {
533 		os_free_mem(NULL, temp_buf1);
534     	os_free_mem(NULL, temp_buf2);
535         return (FALSE);
536     }
537 
538     NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
539     temp_buf2[end_ptr-start_ptr]='\0';
540     len = strlen(temp_buf2);
541     strcpy(temp_buf1, temp_buf2);
542     if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
543     {
544 		os_free_mem(NULL, temp_buf1);
545     	os_free_mem(NULL, temp_buf2);
546         return (FALSE);
547     }
548 
549     strcpy(temp_buf2, start_ptr+1);
550     ptr = temp_buf2;
551 
552     //trim tab
553     /* We cannot trim space(' ') for SSID and key string. */
554     while(*ptr != 0x00)
555     {
556         //if( (*ptr == ' ') || (*ptr == '\t') )
557         if( (*ptr == '\t') )
558             ptr++;
559         else
560            break;
561     }
562 
563     len = strlen(ptr);
564     memset(dest, 0x00, destsize);
565     strncpy(dest, ptr, len >= destsize ?  destsize: len);
566 
567 	os_free_mem(NULL, temp_buf1);
568     os_free_mem(NULL, temp_buf2);
569     return TRUE;
570 }
571 
572 /*
573     ========================================================================
574 
575     Routine Description:
576         Get multiple key parameter.
577 
578     Arguments:
579         key                         Pointer to key string
580         dest                        Pointer to destination
581         destsize                    The datasize of the destination
582         buffer                      Pointer to the buffer to start find the key
583 
584     Return Value:
585         TRUE                        Success
586         FALSE                       Fail
587 
588     Note:
589         This routine get the value with the matched key (case case-sensitive)
590     ========================================================================
591 */
RTMPGetKeyParameterWithOffset(IN PCHAR key,OUT PCHAR dest,OUT USHORT * end_offset,IN INT destsize,IN PCHAR buffer,IN BOOLEAN bTrimSpace)592 INT RTMPGetKeyParameterWithOffset(
593     IN  PCHAR   key,
594     OUT PCHAR   dest,
595     OUT	USHORT	*end_offset,
596     IN  INT     destsize,
597     IN  PCHAR   buffer,
598     IN	BOOLEAN	bTrimSpace)
599 {
600     UCHAR *temp_buf1 = NULL;
601     UCHAR *temp_buf2 = NULL;
602     CHAR *start_ptr;
603     CHAR *end_ptr;
604     CHAR *ptr;
605     CHAR *offset = 0;
606     INT  len;
607 
608 	if (*end_offset >= MAX_INI_BUFFER_SIZE)
609 		return (FALSE);
610 
611 	os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE);
612 
613 	if(temp_buf1 == NULL)
614         return (FALSE);
615 
616 	os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE);
617 	if(temp_buf2 == NULL)
618 	{
619 		os_free_mem(NULL, temp_buf1);
620         return (FALSE);
621 	}
622 
623     //find section
624 	if(*end_offset == 0)
625     {
626 		if ((offset = RTMPFindSection(buffer)) == NULL)
627 		{
628 			os_free_mem(NULL, temp_buf1);
629 	    	os_free_mem(NULL, temp_buf2);
630     	    return (FALSE);
631 		}
632     }
633 	else
634 		offset = buffer + (*end_offset);
635 
636     strcpy(temp_buf1, "\n");
637     strcat(temp_buf1, key);
638     strcat(temp_buf1, "=");
639 
640     //search key
641     if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
642     {
643 		os_free_mem(NULL, temp_buf1);
644     	os_free_mem(NULL, temp_buf2);
645         return (FALSE);
646     }
647 
648     start_ptr+=strlen("\n");
649     if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
650        end_ptr=start_ptr+strlen(start_ptr);
651 
652     if (end_ptr<start_ptr)
653     {
654 		os_free_mem(NULL, temp_buf1);
655     	os_free_mem(NULL, temp_buf2);
656         return (FALSE);
657     }
658 
659 	*end_offset = end_ptr - buffer;
660 
661     NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
662     temp_buf2[end_ptr-start_ptr]='\0';
663     len = strlen(temp_buf2);
664     strcpy(temp_buf1, temp_buf2);
665     if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
666     {
667 		os_free_mem(NULL, temp_buf1);
668     	os_free_mem(NULL, temp_buf2);
669         return (FALSE);
670     }
671 
672     strcpy(temp_buf2, start_ptr+1);
673     ptr = temp_buf2;
674     //trim space or tab
675     while(*ptr != 0x00)
676     {
677         if((bTrimSpace && (*ptr == ' ')) || (*ptr == '\t') )
678             ptr++;
679         else
680            break;
681     }
682 
683     len = strlen(ptr);
684     memset(dest, 0x00, destsize);
685     strncpy(dest, ptr, len >= destsize ?  destsize: len);
686 
687 	os_free_mem(NULL, temp_buf1);
688     os_free_mem(NULL, temp_buf2);
689     return TRUE;
690 }
691 
692 
rtmp_parse_key_buffer_from_file(IN PRTMP_ADAPTER pAd,IN char * buffer,IN ULONG KeyType,IN INT BSSIdx,IN INT KeyIdx)693 static int rtmp_parse_key_buffer_from_file(IN  PRTMP_ADAPTER pAd,IN  char *buffer,IN  ULONG KeyType,IN  INT BSSIdx,IN  INT KeyIdx)
694 {
695 	PUCHAR		keybuff;
696 	INT			i = BSSIdx, idx = KeyIdx;
697 	ULONG		KeyLen;
698 	UCHAR		CipherAlg = CIPHER_WEP64;
699 
700 	keybuff = buffer;
701 	KeyLen = strlen(keybuff);
702 
703 	if (KeyType == 1)
704 	{//Ascii
705 		if( (KeyLen == 5) || (KeyLen == 13))
706 		{
707 			pAd->SharedKey[i][idx].KeyLen = KeyLen;
708 			NdisMoveMemory(pAd->SharedKey[i][idx].Key, keybuff, KeyLen);
709 			if (KeyLen == 5)
710 				CipherAlg = CIPHER_WEP64;
711 			else
712 				CipherAlg = CIPHER_WEP128;
713 			pAd->SharedKey[i][idx].CipherAlg = CipherAlg;
714 
715 			DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) Key%dStr=%s and type=%s\n", i, idx+1, keybuff, (KeyType == 0) ? "Hex":"Ascii"));
716 			return 1;
717 		}
718 		else
719 		{//Invalid key length
720 			DBGPRINT(RT_DEBUG_ERROR, ("Key%dStr is Invalid key length! KeyLen = %ld!\n", idx+1, KeyLen));
721 			return 0;
722 		}
723 	}
724 	else
725 	{//Hex type
726 		if( (KeyLen == 10) || (KeyLen == 26))
727 		{
728 			pAd->SharedKey[i][idx].KeyLen = KeyLen / 2;
729 			AtoH(keybuff, pAd->SharedKey[i][idx].Key, KeyLen / 2);
730 			if (KeyLen == 10)
731 				CipherAlg = CIPHER_WEP64;
732 			else
733 				CipherAlg = CIPHER_WEP128;
734 			pAd->SharedKey[i][idx].CipherAlg = CipherAlg;
735 
736 			DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) Key%dStr=%s and type=%s\n", i, idx+1, keybuff, (KeyType == 0) ? "Hex":"Ascii"));
737 			return 1;
738 		}
739 		else
740 		{//Invalid key length
741 			DBGPRINT(RT_DEBUG_ERROR, ("I/F(ra%d) Key%dStr is Invalid key length! KeyLen = %ld!\n", i, idx+1, KeyLen));
742 			return 0;
743 		}
744 	}
745 }
rtmp_read_key_parms_from_file(IN PRTMP_ADAPTER pAd,char * tmpbuf,char * buffer)746 static void rtmp_read_key_parms_from_file(IN  PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer)
747 {
748 	char		tok_str[16];
749 	PUCHAR		macptr;
750 	INT			i = 0, idx;
751 	ULONG		KeyType[MAX_MBSSID_NUM];
752 	ULONG		KeyIdx;
753 
754 	NdisZeroMemory(KeyType, MAX_MBSSID_NUM);
755 
756 	//DefaultKeyID
757 	if(RTMPGetKeyParameter("DefaultKeyID", tmpbuf, 25, buffer))
758 	{
759 
760 #ifdef CONFIG_STA_SUPPORT
761 		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
762 		{
763 			KeyIdx = simple_strtol(tmpbuf, 0, 10);
764 			if((KeyIdx >= 1 ) && (KeyIdx <= 4))
765 				pAd->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1);
766 			else
767 				pAd->StaCfg.DefaultKeyId = 0;
768 
769 			DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyID(0~3)=%d\n", pAd->StaCfg.DefaultKeyId));
770 		}
771 #endif // CONFIG_STA_SUPPORT //
772 	}
773 
774 
775 	for (idx = 0; idx < 4; idx++)
776 	{
777 		sprintf(tok_str, "Key%dType", idx + 1);
778 		//Key1Type
779 		if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer))
780 		{
781 		    for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
782 		    {
783 			    KeyType[i] = simple_strtol(macptr, 0, 10);
784 		    }
785 
786 #ifdef CONFIG_STA_SUPPORT
787 			IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
788 			{
789 				sprintf(tok_str, "Key%dStr", idx + 1);
790 				if (RTMPGetCriticalParameter(tok_str, tmpbuf, 128, buffer))
791 				{
792 					rtmp_parse_key_buffer_from_file(pAd, tmpbuf, KeyType[BSS0], BSS0, idx);
793 				}
794 			}
795 #endif // CONFIG_STA_SUPPORT //
796 		}
797 	}
798 }
799 
800 
801 #ifdef CONFIG_STA_SUPPORT
rtmp_read_sta_wmm_parms_from_file(IN PRTMP_ADAPTER pAd,char * tmpbuf,char * buffer)802 static void rtmp_read_sta_wmm_parms_from_file(IN  PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer)
803 {
804 	PUCHAR					macptr;
805 	INT						i=0;
806 	BOOLEAN					bWmmEnable = FALSE;
807 
808 	//WmmCapable
809 	if(RTMPGetKeyParameter("WmmCapable", tmpbuf, 32, buffer))
810 	{
811 		if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
812 		{
813 			pAd->CommonCfg.bWmmCapable = TRUE;
814 			bWmmEnable = TRUE;
815 		}
816 		else //Disable
817 		{
818 			pAd->CommonCfg.bWmmCapable = FALSE;
819 		}
820 
821 		DBGPRINT(RT_DEBUG_TRACE, ("WmmCapable=%d\n", pAd->CommonCfg.bWmmCapable));
822 	}
823 
824 #ifdef QOS_DLS_SUPPORT
825 	//DLSCapable
826 	if(RTMPGetKeyParameter("DLSCapable", tmpbuf, 32, buffer))
827 	{
828 		if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
829 		{
830 			pAd->CommonCfg.bDLSCapable = TRUE;
831 		}
832 		else //Disable
833 		{
834 			pAd->CommonCfg.bDLSCapable = FALSE;
835 		}
836 
837 		DBGPRINT(RT_DEBUG_TRACE, ("bDLSCapable=%d\n", pAd->CommonCfg.bDLSCapable));
838 	}
839 #endif // QOS_DLS_SUPPORT //
840 
841 	//AckPolicy for AC_BK, AC_BE, AC_VI, AC_VO
842 	if(RTMPGetKeyParameter("AckPolicy", tmpbuf, 32, buffer))
843 	{
844 		for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
845 		{
846 			pAd->CommonCfg.AckPolicy[i] = (UCHAR)simple_strtol(macptr, 0, 10);
847 
848 			DBGPRINT(RT_DEBUG_TRACE, ("AckPolicy[%d]=%d\n", i, pAd->CommonCfg.AckPolicy[i]));
849 		}
850 	}
851 
852 	if (bWmmEnable)
853 	{
854 		//APSDCapable
855 		if(RTMPGetKeyParameter("APSDCapable", tmpbuf, 10, buffer))
856 		{
857 			if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
858 				pAd->CommonCfg.bAPSDCapable = TRUE;
859 			else
860 				pAd->CommonCfg.bAPSDCapable = FALSE;
861 
862 			DBGPRINT(RT_DEBUG_TRACE, ("APSDCapable=%d\n", pAd->CommonCfg.bAPSDCapable));
863 		}
864 
865 		//APSDAC for AC_BE, AC_BK, AC_VI, AC_VO
866 		if(RTMPGetKeyParameter("APSDAC", tmpbuf, 32, buffer))
867 		{
868 			BOOLEAN apsd_ac[4];
869 
870 			for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
871 			{
872 				apsd_ac[i] = (BOOLEAN)simple_strtol(macptr, 0, 10);
873 
874 				DBGPRINT(RT_DEBUG_TRACE, ("APSDAC%d  %d\n", i,  apsd_ac[i]));
875 			}
876 
877 			pAd->CommonCfg.bAPSDAC_BE = apsd_ac[0];
878 			pAd->CommonCfg.bAPSDAC_BK = apsd_ac[1];
879 			pAd->CommonCfg.bAPSDAC_VI = apsd_ac[2];
880 			pAd->CommonCfg.bAPSDAC_VO = apsd_ac[3];
881 		}
882 	}
883 
884 }
885 #endif // CONFIG_STA_SUPPORT //
886 
887 
RTMPReadParametersHook(IN PRTMP_ADAPTER pAd)888 NDIS_STATUS	RTMPReadParametersHook(
889 	IN	PRTMP_ADAPTER pAd)
890 {
891 	PUCHAR					src = NULL;
892 	struct file				*srcf;
893 	INT 					retval, orgfsuid, orgfsgid;
894    	mm_segment_t			orgfs;
895 	CHAR					*buffer;
896 	CHAR					*tmpbuf;
897 	ULONG					RtsThresh;
898 	ULONG					FragThresh;
899 #ifdef CONFIG_STA_SUPPORT
900 	UCHAR	                keyMaterial[40];
901 #endif // CONFIG_STA_SUPPORT //
902 
903 
904 	PUCHAR					macptr;
905 	INT						i = 0;
906 
907 	buffer = kmalloc(MAX_INI_BUFFER_SIZE, MEM_ALLOC_FLAG);
908 	if(buffer == NULL)
909         return NDIS_STATUS_FAILURE;
910 
911 	tmpbuf = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
912 	if(tmpbuf == NULL)
913 	{
914 		kfree(buffer);
915         return NDIS_STATUS_FAILURE;
916 	}
917 
918 #ifdef CONFIG_STA_SUPPORT
919 	IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
920 		src = STA_PROFILE_PATH;
921 #endif // CONFIG_STA_SUPPORT //
922 #ifdef MULTIPLE_CARD_SUPPORT
923 	src = pAd->MC_FileName;
924 #endif // MULTIPLE_CARD_SUPPORT //
925 
926 	// Save uid and gid used for filesystem access.
927 	// Set user and group to 0 (root)
928 	orgfsuid = current_fsuid();
929 	orgfsgid = current_fsgid();
930 	/* Hm, can't really do this nicely anymore, so rely on these files
931 	 * being set to the proper permission to read them... */
932 	/* current->cred->fsuid = current->cred->fsgid = 0; */
933     orgfs = get_fs();
934     set_fs(KERNEL_DS);
935 
936 	if (src && *src)
937 	{
938 		srcf = filp_open(src, O_RDONLY, 0);
939 		if (IS_ERR(srcf))
940 		{
941 			DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
942 		}
943 		else
944 		{
945 			// The object must have a read method
946 			if (srcf->f_op && srcf->f_op->read)
947 			{
948 				memset(buffer, 0x00, MAX_INI_BUFFER_SIZE);
949 				retval=srcf->f_op->read(srcf, buffer, MAX_INI_BUFFER_SIZE, &srcf->f_pos);
950 				if (retval < 0)
951 				{
952 					DBGPRINT(RT_DEBUG_TRACE, ("--> Read %s error %d\n", src, -retval));
953 				}
954 				else
955 				{
956 					// set file parameter to portcfg
957 					//CountryRegion
958 					if(RTMPGetKeyParameter("CountryRegion", tmpbuf, 25, buffer))
959 					{
960 						pAd->CommonCfg.CountryRegion = (UCHAR) simple_strtol(tmpbuf, 0, 10);
961 						DBGPRINT(RT_DEBUG_TRACE, ("CountryRegion=%d\n", pAd->CommonCfg.CountryRegion));
962 					}
963 					//CountryRegionABand
964 					if(RTMPGetKeyParameter("CountryRegionABand", tmpbuf, 25, buffer))
965 					{
966 						pAd->CommonCfg.CountryRegionForABand= (UCHAR) simple_strtol(tmpbuf, 0, 10);
967 						DBGPRINT(RT_DEBUG_TRACE, ("CountryRegionABand=%d\n", pAd->CommonCfg.CountryRegionForABand));
968 					}
969 					//CountryCode
970 					if(RTMPGetKeyParameter("CountryCode", tmpbuf, 25, buffer))
971 					{
972 						NdisMoveMemory(pAd->CommonCfg.CountryCode, tmpbuf , 2);
973 #ifdef CONFIG_STA_SUPPORT
974 #ifdef EXT_BUILD_CHANNEL_LIST
975 						IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
976 							NdisMoveMemory(pAd->StaCfg.StaOriCountryCode, tmpbuf , 2);
977 #endif // EXT_BUILD_CHANNEL_LIST //
978 #endif // CONFIG_STA_SUPPORT //
979 						if (strlen(pAd->CommonCfg.CountryCode) != 0)
980 						{
981 							pAd->CommonCfg.bCountryFlag = TRUE;
982 						}
983 						DBGPRINT(RT_DEBUG_TRACE, ("CountryCode=%s\n", pAd->CommonCfg.CountryCode));
984 					}
985 					//ChannelGeography
986 					if(RTMPGetKeyParameter("ChannelGeography", tmpbuf, 25, buffer))
987 					{
988 						UCHAR Geography = (UCHAR) simple_strtol(tmpbuf, 0, 10);
989 						if (Geography <= BOTH)
990 						{
991 							pAd->CommonCfg.Geography = Geography;
992 							pAd->CommonCfg.CountryCode[2] =
993 								(pAd->CommonCfg.Geography == BOTH) ? ' ' : ((pAd->CommonCfg.Geography == IDOR) ? 'I' : 'O');
994 #ifdef CONFIG_STA_SUPPORT
995 #ifdef EXT_BUILD_CHANNEL_LIST
996 						IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
997 							pAd->StaCfg.StaOriGeography = pAd->CommonCfg.Geography;
998 #endif // EXT_BUILD_CHANNEL_LIST //
999 #endif // CONFIG_STA_SUPPORT //
1000 							DBGPRINT(RT_DEBUG_TRACE, ("ChannelGeography=%d\n", pAd->CommonCfg.Geography));
1001 						}
1002 					}
1003 					else
1004 					{
1005 						pAd->CommonCfg.Geography = BOTH;
1006 						pAd->CommonCfg.CountryCode[2] = ' ';
1007 					}
1008 
1009 
1010 #ifdef CONFIG_STA_SUPPORT
1011 					IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1012 					{
1013 						//SSID
1014 						if (RTMPGetCriticalParameter("SSID", tmpbuf, 256, buffer))
1015 						{
1016 							if (strlen(tmpbuf) <= 32)
1017 							{
1018 			 					pAd->CommonCfg.SsidLen = (UCHAR) strlen(tmpbuf);
1019 								NdisZeroMemory(pAd->CommonCfg.Ssid, NDIS_802_11_LENGTH_SSID);
1020 								NdisMoveMemory(pAd->CommonCfg.Ssid, tmpbuf, pAd->CommonCfg.SsidLen);
1021 								pAd->MlmeAux.AutoReconnectSsidLen = pAd->CommonCfg.SsidLen;
1022 								NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, NDIS_802_11_LENGTH_SSID);
1023 								NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, tmpbuf, pAd->MlmeAux.AutoReconnectSsidLen);
1024 								pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen;
1025 								NdisZeroMemory(pAd->MlmeAux.Ssid, NDIS_802_11_LENGTH_SSID);
1026 								NdisMoveMemory(pAd->MlmeAux.Ssid, tmpbuf, pAd->MlmeAux.SsidLen);
1027 								DBGPRINT(RT_DEBUG_TRACE, ("%s::(SSID=%s)\n", __func__, tmpbuf));
1028 							}
1029 						}
1030 					}
1031 #endif // CONFIG_STA_SUPPORT //
1032 
1033 #ifdef CONFIG_STA_SUPPORT
1034 					IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1035 					{
1036 						//NetworkType
1037 						if (RTMPGetKeyParameter("NetworkType", tmpbuf, 25, buffer))
1038 						{
1039 							pAd->bConfigChanged = TRUE;
1040 							if (strcmp(tmpbuf, "Adhoc") == 0)
1041 								pAd->StaCfg.BssType = BSS_ADHOC;
1042 							else //Default Infrastructure mode
1043 								pAd->StaCfg.BssType = BSS_INFRA;
1044 							// Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
1045 							pAd->StaCfg.WpaState = SS_NOTUSE;
1046 							DBGPRINT(RT_DEBUG_TRACE, ("%s::(NetworkType=%d)\n", __func__, pAd->StaCfg.BssType));
1047 						}
1048 					}
1049 #endif // CONFIG_STA_SUPPORT //
1050 					//Channel
1051 					if(RTMPGetKeyParameter("Channel", tmpbuf, 10, buffer))
1052 					{
1053 						pAd->CommonCfg.Channel = (UCHAR) simple_strtol(tmpbuf, 0, 10);
1054 						DBGPRINT(RT_DEBUG_TRACE, ("Channel=%d\n", pAd->CommonCfg.Channel));
1055 					}
1056 					//WirelessMode
1057 					if(RTMPGetKeyParameter("WirelessMode", tmpbuf, 10, buffer))
1058 					{
1059 						int value  = 0, maxPhyMode = PHY_11G;
1060 
1061 #ifdef DOT11_N_SUPPORT
1062 						maxPhyMode = PHY_11N_5G;
1063 #endif // DOT11_N_SUPPORT //
1064 
1065 						value = simple_strtol(tmpbuf, 0, 10);
1066 
1067 						if (value <= maxPhyMode)
1068 						{
1069 							pAd->CommonCfg.PhyMode = value;
1070 						}
1071 						DBGPRINT(RT_DEBUG_TRACE, ("PhyMode=%d\n", pAd->CommonCfg.PhyMode));
1072 					}
1073                     //BasicRate
1074 					if(RTMPGetKeyParameter("BasicRate", tmpbuf, 10, buffer))
1075 					{
1076 						pAd->CommonCfg.BasicRateBitmap = (ULONG) simple_strtol(tmpbuf, 0, 10);
1077 						DBGPRINT(RT_DEBUG_TRACE, ("BasicRate=%ld\n", pAd->CommonCfg.BasicRateBitmap));
1078 					}
1079 					//BeaconPeriod
1080 					if(RTMPGetKeyParameter("BeaconPeriod", tmpbuf, 10, buffer))
1081 					{
1082 						pAd->CommonCfg.BeaconPeriod = (USHORT) simple_strtol(tmpbuf, 0, 10);
1083 						DBGPRINT(RT_DEBUG_TRACE, ("BeaconPeriod=%d\n", pAd->CommonCfg.BeaconPeriod));
1084 					}
1085                     //TxPower
1086 					if(RTMPGetKeyParameter("TxPower", tmpbuf, 10, buffer))
1087 					{
1088 						pAd->CommonCfg.TxPowerPercentage = (ULONG) simple_strtol(tmpbuf, 0, 10);
1089 #ifdef CONFIG_STA_SUPPORT
1090 						IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1091 							pAd->CommonCfg.TxPowerDefault = pAd->CommonCfg.TxPowerPercentage;
1092 #endif // CONFIG_STA_SUPPORT //
1093 						DBGPRINT(RT_DEBUG_TRACE, ("TxPower=%ld\n", pAd->CommonCfg.TxPowerPercentage));
1094 					}
1095 					//BGProtection
1096 					if(RTMPGetKeyParameter("BGProtection", tmpbuf, 10, buffer))
1097 					{
1098 						switch (simple_strtol(tmpbuf, 0, 10))
1099 						{
1100 							case 1: //Always On
1101 								pAd->CommonCfg.UseBGProtection = 1;
1102 								break;
1103 							case 2: //Always OFF
1104 								pAd->CommonCfg.UseBGProtection = 2;
1105 								break;
1106 							case 0: //AUTO
1107 							default:
1108 								pAd->CommonCfg.UseBGProtection = 0;
1109 								break;
1110 						}
1111 						DBGPRINT(RT_DEBUG_TRACE, ("BGProtection=%ld\n", pAd->CommonCfg.UseBGProtection));
1112 					}
1113 					//OLBCDetection
1114 					if(RTMPGetKeyParameter("DisableOLBC", tmpbuf, 10, buffer))
1115 					{
1116 						switch (simple_strtol(tmpbuf, 0, 10))
1117 						{
1118 							case 1: //disable OLBC Detection
1119 								pAd->CommonCfg.DisableOLBCDetect = 1;
1120 								break;
1121 							case 0: //enable OLBC Detection
1122 								pAd->CommonCfg.DisableOLBCDetect = 0;
1123 								break;
1124 							default:
1125 								pAd->CommonCfg.DisableOLBCDetect= 0;
1126 								break;
1127 						}
1128 						DBGPRINT(RT_DEBUG_TRACE, ("OLBCDetection=%ld\n", pAd->CommonCfg.DisableOLBCDetect));
1129 					}
1130 					//TxPreamble
1131 					if(RTMPGetKeyParameter("TxPreamble", tmpbuf, 10, buffer))
1132 					{
1133 						switch (simple_strtol(tmpbuf, 0, 10))
1134 						{
1135 							case Rt802_11PreambleShort:
1136 								pAd->CommonCfg.TxPreamble = Rt802_11PreambleShort;
1137 								break;
1138 							case Rt802_11PreambleLong:
1139 							default:
1140 								pAd->CommonCfg.TxPreamble = Rt802_11PreambleLong;
1141 								break;
1142 						}
1143 						DBGPRINT(RT_DEBUG_TRACE, ("TxPreamble=%ld\n", pAd->CommonCfg.TxPreamble));
1144 					}
1145 					//RTSThreshold
1146 					if(RTMPGetKeyParameter("RTSThreshold", tmpbuf, 10, buffer))
1147 					{
1148 						RtsThresh = simple_strtol(tmpbuf, 0, 10);
1149 						if( (RtsThresh >= 1) && (RtsThresh <= MAX_RTS_THRESHOLD) )
1150 							pAd->CommonCfg.RtsThreshold  = (USHORT)RtsThresh;
1151 						else
1152 							pAd->CommonCfg.RtsThreshold = MAX_RTS_THRESHOLD;
1153 
1154 						DBGPRINT(RT_DEBUG_TRACE, ("RTSThreshold=%d\n", pAd->CommonCfg.RtsThreshold));
1155 					}
1156 					//FragThreshold
1157 					if(RTMPGetKeyParameter("FragThreshold", tmpbuf, 10, buffer))
1158 					{
1159 						FragThresh = simple_strtol(tmpbuf, 0, 10);
1160 						pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
1161 
1162 						if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
1163 						{ //illegal FragThresh so we set it to default
1164 							pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
1165 							pAd->CommonCfg.bUseZeroToDisableFragment = TRUE;
1166 						}
1167 						else if (FragThresh % 2 == 1)
1168 						{
1169 							// The length of each fragment shall always be an even number of octets, except for the last fragment
1170 							// of an MSDU or MMPDU, which may be either an even or an odd number of octets.
1171 							pAd->CommonCfg.FragmentThreshold = (USHORT)(FragThresh - 1);
1172 						}
1173 						else
1174 						{
1175 							pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
1176 						}
1177 						//pAd->CommonCfg.AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
1178 						DBGPRINT(RT_DEBUG_TRACE, ("FragThreshold=%d\n", pAd->CommonCfg.FragmentThreshold));
1179 					}
1180 					//TxBurst
1181 					if(RTMPGetKeyParameter("TxBurst", tmpbuf, 10, buffer))
1182 					{
1183 						if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
1184 							pAd->CommonCfg.bEnableTxBurst = TRUE;
1185 						else //Disable
1186 							pAd->CommonCfg.bEnableTxBurst = FALSE;
1187 						DBGPRINT(RT_DEBUG_TRACE, ("TxBurst=%d\n", pAd->CommonCfg.bEnableTxBurst));
1188 					}
1189 
1190 #ifdef AGGREGATION_SUPPORT
1191 					//PktAggregate
1192 					if(RTMPGetKeyParameter("PktAggregate", tmpbuf, 10, buffer))
1193 					{
1194 						if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
1195 							pAd->CommonCfg.bAggregationCapable = TRUE;
1196 						else //Disable
1197 							pAd->CommonCfg.bAggregationCapable = FALSE;
1198 #ifdef PIGGYBACK_SUPPORT
1199 						pAd->CommonCfg.bPiggyBackCapable = pAd->CommonCfg.bAggregationCapable;
1200 #endif // PIGGYBACK_SUPPORT //
1201 						DBGPRINT(RT_DEBUG_TRACE, ("PktAggregate=%d\n", pAd->CommonCfg.bAggregationCapable));
1202 					}
1203 #else
1204 					pAd->CommonCfg.bAggregationCapable = FALSE;
1205 					pAd->CommonCfg.bPiggyBackCapable = FALSE;
1206 #endif // AGGREGATION_SUPPORT //
1207 
1208 					// WmmCapable
1209 
1210 #ifdef CONFIG_STA_SUPPORT
1211 					IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1212 						rtmp_read_sta_wmm_parms_from_file(pAd, tmpbuf, buffer);
1213 #endif // CONFIG_STA_SUPPORT //
1214 
1215 					//ShortSlot
1216 					if(RTMPGetKeyParameter("ShortSlot", tmpbuf, 10, buffer))
1217 					{
1218 						if(simple_strtol(tmpbuf, 0, 10) != 0)  //Enable
1219 							pAd->CommonCfg.bUseShortSlotTime = TRUE;
1220 						else //Disable
1221 							pAd->CommonCfg.bUseShortSlotTime = FALSE;
1222 
1223 						DBGPRINT(RT_DEBUG_TRACE, ("ShortSlot=%d\n", pAd->CommonCfg.bUseShortSlotTime));
1224 					}
1225 					//IEEE80211H
1226 					if(RTMPGetKeyParameter("IEEE80211H", tmpbuf, 10, buffer))
1227 					{
1228 					    for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
1229 					    {
1230     						if(simple_strtol(macptr, 0, 10) != 0)  //Enable
1231     							pAd->CommonCfg.bIEEE80211H = TRUE;
1232     						else //Disable
1233     							pAd->CommonCfg.bIEEE80211H = FALSE;
1234 
1235     						DBGPRINT(RT_DEBUG_TRACE, ("IEEE80211H=%d\n", pAd->CommonCfg.bIEEE80211H));
1236 					    }
1237 					}
1238 					//CSPeriod
1239 					if(RTMPGetKeyParameter("CSPeriod", tmpbuf, 10, buffer))
1240 					{
1241 					    if(simple_strtol(tmpbuf, 0, 10) != 0)
1242 							pAd->CommonCfg.RadarDetect.CSPeriod = simple_strtol(tmpbuf, 0, 10);
1243 						else
1244 							pAd->CommonCfg.RadarDetect.CSPeriod = 0;
1245 
1246    						DBGPRINT(RT_DEBUG_TRACE, ("CSPeriod=%d\n", pAd->CommonCfg.RadarDetect.CSPeriod));
1247 					}
1248 
1249 					//RDRegion
1250 					if(RTMPGetKeyParameter("RDRegion", tmpbuf, 128, buffer))
1251 					{
1252 						if ((strncmp(tmpbuf, "JAP_W53", 7) == 0) || (strncmp(tmpbuf, "jap_w53", 7) == 0))
1253 						{
1254 							pAd->CommonCfg.RadarDetect.RDDurRegion = JAP_W53;
1255 							pAd->CommonCfg.RadarDetect.DfsSessionTime = 15;
1256 						}
1257 						else if ((strncmp(tmpbuf, "JAP_W56", 7) == 0) || (strncmp(tmpbuf, "jap_w56", 7) == 0))
1258 						{
1259 							pAd->CommonCfg.RadarDetect.RDDurRegion = JAP_W56;
1260 							pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
1261 						}
1262 						else if ((strncmp(tmpbuf, "JAP", 3) == 0) || (strncmp(tmpbuf, "jap", 3) == 0))
1263 						{
1264 							pAd->CommonCfg.RadarDetect.RDDurRegion = JAP;
1265 							pAd->CommonCfg.RadarDetect.DfsSessionTime = 5;
1266 						}
1267 						else  if ((strncmp(tmpbuf, "FCC", 3) == 0) || (strncmp(tmpbuf, "fcc", 3) == 0))
1268 						{
1269 							pAd->CommonCfg.RadarDetect.RDDurRegion = FCC;
1270 							pAd->CommonCfg.RadarDetect.DfsSessionTime = 5;
1271 						}
1272 						else if ((strncmp(tmpbuf, "CE", 2) == 0) || (strncmp(tmpbuf, "ce", 2) == 0))
1273 						{
1274 							pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
1275 							pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
1276 						}
1277 						else
1278 						{
1279 							pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
1280 							pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
1281 						}
1282 
1283 						DBGPRINT(RT_DEBUG_TRACE, ("RDRegion=%d\n", pAd->CommonCfg.RadarDetect.RDDurRegion));
1284 					}
1285 					else
1286 					{
1287 						pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
1288 						pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
1289 					}
1290 
1291 					//WirelessEvent
1292 					if(RTMPGetKeyParameter("WirelessEvent", tmpbuf, 10, buffer))
1293 					{
1294 #if WIRELESS_EXT >= 15
1295 					    if(simple_strtol(tmpbuf, 0, 10) != 0)
1296 							pAd->CommonCfg.bWirelessEvent = simple_strtol(tmpbuf, 0, 10);
1297 						else
1298 							pAd->CommonCfg.bWirelessEvent = 0;	// disable
1299 #else
1300 						pAd->CommonCfg.bWirelessEvent = 0;	// disable
1301 #endif
1302    						DBGPRINT(RT_DEBUG_TRACE, ("WirelessEvent=%d\n", pAd->CommonCfg.bWirelessEvent));
1303 					}
1304 					if(RTMPGetKeyParameter("WiFiTest", tmpbuf, 10, buffer))
1305 					{
1306 					    if(simple_strtol(tmpbuf, 0, 10) != 0)
1307 							pAd->CommonCfg.bWiFiTest= simple_strtol(tmpbuf, 0, 10);
1308 						else
1309 							pAd->CommonCfg.bWiFiTest = 0;	// disable
1310 
1311    						DBGPRINT(RT_DEBUG_TRACE, ("WiFiTest=%d\n", pAd->CommonCfg.bWiFiTest));
1312 					}
1313 					//AuthMode
1314 					if(RTMPGetKeyParameter("AuthMode", tmpbuf, 128, buffer))
1315 					{
1316 #ifdef CONFIG_STA_SUPPORT
1317 						IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1318 						{
1319 							if ((strcmp(tmpbuf, "WEPAUTO") == 0) || (strcmp(tmpbuf, "wepauto") == 0))
1320 							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
1321 							else if ((strcmp(tmpbuf, "SHARED") == 0) || (strcmp(tmpbuf, "shared") == 0))
1322 							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeShared;
1323 							else if ((strcmp(tmpbuf, "WPAPSK") == 0) || (strcmp(tmpbuf, "wpapsk") == 0))
1324 							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
1325 							else if ((strcmp(tmpbuf, "WPANONE") == 0) || (strcmp(tmpbuf, "wpanone") == 0))
1326 							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
1327 							else if ((strcmp(tmpbuf, "WPA2PSK") == 0) || (strcmp(tmpbuf, "wpa2psk") == 0))
1328 							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
1329 #ifdef WPA_SUPPLICANT_SUPPORT
1330 							else if ((strcmp(tmpbuf, "WPA") == 0) || (strcmp(tmpbuf, "wpa") == 0))
1331 							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
1332 							else if ((strcmp(tmpbuf, "WPA2") == 0) || (strcmp(tmpbuf, "wpa2") == 0))
1333 							    pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
1334 #endif // WPA_SUPPLICANT_SUPPORT //
1335 				                        else
1336 				                            pAd->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
1337 
1338 				                        pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
1339 
1340 							DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __func__, pAd->StaCfg.WepStatus));
1341 						}
1342 #endif // CONFIG_STA_SUPPORT //
1343 					}
1344 					//EncrypType
1345 					if(RTMPGetKeyParameter("EncrypType", tmpbuf, 128, buffer))
1346 					{
1347 
1348 #ifdef CONFIG_STA_SUPPORT
1349 						IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1350 						{
1351 							if ((strcmp(tmpbuf, "WEP") == 0) || (strcmp(tmpbuf, "wep") == 0))
1352 								pAd->StaCfg.WepStatus	= Ndis802_11WEPEnabled;
1353 							else if ((strcmp(tmpbuf, "TKIP") == 0) || (strcmp(tmpbuf, "tkip") == 0))
1354 								pAd->StaCfg.WepStatus	= Ndis802_11Encryption2Enabled;
1355 							else if ((strcmp(tmpbuf, "AES") == 0) || (strcmp(tmpbuf, "aes") == 0))
1356 								pAd->StaCfg.WepStatus	= Ndis802_11Encryption3Enabled;
1357 							else
1358 								pAd->StaCfg.WepStatus	= Ndis802_11WEPDisabled;
1359 
1360 							// Update all wepstatus related
1361 							pAd->StaCfg.PairCipher		= pAd->StaCfg.WepStatus;
1362 							pAd->StaCfg.GroupCipher 	= pAd->StaCfg.WepStatus;
1363 							pAd->StaCfg.OrigWepStatus 	= pAd->StaCfg.WepStatus;
1364 							pAd->StaCfg.bMixCipher 		= FALSE;
1365 
1366 							DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __func__, pAd->StaCfg.WepStatus));
1367 						}
1368 #endif // CONFIG_STA_SUPPORT //
1369 					}
1370 
1371 
1372 
1373 #ifdef CONFIG_STA_SUPPORT
1374 					IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1375 					{
1376 						if(RTMPGetCriticalParameter("WPAPSK", tmpbuf, 512, buffer))
1377 						{
1378 							int     err=0;
1379 
1380 							tmpbuf[strlen(tmpbuf)] = '\0'; // make STA can process .$^& for WPAPSK input
1381 
1382 							if ((pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
1383 								(pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
1384 								(pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
1385 								)
1386 							{
1387 								err = 1;
1388 							}
1389 							else if ((strlen(tmpbuf) >= 8) && (strlen(tmpbuf) < 64))
1390 							{
1391 								PasswordHash((char *)tmpbuf, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, keyMaterial);
1392 								NdisMoveMemory(pAd->StaCfg.PMK, keyMaterial, 32);
1393 
1394 							}
1395 							else if (strlen(tmpbuf) == 64)
1396 							{
1397 								AtoH(tmpbuf, keyMaterial, 32);
1398 								NdisMoveMemory(pAd->StaCfg.PMK, keyMaterial, 32);
1399 							}
1400 							else
1401 							{
1402 								err = 1;
1403 								DBGPRINT(RT_DEBUG_ERROR, ("%s::(WPAPSK key-string required 8 ~ 64 characters!)\n", __func__));
1404 							}
1405 
1406 							if (err == 0)
1407 	                        			{
1408 	                        				if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
1409 									(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
1410 								{
1411 									// Start STA supplicant state machine
1412 									pAd->StaCfg.WpaState = SS_START;
1413 								}
1414 								else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
1415 								{
1416 									pAd->StaCfg.WpaState = SS_NOTUSE;
1417 								}
1418 
1419 								DBGPRINT(RT_DEBUG_TRACE, ("%s::(WPAPSK=%s)\n", __func__, tmpbuf));
1420 							}
1421 						}
1422 					}
1423 #endif // CONFIG_STA_SUPPORT //
1424 
1425 					//DefaultKeyID, KeyType, KeyStr
1426 					rtmp_read_key_parms_from_file(pAd, tmpbuf, buffer);
1427 
1428 #ifdef DOT11_N_SUPPORT
1429 					HTParametersHook(pAd, tmpbuf, buffer);
1430 #endif // DOT11_N_SUPPORT //
1431 
1432 
1433 #ifdef CARRIER_DETECTION_SUPPORT
1434 						//CarrierDetect
1435 						if(RTMPGetKeyParameter("CarrierDetect", tmpbuf, 128, buffer))
1436 						{
1437 							if ((strncmp(tmpbuf, "0", 1) == 0))
1438 								pAd->CommonCfg.CarrierDetect.Enable = FALSE;
1439 							else if ((strncmp(tmpbuf, "1", 1) == 0))
1440 								pAd->CommonCfg.CarrierDetect.Enable = TRUE;
1441 							else
1442 								pAd->CommonCfg.CarrierDetect.Enable = FALSE;
1443 
1444 							DBGPRINT(RT_DEBUG_TRACE, ("CarrierDetect.Enable=%d\n", pAd->CommonCfg.CarrierDetect.Enable));
1445 						}
1446 						else
1447 							pAd->CommonCfg.CarrierDetect.Enable = FALSE;
1448 #endif // CARRIER_DETECTION_SUPPORT //
1449 
1450 #ifdef CONFIG_STA_SUPPORT
1451 					IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1452 					{
1453 						//PSMode
1454 						if (RTMPGetKeyParameter("PSMode", tmpbuf, 10, buffer))
1455 						{
1456 							if (pAd->StaCfg.BssType == BSS_INFRA)
1457 							{
1458 								if ((strcmp(tmpbuf, "MAX_PSP") == 0) || (strcmp(tmpbuf, "max_psp") == 0))
1459 								{
1460 									// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
1461 									// to exclude certain situations.
1462 									//	   MlmeSetPsm(pAd, PWR_SAVE);
1463 									OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
1464 									if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
1465 										pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
1466 									pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
1467 									pAd->StaCfg.DefaultListenCount = 5;
1468 								}
1469 								else if ((strcmp(tmpbuf, "Fast_PSP") == 0) || (strcmp(tmpbuf, "fast_psp") == 0)
1470 									|| (strcmp(tmpbuf, "FAST_PSP") == 0))
1471 								{
1472 									// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
1473 									// to exclude certain situations.
1474 									//	   MlmeSetPsmBit(pAd, PWR_SAVE);
1475 									OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
1476 									if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
1477 										pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
1478 									pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
1479 									pAd->StaCfg.DefaultListenCount = 3;
1480 								}
1481 								else if ((strcmp(tmpbuf, "Legacy_PSP") == 0) || (strcmp(tmpbuf, "legacy_psp") == 0)
1482 									|| (strcmp(tmpbuf, "LEGACY_PSP") == 0))
1483 								{
1484 									// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
1485 									// to exclude certain situations.
1486 									//	   MlmeSetPsmBit(pAd, PWR_SAVE);
1487 									OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
1488 									if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
1489 										pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
1490 									pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
1491 									pAd->StaCfg.DefaultListenCount = 3;
1492 								}
1493 								else
1494 								{ //Default Ndis802_11PowerModeCAM
1495 									// clear PSM bit immediately
1496 									MlmeSetPsmBit(pAd, PWR_ACTIVE);
1497 									OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
1498 									if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
1499 										pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
1500 									pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
1501 								}
1502 								DBGPRINT(RT_DEBUG_TRACE, ("PSMode=%ld\n", pAd->StaCfg.WindowsPowerMode));
1503 							}
1504 						}
1505 						// FastRoaming
1506 						if (RTMPGetKeyParameter("FastRoaming", tmpbuf, 32, buffer))
1507 						{
1508 							if (simple_strtol(tmpbuf, 0, 10) == 0)
1509 								pAd->StaCfg.bFastRoaming = FALSE;
1510 							else
1511 								pAd->StaCfg.bFastRoaming = TRUE;
1512 
1513 							DBGPRINT(RT_DEBUG_TRACE, ("FastRoaming=%d\n", pAd->StaCfg.bFastRoaming));
1514 						}
1515 						// RoamThreshold
1516 						if (RTMPGetKeyParameter("RoamThreshold", tmpbuf, 32, buffer))
1517 						{
1518 							long lInfo = simple_strtol(tmpbuf, 0, 10);
1519 
1520 							if (lInfo > 90 || lInfo < 60)
1521 								pAd->StaCfg.dBmToRoam = -70;
1522 							else
1523 								pAd->StaCfg.dBmToRoam = (CHAR)(-1)*lInfo;
1524 
1525 							DBGPRINT(RT_DEBUG_TRACE, ("RoamThreshold=%d  dBm\n", pAd->StaCfg.dBmToRoam));
1526 						}
1527 
1528 						if(RTMPGetKeyParameter("TGnWifiTest", tmpbuf, 10, buffer))
1529 						{
1530 							if(simple_strtol(tmpbuf, 0, 10) == 0)
1531 								pAd->StaCfg.bTGnWifiTest = FALSE;
1532 							else
1533 								pAd->StaCfg.bTGnWifiTest = TRUE;
1534 								DBGPRINT(RT_DEBUG_TRACE, ("TGnWifiTest=%d\n", pAd->StaCfg.bTGnWifiTest));
1535 						}
1536 					}
1537 #endif // CONFIG_STA_SUPPORT //
1538 
1539 				}
1540 			}
1541 			else
1542 			{
1543 				DBGPRINT(RT_DEBUG_TRACE, ("--> %s does not have a write method\n", src));
1544 			}
1545 
1546 			retval=filp_close(srcf,NULL);
1547 
1548 			if (retval)
1549 			{
1550 				DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
1551 			}
1552 		}
1553 	}
1554 
1555 	set_fs(orgfs);
1556 
1557 #if 0
1558 	current->cred->fsuid = orgfsuid;
1559 	current->cred->fsgid = orgfsgid;
1560 #endif
1561 
1562 	kfree(buffer);
1563 	kfree(tmpbuf);
1564 
1565 	return (NDIS_STATUS_SUCCESS);
1566 }
1567 
1568 #ifdef DOT11_N_SUPPORT
HTParametersHook(IN PRTMP_ADAPTER pAd,IN CHAR * pValueStr,IN CHAR * pInput)1569 static void	HTParametersHook(
1570 	IN	PRTMP_ADAPTER pAd,
1571 	IN	CHAR		  *pValueStr,
1572 	IN	CHAR		  *pInput)
1573 {
1574 
1575 	INT Value;
1576 
1577     if (RTMPGetKeyParameter("HT_PROTECT", pValueStr, 25, pInput))
1578     {
1579         Value = simple_strtol(pValueStr, 0, 10);
1580         if (Value == 0)
1581         {
1582             pAd->CommonCfg.bHTProtect = FALSE;
1583         }
1584         else
1585         {
1586             pAd->CommonCfg.bHTProtect = TRUE;
1587         }
1588         DBGPRINT(RT_DEBUG_TRACE, ("HT: Protection  = %s\n", (Value==0) ? "Disable" : "Enable"));
1589     }
1590 
1591     if (RTMPGetKeyParameter("HT_MIMOPSEnable", pValueStr, 25, pInput))
1592     {
1593         Value = simple_strtol(pValueStr, 0, 10);
1594         if (Value == 0)
1595         {
1596             pAd->CommonCfg.bMIMOPSEnable = FALSE;
1597         }
1598         else
1599         {
1600             pAd->CommonCfg.bMIMOPSEnable = TRUE;
1601         }
1602         DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPSEnable  = %s\n", (Value==0) ? "Disable" : "Enable"));
1603     }
1604 
1605 
1606     if (RTMPGetKeyParameter("HT_MIMOPSMode", pValueStr, 25, pInput))
1607     {
1608         Value = simple_strtol(pValueStr, 0, 10);
1609         if (Value > MMPS_ENABLE)
1610         {
1611 			pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
1612         }
1613         else
1614         {
1615             //TODO: add mimo power saving mechanism
1616             pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
1617 			//pAd->CommonCfg.BACapability.field.MMPSmode = Value;
1618         }
1619         DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPS Mode  = %d\n", Value));
1620     }
1621 
1622     if (RTMPGetKeyParameter("HT_BADecline", pValueStr, 25, pInput))
1623     {
1624         Value = simple_strtol(pValueStr, 0, 10);
1625         if (Value == 0)
1626         {
1627             pAd->CommonCfg.bBADecline = FALSE;
1628         }
1629         else
1630         {
1631             pAd->CommonCfg.bBADecline = TRUE;
1632         }
1633         DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Decline  = %s\n", (Value==0) ? "Disable" : "Enable"));
1634     }
1635 
1636 
1637     if (RTMPGetKeyParameter("HT_DisableReordering", pValueStr, 25, pInput))
1638     {
1639         Value = simple_strtol(pValueStr, 0, 10);
1640         if (Value == 0)
1641         {
1642             pAd->CommonCfg.bDisableReordering = FALSE;
1643         }
1644         else
1645         {
1646             pAd->CommonCfg.bDisableReordering = TRUE;
1647         }
1648         DBGPRINT(RT_DEBUG_TRACE, ("HT: DisableReordering  = %s\n", (Value==0) ? "Disable" : "Enable"));
1649     }
1650 
1651     if (RTMPGetKeyParameter("HT_AutoBA", pValueStr, 25, pInput))
1652     {
1653         Value = simple_strtol(pValueStr, 0, 10);
1654         if (Value == 0)
1655         {
1656             pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
1657         }
1658         else
1659         {
1660             pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
1661         }
1662         pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
1663         DBGPRINT(RT_DEBUG_TRACE, ("HT: Auto BA  = %s\n", (Value==0) ? "Disable" : "Enable"));
1664     }
1665 
1666 	// Tx_+HTC frame
1667     if (RTMPGetKeyParameter("HT_HTC", pValueStr, 25, pInput))
1668 	{
1669 		Value = simple_strtol(pValueStr, 0, 10);
1670 		if (Value == 0)
1671 		{
1672 			pAd->HTCEnable = FALSE;
1673 		}
1674 		else
1675 		{
1676             		pAd->HTCEnable = TRUE;
1677 		}
1678 		DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx +HTC frame = %s\n", (Value==0) ? "Disable" : "Enable"));
1679 	}
1680 
1681 	// Enable HT Link Adaptation Control
1682 	if (RTMPGetKeyParameter("HT_LinkAdapt", pValueStr, 25, pInput))
1683 	{
1684 		Value = simple_strtol(pValueStr, 0, 10);
1685 		if (Value == 0)
1686 		{
1687 			pAd->bLinkAdapt = FALSE;
1688 		}
1689 		else
1690 		{
1691 			pAd->HTCEnable = TRUE;
1692 			pAd->bLinkAdapt = TRUE;
1693 		}
1694 		DBGPRINT(RT_DEBUG_TRACE, ("HT: Link Adaptation Control = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
1695 	}
1696 
1697 	// Reverse Direction Mechanism
1698     if (RTMPGetKeyParameter("HT_RDG", pValueStr, 25, pInput))
1699 	{
1700 		Value = simple_strtol(pValueStr, 0, 10);
1701 		if (Value == 0)
1702 		{
1703 			pAd->CommonCfg.bRdg = FALSE;
1704 		}
1705 		else
1706 		{
1707 			pAd->HTCEnable = TRUE;
1708             pAd->CommonCfg.bRdg = TRUE;
1709 		}
1710 		DBGPRINT(RT_DEBUG_TRACE, ("HT: RDG = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
1711 	}
1712 
1713 
1714 
1715 
1716 	// Tx A-MSUD ?
1717     if (RTMPGetKeyParameter("HT_AMSDU", pValueStr, 25, pInput))
1718 	{
1719 		Value = simple_strtol(pValueStr, 0, 10);
1720 		if (Value == 0)
1721 		{
1722 			pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE;
1723 		}
1724 		else
1725 		{
1726             pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE;
1727 		}
1728 		DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx A-MSDU = %s\n", (Value==0) ? "Disable" : "Enable"));
1729 	}
1730 
1731 	// MPDU Density
1732     if (RTMPGetKeyParameter("HT_MpduDensity", pValueStr, 25, pInput))
1733 	{
1734 		Value = simple_strtol(pValueStr, 0, 10);
1735 		if (Value <=7 && Value >= 0)
1736 		{
1737 			pAd->CommonCfg.BACapability.field.MpduDensity = Value;
1738 			DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d\n", Value));
1739 		}
1740 		else
1741 		{
1742 			pAd->CommonCfg.BACapability.field.MpduDensity = 4;
1743 			DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d (Default)\n", 4));
1744 		}
1745 	}
1746 
1747 	// Max Rx BA Window Size
1748     if (RTMPGetKeyParameter("HT_BAWinSize", pValueStr, 25, pInput))
1749 	{
1750 		Value = simple_strtol(pValueStr, 0, 10);
1751 
1752 		if (Value >=1 && Value <= 64)
1753 		{
1754 			pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value;
1755 			pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value;
1756 			DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = %d\n", Value));
1757 		}
1758 		else
1759 		{
1760             pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64;
1761 			pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64;
1762 			DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = 64 (Defualt)\n"));
1763 		}
1764 
1765 	}
1766 
1767 	// Guard Interval
1768 	if (RTMPGetKeyParameter("HT_GI", pValueStr, 25, pInput))
1769 	{
1770 		Value = simple_strtol(pValueStr, 0, 10);
1771 
1772 		if (Value == GI_400)
1773 		{
1774 			pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400;
1775 		}
1776 		else
1777 		{
1778 			pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800;
1779 		}
1780 
1781 		DBGPRINT(RT_DEBUG_TRACE, ("HT: Guard Interval = %s\n", (Value==GI_400) ? "400" : "800" ));
1782 	}
1783 
1784 	// HT Operation Mode : Mixed Mode , Green Field
1785 	if (RTMPGetKeyParameter("HT_OpMode", pValueStr, 25, pInput))
1786 	{
1787 		Value = simple_strtol(pValueStr, 0, 10);
1788 
1789 		if (Value == HTMODE_GF)
1790 		{
1791 
1792 			pAd->CommonCfg.RegTransmitSetting.field.HTMODE  = HTMODE_GF;
1793 		}
1794 		else
1795 		{
1796 			pAd->CommonCfg.RegTransmitSetting.field.HTMODE  = HTMODE_MM;
1797 		}
1798 
1799 		DBGPRINT(RT_DEBUG_TRACE, ("HT: Operate Mode = %s\n", (Value==HTMODE_GF) ? "Green Field" : "Mixed Mode" ));
1800 	}
1801 
1802 	// Fixed Tx mode : CCK, OFDM
1803 	if (RTMPGetKeyParameter("FixedTxMode", pValueStr, 25, pInput))
1804 	{
1805 		UCHAR	fix_tx_mode;
1806 
1807 #ifdef CONFIG_STA_SUPPORT
1808 		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1809 		{
1810 			fix_tx_mode = FIXED_TXMODE_HT;
1811 
1812 			if (strcmp(pValueStr, "OFDM") == 0 || strcmp(pValueStr, "ofdm") == 0)
1813 			{
1814 				fix_tx_mode = FIXED_TXMODE_OFDM;
1815 			}
1816 			else if (strcmp(pValueStr, "CCK") == 0 || strcmp(pValueStr, "cck") == 0)
1817 			{
1818 		        fix_tx_mode = FIXED_TXMODE_CCK;
1819 			}
1820 			else if (strcmp(pValueStr, "HT") == 0 || strcmp(pValueStr, "ht") == 0)
1821 			{
1822 		        fix_tx_mode = FIXED_TXMODE_HT;
1823 		}
1824 		else
1825 		{
1826 				Value = simple_strtol(pValueStr, 0, 10);
1827 				// 1 : CCK
1828 				// 2 : OFDM
1829 				// otherwise : HT
1830 				if (Value == FIXED_TXMODE_CCK || Value == FIXED_TXMODE_OFDM)
1831 					fix_tx_mode = Value;
1832 				else
1833 					fix_tx_mode = FIXED_TXMODE_HT;
1834 		}
1835 
1836 			pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode;
1837 			DBGPRINT(RT_DEBUG_TRACE, ("Fixed Tx Mode = %d\n", fix_tx_mode));
1838 
1839 		}
1840 #endif // CONFIG_STA_SUPPORT //
1841 	}
1842 
1843 
1844 	// Channel Width
1845 	if (RTMPGetKeyParameter("HT_BW", pValueStr, 25, pInput))
1846 	{
1847 		Value = simple_strtol(pValueStr, 0, 10);
1848 
1849 		if (Value == BW_40)
1850 		{
1851 			pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_40;
1852 		}
1853 		else
1854 		{
1855             pAd->CommonCfg.RegTransmitSetting.field.BW  = BW_20;
1856 		}
1857 
1858 #ifdef MCAST_RATE_SPECIFIC
1859 		pAd->CommonCfg.MCastPhyMode.field.BW = pAd->CommonCfg.RegTransmitSetting.field.BW;
1860 #endif // MCAST_RATE_SPECIFIC //
1861 
1862 		DBGPRINT(RT_DEBUG_TRACE, ("HT: Channel Width = %s\n", (Value==BW_40) ? "40 MHz" : "20 MHz" ));
1863 	}
1864 
1865 	if (RTMPGetKeyParameter("HT_EXTCHA", pValueStr, 25, pInput))
1866 	{
1867 		Value = simple_strtol(pValueStr, 0, 10);
1868 
1869 		if (Value == 0)
1870 		{
1871 
1872 			pAd->CommonCfg.RegTransmitSetting.field.EXTCHA  = EXTCHA_BELOW;
1873 		}
1874 		else
1875 		{
1876             pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
1877 		}
1878 
1879 		DBGPRINT(RT_DEBUG_TRACE, ("HT: Ext Channel = %s\n", (Value==0) ? "BELOW" : "ABOVE" ));
1880 	}
1881 
1882 	// MSC
1883 	if (RTMPGetKeyParameter("HT_MCS", pValueStr, 50, pInput))
1884 	{
1885 
1886 #ifdef CONFIG_STA_SUPPORT
1887 		IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
1888 		{
1889 			Value = simple_strtol(pValueStr, 0, 10);
1890 
1891 			if ((Value >= 0 && Value <= 23) || (Value == 32)) // 3*3
1892 		{
1893 				pAd->StaCfg.DesiredTransmitSetting.field.MCS  = Value;
1894 				pAd->StaCfg.bAutoTxRateSwitch = FALSE;
1895 				DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = %d\n", pAd->StaCfg.DesiredTransmitSetting.field.MCS));
1896 		}
1897 		else
1898 		{
1899 				pAd->StaCfg.DesiredTransmitSetting.field.MCS  = MCS_AUTO;
1900 				pAd->StaCfg.bAutoTxRateSwitch = TRUE;
1901 				DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = AUTO\n"));
1902 		}
1903 	}
1904 #endif // CONFIG_STA_SUPPORT //
1905 	}
1906 
1907 	// STBC
1908     if (RTMPGetKeyParameter("HT_STBC", pValueStr, 25, pInput))
1909 	{
1910 		Value = simple_strtol(pValueStr, 0, 10);
1911 		if (Value == STBC_USE)
1912 		{
1913 			pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE;
1914 		}
1915 		else
1916 		{
1917 			pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE;
1918 		}
1919 		DBGPRINT(RT_DEBUG_TRACE, ("HT: STBC = %d\n", pAd->CommonCfg.RegTransmitSetting.field.STBC));
1920 	}
1921 
1922 	// 40_Mhz_Intolerant
1923 	if (RTMPGetKeyParameter("HT_40MHZ_INTOLERANT", pValueStr, 25, pInput))
1924 	{
1925 		Value = simple_strtol(pValueStr, 0, 10);
1926 		if (Value == 0)
1927 		{
1928 			pAd->CommonCfg.bForty_Mhz_Intolerant = FALSE;
1929 		}
1930 		else
1931 		{
1932 			pAd->CommonCfg.bForty_Mhz_Intolerant = TRUE;
1933 		}
1934 		DBGPRINT(RT_DEBUG_TRACE, ("HT: 40MHZ INTOLERANT = %d\n", pAd->CommonCfg.bForty_Mhz_Intolerant));
1935 	}
1936 	//HT_TxStream
1937 	if(RTMPGetKeyParameter("HT_TxStream", pValueStr, 10, pInput))
1938 	{
1939 		switch (simple_strtol(pValueStr, 0, 10))
1940 		{
1941 			case 1:
1942 				pAd->CommonCfg.TxStream = 1;
1943 				break;
1944 			case 2:
1945 				pAd->CommonCfg.TxStream = 2;
1946 				break;
1947 			case 3: // 3*3
1948 			default:
1949 				pAd->CommonCfg.TxStream = 3;
1950 
1951 				if (pAd->MACVersion < RALINK_2883_VERSION)
1952 					pAd->CommonCfg.TxStream = 2; // only 2 tx streams for RT2860 series
1953 				break;
1954 		}
1955 		DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx Stream = %d\n", pAd->CommonCfg.TxStream));
1956 	}
1957 	//HT_RxStream
1958 	if(RTMPGetKeyParameter("HT_RxStream", pValueStr, 10, pInput))
1959 	{
1960 		switch (simple_strtol(pValueStr, 0, 10))
1961 		{
1962 			case 1:
1963 				pAd->CommonCfg.RxStream = 1;
1964 				break;
1965 			case 2:
1966 				pAd->CommonCfg.RxStream = 2;
1967 				break;
1968 			case 3:
1969 			default:
1970 				pAd->CommonCfg.RxStream = 3;
1971 
1972 				if (pAd->MACVersion < RALINK_2883_VERSION)
1973 					pAd->CommonCfg.RxStream = 2; // only 2 rx streams for RT2860 series
1974 				break;
1975 		}
1976 		DBGPRINT(RT_DEBUG_TRACE, ("HT: Rx Stream = %d\n", pAd->CommonCfg.RxStream));
1977 	}
1978 
1979 }
1980 #endif // DOT11_N_SUPPORT //
1981 
1982