/* ************************************************************************* * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * Taiwan, R.O.C. * * (c) Copyright 2002-2010, 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" #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(PSTRING s1, PSTRING s2) { int i = 0; PSTRING 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, (PUCHAR)&s2[i++], 1); ptokS = ptokE; if (ptokS == NULL) break; if (i == 6) break; /* parsing finished*/ } return ( i == 6 ? TRUE : FALSE); } /* we assume the s1 and s2 both are strings.*/ BOOLEAN rtstrcasecmp(PSTRING s1, PSTRING s2) { PSTRING 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.*/ PSTRING rtstrstruncasecmp(PSTRING s1, PSTRING 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 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. */ PSTRING __rstrtok; PSTRING rstrtok(PSTRING s,const PSTRING ct) { PSTRING 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(PSTRING s,PSTRING ct) { INT count = 0; /* point to the beginning of the line */ PSTRING 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(PSTRING cp, unsigned int *addr) { unsigned int val; int base, n; STRING 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 = OS_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 ======================================================================== */ PSTRING RTMPFindSection( IN PSTRING buffer) { STRING temp_buf[32]; PSTRING 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 bTrimSpace Set true if you want to strip the space character of the result pattern Return Value: TRUE Success FALSE Fail Note: This routine get the value with the matched key (case case-sensitive) For SSID and security key related parameters, we SHALL NOT trim the space(' ') character. ======================================================================== */ INT RTMPGetKeyParameter( IN PSTRING key, OUT PSTRING dest, IN INT destsize, IN PSTRING buffer, IN BOOLEAN bTrimSpace) { PSTRING pMemBuf, temp_buf1 = NULL, temp_buf2 = NULL; PSTRING start_ptr, end_ptr; PSTRING ptr; PSTRING offset = NULL; INT len, keyLen; keyLen = strlen(key); os_alloc_mem(NULL, (PUCHAR *)&pMemBuf, MAX_PARAM_BUFFER_SIZE * 2); if (pMemBuf == NULL) return (FALSE); memset(pMemBuf, 0, MAX_PARAM_BUFFER_SIZE * 2); temp_buf1 = pMemBuf; temp_buf2 = (PSTRING)(pMemBuf + MAX_PARAM_BUFFER_SIZE); /*find section*/ if((offset = RTMPFindSection(buffer)) == NULL) { os_free_mem(NULL, (PUCHAR)pMemBuf); 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, (PUCHAR)pMemBuf); return (FALSE); } start_ptr += strlen("\n"); if((end_ptr = rtstrstr(start_ptr, "\n"))==NULL) end_ptr = start_ptr+strlen(start_ptr); if (end_ptrStaCfg.DefaultKeyId)); } #endif /* CONFIG_STA_SUPPORT */ } for (idx = 0; idx < 4; idx++) { snprintf(tok_str, sizeof(tok_str), "Key%dType", idx + 1); /*Key1Type*/ if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer, TRUE)) { for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++) { /* do sanity check for KeyType length; or in station mode, the KeyType length > 1, the code will overwrite the stack of caller (RTMPSetProfileParameters) and cause srcbuf = NULL */ if (i < MAX_MBSSID_NUM(pAd)) KeyType[i] = simple_strtol(macptr, 0, 10); } #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { snprintf(tok_str, sizeof(tok_str), "Key%dStr", idx + 1); if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer, FALSE)) { 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) { PSTRING macptr; INT i=0; BOOLEAN bWmmEnable = FALSE; /*WmmCapable*/ if(RTMPGetKeyParameter("WmmCapable", tmpbuf, 32, buffer, TRUE)) { 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, TRUE)) { 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, TRUE)) { 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])); } } #ifdef UAPSD_SUPPORT if (bWmmEnable) { /*APSDCapable*/ if(RTMPGetKeyParameter("APSDCapable", tmpbuf, 10, buffer, TRUE)) { if(simple_strtol(tmpbuf, 0, 10) != 0) /*Enable*/ pAd->StaCfg.UapsdInfo.bAPSDCapable = TRUE; else pAd->StaCfg.UapsdInfo.bAPSDCapable = FALSE; DBGPRINT(RT_DEBUG_TRACE, ("APSDCapable=%d\n", pAd->StaCfg.UapsdInfo.bAPSDCapable)); } /*MaxSPLength*/ if(RTMPGetKeyParameter("MaxSPLength", tmpbuf, 10, buffer, TRUE)) { pAd->CommonCfg.MaxSPLength = simple_strtol(tmpbuf, 0, 10); DBGPRINT(RT_DEBUG_TRACE, ("MaxSPLength=%d\n", pAd->CommonCfg.MaxSPLength)); } /*APSDAC for AC_BE, AC_BK, AC_VI, AC_VO*/ if(RTMPGetKeyParameter("APSDAC", tmpbuf, 32, buffer, TRUE)) { 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]; pAd->CommonCfg.bACMAPSDTr[0] = apsd_ac[0]; pAd->CommonCfg.bACMAPSDTr[1] = apsd_ac[1]; pAd->CommonCfg.bACMAPSDTr[2] = apsd_ac[2]; pAd->CommonCfg.bACMAPSDTr[3] = apsd_ac[3]; } } #endif /* UAPSD_SUPPORT */ } #ifdef XLINK_SUPPORT static void rtmp_get_psp_xlink_mode_from_file(IN PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer) { UINT32 Value = 0; /* Xlink Mode*/ if (RTMPGetKeyParameter("PSP_XLINK_MODE", tmpbuf, 32, buffer, TRUE)) { if(simple_strtol(tmpbuf, 0, 10) != 0) /* enable*/ { pAd->StaCfg.PSPXlink = TRUE; } else /* disable*/ { pAd->StaCfg.PSPXlink = FALSE; } if (pAd->StaCfg.PSPXlink) Value = PSPXLINK; else Value = STANORMAL; RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, Value); DBGPRINT(RT_DEBUG_TRACE, ("PSP_XLINK_MODE=%d\n", pAd->StaCfg.PSPXlink)); } } #endif /* XLINK_SUPPORT */ #endif /* CONFIG_STA_SUPPORT */ #ifdef DOT11_N_SUPPORT static void HTParametersHook( IN PRTMP_ADAPTER pAd, IN PSTRING pValueStr, IN PSTRING pInput) { long Value; if (RTMPGetKeyParameter("HT_PROTECT", pValueStr, 25, pInput, TRUE)) { 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_MIMOPSMode", pValueStr, 25, pInput, TRUE)) { 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", (INT) Value)); } if (RTMPGetKeyParameter("HT_BADecline", pValueStr, 25, pInput, TRUE)) { 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_AutoBA", pValueStr, 25, pInput, TRUE)) { 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, TRUE)) { 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")); } /* Reverse Direction Mechanism*/ if (RTMPGetKeyParameter("HT_RDG", pValueStr, 25, pInput, TRUE)) { 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, TRUE)) { 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, TRUE)) { 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", (INT) 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, TRUE)) { 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", (INT) 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, TRUE)) { 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, TRUE)) { 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, TRUE)) { #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = RT_CfgSetFixedTxPhyMode(pValueStr); DBGPRINT(RT_DEBUG_TRACE, ("Fixed Tx Mode = %d\n", pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode)); } #endif /* CONFIG_STA_SUPPORT */ } /* Channel Width*/ if (RTMPGetKeyParameter("HT_BW", pValueStr, 25, pInput, TRUE)) { 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, TRUE)) { 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, TRUE)) { #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { Value = simple_strtol(pValueStr, 0, 10); /* if ((Value >= 0 && Value <= 15) || (Value == 32))*/ 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, TRUE)) { 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, TRUE)) { 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, TRUE)) { 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, TRUE)) { 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)); } /* HT_DisallowTKIP*/ if (RTMPGetKeyParameter("HT_DisallowTKIP", pValueStr, 25, pInput, TRUE)) { Value = simple_strtol(pValueStr, 0, 10); if (Value == 1) { pAd->CommonCfg.HT_DisallowTKIP = TRUE; } else { pAd->CommonCfg.HT_DisallowTKIP = FALSE; } DBGPRINT(RT_DEBUG_TRACE, ("HT: Disallow TKIP mode = %s\n", (pAd->CommonCfg.HT_DisallowTKIP == TRUE) ? "ON" : "OFF" )); } #ifdef DOT11_N_SUPPORT #ifdef DOT11N_DRAFT3 if (RTMPGetKeyParameter("OBSSScanParam", pValueStr, 32, pInput, TRUE)) { int ObssScanValue, idx; PSTRING macptr; for (idx = 0, macptr = rstrtok(pValueStr,";"); macptr; macptr = rstrtok(NULL,";"), idx++) { ObssScanValue = simple_strtol(macptr, 0, 10); switch (idx) { case 0: if (ObssScanValue < 5 || ObssScanValue > 1000) { DBGPRINT(RT_DEBUG_ERROR, ("Invalid OBSSScanParam for Dot11OBssScanPassiveDwell(%d), should in range 5~1000\n", ObssScanValue)); } else { pAd->CommonCfg.Dot11OBssScanPassiveDwell = ObssScanValue; /* Unit : TU. 5~1000*/ DBGPRINT(RT_DEBUG_TRACE, ("OBSSScanParam for Dot11OBssScanPassiveDwell=%d\n", ObssScanValue)); } break; case 1: if (ObssScanValue < 10 || ObssScanValue > 1000) { DBGPRINT(RT_DEBUG_ERROR, ("Invalid OBSSScanParam for Dot11OBssScanActiveDwell(%d), should in range 10~1000\n", ObssScanValue)); } else { pAd->CommonCfg.Dot11OBssScanActiveDwell = ObssScanValue; /* Unit : TU. 10~1000*/ DBGPRINT(RT_DEBUG_TRACE, ("OBSSScanParam for Dot11OBssScanActiveDwell=%d\n", ObssScanValue)); } break; case 2: pAd->CommonCfg.Dot11BssWidthTriggerScanInt = ObssScanValue; /* Unit : Second*/ DBGPRINT(RT_DEBUG_TRACE, ("OBSSScanParam for Dot11BssWidthTriggerScanInt=%d\n", ObssScanValue)); break; case 3: if (ObssScanValue < 200 || ObssScanValue > 10000) { DBGPRINT(RT_DEBUG_ERROR, ("Invalid OBSSScanParam for Dot11OBssScanPassiveTotalPerChannel(%d), should in range 200~10000\n", ObssScanValue)); } else { pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel = ObssScanValue; /* Unit : TU. 200~10000*/ DBGPRINT(RT_DEBUG_TRACE, ("OBSSScanParam for Dot11OBssScanPassiveTotalPerChannel=%d\n", ObssScanValue)); } break; case 4: if (ObssScanValue < 20 || ObssScanValue > 10000) { DBGPRINT(RT_DEBUG_ERROR, ("Invalid OBSSScanParam for Dot11OBssScanActiveTotalPerChannel(%d), should in range 20~10000\n", ObssScanValue)); } else { pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel = ObssScanValue; /* Unit : TU. 20~10000*/ DBGPRINT(RT_DEBUG_TRACE, ("OBSSScanParam for Dot11OBssScanActiveTotalPerChannel=%d\n", ObssScanValue)); } break; case 5: pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor = ObssScanValue; DBGPRINT(RT_DEBUG_TRACE, ("OBSSScanParam for Dot11BssWidthChanTranDelayFactor=%d\n", ObssScanValue)); break; case 6: pAd->CommonCfg.Dot11OBssScanActivityThre = ObssScanValue; /* Unit : percentage*/ DBGPRINT(RT_DEBUG_TRACE, ("OBSSScanParam for Dot11BssWidthChanTranDelayFactor=%d\n", ObssScanValue)); break; } } if (idx != 7) { DBGPRINT(RT_DEBUG_ERROR, ("Wrong OBSSScanParamtetrs format in dat file!!!!! Use default value.\n")); pAd->CommonCfg.Dot11OBssScanPassiveDwell = dot11OBSSScanPassiveDwell; /* Unit : TU. 5~1000*/ pAd->CommonCfg.Dot11OBssScanActiveDwell = dot11OBSSScanActiveDwell; /* Unit : TU. 10~1000*/ pAd->CommonCfg.Dot11BssWidthTriggerScanInt = dot11BSSWidthTriggerScanInterval; /* Unit : Second */ pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel = dot11OBSSScanPassiveTotalPerChannel; /* Unit : TU. 200~10000*/ pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel = dot11OBSSScanActiveTotalPerChannel; /* Unit : TU. 20~10000*/ pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor = dot11BSSWidthChannelTransactionDelayFactor; pAd->CommonCfg.Dot11OBssScanActivityThre = dot11BSSScanActivityThreshold; /* Unit : percentage*/ } pAd->CommonCfg.Dot11BssWidthChanTranDelay = (pAd->CommonCfg.Dot11BssWidthTriggerScanInt * pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor); DBGPRINT(RT_DEBUG_TRACE, ("OBSSScanParam for Dot11BssWidthChanTranDelay=%ld\n", pAd->CommonCfg.Dot11BssWidthChanTranDelay)); } if (RTMPGetKeyParameter("HT_BSSCoexistence", pValueStr, 25, pInput, TRUE)) { Value = simple_strtol(pValueStr, 0, 10); pAd->CommonCfg.bBssCoexEnable = ((Value == 1) ? TRUE : FALSE); DBGPRINT(RT_DEBUG_TRACE, ("HT: 20/40 BssCoexSupport = %s\n", (pAd->CommonCfg.bBssCoexEnable == TRUE) ? "ON" : "OFF" )); } if (RTMPGetKeyParameter("HT_BSSCoexApCntThr", pValueStr, 25, pInput, TRUE)) { pAd->CommonCfg.BssCoexApCntThr = simple_strtol(pValueStr, 0, 10);; DBGPRINT(RT_DEBUG_TRACE, ("HT: 20/40 BssCoexApCntThr = %d\n", pAd->CommonCfg.BssCoexApCntThr)); } #endif /* DOT11N_DRAFT3 */ if (RTMPGetKeyParameter("BurstMode", pValueStr, 25, pInput, TRUE)) { Value = simple_strtol(pValueStr, 0, 10); pAd->CommonCfg.bRalinkBurstMode = ((Value == 1) ? 1 : 0); DBGPRINT(RT_DEBUG_TRACE, ("HT: RaBurstMode= %d\n", pAd->CommonCfg.bRalinkBurstMode)); } #endif /* DOT11_N_SUPPORT */ } #endif /* DOT11_N_SUPPORT */ #ifdef CONFIG_STA_SUPPORT void RTMPSetSTASSID(RTMP_ADAPTER *pAd, PSTRING SSID) { pAd->CommonCfg.SsidLen = (UCHAR) strlen(SSID); NdisZeroMemory(pAd->CommonCfg.Ssid, NDIS_802_11_LENGTH_SSID); NdisMoveMemory(pAd->CommonCfg.Ssid, SSID, pAd->CommonCfg.SsidLen); pAd->CommonCfg.LastSsidLen= pAd->CommonCfg.SsidLen; NdisZeroMemory(pAd->CommonCfg.LastSsid, NDIS_802_11_LENGTH_SSID); NdisMoveMemory(pAd->CommonCfg.LastSsid, SSID, pAd->CommonCfg.LastSsidLen); pAd->MlmeAux.AutoReconnectSsidLen = pAd->CommonCfg.SsidLen; NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, NDIS_802_11_LENGTH_SSID); NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, SSID, pAd->MlmeAux.AutoReconnectSsidLen); pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen; NdisZeroMemory(pAd->MlmeAux.Ssid, NDIS_802_11_LENGTH_SSID); NdisMoveMemory(pAd->MlmeAux.Ssid, SSID, pAd->MlmeAux.SsidLen); } void RTMPSetSTAPassPhrase(RTMP_ADAPTER *pAd, PSTRING PassPh) { int ret = TRUE; PassPh[strlen(PassPh)] = '\0'; /* make STA can process .$^& for WPAPSK input */ if ((pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) && (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) && (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone) ) { ret = FALSE; } else { ret = RT_CfgSetWPAPSKKey(pAd, PassPh, strlen(PassPh), (PUCHAR)pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->StaCfg.PMK); } if (ret == TRUE) { RTMPZeroMemory(pAd->StaCfg.WpaPassPhrase, 64); RTMPMoveMemory(pAd->StaCfg.WpaPassPhrase, PassPh, strlen(PassPh)); pAd->StaCfg.WpaPassPhraseLen= strlen(PassPh); 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", __FUNCTION__, PassPh)); } } inline void RTMPSetSTACipherSuites(RTMP_ADAPTER *pAd, NDIS_802_11_ENCRYPTION_STATUS WepStatus) { /* Update all wepstatus related*/ pAd->StaCfg.PairCipher = WepStatus; pAd->StaCfg.GroupCipher = WepStatus; pAd->StaCfg.bMixCipher = FALSE; } #ifdef CREDENTIAL_STORE /*RECOVER THE OLD CONNECT INFO */ NDIS_STATUS RecoverConnectInfo( IN RTMP_ADAPTER *pAd) { INT idx; char ssidStr[NDIS_802_11_LENGTH_SSID + 1]; NdisZeroMemory(&ssidStr[0], sizeof(ssidStr)); RTMP_SEM_LOCK(&pAd->StaCtIf.Lock); if ((pAd->StaCtIf.Changeable== FALSE) || (pAd->StaCtIf.SsidLen > NDIS_802_11_LENGTH_SSID)) { DBGPRINT(RT_DEBUG_TRACE, (" DRIVER INIT not need to RecoverConnectInfo() \n")); RTMP_SEM_UNLOCK(&pAd->StaCtIf.Lock); return 0; } DBGPRINT(RT_DEBUG_TRACE, ("-->RecoverConnectInfo()\n")); NdisMoveMemory(ssidStr, pAd->StaCtIf.Ssid, pAd->StaCtIf.SsidLen); RTMPSetSTASSID(pAd, &ssidStr[0]); pAd->StaCfg.AuthMode = pAd->StaCtIf.AuthMode; pAd->StaCfg.WepStatus = pAd->StaCtIf.WepStatus; #ifdef WPA_SUPPLICANT_SUPPORT pAd->StaCfg.IEEE8021X = pAd->StaCtIf.IEEE8021X; pAd->StaCfg.DesireSharedKeyId = pAd->StaCtIf.DefaultKeyId; #endif // WPA_SUPPLICANT_SUPPORT // pAd->StaCfg.DefaultKeyId = pAd->StaCtIf.DefaultKeyId; NdisMoveMemory( pAd->StaCfg.PMK, pAd->StaCtIf.PMK, 32); RTMPMoveMemory(pAd->StaCfg.WpaPassPhrase, pAd->StaCtIf.WpaPassPhrase, pAd->StaCfg.WpaPassPhraseLen); pAd->StaCfg.WpaPassPhraseLen = pAd->StaCtIf.WpaPassPhraseLen; for (idx = 0; idx < 4; idx++) { NdisMoveMemory(&pAd->SharedKey[BSS0][idx], &pAd->StaCtIf.SharedKey[BSS0][idx], sizeof(CIPHER_KEY)); #ifdef WPA_SUPPLICANT_SUPPORT NdisMoveMemory(&pAd->StaCfg.DesireSharedKey[idx], &pAd->StaCtIf.SharedKey[BSS0][idx], sizeof(CIPHER_KEY)); #endif // WPA_SUPPLICANT_SUPPORT // } 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; } RTMP_SEM_UNLOCK(&pAd->StaCtIf.Lock); DBGPRINT(RT_DEBUG_TRACE, ("<--RecoverConnectInfo()\n")); return 0; } /*STORE THE CONNECT INFO*/ NDIS_STATUS StoreConnectInfo( IN RTMP_ADAPTER *pAd) { INT idx; DBGPRINT(RT_DEBUG_TRACE, ("-->StoreConnectInfo()\n")); RTMP_SEM_LOCK(&pAd->StaCtIf.Lock); pAd->StaCtIf.Changeable = TRUE; pAd->StaCtIf.SsidLen = pAd->CommonCfg.SsidLen; NdisMoveMemory(pAd->StaCtIf.Ssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen); pAd->StaCtIf.AuthMode = pAd->StaCfg.AuthMode; pAd->StaCtIf.WepStatus = pAd->StaCfg.WepStatus; pAd->StaCtIf.DefaultKeyId = pAd->StaCfg.DefaultKeyId; #ifdef WPA_SUPPLICANT_SUPPORT pAd->StaCtIf.DefaultKeyId = pAd->StaCfg.DesireSharedKeyId; pAd->StaCtIf.IEEE8021X = pAd->StaCfg.IEEE8021X; #endif // WPA_SUPPLICANT_SUPPORT // NdisMoveMemory(pAd->StaCtIf.PMK, pAd->StaCfg.PMK, 32); RTMPMoveMemory(pAd->StaCtIf.WpaPassPhrase, pAd->StaCfg.WpaPassPhrase, pAd->StaCfg.WpaPassPhraseLen); pAd->StaCtIf.WpaPassPhraseLen = pAd->StaCfg.WpaPassPhraseLen; for (idx = 0; idx < 4; idx++) { NdisMoveMemory(&pAd->StaCtIf.SharedKey[BSS0][idx], &pAd->SharedKey[BSS0][idx], sizeof(CIPHER_KEY)); } RTMP_SEM_UNLOCK(&pAd->StaCtIf.Lock); DBGPRINT(RT_DEBUG_TRACE, ("<--StoreConnectInfo()\n")); return 0; } #endif /* CREDENTIAL_STORE */ #endif /* CONFIG_STA_SUPPORT */ void RTMPSetCountryCode(RTMP_ADAPTER *pAd, PSTRING CountryCode) { NdisMoveMemory(pAd->CommonCfg.CountryCode, CountryCode , 2); pAd->CommonCfg.CountryCode[2] = ' '; #ifdef CONFIG_STA_SUPPORT #ifdef EXT_BUILD_CHANNEL_LIST IF_DEV_CONFIG_OPMODE_ON_STA(pAd) NdisMoveMemory(pAd->StaCfg.StaOriCountryCode, CountryCode , 2); #endif /* EXT_BUILD_CHANNEL_LIST */ #endif /* CONFIG_STA_SUPPORT */ if (strlen((PSTRING) pAd->CommonCfg.CountryCode) != 0) pAd->CommonCfg.bCountryFlag = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("CountryCode=%s\n", pAd->CommonCfg.CountryCode)); } NDIS_STATUS RTMPSetProfileParameters( IN RTMP_ADAPTER *pAd, IN PSTRING pBuffer) { PSTRING tmpbuf; ULONG RtsThresh; ULONG FragThresh; PSTRING macptr; INT i = 0, retval; /* tmpbuf = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);*/ os_alloc_mem(NULL, (UCHAR **)&tmpbuf, MAX_PARAM_BUFFER_SIZE); if(tmpbuf == NULL) return NDIS_STATUS_FAILURE; do { /* set file parameter to portcfg*/ if (RTMPGetKeyParameter("MacAddress", tmpbuf, 25, pBuffer, TRUE)) { retval = RT_CfgSetMacAddress(pAd, tmpbuf); if (retval) DBGPRINT(RT_DEBUG_TRACE, ("MacAddress = %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(pAd->CurrentAddress))); } /*CountryRegion*/ if(RTMPGetKeyParameter("CountryRegion", tmpbuf, 25, pBuffer, TRUE)) { retval = RT_CfgSetCountryRegion(pAd, tmpbuf, BAND_24G); DBGPRINT(RT_DEBUG_TRACE, ("CountryRegion=%d\n", pAd->CommonCfg.CountryRegion)); } /*CountryRegionABand*/ if(RTMPGetKeyParameter("CountryRegionABand", tmpbuf, 25, pBuffer, TRUE)) { retval = RT_CfgSetCountryRegion(pAd, tmpbuf, BAND_5G); DBGPRINT(RT_DEBUG_TRACE, ("CountryRegionABand=%d\n", pAd->CommonCfg.CountryRegionForABand)); } #ifdef RTMP_EFUSE_SUPPORT #ifdef RT30xx #endif /* RT30xx */ #endif /* RTMP_EFUSE_SUPPORT */ /*CountryCode*/ if (pAd->CommonCfg.bCountryFlag == 0) { if(RTMPGetKeyParameter("CountryCode", tmpbuf, 25, pBuffer, TRUE)) RTMPSetCountryCode(pAd, tmpbuf); } #ifdef EXT_BUILD_CHANNEL_LIST /*ChannelGeography*/ if(RTMPGetKeyParameter("ChannelGeography", tmpbuf, 25, pBuffer, TRUE)) { 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] = ' '; } #endif /* EXT_BUILD_CHANNEL_LIST */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { /*SSID*/ if (RTMPGetKeyParameter("SSID", tmpbuf, 256, pBuffer, FALSE)) { if (strlen(tmpbuf) <= 32) { RTMPSetSTASSID(pAd, tmpbuf); DBGPRINT(RT_DEBUG_TRACE, ("%s::(SSID=%s)\n", __FUNCTION__, tmpbuf)); } } } #endif /* CONFIG_STA_SUPPORT */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { /*NetworkType*/ if (RTMPGetKeyParameter("NetworkType", tmpbuf, 25, pBuffer, TRUE)) { 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", __FUNCTION__, pAd->StaCfg.BssType)); } } #endif /* CONFIG_STA_SUPPORT */ /*Channel*/ if(RTMPGetKeyParameter("Channel", tmpbuf, 10, pBuffer, TRUE)) { pAd->CommonCfg.Channel = (UCHAR) simple_strtol(tmpbuf, 0, 10); DBGPRINT(RT_DEBUG_TRACE, ("Channel=%d\n", pAd->CommonCfg.Channel)); } /*WirelessMode*/ /*Note: BssidNum must be put before WirelessMode in dat file*/ if(RTMPGetKeyParameter("WirelessMode", tmpbuf, 32, pBuffer, TRUE)) { for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++) { if (i == 0) { /* set mode for 1st time */ /* in old design, we also only accept the 1st mode */ RT_CfgSetWirelessMode(pAd, macptr); } } DBGPRINT(RT_DEBUG_TRACE, ("PhyMode=%d\n", pAd->CommonCfg.PhyMode)); } /*BasicRate*/ if(RTMPGetKeyParameter("BasicRate", tmpbuf, 10, pBuffer, TRUE)) { pAd->CommonCfg.BasicRateBitmap = (ULONG) simple_strtol(tmpbuf, 0, 10); pAd->CommonCfg.BasicRateBitmapOld = (ULONG) simple_strtol(tmpbuf, 0, 10); DBGPRINT(RT_DEBUG_TRACE, ("BasicRate=%ld\n", pAd->CommonCfg.BasicRateBitmap)); } /*BeaconPeriod*/ if(RTMPGetKeyParameter("BeaconPeriod", tmpbuf, 10, pBuffer, TRUE)) { USHORT bcn_val = (USHORT) simple_strtol(tmpbuf, 0, 10); /* The acceptable is 20~1000 ms. Refer to WiFi test plan. */ if (bcn_val >= 20 && bcn_val <= 1000) pAd->CommonCfg.BeaconPeriod = bcn_val; else pAd->CommonCfg.BeaconPeriod = 100; /* Default value*/ DBGPRINT(RT_DEBUG_TRACE, ("BeaconPeriod=%d\n", pAd->CommonCfg.BeaconPeriod)); } /*TxPower*/ if(RTMPGetKeyParameter("TxPower", tmpbuf, 10, pBuffer, TRUE)) { 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, pBuffer, TRUE)) { /*#if 0 #ifndef WIFI_TEST*/ /* pAd->CommonCfg.UseBGProtection = 2; disable b/g protection for throughput test*/ /*#else*/ 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; } /*#endif*/ DBGPRINT(RT_DEBUG_TRACE, ("BGProtection=%ld\n", pAd->CommonCfg.UseBGProtection)); } /*TxPreamble*/ if(RTMPGetKeyParameter("TxPreamble", tmpbuf, 10, pBuffer, TRUE)) { 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, pBuffer, TRUE)) { 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, pBuffer, TRUE)) { 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, pBuffer, TRUE)) { /*#ifdef WIFI_TEST*/ /* pAd->CommonCfg.bEnableTxBurst = FALSE;*/ /*#else*/ if(simple_strtol(tmpbuf, 0, 10) != 0) /*Enable*/ pAd->CommonCfg.bEnableTxBurst = TRUE; else /*Disable*/ pAd->CommonCfg.bEnableTxBurst = FALSE; /*#endif*/ DBGPRINT(RT_DEBUG_TRACE, ("TxBurst=%d\n", pAd->CommonCfg.bEnableTxBurst)); } #ifdef AGGREGATION_SUPPORT /*PktAggregate*/ if(RTMPGetKeyParameter("PktAggregate", tmpbuf, 10, pBuffer, TRUE)) { 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, pBuffer); #ifdef XLINK_SUPPORT rtmp_get_psp_xlink_mode_from_file(pAd, tmpbuf, pBuffer); #endif /* XLINK_SUPPORT */ } #endif /* CONFIG_STA_SUPPORT */ /*ShortSlot*/ if(RTMPGetKeyParameter("ShortSlot", tmpbuf, 10, pBuffer, TRUE)) { RT_CfgSetShortSlot(pAd, tmpbuf); DBGPRINT(RT_DEBUG_TRACE, ("ShortSlot=%d\n", pAd->CommonCfg.bUseShortSlotTime)); } #ifdef PRE_ANT_SWITCH /*PreAntSwitch*/ if(RTMPGetKeyParameter("PreAntSwitch", tmpbuf, 32, pBuffer, TRUE)) { pAd->CommonCfg.PreAntSwitch = (simple_strtol(tmpbuf, 0, 10) != 0); DBGPRINT(RT_DEBUG_TRACE, ("PreAntSwitch = %d\n", pAd->CommonCfg.PreAntSwitch)); } #endif /* PRE_ANT_SWITCH */ #ifdef STREAM_MODE_SUPPORT /* StreamMode*/ if (pAd->chipCap.FlgHwStreamMode) { if(RTMPGetKeyParameter("StreamMode", tmpbuf, 32, pBuffer, TRUE)) { pAd->CommonCfg.StreamMode = (simple_strtol(tmpbuf, 0, 10) & 0x03); DBGPRINT(RT_DEBUG_TRACE, ("StreamMode= %d\n", pAd->CommonCfg.StreamMode)); } /* StreamModeMac*/ for (i = 0; i < STREAM_MODE_STA_NUM; i++) { STRING tok_str[32]; sprintf(tok_str, "StreamModeMac%d", i); if (RTMPGetKeyParameter(tok_str, tmpbuf, MAX_PARAM_BUFFER_SIZE, pBuffer, TRUE)) { int j; if(strlen(tmpbuf) != 17) /*Mac address acceptable format 01:02:03:04:05:06 length 17*/ continue; for (j=0; jCommonCfg.StreamModeMac[i][j], 1); tmpbuf=tmpbuf+3; } } } if (NdisEqualMemory(ZERO_MAC_ADDR, &pAd->CommonCfg.StreamModeMac[0][0], MAC_ADDR_LEN)) { /* set default broadcast mac to entry 0 if user not set it */ NdisMoveMemory(&pAd->CommonCfg.StreamModeMac[0][0], BROADCAST_ADDR, MAC_ADDR_LEN); } } #endif /* STREAM_MODE_SUPPORT */ #ifdef DBG_CTRL_SUPPORT /*DebugFlags*/ if(RTMPGetKeyParameter("DebugFlags", tmpbuf, 32, pBuffer, TRUE)) { pAd->CommonCfg.DebugFlags = simple_strtol(tmpbuf, 0, 16); DBGPRINT(RT_DEBUG_TRACE, ("DebugFlags = 0x%02lx\n", pAd->CommonCfg.DebugFlags)); } #endif /* DBG_CTRL_SUPPORT */ /*IEEE80211H*/ if(RTMPGetKeyParameter("IEEE80211H", tmpbuf, 10, pBuffer, TRUE)) { 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)); } } /*RDRegion*/ if(RTMPGetKeyParameter("RDRegion", tmpbuf, 128, pBuffer, TRUE)) { if ((strncmp(tmpbuf, "JAP_W53", 7) == 0) || (strncmp(tmpbuf, "jap_w53", 7) == 0)) { pAd->CommonCfg.RDDurRegion = JAP_W53; /*pRadarDetect->DfsSessionTime = 15;*/ } else if ((strncmp(tmpbuf, "JAP_W56", 7) == 0) || (strncmp(tmpbuf, "jap_w56", 7) == 0)) { pAd->CommonCfg.RDDurRegion = JAP_W56; /*pRadarDetect->DfsSessionTime = 13;*/ } else if ((strncmp(tmpbuf, "JAP", 3) == 0) || (strncmp(tmpbuf, "jap", 3) == 0)) { pAd->CommonCfg.RDDurRegion = JAP; /*pRadarDetect->DfsSessionTime = 5;*/ } else if ((strncmp(tmpbuf, "FCC", 3) == 0) || (strncmp(tmpbuf, "fcc", 3) == 0)) { pAd->CommonCfg.RDDurRegion = FCC; /*pRadarDetect->DfsSessionTime = 5;*/ } else if ((strncmp(tmpbuf, "CE", 2) == 0) || (strncmp(tmpbuf, "ce", 2) == 0)) { pAd->CommonCfg.RDDurRegion = CE; /*pRadarDetect->DfsSessionTime = 13;*/ } else { pAd->CommonCfg.RDDurRegion = CE; /*pRadarDetect->DfsSessionTime = 13;*/ } DBGPRINT(RT_DEBUG_TRACE, ("RDRegion=%d\n", pAd->CommonCfg.RDDurRegion)); } else { pAd->CommonCfg.RDDurRegion = CE; /*pRadarDetect->DfsSessionTime = 13;*/ } #ifdef SYSTEM_LOG_SUPPORT /*WirelessEvent*/ if(RTMPGetKeyParameter("WirelessEvent", tmpbuf, 10, pBuffer, TRUE)) { BOOLEAN FlgIsWEntSup = FALSE; if(simple_strtol(tmpbuf, 0, 10) != 0) FlgIsWEntSup = TRUE; RtmpOsWlanEventSet(pAd, &pAd->CommonCfg.bWirelessEvent, FlgIsWEntSup); DBGPRINT(RT_DEBUG_TRACE, ("WirelessEvent=%d\n", pAd->CommonCfg.bWirelessEvent)); } #endif /* SYSTEM_LOG_SUPPORT */ /*AuthMode*/ if(RTMPGetKeyParameter("AuthMode", tmpbuf, 128, pBuffer, TRUE)) { #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::(AuthMode=%d)\n", __FUNCTION__, pAd->StaCfg.AuthMode)); } #endif /* CONFIG_STA_SUPPORT */ } /*EncrypType*/ if(RTMPGetKeyParameter("EncrypType", tmpbuf, 128, pBuffer, TRUE)) { #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; RTMPSetSTACipherSuites(pAd, pAd->StaCfg.WepStatus); /*RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);*/ DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __FUNCTION__, pAd->StaCfg.WepStatus)); } #endif /* CONFIG_STA_SUPPORT */ } #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { if(RTMPGetKeyParameter("WPAPSK", tmpbuf, 512, pBuffer, FALSE)) RTMPSetSTAPassPhrase(pAd, tmpbuf); } #endif /* CONFIG_STA_SUPPORT */ /*DefaultKeyID, KeyType, KeyStr*/ rtmp_read_key_parms_from_file(pAd, tmpbuf, pBuffer); #ifdef DOT11_N_SUPPORT HTParametersHook(pAd, tmpbuf, pBuffer); #endif /* DOT11_N_SUPPORT */ #ifdef CARRIER_DETECTION_SUPPORT /*CarrierDetect*/ if(RTMPGetKeyParameter("CarrierDetect", tmpbuf, 128, pBuffer, TRUE)) { 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, 10, pBuffer, TRUE)) { 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.*/ 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.*/ 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*/ RTMP_SET_PSM_BIT(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)); } } /* AutoRoaming by RSSI*/ if (RTMPGetKeyParameter("AutoRoaming", tmpbuf, 32, pBuffer, TRUE)) { if (simple_strtol(tmpbuf, 0, 10) == 0) pAd->StaCfg.bAutoRoaming = FALSE; else pAd->StaCfg.bAutoRoaming = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("AutoRoaming=%d\n", pAd->StaCfg.bAutoRoaming)); } /* RoamThreshold*/ if (RTMPGetKeyParameter("RoamThreshold", tmpbuf, 32, pBuffer, TRUE)) { 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, pBuffer, TRUE)) { 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)); } /* Beacon Lost Time*/ if (RTMPGetKeyParameter("BeaconLostTime", tmpbuf, 32, pBuffer, TRUE)) { ULONG lInfo = (ULONG)simple_strtol(tmpbuf, 0, 10); if ((lInfo != 0) && (lInfo <= 60)) pAd->StaCfg.BeaconLostTime = (lInfo * OS_HZ); DBGPRINT(RT_DEBUG_TRACE, ("BeaconLostTime=%ld \n", pAd->StaCfg.BeaconLostTime)); } /* Auto Connet Setting if no SSID */ if (RTMPGetKeyParameter("AutoConnect", tmpbuf, 32, pBuffer, TRUE)) { if (simple_strtol(tmpbuf, 0, 10) == 0) pAd->StaCfg.bAutoConnectIfNoSSID = FALSE; else pAd->StaCfg.bAutoConnectIfNoSSID = TRUE; } /* FastConnect*/ if(RTMPGetKeyParameter("FastConnect", tmpbuf, 32, pBuffer, TRUE)) { if (simple_strtol(tmpbuf, 0, 10) == 0) pAd->StaCfg.bFastConnect = FALSE; else pAd->StaCfg.bFastConnect = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("FastConnect=%d\n", pAd->StaCfg.bFastConnect)); } } #endif /* CONFIG_STA_SUPPORT */ #ifdef RT30xx #endif /* RT30xx */ #ifdef SINGLE_SKU if(RTMPGetKeyParameter("AntGain", tmpbuf, 10, pBuffer, TRUE)) { UCHAR AntGain = simple_strtol(tmpbuf, 0, 10); pAd->CommonCfg.AntGain= AntGain; DBGPRINT(RT_DEBUG_TRACE, ("AntGain=%d\n", pAd->CommonCfg.AntGain)); } if(RTMPGetKeyParameter("BandedgeDelta", tmpbuf, 10, pBuffer, TRUE)) { UCHAR Bandedge = simple_strtol(tmpbuf, 0, 10); pAd->CommonCfg.BandedgeDelta = Bandedge; DBGPRINT(RT_DEBUG_TRACE, ("BandedgeDelta=%d\n", pAd->CommonCfg.BandedgeDelta)); } #endif /* SINGLE_SKU */ }while(0); /* kfree(tmpbuf);*/ os_free_mem(NULL, tmpbuf); return NDIS_STATUS_SUCCESS; } #ifdef MULTIPLE_CARD_SUPPORT /* record whether the card in the card list is used in the card file*/ UINT8 MC_CardUsed[MAX_NUM_OF_MULTIPLE_CARD] = {0}; /* record used card mac address in the card list*/ static UINT8 MC_CardMac[MAX_NUM_OF_MULTIPLE_CARD][6]; BOOLEAN get_mac_from_eeprom(RTMP_ADAPTER *pAd, UCHAR *mac) { USHORT addr, ee_addr; INT idx; for (ee_addr = 0x04, idx = 0; ee_addr <= 0x08; ee_addr += 2, idx +=2) { RT28xx_EEPROM_READ16(pAd, ee_addr, addr); mac[idx] = (UCHAR)(addr & 0xff); mac[idx + 1] = (UCHAR)(addr >> 8); } return TRUE; } #ifdef RTMP_FLASH_SUPPORT #define EEPROM_SEG_IN_NVM 2 /* segments for EEPROM in flash */ #endif /* RTMP_FLASH_SUPPORT */ /* ======================================================================== Routine Description: Get card profile path. Arguments: pAd Return Value: TRUE - Find a card profile FALSE - use default profile Note: ======================================================================== */ BOOLEAN RTMP_CardInfoRead( IN PRTMP_ADAPTER pAd) { #define MC_SELECT_CARDID 0 /* use CARD ID (0 ~ 31) to identify different cards */ #define MC_SELECT_MAC 1 /* use CARD MAC to identify different cards */ #define MC_SELECT_CARDTYPE 2 /* use CARD type (abgn or bgn) to identify different cards */ #define LETTER_CASE_TRANSLATE(txt_p, card_id) \ { UINT32 _len; char _char; \ for(_len=0; _len Error opening %s\n", CARD_INFO_PATH)); goto free_resource; } /* card information file exists so reading the card information */ memset(buffer, 0x00, MAX_INI_BUFFER_SIZE); retval = RtmpOSFileRead(srcf, buffer, MAX_INI_BUFFER_SIZE); if (retval < 0) { /* read fail */ DBGPRINT(RT_DEBUG_TRACE, ("--> Read %s error %d\n", CARD_INFO_PATH, -retval)); } else { /* get card selection method */ memset(tmpbuf, 0x00, MAX_PARAM_BUFFER_SIZE); card_select_method = MC_SELECT_CARDTYPE; /* default*/ if (RTMPGetKeyParameter("SELECT", tmpbuf, 256, buffer, TRUE)) { if (strcmp(tmpbuf, "CARDID") == 0) card_select_method = MC_SELECT_CARDID; else if (strcmp(tmpbuf, "MAC") == 0) card_select_method = MC_SELECT_MAC; else if (strcmp(tmpbuf, "CARDTYPE") == 0) card_select_method = MC_SELECT_CARDTYPE; } DBGPRINT(RT_DEBUG_TRACE, ("MC> Card Selection = %d\n", card_select_method)); /* init*/ card_free_id = -1; card_nouse_id = -1; card_same_mac_id = -1; card_match_id = -1; /* search current card information records*/ for (card_index=0; card_index Free = %d, Same = %d, NOUSE = %d\n", card_free_id, card_same_mac_id, card_nouse_id)); if ((card_same_mac_id >= 0) && ((card_select_method == MC_SELECT_CARDID) || (card_select_method == MC_SELECT_CARDTYPE))) { /* same MAC entry is found*/ card_match_id = card_same_mac_id; if (card_select_method == MC_SELECT_CARDTYPE) { /* for CARDTYPE*/ snprintf(card_id_buf, sizeof(card_id_buf), "%02dCARDTYPE%s", card_match_id, RFIC_word); if ((start_ptr = (PUCHAR)rtstrstruncasecmp(buffer, card_id_buf)) != NULL) { /* we found the card ID*/ LETTER_CASE_TRANSLATE(start_ptr, card_id_buf); } } } else { /* the card is 1st plug-in, try to find the match card profile*/ switch(card_select_method) { case MC_SELECT_CARDID: /* CARDID*/ default: if (card_free_id >= 0) card_match_id = card_free_id; else card_match_id = card_nouse_id; break; case MC_SELECT_MAC: /* MAC*/ #ifdef RTMP_FLASH_SUPPORT memcpy(&mac[0], &mac_maybe[segment][0], MAC_ADDR_LEN); #endif /* RTMP_FLASH_SUPPORT */ snprintf(card_id_buf, sizeof(card_id_buf), "MAC%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); /* try to find the key word in the card file */ if ((start_ptr = (PUCHAR)rtstrstruncasecmp(buffer, card_id_buf)) != NULL) { LETTER_CASE_TRANSLATE(start_ptr, card_id_buf); /* get the row ID (2 ASCII characters) */ start_ptr -= 2; card_id_buf[0] = *(start_ptr); card_id_buf[1] = *(start_ptr+1); card_id_buf[2] = 0x00; card_match_id = simple_strtol(card_id_buf, 0, 10); #ifdef RTMP_FLASH_SUPPORT if (MC_CardUsed[card_match_id] == 1) { /* try again to find the key word in the card file by the other MAC address */ segment += 1; memcpy(&mac[0], &mac_maybe[segment][0], MAC_ADDR_LEN); snprintf(card_id_buf, sizeof(card_id_buf), "MAC%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); if ((start_ptr = (PUCHAR)rtstrstruncasecmp(buffer, card_id_buf)) != NULL) { LETTER_CASE_TRANSLATE(start_ptr, card_id_buf); /* get the row ID (2 ASCII characters) */ start_ptr -= 2; card_id_buf[0] = *(start_ptr); card_id_buf[1] = *(start_ptr+1); card_id_buf[2] = 0x00; card_match_id = simple_strtol(card_id_buf, 0, 10); } } #endif /* RTMP_FLASH_SUPPORT */ } break; case MC_SELECT_CARDTYPE: /* CARDTYPE*/ card_nouse_id = -1; for(card_index=0; card_index= 0) { /* make up search keyword*/ switch(card_select_method) { case MC_SELECT_CARDID: /* CARDID*/ snprintf(card_id_buf, sizeof(card_id_buf), "%02dCARDID", card_match_id); break; case MC_SELECT_MAC: /* MAC*/ snprintf(card_id_buf, sizeof(card_id_buf), "%02dmac%02x:%02x:%02x:%02x:%02x:%02x", card_match_id, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); break; case MC_SELECT_CARDTYPE: /* CARDTYPE*/ default: snprintf(card_id_buf, sizeof(card_id_buf), "%02dcardtype%s", card_match_id, RFIC_word); break; } DBGPRINT(RT_DEBUG_TRACE, ("Search Keyword = %s\n", card_id_buf)); /* read card file path*/ if (RTMPGetKeyParameter(card_id_buf, tmpbuf, 256, buffer, TRUE)) { if (strlen(tmpbuf) < sizeof(pAd->MC_FileName)) { /* backup card information*/ pAd->MC_RowID = card_match_id; /* base 0 */ /* If we are run in Multicard mode, the eeinit shall execute here instead of NICReadEEPROMParameters() */ if (pAd->chipOps.eeinit) pAd->chipOps.eeinit(pAd); get_mac_from_eeprom(pAd, &mac[0]); MC_CardUsed[card_match_id] = 1; memcpy(MC_CardMac[card_match_id], mac, sizeof(mac)); /* backup card file path*/ NdisMoveMemory(pAd->MC_FileName, tmpbuf , strlen(tmpbuf)); pAd->MC_FileName[strlen(tmpbuf)] = '\0'; flg_match_ok = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("Card Profile Name = %s\n", pAd->MC_FileName)); } else { DBGPRINT(RT_DEBUG_ERROR, ("Card Profile Name length too large!\n")); } } else { DBGPRINT(RT_DEBUG_ERROR, ("Can not find search key word in card.dat!\n")); } if ((flg_match_ok != TRUE) && (card_match_id < MAX_NUM_OF_MULTIPLE_CARD)) { MC_CardUsed[card_match_id] = 0; memset(MC_CardMac[card_match_id], 0, sizeof(mac)); } } /* if (card_match_id >= 0)*/ } /* close file*/ retval = RtmpOSFileClose(srcf); free_resource: RtmpOSFSInfoChange(&osFSInfo, FALSE); /* kfree(buffer);*/ /* kfree(tmpbuf);*/ os_free_mem(NULL, buffer); os_free_mem(NULL, tmpbuf); return flg_match_ok; } #endif /* MULTIPLE_CARD_SUPPORT */