1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
10  * This program is free software; you can redistribute it and/or modify  *
11  * it under the terms of the GNU General Public License as published by  *
12  * the Free Software Foundation; either version 2 of the License, or     *
13  * (at your option) any later version.                                   *
14  *                                                                       *
15  * This program is distributed in the hope that it will be useful,       *
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  * GNU General Public License for more details.                          *
19  *                                                                       *
20  * You should have received a copy of the GNU General Public License     *
21  * along with this program; if not, write to the                         *
22  * Free Software Foundation, Inc.,                                       *
23  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24  *                                                                       *
25  *************************************************************************
26 
27     Module Name:
28 	cmm_cfg.c
29 
30     Abstract:
31     Ralink WiFi Driver configuration related subroutines
32 
33     Revision History:
34     Who          When          What
35     ---------    ----------    ----------------------------------------------
36 */
37 
38 #include "../rt_config.h"
39 
GetPhyMode(int Mode)40 char *GetPhyMode(int Mode)
41 {
42 	switch (Mode) {
43 	case MODE_CCK:
44 		return "CCK";
45 
46 	case MODE_OFDM:
47 		return "OFDM";
48 	case MODE_HTMIX:
49 		return "HTMIX";
50 
51 	case MODE_HTGREENFIELD:
52 		return "GREEN";
53 	default:
54 		return "N/A";
55 	}
56 }
57 
GetBW(int BW)58 char *GetBW(int BW)
59 {
60 	switch (BW) {
61 	case BW_10:
62 		return "10M";
63 
64 	case BW_20:
65 		return "20M";
66 	case BW_40:
67 		return "40M";
68 	default:
69 		return "N/A";
70 	}
71 }
72 
73 /*
74     ==========================================================================
75     Description:
76         Set Country Region to pAd->CommonCfg.CountryRegion.
77         This command will not work, if the field of CountryRegion in eeprom is programmed.
78 
79     Return:
80         TRUE if all parameters are OK, FALSE otherwise
81     ==========================================================================
82 */
RT_CfgSetCountryRegion(struct rt_rtmp_adapter * pAd,char * arg,int band)83 int RT_CfgSetCountryRegion(struct rt_rtmp_adapter *pAd, char *arg, int band)
84 {
85 	long region, regionMax;
86 	u8 *pCountryRegion;
87 
88 	region = simple_strtol(arg, 0, 10);
89 
90 	if (band == BAND_24G) {
91 		pCountryRegion = &pAd->CommonCfg.CountryRegion;
92 		regionMax = REGION_MAXIMUM_BG_BAND;
93 	} else {
94 		pCountryRegion = &pAd->CommonCfg.CountryRegionForABand;
95 		regionMax = REGION_MAXIMUM_A_BAND;
96 	}
97 
98 	/* TODO: Is it neccesay for following check??? */
99 	/* Country can be set only when EEPROM not programmed */
100 	if (*pCountryRegion & 0x80) {
101 		DBGPRINT(RT_DEBUG_ERROR,
102 			 ("CfgSetCountryRegion():CountryRegion in eeprom was programmed\n"));
103 		return FALSE;
104 	}
105 
106 	if ((region >= 0) && (region <= REGION_MAXIMUM_BG_BAND)) {
107 		*pCountryRegion = (u8)region;
108 	} else if ((region == REGION_31_BG_BAND) && (band == BAND_24G)) {
109 		*pCountryRegion = (u8)region;
110 	} else {
111 		DBGPRINT(RT_DEBUG_ERROR,
112 			 ("CfgSetCountryRegion():region(%ld) out of range!\n",
113 			  region));
114 		return FALSE;
115 	}
116 
117 	return TRUE;
118 
119 }
120 
121 /*
122     ==========================================================================
123     Description:
124         Set Wireless Mode
125     Return:
126         TRUE if all parameters are OK, FALSE otherwise
127     ==========================================================================
128 */
RT_CfgSetWirelessMode(struct rt_rtmp_adapter * pAd,char * arg)129 int RT_CfgSetWirelessMode(struct rt_rtmp_adapter *pAd, char *arg)
130 {
131 	int MaxPhyMode = PHY_11G;
132 	long WirelessMode;
133 
134 	MaxPhyMode = PHY_11N_5G;
135 
136 	WirelessMode = simple_strtol(arg, 0, 10);
137 	if (WirelessMode <= MaxPhyMode) {
138 		pAd->CommonCfg.PhyMode = WirelessMode;
139 		return TRUE;
140 	}
141 
142 	return FALSE;
143 
144 }
145 
RT_CfgSetShortSlot(struct rt_rtmp_adapter * pAd,char * arg)146 int RT_CfgSetShortSlot(struct rt_rtmp_adapter *pAd, char *arg)
147 {
148 	long ShortSlot;
149 
150 	ShortSlot = simple_strtol(arg, 0, 10);
151 
152 	if (ShortSlot == 1)
153 		pAd->CommonCfg.bUseShortSlotTime = TRUE;
154 	else if (ShortSlot == 0)
155 		pAd->CommonCfg.bUseShortSlotTime = FALSE;
156 	else
157 		return FALSE;	/*Invalid argument */
158 
159 	return TRUE;
160 }
161 
162 /*
163     ==========================================================================
164     Description:
165         Set WEP KEY base on KeyIdx
166     Return:
167         TRUE if all parameters are OK, FALSE otherwise
168     ==========================================================================
169 */
RT_CfgSetWepKey(struct rt_rtmp_adapter * pAd,char * keyString,struct rt_cipher_key * pSharedKey,int keyIdx)170 int RT_CfgSetWepKey(struct rt_rtmp_adapter *pAd,
171 		    char *keyString,
172 		    struct rt_cipher_key *pSharedKey, int keyIdx)
173 {
174 	int KeyLen;
175 	int i;
176 	u8 CipherAlg = CIPHER_NONE;
177 	BOOLEAN bKeyIsHex = FALSE;
178 
179 	/* TODO: Shall we do memset for the original key info?? */
180 	memset(pSharedKey, 0, sizeof(struct rt_cipher_key));
181 	KeyLen = strlen(keyString);
182 	switch (KeyLen) {
183 	case 5:		/*wep 40 Ascii type */
184 	case 13:		/*wep 104 Ascii type */
185 		bKeyIsHex = FALSE;
186 		pSharedKey->KeyLen = KeyLen;
187 		NdisMoveMemory(pSharedKey->Key, keyString, KeyLen);
188 		break;
189 
190 	case 10:		/*wep 40 Hex type */
191 	case 26:		/*wep 104 Hex type */
192 		for (i = 0; i < KeyLen; i++) {
193 			if (!isxdigit(*(keyString + i)))
194 				return FALSE;	/*Not Hex value; */
195 		}
196 		bKeyIsHex = TRUE;
197 		pSharedKey->KeyLen = KeyLen / 2;
198 		AtoH(keyString, pSharedKey->Key, pSharedKey->KeyLen);
199 		break;
200 
201 	default:		/*Invalid argument */
202 		DBGPRINT(RT_DEBUG_TRACE,
203 			 ("RT_CfgSetWepKey(keyIdx=%d):Invalid argument (arg=%s)\n",
204 			  keyIdx, keyString));
205 		return FALSE;
206 	}
207 
208 	pSharedKey->CipherAlg = ((KeyLen % 5) ? CIPHER_WEP128 : CIPHER_WEP64);
209 	DBGPRINT(RT_DEBUG_TRACE,
210 		 ("RT_CfgSetWepKey:(KeyIdx=%d,type=%s, Alg=%s)\n", keyIdx,
211 		  (bKeyIsHex == FALSE ? "Ascii" : "Hex"),
212 		  CipherName[CipherAlg]));
213 
214 	return TRUE;
215 }
216 
217 /*
218     ==========================================================================
219     Description:
220         Set WPA PSK key
221 
222     Arguments:
223         pAdapter	Pointer to our adapter
224         keyString	WPA pre-shared key string
225         pHashStr	String used for password hash function
226         hashStrLen	Length of the hash string
227         pPMKBuf		Output buffer of WPAPSK key
228 
229     Return:
230         TRUE if all parameters are OK, FALSE otherwise
231     ==========================================================================
232 */
RT_CfgSetWPAPSKKey(struct rt_rtmp_adapter * pAd,char * keyString,u8 * pHashStr,int hashStrLen,u8 * pPMKBuf)233 int RT_CfgSetWPAPSKKey(struct rt_rtmp_adapter *pAd,
234 		       char *keyString,
235 		       u8 * pHashStr,
236 		       int hashStrLen, u8 *pPMKBuf)
237 {
238 	int keyLen;
239 	u8 keyMaterial[40];
240 
241 	keyLen = strlen(keyString);
242 	if ((keyLen < 8) || (keyLen > 64)) {
243 		DBGPRINT(RT_DEBUG_TRACE,
244 			 ("WPAPSK Key length(%d) error, required 8 ~ 64 characters!(keyStr=%s)\n",
245 			  keyLen, keyString));
246 		return FALSE;
247 	}
248 
249 	memset(pPMKBuf, 0, 32);
250 	if (keyLen == 64) {
251 		AtoH(keyString, pPMKBuf, 32);
252 	} else {
253 		PasswordHash(keyString, pHashStr, hashStrLen, keyMaterial);
254 		NdisMoveMemory(pPMKBuf, keyMaterial, 32);
255 	}
256 
257 	return TRUE;
258 }
259