/* ************************************************************************* * 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" static void HTParametersHook( IN PRTMP_ADAPTER pAd, IN CHAR *pValueStr, IN CHAR *pInput); #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) { 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_ptrSharedKey[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(wlan%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(wlan%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)) { { 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)); } } 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); } { 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); } } } } } 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)); } //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]; } } } NDIS_STATUS RTMPReadParametersHook( IN PRTMP_ADAPTER pAd) { PUCHAR src = NULL; struct file *srcf; INT retval; mm_segment_t orgfs; CHAR *buffer; CHAR *tmpbuf; ULONG RtsThresh; ULONG FragThresh; UCHAR keyMaterial[40]; 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; } src = STA_PROFILE_PATH; 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); 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'); DBGPRINT(RT_DEBUG_TRACE, ("ChannelGeography=%d\n", pAd->CommonCfg.Geography)); } } else { pAd->CommonCfg.Geography = BOTH; pAd->CommonCfg.CountryCode[2] = ' '; } { //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)); } } } { //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)); } } //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; maxPhyMode = PHY_11N_5G; 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); pAd->CommonCfg.TxPowerDefault = pAd->CommonCfg.TxPowerPercentage; 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 rtmp_read_sta_wmm_parms_from_file(pAd, tmpbuf, buffer); //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(simple_strtol(tmpbuf, 0, 10) != 0) pAd->CommonCfg.bWirelessEvent = simple_strtol(tmpbuf, 0, 10); else pAd->CommonCfg.bWirelessEvent = 0; // disable 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)) { { 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; 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; 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)); } } //EncrypType if(RTMPGetKeyParameter("EncrypType", tmpbuf, 128, buffer)) { { 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)); } } { 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)); } } } //DefaultKeyID, KeyType, KeyStr rtmp_read_key_parms_from_file(pAd, tmpbuf, buffer); HTParametersHook(pAd, tmpbuf, buffer); { //PSMode #ifdef RT2860 if (RTMPGetKeyParameter("PSMode", tmpbuf, 32, buffer)) #endif #ifdef RT2870 if (RTMPGetKeyParameter("PSMode", tmpbuf, 10, buffer)) #endif { 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)); } } } } 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); kfree(buffer); kfree(tmpbuf); return (NDIS_STATUS_SUCCESS); } 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; pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE; } else { pAd->CommonCfg.BACapability.field.AutoBA = TRUE; pAd->CommonCfg.BACapability.field.Policy = IMMED_BA; } pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA; pAd->CommonCfg.REGBACapability.field.Policy = pAd->CommonCfg.BACapability.field.Policy; 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; { 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)); } } // 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)) { { 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")); } } } // 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)); } }