Archived
14
0
Fork 0
This repository has been archived on 2022-02-17. You can view files and clone it, but cannot push or open issues or pull requests.
linux-2.6/drivers/staging/rt2860/rt_profile.c
Adam McDaniel ed291e8051 Staging: rt2860: Ported v1.7.1.1 changes into v1.8.0.0, becoming v1.8.1.1
Staging: rt2860: Ported v1.7.1.1 changes into v1.8.0.0, becoming v1.8.1.1

When RaLink released rt2860 v1.7.0.0, it lacked proper support for both WEP
and WPA/WPA2 encryption. Either was possible, but the module had to be
compiled to support only one or the other, never both.

Since the EeePC was the most common device with this hardware (and these
users were complaining to RaLink that WPA/WPA2 encryption didn't work)
RaLink released a fix as an "eeepc-specific" version of this driver, v1.7.1.1

Unfortunately, when v1.8.0.0 was released, this WPA/WPA2 fix was never
included.

What complicates things further is that RaLink has no interest in
continuing work on this Linux driver for their hardware.

This commit ports the changes introduced in v1.7.1.1 into the v1.8.0.0
release, upgrading the kernel's module to v1.8.1.1

Signed-off-by: Adam McDaniel <adam@array.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
2009-04-03 14:53:31 -07:00

1982 lines
54 KiB
C

/*
*************************************************************************
* Ralink Tech Inc.
* 5F., No.36, Taiyuan St., Jhubei City,
* Hsinchu County 302,
* Taiwan, R.O.C.
*
* (c) Copyright 2002-2007, Ralink Technology, Inc.
*
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
* *
*************************************************************************
*/
#include "rt_config.h"
#ifdef DOT11_N_SUPPORT
static void HTParametersHook(
IN PRTMP_ADAPTER pAd,
IN CHAR *pValueStr,
IN CHAR *pInput);
#endif // DOT11_N_SUPPORT //
#define ETH_MAC_ADDR_STR_LEN 17 // in format of xx:xx:xx:xx:xx:xx
// We assume the s1 is a sting, s2 is a memory space with 6 bytes. and content of s1 will be changed.
BOOLEAN rtstrmactohex(char *s1, char *s2)
{
int i = 0;
char *ptokS = s1, *ptokE = s1;
if (strlen(s1) != ETH_MAC_ADDR_STR_LEN)
return FALSE;
while((*ptokS) != '\0')
{
if((ptokE = strchr(ptokS, ':')) != NULL)
*ptokE++ = '\0';
if ((strlen(ptokS) != 2) || (!isxdigit(*ptokS)) || (!isxdigit(*(ptokS+1))))
break; // fail
AtoH(ptokS, &s2[i++], 1);
ptokS = ptokE;
if (i == 6)
break; // parsing finished
}
return ( i == 6 ? TRUE : FALSE);
}
// we assume the s1 and s2 both are strings.
BOOLEAN rtstrcasecmp(char *s1, char *s2)
{
char *p1 = s1, *p2 = s2;
if (strlen(s1) != strlen(s2))
return FALSE;
while(*p1 != '\0')
{
if((*p1 != *p2) && ((*p1 ^ *p2) != 0x20))
return FALSE;
p1++;
p2++;
}
return TRUE;
}
// we assume the s1 (buffer) and s2 (key) both are strings.
char * rtstrstruncasecmp(char * s1, char * s2)
{
INT l1, l2, i;
char temp1, temp2;
l2 = strlen(s2);
if (!l2)
return (char *) s1;
l1 = strlen(s1);
while (l1 >= l2)
{
l1--;
for(i=0; i<l2; i++)
{
temp1 = *(s1+i);
temp2 = *(s2+i);
if (('a' <= temp1) && (temp1 <= 'z'))
temp1 = 'A'+(temp1-'a');
if (('a' <= temp2) && (temp2 <= 'z'))
temp2 = 'A'+(temp2-'a');
if (temp1 != temp2)
break;
}
if (i == l2)
return (char *) s1;
s1++;
}
return NULL; // not found
}
//add by kathy
/**
* strstr - Find the first substring in a %NUL terminated string
* @s1: The string to be searched
* @s2: The string to search for
*/
char * rtstrstr(const char * s1,const char * s2)
{
INT l1, l2;
l2 = strlen(s2);
if (!l2)
return (char *) s1;
l1 = strlen(s1);
while (l1 >= l2)
{
l1--;
if (!memcmp(s1,s2,l2))
return (char *) s1;
s1++;
}
return NULL;
}
/**
* rstrtok - Split a string into tokens
* @s: The string to be searched
* @ct: The characters to search for
* * WARNING: strtok is deprecated, use strsep instead. However strsep is not compatible with old architecture.
*/
char * __rstrtok;
char * rstrtok(char * s,const char * ct)
{
char *sbegin, *send;
sbegin = s ? s : __rstrtok;
if (!sbegin)
{
return NULL;
}
sbegin += strspn(sbegin,ct);
if (*sbegin == '\0')
{
__rstrtok = NULL;
return( NULL );
}
send = strpbrk( sbegin, ct);
if (send && *send != '\0')
*send++ = '\0';
__rstrtok = send;
return (sbegin);
}
/**
* delimitcnt - return the count of a given delimiter in a given string.
* @s: The string to be searched.
* @ct: The delimiter to search for.
* Notice : We suppose the delimiter is a single-char string(for example : ";").
*/
INT delimitcnt(char * s,const char * ct)
{
INT count = 0;
/* point to the beginning of the line */
const char *token = s;
for ( ;; )
{
token = strpbrk(token, ct); /* search for delimiters */
if ( token == NULL )
{
/* advanced to the terminating null character */
break;
}
/* skip the delimiter */
++token;
/*
* Print the found text: use len with %.*s to specify field width.
*/
/* accumulate delimiter count */
++count;
}
return count;
}
/*
* converts the Internet host address from the standard numbers-and-dots notation
* into binary data.
* returns nonzero if the address is valid, zero if not.
*/
int rtinet_aton(const char *cp, unsigned int *addr)
{
unsigned int val;
int base, n;
char c;
unsigned int parts[4];
unsigned int *pp = parts;
for (;;)
{
/*
* Collect number up to ``.''.
* Values are specified as for C:
* 0x=hex, 0=octal, other=decimal.
*/
val = 0;
base = 10;
if (*cp == '0')
{
if (*++cp == 'x' || *cp == 'X')
base = 16, cp++;
else
base = 8;
}
while ((c = *cp) != '\0')
{
if (isdigit((unsigned char) c))
{
val = (val * base) + (c - '0');
cp++;
continue;
}
if (base == 16 && isxdigit((unsigned char) c))
{
val = (val << 4) +
(c + 10 - (islower((unsigned char) c) ? 'a' : 'A'));
cp++;
continue;
}
break;
}
if (*cp == '.')
{
/*
* Internet format: a.b.c.d a.b.c (with c treated as 16-bits)
* a.b (with b treated as 24 bits)
*/
if (pp >= parts + 3 || val > 0xff)
return 0;
*pp++ = val, cp++;
}
else
break;
}
/*
* Check for trailing junk.
*/
while (*cp)
if (!isspace((unsigned char) *cp++))
return 0;
/*
* Concoct the address according to the number of parts specified.
*/
n = pp - parts + 1;
switch (n)
{
case 1: /* a -- 32 bits */
break;
case 2: /* a.b -- 8.24 bits */
if (val > 0xffffff)
return 0;
val |= parts[0] << 24;
break;
case 3: /* a.b.c -- 8.8.16 bits */
if (val > 0xffff)
return 0;
val |= (parts[0] << 24) | (parts[1] << 16);
break;
case 4: /* a.b.c.d -- 8.8.8.8 bits */
if (val > 0xff)
return 0;
val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
break;
}
*addr = htonl(val);
return 1;
}
/*
========================================================================
Routine Description:
Find key section for Get key parameter.
Arguments:
buffer Pointer to the buffer to start find the key section
section the key of the secion to be find
Return Value:
NULL Fail
Others Success
========================================================================
*/
PUCHAR RTMPFindSection(
IN PCHAR buffer)
{
CHAR temp_buf[32];
PUCHAR ptr;
strcpy(temp_buf, "Default");
if((ptr = rtstrstr(buffer, temp_buf)) != NULL)
return (ptr+strlen("\n"));
else
return NULL;
}
/*
========================================================================
Routine Description:
Get key parameter.
Arguments:
key Pointer to key string
dest Pointer to destination
destsize The datasize of the destination
buffer Pointer to the buffer to start find the key
Return Value:
TRUE Success
FALSE Fail
Note:
This routine get the value with the matched key (case case-sensitive)
========================================================================
*/
INT RTMPGetKeyParameter(
IN PCHAR key,
OUT PCHAR dest,
IN INT destsize,
IN PCHAR buffer)
{
UCHAR *temp_buf1 = NULL;
UCHAR *temp_buf2 = NULL;
CHAR *start_ptr;
CHAR *end_ptr;
CHAR *ptr;
CHAR *offset = 0;
INT len;
//temp_buf1 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE);
if(temp_buf1 == NULL)
return (FALSE);
//temp_buf2 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE);
if(temp_buf2 == NULL)
{
os_free_mem(NULL, temp_buf1);
return (FALSE);
}
//find section
if((offset = RTMPFindSection(buffer)) == NULL)
{
os_free_mem(NULL, temp_buf1);
os_free_mem(NULL, temp_buf2);
return (FALSE);
}
strcpy(temp_buf1, "\n");
strcat(temp_buf1, key);
strcat(temp_buf1, "=");
//search key
if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
{
os_free_mem(NULL, temp_buf1);
os_free_mem(NULL, temp_buf2);
return (FALSE);
}
start_ptr+=strlen("\n");
if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
end_ptr=start_ptr+strlen(start_ptr);
if (end_ptr<start_ptr)
{
os_free_mem(NULL, temp_buf1);
os_free_mem(NULL, temp_buf2);
return (FALSE);
}
NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
temp_buf2[end_ptr-start_ptr]='\0';
len = strlen(temp_buf2);
strcpy(temp_buf1, temp_buf2);
if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
{
os_free_mem(NULL, temp_buf1);
os_free_mem(NULL, temp_buf2);
return (FALSE);
}
strcpy(temp_buf2, start_ptr+1);
ptr = temp_buf2;
//trim space or tab
while(*ptr != 0x00)
{
if( (*ptr == ' ') || (*ptr == '\t') )
ptr++;
else
break;
}
len = strlen(ptr);
memset(dest, 0x00, destsize);
strncpy(dest, ptr, len >= destsize ? destsize: len);
os_free_mem(NULL, temp_buf1);
os_free_mem(NULL, temp_buf2);
return TRUE;
}
/*
========================================================================
Routine Description:
Get key parameter.
Arguments:
key Pointer to key string
dest Pointer to destination
destsize The datasize of the destination
buffer Pointer to the buffer to start find the key
Return Value:
TRUE Success
FALSE Fail
Note:
This routine get the value with the matched key (case case-sensitive).
It is called for parsing SSID and any key string.
========================================================================
*/
INT RTMPGetCriticalParameter(
IN PCHAR key,
OUT PCHAR dest,
IN INT destsize,
IN PCHAR buffer)
{
UCHAR *temp_buf1 = NULL;
UCHAR *temp_buf2 = NULL;
CHAR *start_ptr;
CHAR *end_ptr;
CHAR *ptr;
CHAR *offset = 0;
INT len;
//temp_buf1 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE);
if(temp_buf1 == NULL)
return (FALSE);
//temp_buf2 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE);
if(temp_buf2 == NULL)
{
os_free_mem(NULL, temp_buf1);
return (FALSE);
}
//find section
if((offset = RTMPFindSection(buffer)) == NULL)
{
os_free_mem(NULL, temp_buf1);
os_free_mem(NULL, temp_buf2);
return (FALSE);
}
strcpy(temp_buf1, "\n");
strcat(temp_buf1, key);
strcat(temp_buf1, "=");
//search key
if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
{
os_free_mem(NULL, temp_buf1);
os_free_mem(NULL, temp_buf2);
return (FALSE);
}
start_ptr+=strlen("\n");
if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
end_ptr=start_ptr+strlen(start_ptr);
if (end_ptr<start_ptr)
{
os_free_mem(NULL, temp_buf1);
os_free_mem(NULL, temp_buf2);
return (FALSE);
}
NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
temp_buf2[end_ptr-start_ptr]='\0';
len = strlen(temp_buf2);
strcpy(temp_buf1, temp_buf2);
if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
{
os_free_mem(NULL, temp_buf1);
os_free_mem(NULL, temp_buf2);
return (FALSE);
}
strcpy(temp_buf2, start_ptr+1);
ptr = temp_buf2;
//trim tab
/* We cannot trim space(' ') for SSID and key string. */
while(*ptr != 0x00)
{
//if( (*ptr == ' ') || (*ptr == '\t') )
if( (*ptr == '\t') )
ptr++;
else
break;
}
len = strlen(ptr);
memset(dest, 0x00, destsize);
strncpy(dest, ptr, len >= destsize ? destsize: len);
os_free_mem(NULL, temp_buf1);
os_free_mem(NULL, temp_buf2);
return TRUE;
}
/*
========================================================================
Routine Description:
Get multiple key parameter.
Arguments:
key Pointer to key string
dest Pointer to destination
destsize The datasize of the destination
buffer Pointer to the buffer to start find the key
Return Value:
TRUE Success
FALSE Fail
Note:
This routine get the value with the matched key (case case-sensitive)
========================================================================
*/
INT RTMPGetKeyParameterWithOffset(
IN PCHAR key,
OUT PCHAR dest,
OUT USHORT *end_offset,
IN INT destsize,
IN PCHAR buffer,
IN BOOLEAN bTrimSpace)
{
UCHAR *temp_buf1 = NULL;
UCHAR *temp_buf2 = NULL;
CHAR *start_ptr;
CHAR *end_ptr;
CHAR *ptr;
CHAR *offset = 0;
INT len;
if (*end_offset >= MAX_INI_BUFFER_SIZE)
return (FALSE);
os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE);
if(temp_buf1 == NULL)
return (FALSE);
os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE);
if(temp_buf2 == NULL)
{
os_free_mem(NULL, temp_buf1);
return (FALSE);
}
//find section
if(*end_offset == 0)
{
if ((offset = RTMPFindSection(buffer)) == NULL)
{
os_free_mem(NULL, temp_buf1);
os_free_mem(NULL, temp_buf2);
return (FALSE);
}
}
else
offset = buffer + (*end_offset);
strcpy(temp_buf1, "\n");
strcat(temp_buf1, key);
strcat(temp_buf1, "=");
//search key
if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
{
os_free_mem(NULL, temp_buf1);
os_free_mem(NULL, temp_buf2);
return (FALSE);
}
start_ptr+=strlen("\n");
if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
end_ptr=start_ptr+strlen(start_ptr);
if (end_ptr<start_ptr)
{
os_free_mem(NULL, temp_buf1);
os_free_mem(NULL, temp_buf2);
return (FALSE);
}
*end_offset = end_ptr - buffer;
NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
temp_buf2[end_ptr-start_ptr]='\0';
len = strlen(temp_buf2);
strcpy(temp_buf1, temp_buf2);
if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
{
os_free_mem(NULL, temp_buf1);
os_free_mem(NULL, temp_buf2);
return (FALSE);
}
strcpy(temp_buf2, start_ptr+1);
ptr = temp_buf2;
//trim space or tab
while(*ptr != 0x00)
{
if((bTrimSpace && (*ptr == ' ')) || (*ptr == '\t') )
ptr++;
else
break;
}
len = strlen(ptr);
memset(dest, 0x00, destsize);
strncpy(dest, ptr, len >= destsize ? destsize: len);
os_free_mem(NULL, temp_buf1);
os_free_mem(NULL, temp_buf2);
return TRUE;
}
static int rtmp_parse_key_buffer_from_file(IN PRTMP_ADAPTER pAd,IN char *buffer,IN ULONG KeyType,IN INT BSSIdx,IN INT KeyIdx)
{
PUCHAR keybuff;
INT i = BSSIdx, idx = KeyIdx;
ULONG KeyLen;
UCHAR CipherAlg = CIPHER_WEP64;
keybuff = buffer;
KeyLen = strlen(keybuff);
if (KeyType == 1)
{//Ascii
if( (KeyLen == 5) || (KeyLen == 13))
{
pAd->SharedKey[i][idx].KeyLen = KeyLen;
NdisMoveMemory(pAd->SharedKey[i][idx].Key, keybuff, KeyLen);
if (KeyLen == 5)
CipherAlg = CIPHER_WEP64;
else
CipherAlg = CIPHER_WEP128;
pAd->SharedKey[i][idx].CipherAlg = CipherAlg;
DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) Key%dStr=%s and type=%s\n", i, idx+1, keybuff, (KeyType == 0) ? "Hex":"Ascii"));
return 1;
}
else
{//Invalid key length
DBGPRINT(RT_DEBUG_ERROR, ("Key%dStr is Invalid key length! KeyLen = %ld!\n", idx+1, KeyLen));
return 0;
}
}
else
{//Hex type
if( (KeyLen == 10) || (KeyLen == 26))
{
pAd->SharedKey[i][idx].KeyLen = KeyLen / 2;
AtoH(keybuff, pAd->SharedKey[i][idx].Key, KeyLen / 2);
if (KeyLen == 10)
CipherAlg = CIPHER_WEP64;
else
CipherAlg = CIPHER_WEP128;
pAd->SharedKey[i][idx].CipherAlg = CipherAlg;
DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) Key%dStr=%s and type=%s\n", i, idx+1, keybuff, (KeyType == 0) ? "Hex":"Ascii"));
return 1;
}
else
{//Invalid key length
DBGPRINT(RT_DEBUG_ERROR, ("I/F(ra%d) Key%dStr is Invalid key length! KeyLen = %ld!\n", i, idx+1, KeyLen));
return 0;
}
}
}
static void rtmp_read_key_parms_from_file(IN PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer)
{
char tok_str[16];
PUCHAR macptr;
INT i = 0, idx;
ULONG KeyType[MAX_MBSSID_NUM];
ULONG KeyIdx;
NdisZeroMemory(KeyType, MAX_MBSSID_NUM);
//DefaultKeyID
if(RTMPGetKeyParameter("DefaultKeyID", tmpbuf, 25, buffer))
{
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
KeyIdx = simple_strtol(tmpbuf, 0, 10);
if((KeyIdx >= 1 ) && (KeyIdx <= 4))
pAd->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1);
else
pAd->StaCfg.DefaultKeyId = 0;
DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyID(0~3)=%d\n", pAd->StaCfg.DefaultKeyId));
}
#endif // CONFIG_STA_SUPPORT //
}
for (idx = 0; idx < 4; idx++)
{
sprintf(tok_str, "Key%dType", idx + 1);
//Key1Type
if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer))
{
for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
{
KeyType[i] = simple_strtol(macptr, 0, 10);
}
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
sprintf(tok_str, "Key%dStr", idx + 1);
if (RTMPGetCriticalParameter(tok_str, tmpbuf, 128, buffer))
{
rtmp_parse_key_buffer_from_file(pAd, tmpbuf, KeyType[BSS0], BSS0, idx);
}
}
#endif // CONFIG_STA_SUPPORT //
}
}
}
#ifdef CONFIG_STA_SUPPORT
static void rtmp_read_sta_wmm_parms_from_file(IN PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer)
{
PUCHAR macptr;
INT i=0;
BOOLEAN bWmmEnable = FALSE;
//WmmCapable
if(RTMPGetKeyParameter("WmmCapable", tmpbuf, 32, buffer))
{
if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
{
pAd->CommonCfg.bWmmCapable = TRUE;
bWmmEnable = TRUE;
}
else //Disable
{
pAd->CommonCfg.bWmmCapable = FALSE;
}
DBGPRINT(RT_DEBUG_TRACE, ("WmmCapable=%d\n", pAd->CommonCfg.bWmmCapable));
}
#ifdef QOS_DLS_SUPPORT
//DLSCapable
if(RTMPGetKeyParameter("DLSCapable", tmpbuf, 32, buffer))
{
if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
{
pAd->CommonCfg.bDLSCapable = TRUE;
}
else //Disable
{
pAd->CommonCfg.bDLSCapable = FALSE;
}
DBGPRINT(RT_DEBUG_TRACE, ("bDLSCapable=%d\n", pAd->CommonCfg.bDLSCapable));
}
#endif // QOS_DLS_SUPPORT //
//AckPolicy for AC_BK, AC_BE, AC_VI, AC_VO
if(RTMPGetKeyParameter("AckPolicy", tmpbuf, 32, buffer))
{
for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
{
pAd->CommonCfg.AckPolicy[i] = (UCHAR)simple_strtol(macptr, 0, 10);
DBGPRINT(RT_DEBUG_TRACE, ("AckPolicy[%d]=%d\n", i, pAd->CommonCfg.AckPolicy[i]));
}
}
if (bWmmEnable)
{
//APSDCapable
if(RTMPGetKeyParameter("APSDCapable", tmpbuf, 10, buffer))
{
if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
pAd->CommonCfg.bAPSDCapable = TRUE;
else
pAd->CommonCfg.bAPSDCapable = FALSE;
DBGPRINT(RT_DEBUG_TRACE, ("APSDCapable=%d\n", pAd->CommonCfg.bAPSDCapable));
}
//APSDAC for AC_BE, AC_BK, AC_VI, AC_VO
if(RTMPGetKeyParameter("APSDAC", tmpbuf, 32, buffer))
{
BOOLEAN apsd_ac[4];
for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
{
apsd_ac[i] = (BOOLEAN)simple_strtol(macptr, 0, 10);
DBGPRINT(RT_DEBUG_TRACE, ("APSDAC%d %d\n", i, apsd_ac[i]));
}
pAd->CommonCfg.bAPSDAC_BE = apsd_ac[0];
pAd->CommonCfg.bAPSDAC_BK = apsd_ac[1];
pAd->CommonCfg.bAPSDAC_VI = apsd_ac[2];
pAd->CommonCfg.bAPSDAC_VO = apsd_ac[3];
}
}
}
#endif // CONFIG_STA_SUPPORT //
NDIS_STATUS RTMPReadParametersHook(
IN PRTMP_ADAPTER pAd)
{
PUCHAR src = NULL;
struct file *srcf;
INT retval, orgfsuid, orgfsgid;
mm_segment_t orgfs;
CHAR *buffer;
CHAR *tmpbuf;
ULONG RtsThresh;
ULONG FragThresh;
#ifdef CONFIG_STA_SUPPORT
UCHAR keyMaterial[40];
#endif // CONFIG_STA_SUPPORT //
PUCHAR macptr;
INT i = 0;
buffer = kmalloc(MAX_INI_BUFFER_SIZE, MEM_ALLOC_FLAG);
if(buffer == NULL)
return NDIS_STATUS_FAILURE;
tmpbuf = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
if(tmpbuf == NULL)
{
kfree(buffer);
return NDIS_STATUS_FAILURE;
}
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
src = STA_PROFILE_PATH;
#endif // CONFIG_STA_SUPPORT //
#ifdef MULTIPLE_CARD_SUPPORT
src = pAd->MC_FileName;
#endif // MULTIPLE_CARD_SUPPORT //
// Save uid and gid used for filesystem access.
// Set user and group to 0 (root)
orgfsuid = current_fsuid();
orgfsgid = current_fsgid();
/* Hm, can't really do this nicely anymore, so rely on these files
* being set to the proper permission to read them... */
/* current->cred->fsuid = current->cred->fsgid = 0; */
orgfs = get_fs();
set_fs(KERNEL_DS);
if (src && *src)
{
srcf = filp_open(src, O_RDONLY, 0);
if (IS_ERR(srcf))
{
DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
}
else
{
// The object must have a read method
if (srcf->f_op && srcf->f_op->read)
{
memset(buffer, 0x00, MAX_INI_BUFFER_SIZE);
retval=srcf->f_op->read(srcf, buffer, MAX_INI_BUFFER_SIZE, &srcf->f_pos);
if (retval < 0)
{
DBGPRINT(RT_DEBUG_TRACE, ("--> Read %s error %d\n", src, -retval));
}
else
{
// set file parameter to portcfg
//CountryRegion
if(RTMPGetKeyParameter("CountryRegion", tmpbuf, 25, buffer))
{
pAd->CommonCfg.CountryRegion = (UCHAR) simple_strtol(tmpbuf, 0, 10);
DBGPRINT(RT_DEBUG_TRACE, ("CountryRegion=%d\n", pAd->CommonCfg.CountryRegion));
}
//CountryRegionABand
if(RTMPGetKeyParameter("CountryRegionABand", tmpbuf, 25, buffer))
{
pAd->CommonCfg.CountryRegionForABand= (UCHAR) simple_strtol(tmpbuf, 0, 10);
DBGPRINT(RT_DEBUG_TRACE, ("CountryRegionABand=%d\n", pAd->CommonCfg.CountryRegionForABand));
}
//CountryCode
if(RTMPGetKeyParameter("CountryCode", tmpbuf, 25, buffer))
{
NdisMoveMemory(pAd->CommonCfg.CountryCode, tmpbuf , 2);
#ifdef CONFIG_STA_SUPPORT
#ifdef EXT_BUILD_CHANNEL_LIST
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
NdisMoveMemory(pAd->StaCfg.StaOriCountryCode, tmpbuf , 2);
#endif // EXT_BUILD_CHANNEL_LIST //
#endif // CONFIG_STA_SUPPORT //
if (strlen(pAd->CommonCfg.CountryCode) != 0)
{
pAd->CommonCfg.bCountryFlag = TRUE;
}
DBGPRINT(RT_DEBUG_TRACE, ("CountryCode=%s\n", pAd->CommonCfg.CountryCode));
}
//ChannelGeography
if(RTMPGetKeyParameter("ChannelGeography", tmpbuf, 25, buffer))
{
UCHAR Geography = (UCHAR) simple_strtol(tmpbuf, 0, 10);
if (Geography <= BOTH)
{
pAd->CommonCfg.Geography = Geography;
pAd->CommonCfg.CountryCode[2] =
(pAd->CommonCfg.Geography == BOTH) ? ' ' : ((pAd->CommonCfg.Geography == IDOR) ? 'I' : 'O');
#ifdef CONFIG_STA_SUPPORT
#ifdef EXT_BUILD_CHANNEL_LIST
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
pAd->StaCfg.StaOriGeography = pAd->CommonCfg.Geography;
#endif // EXT_BUILD_CHANNEL_LIST //
#endif // CONFIG_STA_SUPPORT //
DBGPRINT(RT_DEBUG_TRACE, ("ChannelGeography=%d\n", pAd->CommonCfg.Geography));
}
}
else
{
pAd->CommonCfg.Geography = BOTH;
pAd->CommonCfg.CountryCode[2] = ' ';
}
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
//SSID
if (RTMPGetCriticalParameter("SSID", tmpbuf, 256, buffer))
{
if (strlen(tmpbuf) <= 32)
{
pAd->CommonCfg.SsidLen = (UCHAR) strlen(tmpbuf);
NdisZeroMemory(pAd->CommonCfg.Ssid, NDIS_802_11_LENGTH_SSID);
NdisMoveMemory(pAd->CommonCfg.Ssid, tmpbuf, pAd->CommonCfg.SsidLen);
pAd->MlmeAux.AutoReconnectSsidLen = pAd->CommonCfg.SsidLen;
NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, NDIS_802_11_LENGTH_SSID);
NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, tmpbuf, pAd->MlmeAux.AutoReconnectSsidLen);
pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen;
NdisZeroMemory(pAd->MlmeAux.Ssid, NDIS_802_11_LENGTH_SSID);
NdisMoveMemory(pAd->MlmeAux.Ssid, tmpbuf, pAd->MlmeAux.SsidLen);
DBGPRINT(RT_DEBUG_TRACE, ("%s::(SSID=%s)\n", __func__, tmpbuf));
}
}
}
#endif // CONFIG_STA_SUPPORT //
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
//NetworkType
if (RTMPGetKeyParameter("NetworkType", tmpbuf, 25, buffer))
{
pAd->bConfigChanged = TRUE;
if (strcmp(tmpbuf, "Adhoc") == 0)
pAd->StaCfg.BssType = BSS_ADHOC;
else //Default Infrastructure mode
pAd->StaCfg.BssType = BSS_INFRA;
// Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
pAd->StaCfg.WpaState = SS_NOTUSE;
DBGPRINT(RT_DEBUG_TRACE, ("%s::(NetworkType=%d)\n", __func__, pAd->StaCfg.BssType));
}
}
#endif // CONFIG_STA_SUPPORT //
//Channel
if(RTMPGetKeyParameter("Channel", tmpbuf, 10, buffer))
{
pAd->CommonCfg.Channel = (UCHAR) simple_strtol(tmpbuf, 0, 10);
DBGPRINT(RT_DEBUG_TRACE, ("Channel=%d\n", pAd->CommonCfg.Channel));
}
//WirelessMode
if(RTMPGetKeyParameter("WirelessMode", tmpbuf, 10, buffer))
{
int value = 0, maxPhyMode = PHY_11G;
#ifdef DOT11_N_SUPPORT
maxPhyMode = PHY_11N_5G;
#endif // DOT11_N_SUPPORT //
value = simple_strtol(tmpbuf, 0, 10);
if (value <= maxPhyMode)
{
pAd->CommonCfg.PhyMode = value;
}
DBGPRINT(RT_DEBUG_TRACE, ("PhyMode=%d\n", pAd->CommonCfg.PhyMode));
}
//BasicRate
if(RTMPGetKeyParameter("BasicRate", tmpbuf, 10, buffer))
{
pAd->CommonCfg.BasicRateBitmap = (ULONG) simple_strtol(tmpbuf, 0, 10);
DBGPRINT(RT_DEBUG_TRACE, ("BasicRate=%ld\n", pAd->CommonCfg.BasicRateBitmap));
}
//BeaconPeriod
if(RTMPGetKeyParameter("BeaconPeriod", tmpbuf, 10, buffer))
{
pAd->CommonCfg.BeaconPeriod = (USHORT) simple_strtol(tmpbuf, 0, 10);
DBGPRINT(RT_DEBUG_TRACE, ("BeaconPeriod=%d\n", pAd->CommonCfg.BeaconPeriod));
}
//TxPower
if(RTMPGetKeyParameter("TxPower", tmpbuf, 10, buffer))
{
pAd->CommonCfg.TxPowerPercentage = (ULONG) simple_strtol(tmpbuf, 0, 10);
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
pAd->CommonCfg.TxPowerDefault = pAd->CommonCfg.TxPowerPercentage;
#endif // CONFIG_STA_SUPPORT //
DBGPRINT(RT_DEBUG_TRACE, ("TxPower=%ld\n", pAd->CommonCfg.TxPowerPercentage));
}
//BGProtection
if(RTMPGetKeyParameter("BGProtection", tmpbuf, 10, buffer))
{
switch (simple_strtol(tmpbuf, 0, 10))
{
case 1: //Always On
pAd->CommonCfg.UseBGProtection = 1;
break;
case 2: //Always OFF
pAd->CommonCfg.UseBGProtection = 2;
break;
case 0: //AUTO
default:
pAd->CommonCfg.UseBGProtection = 0;
break;
}
DBGPRINT(RT_DEBUG_TRACE, ("BGProtection=%ld\n", pAd->CommonCfg.UseBGProtection));
}
//OLBCDetection
if(RTMPGetKeyParameter("DisableOLBC", tmpbuf, 10, buffer))
{
switch (simple_strtol(tmpbuf, 0, 10))
{
case 1: //disable OLBC Detection
pAd->CommonCfg.DisableOLBCDetect = 1;
break;
case 0: //enable OLBC Detection
pAd->CommonCfg.DisableOLBCDetect = 0;
break;
default:
pAd->CommonCfg.DisableOLBCDetect= 0;
break;
}
DBGPRINT(RT_DEBUG_TRACE, ("OLBCDetection=%ld\n", pAd->CommonCfg.DisableOLBCDetect));
}
//TxPreamble
if(RTMPGetKeyParameter("TxPreamble", tmpbuf, 10, buffer))
{
switch (simple_strtol(tmpbuf, 0, 10))
{
case Rt802_11PreambleShort:
pAd->CommonCfg.TxPreamble = Rt802_11PreambleShort;
break;
case Rt802_11PreambleLong:
default:
pAd->CommonCfg.TxPreamble = Rt802_11PreambleLong;
break;
}
DBGPRINT(RT_DEBUG_TRACE, ("TxPreamble=%ld\n", pAd->CommonCfg.TxPreamble));
}
//RTSThreshold
if(RTMPGetKeyParameter("RTSThreshold", tmpbuf, 10, buffer))
{
RtsThresh = simple_strtol(tmpbuf, 0, 10);
if( (RtsThresh >= 1) && (RtsThresh <= MAX_RTS_THRESHOLD) )
pAd->CommonCfg.RtsThreshold = (USHORT)RtsThresh;
else
pAd->CommonCfg.RtsThreshold = MAX_RTS_THRESHOLD;
DBGPRINT(RT_DEBUG_TRACE, ("RTSThreshold=%d\n", pAd->CommonCfg.RtsThreshold));
}
//FragThreshold
if(RTMPGetKeyParameter("FragThreshold", tmpbuf, 10, buffer))
{
FragThresh = simple_strtol(tmpbuf, 0, 10);
pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
{ //illegal FragThresh so we set it to default
pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
pAd->CommonCfg.bUseZeroToDisableFragment = TRUE;
}
else if (FragThresh % 2 == 1)
{
// The length of each fragment shall always be an even number of octets, except for the last fragment
// of an MSDU or MMPDU, which may be either an even or an odd number of octets.
pAd->CommonCfg.FragmentThreshold = (USHORT)(FragThresh - 1);
}
else
{
pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
}
//pAd->CommonCfg.AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
DBGPRINT(RT_DEBUG_TRACE, ("FragThreshold=%d\n", pAd->CommonCfg.FragmentThreshold));
}
//TxBurst
if(RTMPGetKeyParameter("TxBurst", tmpbuf, 10, buffer))
{
if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
pAd->CommonCfg.bEnableTxBurst = TRUE;
else //Disable
pAd->CommonCfg.bEnableTxBurst = FALSE;
DBGPRINT(RT_DEBUG_TRACE, ("TxBurst=%d\n", pAd->CommonCfg.bEnableTxBurst));
}
#ifdef AGGREGATION_SUPPORT
//PktAggregate
if(RTMPGetKeyParameter("PktAggregate", tmpbuf, 10, buffer))
{
if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
pAd->CommonCfg.bAggregationCapable = TRUE;
else //Disable
pAd->CommonCfg.bAggregationCapable = FALSE;
#ifdef PIGGYBACK_SUPPORT
pAd->CommonCfg.bPiggyBackCapable = pAd->CommonCfg.bAggregationCapable;
#endif // PIGGYBACK_SUPPORT //
DBGPRINT(RT_DEBUG_TRACE, ("PktAggregate=%d\n", pAd->CommonCfg.bAggregationCapable));
}
#else
pAd->CommonCfg.bAggregationCapable = FALSE;
pAd->CommonCfg.bPiggyBackCapable = FALSE;
#endif // AGGREGATION_SUPPORT //
// WmmCapable
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
rtmp_read_sta_wmm_parms_from_file(pAd, tmpbuf, buffer);
#endif // CONFIG_STA_SUPPORT //
//ShortSlot
if(RTMPGetKeyParameter("ShortSlot", tmpbuf, 10, buffer))
{
if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
pAd->CommonCfg.bUseShortSlotTime = TRUE;
else //Disable
pAd->CommonCfg.bUseShortSlotTime = FALSE;
DBGPRINT(RT_DEBUG_TRACE, ("ShortSlot=%d\n", pAd->CommonCfg.bUseShortSlotTime));
}
//IEEE80211H
if(RTMPGetKeyParameter("IEEE80211H", tmpbuf, 10, buffer))
{
for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
{
if(simple_strtol(macptr, 0, 10) != 0) //Enable
pAd->CommonCfg.bIEEE80211H = TRUE;
else //Disable
pAd->CommonCfg.bIEEE80211H = FALSE;
DBGPRINT(RT_DEBUG_TRACE, ("IEEE80211H=%d\n", pAd->CommonCfg.bIEEE80211H));
}
}
//CSPeriod
if(RTMPGetKeyParameter("CSPeriod", tmpbuf, 10, buffer))
{
if(simple_strtol(tmpbuf, 0, 10) != 0)
pAd->CommonCfg.RadarDetect.CSPeriod = simple_strtol(tmpbuf, 0, 10);
else
pAd->CommonCfg.RadarDetect.CSPeriod = 0;
DBGPRINT(RT_DEBUG_TRACE, ("CSPeriod=%d\n", pAd->CommonCfg.RadarDetect.CSPeriod));
}
//RDRegion
if(RTMPGetKeyParameter("RDRegion", tmpbuf, 128, buffer))
{
if ((strncmp(tmpbuf, "JAP_W53", 7) == 0) || (strncmp(tmpbuf, "jap_w53", 7) == 0))
{
pAd->CommonCfg.RadarDetect.RDDurRegion = JAP_W53;
pAd->CommonCfg.RadarDetect.DfsSessionTime = 15;
}
else if ((strncmp(tmpbuf, "JAP_W56", 7) == 0) || (strncmp(tmpbuf, "jap_w56", 7) == 0))
{
pAd->CommonCfg.RadarDetect.RDDurRegion = JAP_W56;
pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
}
else if ((strncmp(tmpbuf, "JAP", 3) == 0) || (strncmp(tmpbuf, "jap", 3) == 0))
{
pAd->CommonCfg.RadarDetect.RDDurRegion = JAP;
pAd->CommonCfg.RadarDetect.DfsSessionTime = 5;
}
else if ((strncmp(tmpbuf, "FCC", 3) == 0) || (strncmp(tmpbuf, "fcc", 3) == 0))
{
pAd->CommonCfg.RadarDetect.RDDurRegion = FCC;
pAd->CommonCfg.RadarDetect.DfsSessionTime = 5;
}
else if ((strncmp(tmpbuf, "CE", 2) == 0) || (strncmp(tmpbuf, "ce", 2) == 0))
{
pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
}
else
{
pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
}
DBGPRINT(RT_DEBUG_TRACE, ("RDRegion=%d\n", pAd->CommonCfg.RadarDetect.RDDurRegion));
}
else
{
pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
}
//WirelessEvent
if(RTMPGetKeyParameter("WirelessEvent", tmpbuf, 10, buffer))
{
#if WIRELESS_EXT >= 15
if(simple_strtol(tmpbuf, 0, 10) != 0)
pAd->CommonCfg.bWirelessEvent = simple_strtol(tmpbuf, 0, 10);
else
pAd->CommonCfg.bWirelessEvent = 0; // disable
#else
pAd->CommonCfg.bWirelessEvent = 0; // disable
#endif
DBGPRINT(RT_DEBUG_TRACE, ("WirelessEvent=%d\n", pAd->CommonCfg.bWirelessEvent));
}
if(RTMPGetKeyParameter("WiFiTest", tmpbuf, 10, buffer))
{
if(simple_strtol(tmpbuf, 0, 10) != 0)
pAd->CommonCfg.bWiFiTest= simple_strtol(tmpbuf, 0, 10);
else
pAd->CommonCfg.bWiFiTest = 0; // disable
DBGPRINT(RT_DEBUG_TRACE, ("WiFiTest=%d\n", pAd->CommonCfg.bWiFiTest));
}
//AuthMode
if(RTMPGetKeyParameter("AuthMode", tmpbuf, 128, buffer))
{
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
if ((strcmp(tmpbuf, "WEPAUTO") == 0) || (strcmp(tmpbuf, "wepauto") == 0))
pAd->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
else if ((strcmp(tmpbuf, "SHARED") == 0) || (strcmp(tmpbuf, "shared") == 0))
pAd->StaCfg.AuthMode = Ndis802_11AuthModeShared;
else if ((strcmp(tmpbuf, "WPAPSK") == 0) || (strcmp(tmpbuf, "wpapsk") == 0))
pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
else if ((strcmp(tmpbuf, "WPANONE") == 0) || (strcmp(tmpbuf, "wpanone") == 0))
pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
else if ((strcmp(tmpbuf, "WPA2PSK") == 0) || (strcmp(tmpbuf, "wpa2psk") == 0))
pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
#ifdef WPA_SUPPLICANT_SUPPORT
else if ((strcmp(tmpbuf, "WPA") == 0) || (strcmp(tmpbuf, "wpa") == 0))
pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
else if ((strcmp(tmpbuf, "WPA2") == 0) || (strcmp(tmpbuf, "wpa2") == 0))
pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
#endif // WPA_SUPPLICANT_SUPPORT //
else
pAd->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __func__, pAd->StaCfg.WepStatus));
}
#endif // CONFIG_STA_SUPPORT //
}
//EncrypType
if(RTMPGetKeyParameter("EncrypType", tmpbuf, 128, buffer))
{
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
if ((strcmp(tmpbuf, "WEP") == 0) || (strcmp(tmpbuf, "wep") == 0))
pAd->StaCfg.WepStatus = Ndis802_11WEPEnabled;
else if ((strcmp(tmpbuf, "TKIP") == 0) || (strcmp(tmpbuf, "tkip") == 0))
pAd->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
else if ((strcmp(tmpbuf, "AES") == 0) || (strcmp(tmpbuf, "aes") == 0))
pAd->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
else
pAd->StaCfg.WepStatus = Ndis802_11WEPDisabled;
// Update all wepstatus related
pAd->StaCfg.PairCipher = pAd->StaCfg.WepStatus;
pAd->StaCfg.GroupCipher = pAd->StaCfg.WepStatus;
pAd->StaCfg.OrigWepStatus = pAd->StaCfg.WepStatus;
pAd->StaCfg.bMixCipher = FALSE;
DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __func__, pAd->StaCfg.WepStatus));
}
#endif // CONFIG_STA_SUPPORT //
}
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
if(RTMPGetCriticalParameter("WPAPSK", tmpbuf, 512, buffer))
{
int err=0;
tmpbuf[strlen(tmpbuf)] = '\0'; // make STA can process .$^& for WPAPSK input
if ((pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
(pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
(pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
)
{
err = 1;
}
else if ((strlen(tmpbuf) >= 8) && (strlen(tmpbuf) < 64))
{
PasswordHash((char *)tmpbuf, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, keyMaterial);
NdisMoveMemory(pAd->StaCfg.PMK, keyMaterial, 32);
}
else if (strlen(tmpbuf) == 64)
{
AtoH(tmpbuf, keyMaterial, 32);
NdisMoveMemory(pAd->StaCfg.PMK, keyMaterial, 32);
}
else
{
err = 1;
DBGPRINT(RT_DEBUG_ERROR, ("%s::(WPAPSK key-string required 8 ~ 64 characters!)\n", __func__));
}
if (err == 0)
{
if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
{
// Start STA supplicant state machine
pAd->StaCfg.WpaState = SS_START;
}
else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
{
pAd->StaCfg.WpaState = SS_NOTUSE;
}
DBGPRINT(RT_DEBUG_TRACE, ("%s::(WPAPSK=%s)\n", __func__, tmpbuf));
}
}
}
#endif // CONFIG_STA_SUPPORT //
//DefaultKeyID, KeyType, KeyStr
rtmp_read_key_parms_from_file(pAd, tmpbuf, buffer);
#ifdef DOT11_N_SUPPORT
HTParametersHook(pAd, tmpbuf, buffer);
#endif // DOT11_N_SUPPORT //
#ifdef CARRIER_DETECTION_SUPPORT
//CarrierDetect
if(RTMPGetKeyParameter("CarrierDetect", tmpbuf, 128, buffer))
{
if ((strncmp(tmpbuf, "0", 1) == 0))
pAd->CommonCfg.CarrierDetect.Enable = FALSE;
else if ((strncmp(tmpbuf, "1", 1) == 0))
pAd->CommonCfg.CarrierDetect.Enable = TRUE;
else
pAd->CommonCfg.CarrierDetect.Enable = FALSE;
DBGPRINT(RT_DEBUG_TRACE, ("CarrierDetect.Enable=%d\n", pAd->CommonCfg.CarrierDetect.Enable));
}
else
pAd->CommonCfg.CarrierDetect.Enable = FALSE;
#endif // CARRIER_DETECTION_SUPPORT //
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
//PSMode
if (RTMPGetKeyParameter("PSMode", tmpbuf, 32, buffer))
{
if (pAd->StaCfg.BssType == BSS_INFRA)
{
if ((strcmp(tmpbuf, "MAX_PSP") == 0) || (strcmp(tmpbuf, "max_psp") == 0))
{
// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
// to exclude certain situations.
// MlmeSetPsm(pAd, PWR_SAVE);
OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
pAd->StaCfg.DefaultListenCount = 5;
}
else if ((strcmp(tmpbuf, "Fast_PSP") == 0) || (strcmp(tmpbuf, "fast_psp") == 0)
|| (strcmp(tmpbuf, "FAST_PSP") == 0))
{
// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
// to exclude certain situations.
// MlmeSetPsmBit(pAd, PWR_SAVE);
OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
pAd->StaCfg.DefaultListenCount = 3;
}
else if ((strcmp(tmpbuf, "Legacy_PSP") == 0) || (strcmp(tmpbuf, "legacy_psp") == 0)
|| (strcmp(tmpbuf, "LEGACY_PSP") == 0))
{
// do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
// to exclude certain situations.
// MlmeSetPsmBit(pAd, PWR_SAVE);
OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
pAd->StaCfg.DefaultListenCount = 3;
}
else
{ //Default Ndis802_11PowerModeCAM
// clear PSM bit immediately
MlmeSetPsmBit(pAd, PWR_ACTIVE);
OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
}
DBGPRINT(RT_DEBUG_TRACE, ("PSMode=%ld\n", pAd->StaCfg.WindowsPowerMode));
}
}
// FastRoaming
if (RTMPGetKeyParameter("FastRoaming", tmpbuf, 32, buffer))
{
if (simple_strtol(tmpbuf, 0, 10) == 0)
pAd->StaCfg.bFastRoaming = FALSE;
else
pAd->StaCfg.bFastRoaming = TRUE;
DBGPRINT(RT_DEBUG_TRACE, ("FastRoaming=%d\n", pAd->StaCfg.bFastRoaming));
}
// RoamThreshold
if (RTMPGetKeyParameter("RoamThreshold", tmpbuf, 32, buffer))
{
long lInfo = simple_strtol(tmpbuf, 0, 10);
if (lInfo > 90 || lInfo < 60)
pAd->StaCfg.dBmToRoam = -70;
else
pAd->StaCfg.dBmToRoam = (CHAR)(-1)*lInfo;
DBGPRINT(RT_DEBUG_TRACE, ("RoamThreshold=%d dBm\n", pAd->StaCfg.dBmToRoam));
}
if(RTMPGetKeyParameter("TGnWifiTest", tmpbuf, 10, buffer))
{
if(simple_strtol(tmpbuf, 0, 10) == 0)
pAd->StaCfg.bTGnWifiTest = FALSE;
else
pAd->StaCfg.bTGnWifiTest = TRUE;
DBGPRINT(RT_DEBUG_TRACE, ("TGnWifiTest=%d\n", pAd->StaCfg.bTGnWifiTest));
}
}
#endif // CONFIG_STA_SUPPORT //
}
}
else
{
DBGPRINT(RT_DEBUG_TRACE, ("--> %s does not have a write method\n", src));
}
retval=filp_close(srcf,NULL);
if (retval)
{
DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
}
}
}
set_fs(orgfs);
#if 0
current->cred->fsuid = orgfsuid;
current->cred->fsgid = orgfsgid;
#endif
kfree(buffer);
kfree(tmpbuf);
return (NDIS_STATUS_SUCCESS);
}
#ifdef DOT11_N_SUPPORT
static void HTParametersHook(
IN PRTMP_ADAPTER pAd,
IN CHAR *pValueStr,
IN CHAR *pInput)
{
INT Value;
if (RTMPGetKeyParameter("HT_PROTECT", pValueStr, 25, pInput))
{
Value = simple_strtol(pValueStr, 0, 10);
if (Value == 0)
{
pAd->CommonCfg.bHTProtect = FALSE;
}
else
{
pAd->CommonCfg.bHTProtect = TRUE;
}
DBGPRINT(RT_DEBUG_TRACE, ("HT: Protection = %s\n", (Value==0) ? "Disable" : "Enable"));
}
if (RTMPGetKeyParameter("HT_MIMOPSEnable", pValueStr, 25, pInput))
{
Value = simple_strtol(pValueStr, 0, 10);
if (Value == 0)
{
pAd->CommonCfg.bMIMOPSEnable = FALSE;
}
else
{
pAd->CommonCfg.bMIMOPSEnable = TRUE;
}
DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPSEnable = %s\n", (Value==0) ? "Disable" : "Enable"));
}
if (RTMPGetKeyParameter("HT_MIMOPSMode", pValueStr, 25, pInput))
{
Value = simple_strtol(pValueStr, 0, 10);
if (Value > MMPS_ENABLE)
{
pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
}
else
{
//TODO: add mimo power saving mechanism
pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
//pAd->CommonCfg.BACapability.field.MMPSmode = Value;
}
DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPS Mode = %d\n", Value));
}
if (RTMPGetKeyParameter("HT_BADecline", pValueStr, 25, pInput))
{
Value = simple_strtol(pValueStr, 0, 10);
if (Value == 0)
{
pAd->CommonCfg.bBADecline = FALSE;
}
else
{
pAd->CommonCfg.bBADecline = TRUE;
}
DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Decline = %s\n", (Value==0) ? "Disable" : "Enable"));
}
if (RTMPGetKeyParameter("HT_DisableReordering", pValueStr, 25, pInput))
{
Value = simple_strtol(pValueStr, 0, 10);
if (Value == 0)
{
pAd->CommonCfg.bDisableReordering = FALSE;
}
else
{
pAd->CommonCfg.bDisableReordering = TRUE;
}
DBGPRINT(RT_DEBUG_TRACE, ("HT: DisableReordering = %s\n", (Value==0) ? "Disable" : "Enable"));
}
if (RTMPGetKeyParameter("HT_AutoBA", pValueStr, 25, pInput))
{
Value = simple_strtol(pValueStr, 0, 10);
if (Value == 0)
{
pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
}
else
{
pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
}
pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
DBGPRINT(RT_DEBUG_TRACE, ("HT: Auto BA = %s\n", (Value==0) ? "Disable" : "Enable"));
}
// Tx_+HTC frame
if (RTMPGetKeyParameter("HT_HTC", pValueStr, 25, pInput))
{
Value = simple_strtol(pValueStr, 0, 10);
if (Value == 0)
{
pAd->HTCEnable = FALSE;
}
else
{
pAd->HTCEnable = TRUE;
}
DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx +HTC frame = %s\n", (Value==0) ? "Disable" : "Enable"));
}
// Enable HT Link Adaptation Control
if (RTMPGetKeyParameter("HT_LinkAdapt", pValueStr, 25, pInput))
{
Value = simple_strtol(pValueStr, 0, 10);
if (Value == 0)
{
pAd->bLinkAdapt = FALSE;
}
else
{
pAd->HTCEnable = TRUE;
pAd->bLinkAdapt = TRUE;
}
DBGPRINT(RT_DEBUG_TRACE, ("HT: Link Adaptation Control = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
}
// Reverse Direction Mechanism
if (RTMPGetKeyParameter("HT_RDG", pValueStr, 25, pInput))
{
Value = simple_strtol(pValueStr, 0, 10);
if (Value == 0)
{
pAd->CommonCfg.bRdg = FALSE;
}
else
{
pAd->HTCEnable = TRUE;
pAd->CommonCfg.bRdg = TRUE;
}
DBGPRINT(RT_DEBUG_TRACE, ("HT: RDG = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
}
// Tx A-MSUD ?
if (RTMPGetKeyParameter("HT_AMSDU", pValueStr, 25, pInput))
{
Value = simple_strtol(pValueStr, 0, 10);
if (Value == 0)
{
pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE;
}
else
{
pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE;
}
DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx A-MSDU = %s\n", (Value==0) ? "Disable" : "Enable"));
}
// MPDU Density
if (RTMPGetKeyParameter("HT_MpduDensity", pValueStr, 25, pInput))
{
Value = simple_strtol(pValueStr, 0, 10);
if (Value <=7 && Value >= 0)
{
pAd->CommonCfg.BACapability.field.MpduDensity = Value;
DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d\n", Value));
}
else
{
pAd->CommonCfg.BACapability.field.MpduDensity = 4;
DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d (Default)\n", 4));
}
}
// Max Rx BA Window Size
if (RTMPGetKeyParameter("HT_BAWinSize", pValueStr, 25, pInput))
{
Value = simple_strtol(pValueStr, 0, 10);
if (Value >=1 && Value <= 64)
{
pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value;
pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value;
DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = %d\n", Value));
}
else
{
pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64;
pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64;
DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = 64 (Defualt)\n"));
}
}
// Guard Interval
if (RTMPGetKeyParameter("HT_GI", pValueStr, 25, pInput))
{
Value = simple_strtol(pValueStr, 0, 10);
if (Value == GI_400)
{
pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400;
}
else
{
pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800;
}
DBGPRINT(RT_DEBUG_TRACE, ("HT: Guard Interval = %s\n", (Value==GI_400) ? "400" : "800" ));
}
// HT Operation Mode : Mixed Mode , Green Field
if (RTMPGetKeyParameter("HT_OpMode", pValueStr, 25, pInput))
{
Value = simple_strtol(pValueStr, 0, 10);
if (Value == HTMODE_GF)
{
pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_GF;
}
else
{
pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_MM;
}
DBGPRINT(RT_DEBUG_TRACE, ("HT: Operate Mode = %s\n", (Value==HTMODE_GF) ? "Green Field" : "Mixed Mode" ));
}
// Fixed Tx mode : CCK, OFDM
if (RTMPGetKeyParameter("FixedTxMode", pValueStr, 25, pInput))
{
UCHAR fix_tx_mode;
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
fix_tx_mode = FIXED_TXMODE_HT;
if (strcmp(pValueStr, "OFDM") == 0 || strcmp(pValueStr, "ofdm") == 0)
{
fix_tx_mode = FIXED_TXMODE_OFDM;
}
else if (strcmp(pValueStr, "CCK") == 0 || strcmp(pValueStr, "cck") == 0)
{
fix_tx_mode = FIXED_TXMODE_CCK;
}
else if (strcmp(pValueStr, "HT") == 0 || strcmp(pValueStr, "ht") == 0)
{
fix_tx_mode = FIXED_TXMODE_HT;
}
else
{
Value = simple_strtol(pValueStr, 0, 10);
// 1 : CCK
// 2 : OFDM
// otherwise : HT
if (Value == FIXED_TXMODE_CCK || Value == FIXED_TXMODE_OFDM)
fix_tx_mode = Value;
else
fix_tx_mode = FIXED_TXMODE_HT;
}
pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode;
DBGPRINT(RT_DEBUG_TRACE, ("Fixed Tx Mode = %d\n", fix_tx_mode));
}
#endif // CONFIG_STA_SUPPORT //
}
// Channel Width
if (RTMPGetKeyParameter("HT_BW", pValueStr, 25, pInput))
{
Value = simple_strtol(pValueStr, 0, 10);
if (Value == BW_40)
{
pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
}
else
{
pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
}
#ifdef MCAST_RATE_SPECIFIC
pAd->CommonCfg.MCastPhyMode.field.BW = pAd->CommonCfg.RegTransmitSetting.field.BW;
#endif // MCAST_RATE_SPECIFIC //
DBGPRINT(RT_DEBUG_TRACE, ("HT: Channel Width = %s\n", (Value==BW_40) ? "40 MHz" : "20 MHz" ));
}
if (RTMPGetKeyParameter("HT_EXTCHA", pValueStr, 25, pInput))
{
Value = simple_strtol(pValueStr, 0, 10);
if (Value == 0)
{
pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
}
else
{
pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
}
DBGPRINT(RT_DEBUG_TRACE, ("HT: Ext Channel = %s\n", (Value==0) ? "BELOW" : "ABOVE" ));
}
// MSC
if (RTMPGetKeyParameter("HT_MCS", pValueStr, 50, pInput))
{
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
Value = simple_strtol(pValueStr, 0, 10);
if ((Value >= 0 && Value <= 23) || (Value == 32)) // 3*3
{
pAd->StaCfg.DesiredTransmitSetting.field.MCS = Value;
pAd->StaCfg.bAutoTxRateSwitch = FALSE;
DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = %d\n", pAd->StaCfg.DesiredTransmitSetting.field.MCS));
}
else
{
pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
pAd->StaCfg.bAutoTxRateSwitch = TRUE;
DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = AUTO\n"));
}
}
#endif // CONFIG_STA_SUPPORT //
}
// STBC
if (RTMPGetKeyParameter("HT_STBC", pValueStr, 25, pInput))
{
Value = simple_strtol(pValueStr, 0, 10);
if (Value == STBC_USE)
{
pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE;
}
else
{
pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE;
}
DBGPRINT(RT_DEBUG_TRACE, ("HT: STBC = %d\n", pAd->CommonCfg.RegTransmitSetting.field.STBC));
}
// 40_Mhz_Intolerant
if (RTMPGetKeyParameter("HT_40MHZ_INTOLERANT", pValueStr, 25, pInput))
{
Value = simple_strtol(pValueStr, 0, 10);
if (Value == 0)
{
pAd->CommonCfg.bForty_Mhz_Intolerant = FALSE;
}
else
{
pAd->CommonCfg.bForty_Mhz_Intolerant = TRUE;
}
DBGPRINT(RT_DEBUG_TRACE, ("HT: 40MHZ INTOLERANT = %d\n", pAd->CommonCfg.bForty_Mhz_Intolerant));
}
//HT_TxStream
if(RTMPGetKeyParameter("HT_TxStream", pValueStr, 10, pInput))
{
switch (simple_strtol(pValueStr, 0, 10))
{
case 1:
pAd->CommonCfg.TxStream = 1;
break;
case 2:
pAd->CommonCfg.TxStream = 2;
break;
case 3: // 3*3
default:
pAd->CommonCfg.TxStream = 3;
if (pAd->MACVersion < RALINK_2883_VERSION)
pAd->CommonCfg.TxStream = 2; // only 2 tx streams for RT2860 series
break;
}
DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx Stream = %d\n", pAd->CommonCfg.TxStream));
}
//HT_RxStream
if(RTMPGetKeyParameter("HT_RxStream", pValueStr, 10, pInput))
{
switch (simple_strtol(pValueStr, 0, 10))
{
case 1:
pAd->CommonCfg.RxStream = 1;
break;
case 2:
pAd->CommonCfg.RxStream = 2;
break;
case 3:
default:
pAd->CommonCfg.RxStream = 3;
if (pAd->MACVersion < RALINK_2883_VERSION)
pAd->CommonCfg.RxStream = 2; // only 2 rx streams for RT2860 series
break;
}
DBGPRINT(RT_DEBUG_TRACE, ("HT: Rx Stream = %d\n", pAd->CommonCfg.RxStream));
}
}
#endif // DOT11_N_SUPPORT //