• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/staging/rt2860/common/
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify  *
11 * it under the terms of the GNU General Public License as published by  *
12 * the Free Software Foundation; either version 2 of the License, or     *
13 * (at your option) any later version.                                   *
14 *                                                                       *
15 * This program is distributed in the hope that it will be useful,       *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18 * GNU General Public License for more details.                          *
19 *                                                                       *
20 * You should have received a copy of the GNU General Public License     *
21 * along with this program; if not, write to the                         *
22 * Free Software Foundation, Inc.,                                       *
23 * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
24 *                                                                       *
25 *************************************************************************
26 */
27
28#include <linux/sched.h>
29#include "../rt_config.h"
30
31/*
32	========================================================================
33
34	Routine Description:
35		Remove WPA Key process
36
37	Arguments:
38		pAd 					Pointer to our adapter
39		pBuf							Pointer to the where the key stored
40
41	Return Value:
42		NDIS_SUCCESS					Add key successfully
43
44	IRQL = DISPATCH_LEVEL
45
46	Note:
47
48	========================================================================
49*/
50void RTMPSetDesiredRates(struct rt_rtmp_adapter *pAdapter, long Rates)
51{
52	NDIS_802_11_RATES aryRates;
53
54	memset(&aryRates, 0x00, sizeof(NDIS_802_11_RATES));
55	switch (pAdapter->CommonCfg.PhyMode) {
56	case PHY_11A:		/* A only */
57		switch (Rates) {
58		case 6000000:	/*6M */
59			aryRates[0] = 0x0c;	/* 6M */
60			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
61			    MCS_0;
62			break;
63		case 9000000:	/*9M */
64			aryRates[0] = 0x12;	/* 9M */
65			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
66			    MCS_1;
67			break;
68		case 12000000:	/*12M */
69			aryRates[0] = 0x18;	/* 12M */
70			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
71			    MCS_2;
72			break;
73		case 18000000:	/*18M */
74			aryRates[0] = 0x24;	/* 18M */
75			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
76			    MCS_3;
77			break;
78		case 24000000:	/*24M */
79			aryRates[0] = 0x30;	/* 24M */
80			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
81			    MCS_4;
82			break;
83		case 36000000:	/*36M */
84			aryRates[0] = 0x48;	/* 36M */
85			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
86			    MCS_5;
87			break;
88		case 48000000:	/*48M */
89			aryRates[0] = 0x60;	/* 48M */
90			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
91			    MCS_6;
92			break;
93		case 54000000:	/*54M */
94			aryRates[0] = 0x6c;	/* 54M */
95			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
96			    MCS_7;
97			break;
98		case -1:	/*Auto */
99		default:
100			aryRates[0] = 0x6c;	/* 54Mbps */
101			aryRates[1] = 0x60;	/* 48Mbps */
102			aryRates[2] = 0x48;	/* 36Mbps */
103			aryRates[3] = 0x30;	/* 24Mbps */
104			aryRates[4] = 0x24;	/* 18M */
105			aryRates[5] = 0x18;	/* 12M */
106			aryRates[6] = 0x12;	/* 9M */
107			aryRates[7] = 0x0c;	/* 6M */
108			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
109			    MCS_AUTO;
110			break;
111		}
112		break;
113	case PHY_11BG_MIXED:	/* B/G Mixed */
114	case PHY_11B:		/* B only */
115	case PHY_11ABG_MIXED:	/* A/B/G Mixed */
116	default:
117		switch (Rates) {
118		case 1000000:	/*1M */
119			aryRates[0] = 0x02;
120			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
121			    MCS_0;
122			break;
123		case 2000000:	/*2M */
124			aryRates[0] = 0x04;
125			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
126			    MCS_1;
127			break;
128		case 5000000:	/*5.5M */
129			aryRates[0] = 0x0b;	/* 5.5M */
130			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
131			    MCS_2;
132			break;
133		case 11000000:	/*11M */
134			aryRates[0] = 0x16;	/* 11M */
135			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
136			    MCS_3;
137			break;
138		case 6000000:	/*6M */
139			aryRates[0] = 0x0c;	/* 6M */
140			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
141			    MCS_0;
142			break;
143		case 9000000:	/*9M */
144			aryRates[0] = 0x12;	/* 9M */
145			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
146			    MCS_1;
147			break;
148		case 12000000:	/*12M */
149			aryRates[0] = 0x18;	/* 12M */
150			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
151			    MCS_2;
152			break;
153		case 18000000:	/*18M */
154			aryRates[0] = 0x24;	/* 18M */
155			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
156			    MCS_3;
157			break;
158		case 24000000:	/*24M */
159			aryRates[0] = 0x30;	/* 24M */
160			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
161			    MCS_4;
162			break;
163		case 36000000:	/*36M */
164			aryRates[0] = 0x48;	/* 36M */
165			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
166			    MCS_5;
167			break;
168		case 48000000:	/*48M */
169			aryRates[0] = 0x60;	/* 48M */
170			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
171			    MCS_6;
172			break;
173		case 54000000:	/*54M */
174			aryRates[0] = 0x6c;	/* 54M */
175			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
176			    MCS_7;
177			break;
178		case -1:	/*Auto */
179		default:
180			if (pAdapter->CommonCfg.PhyMode == PHY_11B) {	/*B Only */
181				aryRates[0] = 0x16;	/* 11Mbps */
182				aryRates[1] = 0x0b;	/* 5.5Mbps */
183				aryRates[2] = 0x04;	/* 2Mbps */
184				aryRates[3] = 0x02;	/* 1Mbps */
185			} else {	/*(B/G) Mixed or (A/B/G) Mixed */
186				aryRates[0] = 0x6c;	/* 54Mbps */
187				aryRates[1] = 0x60;	/* 48Mbps */
188				aryRates[2] = 0x48;	/* 36Mbps */
189				aryRates[3] = 0x30;	/* 24Mbps */
190				aryRates[4] = 0x16;	/* 11Mbps */
191				aryRates[5] = 0x0b;	/* 5.5Mbps */
192				aryRates[6] = 0x04;	/* 2Mbps */
193				aryRates[7] = 0x02;	/* 1Mbps */
194			}
195			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
196			    MCS_AUTO;
197			break;
198		}
199		break;
200	}
201
202	NdisZeroMemory(pAdapter->CommonCfg.DesireRate,
203		       MAX_LEN_OF_SUPPORTED_RATES);
204	NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates,
205		       sizeof(NDIS_802_11_RATES));
206	DBGPRINT(RT_DEBUG_TRACE,
207		 (" RTMPSetDesiredRates (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
208		  pAdapter->CommonCfg.DesireRate[0],
209		  pAdapter->CommonCfg.DesireRate[1],
210		  pAdapter->CommonCfg.DesireRate[2],
211		  pAdapter->CommonCfg.DesireRate[3],
212		  pAdapter->CommonCfg.DesireRate[4],
213		  pAdapter->CommonCfg.DesireRate[5],
214		  pAdapter->CommonCfg.DesireRate[6],
215		  pAdapter->CommonCfg.DesireRate[7]));
216	/* Changing DesiredRate may affect the MAX TX rate we used to TX frames out */
217	MlmeUpdateTxRates(pAdapter, FALSE, 0);
218}
219
220/*
221	========================================================================
222
223	Routine Description:
224		Remove All WPA Keys
225
226	Arguments:
227		pAd 					Pointer to our adapter
228
229	Return Value:
230		None
231
232	IRQL = DISPATCH_LEVEL
233
234	Note:
235
236	========================================================================
237*/
238void RTMPWPARemoveAllKeys(struct rt_rtmp_adapter *pAd)
239{
240
241	u8 i;
242
243	DBGPRINT(RT_DEBUG_TRACE,
244		 ("RTMPWPARemoveAllKeys(AuthMode=%d, WepStatus=%d)\n",
245		  pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus));
246	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
247	/* For WEP/CKIP, there is no need to remove it, since WinXP won't set it again after */
248	/* Link up. And it will be replaced if user changed it. */
249	if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
250		return;
251
252	/* For WPA-None, there is no need to remove it, since WinXP won't set it again after */
253	/* Link up. And it will be replaced if user changed it. */
254	if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
255		return;
256
257	/* set BSSID wcid entry of the Pair-wise Key table as no-security mode */
258	AsicRemovePairwiseKeyEntry(pAd, BSS0, BSSID_WCID);
259
260	/* set all shared key mode as no-security. */
261	for (i = 0; i < SHARE_KEY_NUM; i++) {
262		DBGPRINT(RT_DEBUG_TRACE,
263			 ("remove %s key #%d\n",
264			  CipherName[pAd->SharedKey[BSS0][i].CipherAlg], i));
265		NdisZeroMemory(&pAd->SharedKey[BSS0][i], sizeof(struct rt_cipher_key));
266
267		AsicRemoveSharedKeyEntry(pAd, BSS0, i);
268	}
269	RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
270}
271
272/*
273	========================================================================
274
275	Routine Description:
276		As STA's BSSID is a WC too, it uses shared key table.
277		This function write correct unicast TX key to ASIC WCID.
278		And we still make a copy in our MacTab.Content[BSSID_WCID].PairwiseKey.
279		Caller guarantee TKIP/AES always has keyidx = 0. (pairwise key)
280		Caller guarantee WEP calls this function when set Txkey,  default key index=0~3.
281
282	Arguments:
283		pAd					Pointer to our adapter
284		pKey							Pointer to the where the key stored
285
286	Return Value:
287		NDIS_SUCCESS					Add key successfully
288
289	IRQL = DISPATCH_LEVEL
290
291	Note:
292
293	========================================================================
294*/
295/*
296	========================================================================
297	Routine Description:
298		Change NIC PHY mode. Re-association may be necessary. possible settings
299		include - PHY_11B, PHY_11BG_MIXED, PHY_11A, and PHY_11ABG_MIXED
300
301	Arguments:
302		pAd - Pointer to our adapter
303		phymode  -
304
305	IRQL = PASSIVE_LEVEL
306	IRQL = DISPATCH_LEVEL
307
308	========================================================================
309*/
310void RTMPSetPhyMode(struct rt_rtmp_adapter *pAd, unsigned long phymode)
311{
312	int i;
313	/* the selected phymode must be supported by the RF IC encoded in E2PROM */
314
315	/* if no change, do nothing */
316	/* bug fix
317	   if (pAd->CommonCfg.PhyMode == phymode)
318	   return;
319	 */
320	pAd->CommonCfg.PhyMode = (u8)phymode;
321
322	DBGPRINT(RT_DEBUG_TRACE,
323		 ("RTMPSetPhyMode : PhyMode=%d, channel=%d \n",
324		  pAd->CommonCfg.PhyMode, pAd->CommonCfg.Channel));
325
326	BuildChannelList(pAd);
327
328	/* sanity check user setting */
329	for (i = 0; i < pAd->ChannelListNum; i++) {
330		if (pAd->CommonCfg.Channel == pAd->ChannelList[i].Channel)
331			break;
332	}
333
334	if (i == pAd->ChannelListNum) {
335		pAd->CommonCfg.Channel = FirstChannel(pAd);
336		DBGPRINT(RT_DEBUG_ERROR,
337			 ("RTMPSetPhyMode: channel is out of range, use first channel=%d \n",
338			  pAd->CommonCfg.Channel));
339	}
340
341	NdisZeroMemory(pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
342	NdisZeroMemory(pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
343	NdisZeroMemory(pAd->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
344	switch (phymode) {
345	case PHY_11B:
346		pAd->CommonCfg.SupRate[0] = 0x82;	/* 1 mbps, in units of 0.5 Mbps, basic rate */
347		pAd->CommonCfg.SupRate[1] = 0x84;	/* 2 mbps, in units of 0.5 Mbps, basic rate */
348		pAd->CommonCfg.SupRate[2] = 0x8B;	/* 5.5 mbps, in units of 0.5 Mbps, basic rate */
349		pAd->CommonCfg.SupRate[3] = 0x96;	/* 11 mbps, in units of 0.5 Mbps, basic rate */
350		pAd->CommonCfg.SupRateLen = 4;
351		pAd->CommonCfg.ExtRateLen = 0;
352		pAd->CommonCfg.DesireRate[0] = 2;	/* 1 mbps, in units of 0.5 Mbps */
353		pAd->CommonCfg.DesireRate[1] = 4;	/* 2 mbps, in units of 0.5 Mbps */
354		pAd->CommonCfg.DesireRate[2] = 11;	/* 5.5 mbps, in units of 0.5 Mbps */
355		pAd->CommonCfg.DesireRate[3] = 22;	/* 11 mbps, in units of 0.5 Mbps */
356		/*pAd->CommonCfg.HTPhyMode.field.MODE = MODE_CCK; // This MODE is only FYI. not use */
357		break;
358
359	case PHY_11G:
360	case PHY_11BG_MIXED:
361	case PHY_11ABG_MIXED:
362	case PHY_11N_2_4G:
363	case PHY_11ABGN_MIXED:
364	case PHY_11BGN_MIXED:
365	case PHY_11GN_MIXED:
366		pAd->CommonCfg.SupRate[0] = 0x82;	/* 1 mbps, in units of 0.5 Mbps, basic rate */
367		pAd->CommonCfg.SupRate[1] = 0x84;	/* 2 mbps, in units of 0.5 Mbps, basic rate */
368		pAd->CommonCfg.SupRate[2] = 0x8B;	/* 5.5 mbps, in units of 0.5 Mbps, basic rate */
369		pAd->CommonCfg.SupRate[3] = 0x96;	/* 11 mbps, in units of 0.5 Mbps, basic rate */
370		pAd->CommonCfg.SupRate[4] = 0x12;	/* 9 mbps, in units of 0.5 Mbps */
371		pAd->CommonCfg.SupRate[5] = 0x24;	/* 18 mbps, in units of 0.5 Mbps */
372		pAd->CommonCfg.SupRate[6] = 0x48;	/* 36 mbps, in units of 0.5 Mbps */
373		pAd->CommonCfg.SupRate[7] = 0x6c;	/* 54 mbps, in units of 0.5 Mbps */
374		pAd->CommonCfg.SupRateLen = 8;
375		pAd->CommonCfg.ExtRate[0] = 0x0C;	/* 6 mbps, in units of 0.5 Mbps */
376		pAd->CommonCfg.ExtRate[1] = 0x18;	/* 12 mbps, in units of 0.5 Mbps */
377		pAd->CommonCfg.ExtRate[2] = 0x30;	/* 24 mbps, in units of 0.5 Mbps */
378		pAd->CommonCfg.ExtRate[3] = 0x60;	/* 48 mbps, in units of 0.5 Mbps */
379		pAd->CommonCfg.ExtRateLen = 4;
380		pAd->CommonCfg.DesireRate[0] = 2;	/* 1 mbps, in units of 0.5 Mbps */
381		pAd->CommonCfg.DesireRate[1] = 4;	/* 2 mbps, in units of 0.5 Mbps */
382		pAd->CommonCfg.DesireRate[2] = 11;	/* 5.5 mbps, in units of 0.5 Mbps */
383		pAd->CommonCfg.DesireRate[3] = 22;	/* 11 mbps, in units of 0.5 Mbps */
384		pAd->CommonCfg.DesireRate[4] = 12;	/* 6 mbps, in units of 0.5 Mbps */
385		pAd->CommonCfg.DesireRate[5] = 18;	/* 9 mbps, in units of 0.5 Mbps */
386		pAd->CommonCfg.DesireRate[6] = 24;	/* 12 mbps, in units of 0.5 Mbps */
387		pAd->CommonCfg.DesireRate[7] = 36;	/* 18 mbps, in units of 0.5 Mbps */
388		pAd->CommonCfg.DesireRate[8] = 48;	/* 24 mbps, in units of 0.5 Mbps */
389		pAd->CommonCfg.DesireRate[9] = 72;	/* 36 mbps, in units of 0.5 Mbps */
390		pAd->CommonCfg.DesireRate[10] = 96;	/* 48 mbps, in units of 0.5 Mbps */
391		pAd->CommonCfg.DesireRate[11] = 108;	/* 54 mbps, in units of 0.5 Mbps */
392		break;
393
394	case PHY_11A:
395	case PHY_11AN_MIXED:
396	case PHY_11AGN_MIXED:
397	case PHY_11N_5G:
398		pAd->CommonCfg.SupRate[0] = 0x8C;	/* 6 mbps, in units of 0.5 Mbps, basic rate */
399		pAd->CommonCfg.SupRate[1] = 0x12;	/* 9 mbps, in units of 0.5 Mbps */
400		pAd->CommonCfg.SupRate[2] = 0x98;	/* 12 mbps, in units of 0.5 Mbps, basic rate */
401		pAd->CommonCfg.SupRate[3] = 0x24;	/* 18 mbps, in units of 0.5 Mbps */
402		pAd->CommonCfg.SupRate[4] = 0xb0;	/* 24 mbps, in units of 0.5 Mbps, basic rate */
403		pAd->CommonCfg.SupRate[5] = 0x48;	/* 36 mbps, in units of 0.5 Mbps */
404		pAd->CommonCfg.SupRate[6] = 0x60;	/* 48 mbps, in units of 0.5 Mbps */
405		pAd->CommonCfg.SupRate[7] = 0x6c;	/* 54 mbps, in units of 0.5 Mbps */
406		pAd->CommonCfg.SupRateLen = 8;
407		pAd->CommonCfg.ExtRateLen = 0;
408		pAd->CommonCfg.DesireRate[0] = 12;	/* 6 mbps, in units of 0.5 Mbps */
409		pAd->CommonCfg.DesireRate[1] = 18;	/* 9 mbps, in units of 0.5 Mbps */
410		pAd->CommonCfg.DesireRate[2] = 24;	/* 12 mbps, in units of 0.5 Mbps */
411		pAd->CommonCfg.DesireRate[3] = 36;	/* 18 mbps, in units of 0.5 Mbps */
412		pAd->CommonCfg.DesireRate[4] = 48;	/* 24 mbps, in units of 0.5 Mbps */
413		pAd->CommonCfg.DesireRate[5] = 72;	/* 36 mbps, in units of 0.5 Mbps */
414		pAd->CommonCfg.DesireRate[6] = 96;	/* 48 mbps, in units of 0.5 Mbps */
415		pAd->CommonCfg.DesireRate[7] = 108;	/* 54 mbps, in units of 0.5 Mbps */
416		/*pAd->CommonCfg.HTPhyMode.field.MODE = MODE_OFDM; // This MODE is only FYI. not use */
417		break;
418
419	default:
420		break;
421	}
422
423	pAd->CommonCfg.BandState = UNKNOWN_BAND;
424}
425
426/*
427	========================================================================
428	Routine Description:
429		Caller ensures we has 802.11n support.
430		Calls at setting HT from AP/STASetinformation
431
432	Arguments:
433		pAd - Pointer to our adapter
434		phymode  -
435
436	========================================================================
437*/
438void RTMPSetHT(struct rt_rtmp_adapter *pAd, struct rt_oid_set_ht_phymode *pHTPhyMode)
439{
440	/*unsigned long *pmcs; */
441	u32 Value = 0;
442	u8 BBPValue = 0;
443	u8 BBP3Value = 0;
444	u8 RxStream = pAd->CommonCfg.RxStream;
445
446	DBGPRINT(RT_DEBUG_TRACE,
447		 ("RTMPSetHT : HT_mode(%d), ExtOffset(%d), MCS(%d), BW(%d), STBC(%d), SHORTGI(%d)\n",
448		  pHTPhyMode->HtMode, pHTPhyMode->ExtOffset, pHTPhyMode->MCS,
449		  pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->SHORTGI));
450
451	/* Don't zero supportedHyPhy structure. */
452	RTMPZeroMemory(&pAd->CommonCfg.HtCapability,
453		       sizeof(pAd->CommonCfg.HtCapability));
454	RTMPZeroMemory(&pAd->CommonCfg.AddHTInfo,
455		       sizeof(pAd->CommonCfg.AddHTInfo));
456	RTMPZeroMemory(&pAd->CommonCfg.NewExtChanOffset,
457		       sizeof(pAd->CommonCfg.NewExtChanOffset));
458	RTMPZeroMemory(&pAd->CommonCfg.DesiredHtPhy,
459		       sizeof(pAd->CommonCfg.DesiredHtPhy));
460
461	if (pAd->CommonCfg.bRdg) {
462		pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 1;
463		pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 1;
464	} else {
465		pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 0;
466		pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 0;
467	}
468
469	pAd->CommonCfg.HtCapability.HtCapParm.MaxRAmpduFactor = 3;
470	pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor = 3;
471
472	DBGPRINT(RT_DEBUG_TRACE,
473		 ("RTMPSetHT : RxBAWinLimit = %d\n",
474		  pAd->CommonCfg.BACapability.field.RxBAWinLimit));
475
476	/* Mimo power save, A-MSDU size, */
477	pAd->CommonCfg.DesiredHtPhy.AmsduEnable =
478	    (u16)pAd->CommonCfg.BACapability.field.AmsduEnable;
479	pAd->CommonCfg.DesiredHtPhy.AmsduSize =
480	    (u8)pAd->CommonCfg.BACapability.field.AmsduSize;
481	pAd->CommonCfg.DesiredHtPhy.MimoPs =
482	    (u8)pAd->CommonCfg.BACapability.field.MMPSmode;
483	pAd->CommonCfg.DesiredHtPhy.MpduDensity =
484	    (u8)pAd->CommonCfg.BACapability.field.MpduDensity;
485
486	pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize =
487	    (u16)pAd->CommonCfg.BACapability.field.AmsduSize;
488	pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs =
489	    (u16)pAd->CommonCfg.BACapability.field.MMPSmode;
490	pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity =
491	    (u8)pAd->CommonCfg.BACapability.field.MpduDensity;
492
493	DBGPRINT(RT_DEBUG_TRACE,
494		 ("RTMPSetHT : AMsduSize = %d, MimoPs = %d, MpduDensity = %d, MaxRAmpduFactor = %d\n",
495		  pAd->CommonCfg.DesiredHtPhy.AmsduSize,
496		  pAd->CommonCfg.DesiredHtPhy.MimoPs,
497		  pAd->CommonCfg.DesiredHtPhy.MpduDensity,
498		  pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor));
499
500	if (pHTPhyMode->HtMode == HTMODE_GF) {
501		pAd->CommonCfg.HtCapability.HtCapInfo.GF = 1;
502		pAd->CommonCfg.DesiredHtPhy.GF = 1;
503	} else
504		pAd->CommonCfg.DesiredHtPhy.GF = 0;
505
506	/* Decide Rx MCSSet */
507	switch (RxStream) {
508	case 1:
509		pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
510		pAd->CommonCfg.HtCapability.MCSSet[1] = 0x00;
511		break;
512
513	case 2:
514		pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
515		pAd->CommonCfg.HtCapability.MCSSet[1] = 0xff;
516		break;
517
518	case 3:		/* 3*3 */
519		pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
520		pAd->CommonCfg.HtCapability.MCSSet[1] = 0xff;
521		pAd->CommonCfg.HtCapability.MCSSet[2] = 0xff;
522		break;
523	}
524
525	if (pAd->CommonCfg.bForty_Mhz_Intolerant
526	    && (pAd->CommonCfg.Channel <= 14) && (pHTPhyMode->BW == BW_40)) {
527		pHTPhyMode->BW = BW_20;
528		pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant = 1;
529	}
530
531	if (pHTPhyMode->BW == BW_40) {
532		pAd->CommonCfg.HtCapability.MCSSet[4] = 0x1;	/* MCS 32 */
533		pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 1;
534		if (pAd->CommonCfg.Channel <= 14)
535			pAd->CommonCfg.HtCapability.HtCapInfo.CCKmodein40 = 1;
536
537		pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 1;
538		pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 1;
539		pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset =
540		    (pHTPhyMode->ExtOffset ==
541		     EXTCHA_BELOW) ? (EXTCHA_BELOW) : EXTCHA_ABOVE;
542		/* Set Regsiter for extension channel position. */
543		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
544		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBP3Value);
545		if ((pHTPhyMode->ExtOffset == EXTCHA_BELOW)) {
546			Value |= 0x1;
547			BBP3Value |= (0x20);
548			RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
549		} else if ((pHTPhyMode->ExtOffset == EXTCHA_ABOVE)) {
550			Value &= 0xfe;
551			BBP3Value &= (~0x20);
552			RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
553		}
554		/* Turn on BBP 40MHz mode now only as AP . */
555		/* Sta can turn on BBP 40MHz after connection with 40MHz AP. Sta only broadcast 40MHz capability before connection. */
556		if ((pAd->OpMode == OPMODE_AP) || INFRA_ON(pAd) || ADHOC_ON(pAd)
557		    ) {
558			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
559			BBPValue &= (~0x18);
560			BBPValue |= 0x10;
561			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
562
563			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBP3Value);
564			pAd->CommonCfg.BBPCurrentBW = BW_40;
565		}
566	} else {
567		pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 0;
568		pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 0;
569		pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0;
570		pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = EXTCHA_NONE;
571		pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
572		/* Turn on BBP 20MHz mode by request here. */
573		{
574			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
575			BBPValue &= (~0x18);
576			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
577			pAd->CommonCfg.BBPCurrentBW = BW_20;
578		}
579	}
580
581	if (pHTPhyMode->STBC == STBC_USE) {
582		pAd->CommonCfg.HtCapability.HtCapInfo.TxSTBC = 1;
583		pAd->CommonCfg.DesiredHtPhy.TxSTBC = 1;
584		pAd->CommonCfg.HtCapability.HtCapInfo.RxSTBC = 1;
585		pAd->CommonCfg.DesiredHtPhy.RxSTBC = 1;
586	} else {
587		pAd->CommonCfg.DesiredHtPhy.TxSTBC = 0;
588		pAd->CommonCfg.DesiredHtPhy.RxSTBC = 0;
589	}
590
591	if (pHTPhyMode->SHORTGI == GI_400) {
592		pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 1;
593		pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 1;
594		pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 1;
595		pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 1;
596	} else {
597		pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 0;
598		pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 0;
599		pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 0;
600		pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 0;
601	}
602
603	/* We support link adaptation for unsolicit MCS feedback, set to 2. */
604	pAd->CommonCfg.HtCapability.ExtHtCapInfo.MCSFeedback = MCSFBK_NONE;	/*MCSFBK_UNSOLICIT; */
605	pAd->CommonCfg.AddHTInfo.ControlChan = pAd->CommonCfg.Channel;
606	/* 1, the extension channel above the control channel. */
607
608	/* EDCA parameters used for AP's own transmission */
609	if (pAd->CommonCfg.APEdcaParm.bValid == FALSE) {
610		pAd->CommonCfg.APEdcaParm.bValid = TRUE;
611		pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
612		pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
613		pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
614		pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
615
616		pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
617		pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
618		pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
619		pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
620
621		pAd->CommonCfg.APEdcaParm.Cwmax[0] = 6;
622		pAd->CommonCfg.APEdcaParm.Cwmax[1] = 10;
623		pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
624		pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
625
626		pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
627		pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
628		pAd->CommonCfg.APEdcaParm.Txop[2] = 94;
629		pAd->CommonCfg.APEdcaParm.Txop[3] = 47;
630	}
631	AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
632
633	{
634		RTMPSetIndividualHT(pAd, 0);
635	}
636
637}
638
639/*
640	========================================================================
641	Routine Description:
642		Caller ensures we has 802.11n support.
643		Calls at setting HT from AP/STASetinformation
644
645	Arguments:
646		pAd - Pointer to our adapter
647		phymode  -
648
649	========================================================================
650*/
651void RTMPSetIndividualHT(struct rt_rtmp_adapter *pAd, u8 apidx)
652{
653	struct rt_ht_phy_info *pDesired_ht_phy = NULL;
654	u8 TxStream = pAd->CommonCfg.TxStream;
655	u8 DesiredMcs = MCS_AUTO;
656
657	do {
658		{
659			pDesired_ht_phy = &pAd->StaCfg.DesiredHtPhyInfo;
660			DesiredMcs =
661			    pAd->StaCfg.DesiredTransmitSetting.field.MCS;
662			/*pAd->StaCfg.bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE; */
663			break;
664		}
665	} while (FALSE);
666
667	if (pDesired_ht_phy == NULL) {
668		DBGPRINT(RT_DEBUG_ERROR,
669			 ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx));
670		return;
671	}
672	RTMPZeroMemory(pDesired_ht_phy, sizeof(struct rt_ht_phy_info));
673
674	DBGPRINT(RT_DEBUG_TRACE,
675		 ("RTMPSetIndividualHT : Desired MCS = %d\n", DesiredMcs));
676	/* Check the validity of MCS */
677	if ((TxStream == 1)
678	    && ((DesiredMcs >= MCS_8) && (DesiredMcs <= MCS_15))) {
679		DBGPRINT(RT_DEBUG_WARN,
680			 ("RTMPSetIndividualHT: MCS(%d) is invalid in 1S, reset it as MCS_7\n",
681			  DesiredMcs));
682		DesiredMcs = MCS_7;
683	}
684
685	if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_20)
686	    && (DesiredMcs == MCS_32)) {
687		DBGPRINT(RT_DEBUG_WARN,
688			 ("RTMPSetIndividualHT: MCS_32 is only supported in 40-MHz, reset it as MCS_0\n"));
689		DesiredMcs = MCS_0;
690	}
691
692	pDesired_ht_phy->bHtEnable = TRUE;
693
694	/* Decide desired Tx MCS */
695	switch (TxStream) {
696	case 1:
697		if (DesiredMcs == MCS_AUTO) {
698			pDesired_ht_phy->MCSSet[0] = 0xff;
699			pDesired_ht_phy->MCSSet[1] = 0x00;
700		} else if (DesiredMcs <= MCS_7) {
701			pDesired_ht_phy->MCSSet[0] = 1 << DesiredMcs;
702			pDesired_ht_phy->MCSSet[1] = 0x00;
703		}
704		break;
705
706	case 2:
707		if (DesiredMcs == MCS_AUTO) {
708			pDesired_ht_phy->MCSSet[0] = 0xff;
709			pDesired_ht_phy->MCSSet[1] = 0xff;
710		} else if (DesiredMcs <= MCS_15) {
711			unsigned long mode;
712
713			mode = DesiredMcs / 8;
714			if (mode < 2)
715				pDesired_ht_phy->MCSSet[mode] =
716				    (1 << (DesiredMcs - mode * 8));
717		}
718		break;
719
720	case 3:		/* 3*3 */
721		if (DesiredMcs == MCS_AUTO) {
722			/* MCS0 ~ MCS23, 3 bytes */
723			pDesired_ht_phy->MCSSet[0] = 0xff;
724			pDesired_ht_phy->MCSSet[1] = 0xff;
725			pDesired_ht_phy->MCSSet[2] = 0xff;
726		} else if (DesiredMcs <= MCS_23) {
727			unsigned long mode;
728
729			mode = DesiredMcs / 8;
730			if (mode < 3)
731				pDesired_ht_phy->MCSSet[mode] =
732				    (1 << (DesiredMcs - mode * 8));
733		}
734		break;
735	}
736
737	if (pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_40) {
738		if (DesiredMcs == MCS_AUTO || DesiredMcs == MCS_32)
739			pDesired_ht_phy->MCSSet[4] = 0x1;
740	}
741	/* update HT Rate setting */
742	if (pAd->OpMode == OPMODE_STA)
743		MlmeUpdateHtTxRates(pAd, BSS0);
744	else
745		MlmeUpdateHtTxRates(pAd, apidx);
746}
747
748/*
749	========================================================================
750	Routine Description:
751		Update HT IE from our capability.
752
753	Arguments:
754		Send all HT IE in beacon/probe rsp/assoc rsp/action frame.
755
756	========================================================================
757*/
758void RTMPUpdateHTIE(struct rt_ht_capability *pRtHt,
759		    u8 * pMcsSet,
760		    struct rt_ht_capability_ie * pHtCapability,
761		    struct rt_add_ht_info_ie * pAddHtInfo)
762{
763	RTMPZeroMemory(pHtCapability, sizeof(struct rt_ht_capability_ie));
764	RTMPZeroMemory(pAddHtInfo, sizeof(struct rt_add_ht_info_ie));
765
766	pHtCapability->HtCapInfo.ChannelWidth = pRtHt->ChannelWidth;
767	pHtCapability->HtCapInfo.MimoPs = pRtHt->MimoPs;
768	pHtCapability->HtCapInfo.GF = pRtHt->GF;
769	pHtCapability->HtCapInfo.ShortGIfor20 = pRtHt->ShortGIfor20;
770	pHtCapability->HtCapInfo.ShortGIfor40 = pRtHt->ShortGIfor40;
771	pHtCapability->HtCapInfo.TxSTBC = pRtHt->TxSTBC;
772	pHtCapability->HtCapInfo.RxSTBC = pRtHt->RxSTBC;
773	pHtCapability->HtCapInfo.AMsduSize = pRtHt->AmsduSize;
774	pHtCapability->HtCapParm.MaxRAmpduFactor = pRtHt->MaxRAmpduFactor;
775	pHtCapability->HtCapParm.MpduDensity = pRtHt->MpduDensity;
776
777	pAddHtInfo->AddHtInfo.ExtChanOffset = pRtHt->ExtChanOffset;
778	pAddHtInfo->AddHtInfo.RecomWidth = pRtHt->RecomWidth;
779	pAddHtInfo->AddHtInfo2.OperaionMode = pRtHt->OperaionMode;
780	pAddHtInfo->AddHtInfo2.NonGfPresent = pRtHt->NonGfPresent;
781	RTMPMoveMemory(pAddHtInfo->MCSSet, /*pRtHt->MCSSet */ pMcsSet, 4);	/* rt2860 only support MCS max=32, no need to copy all 16 uchar. */
782
783	DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateHTIE <== \n"));
784}
785
786/*
787	========================================================================
788	Description:
789		Add Client security information into ASIC WCID table and IVEIV table.
790    Return:
791	========================================================================
792*/
793void RTMPAddWcidAttributeEntry(struct rt_rtmp_adapter *pAd,
794			       u8 BssIdx,
795			       u8 KeyIdx,
796			       u8 CipherAlg, struct rt_mac_table_entry *pEntry)
797{
798	u32 WCIDAttri = 0;
799	u16 offset;
800	u8 IVEIV = 0;
801	u16 Wcid = 0;
802
803	{
804		{
805			if (BssIdx > BSS0) {
806				DBGPRINT(RT_DEBUG_ERROR,
807					 ("RTMPAddWcidAttributeEntry: The BSS-index(%d) is out of range for Infra link. \n",
808					  BssIdx));
809				return;
810			}
811			/* 1.   In ADHOC mode, the AID is wcid number. And NO mesh link exists. */
812			/* 2.   In Infra mode, the AID:1 MUST be wcid of infra STA. */
813			/*                                         the AID:2~ assign to mesh link entry. */
814			if (pEntry)
815				Wcid = pEntry->Aid;
816			else
817				Wcid = MCAST_WCID;
818		}
819	}
820
821	/* Update WCID attribute table */
822	offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
823
824	{
825		if (pEntry && pEntry->ValidAsMesh)
826			WCIDAttri = (CipherAlg << 1) | PAIRWISEKEYTABLE;
827		else
828			WCIDAttri = (CipherAlg << 1) | SHAREDKEYTABLE;
829	}
830
831	RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
832
833	/* Update IV/EIV table */
834	offset = MAC_IVEIV_TABLE_BASE + (Wcid * HW_IVEIV_ENTRY_SIZE);
835
836	/* WPA mode */
837	if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC)
838	    || (CipherAlg == CIPHER_AES)) {
839		/* Eiv bit on. keyid always is 0 for pairwise key */
840		IVEIV = (KeyIdx << 6) | 0x20;
841	} else {
842		/* WEP KeyIdx is default tx key. */
843		IVEIV = (KeyIdx << 6);
844	}
845
846	/* For key index and ext IV bit, so only need to update the position(offset+3). */
847#ifdef RTMP_MAC_PCI
848	RTMP_IO_WRITE8(pAd, offset + 3, IVEIV);
849#endif /* RTMP_MAC_PCI // */
850#ifdef RTMP_MAC_USB
851	RTUSBMultiWrite_OneByte(pAd, offset + 3, &IVEIV);
852#endif /* RTMP_MAC_USB // */
853
854	DBGPRINT(RT_DEBUG_TRACE,
855		 ("RTMPAddWcidAttributeEntry: WCID #%d, KeyIndex #%d, Alg=%s\n",
856		  Wcid, KeyIdx, CipherName[CipherAlg]));
857	DBGPRINT(RT_DEBUG_TRACE, ("	WCIDAttri = 0x%x \n", WCIDAttri));
858
859}
860
861/*
862    ==========================================================================
863    Description:
864        Parse encryption type
865Arguments:
866    pAdapter                    Pointer to our adapter
867    wrq                         Pointer to the ioctl argument
868
869    Return Value:
870        None
871
872    Note:
873    ==========================================================================
874*/
875char *GetEncryptType(char enc)
876{
877	if (enc == Ndis802_11WEPDisabled)
878		return "NONE";
879	if (enc == Ndis802_11WEPEnabled)
880		return "WEP";
881	if (enc == Ndis802_11Encryption2Enabled)
882		return "TKIP";
883	if (enc == Ndis802_11Encryption3Enabled)
884		return "AES";
885	if (enc == Ndis802_11Encryption4Enabled)
886		return "TKIPAES";
887	else
888		return "UNKNOW";
889}
890
891char *GetAuthMode(char auth)
892{
893	if (auth == Ndis802_11AuthModeOpen)
894		return "OPEN";
895	if (auth == Ndis802_11AuthModeShared)
896		return "SHARED";
897	if (auth == Ndis802_11AuthModeAutoSwitch)
898		return "AUTOWEP";
899	if (auth == Ndis802_11AuthModeWPA)
900		return "WPA";
901	if (auth == Ndis802_11AuthModeWPAPSK)
902		return "WPAPSK";
903	if (auth == Ndis802_11AuthModeWPANone)
904		return "WPANONE";
905	if (auth == Ndis802_11AuthModeWPA2)
906		return "WPA2";
907	if (auth == Ndis802_11AuthModeWPA2PSK)
908		return "WPA2PSK";
909	if (auth == Ndis802_11AuthModeWPA1WPA2)
910		return "WPA1WPA2";
911	if (auth == Ndis802_11AuthModeWPA1PSKWPA2PSK)
912		return "WPA1PSKWPA2PSK";
913
914	return "UNKNOW";
915}
916
917int SetCommonHT(struct rt_rtmp_adapter *pAd)
918{
919	struct rt_oid_set_ht_phymode SetHT;
920
921	if (pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED)
922		return FALSE;
923
924	SetHT.PhyMode = pAd->CommonCfg.PhyMode;
925	SetHT.TransmitNo = ((u8)pAd->Antenna.field.TxPath);
926	SetHT.HtMode = (u8)pAd->CommonCfg.RegTransmitSetting.field.HTMODE;
927	SetHT.ExtOffset =
928	    (u8)pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
929	SetHT.MCS = MCS_AUTO;
930	SetHT.BW = (u8)pAd->CommonCfg.RegTransmitSetting.field.BW;
931	SetHT.STBC = (u8)pAd->CommonCfg.RegTransmitSetting.field.STBC;
932	SetHT.SHORTGI = (u8)pAd->CommonCfg.RegTransmitSetting.field.ShortGI;
933
934	RTMPSetHT(pAd, &SetHT);
935
936	return TRUE;
937}
938
939char *RTMPGetRalinkEncryModeStr(u16 encryMode)
940{
941	switch (encryMode) {
942	case Ndis802_11WEPDisabled:
943		return "NONE";
944	case Ndis802_11WEPEnabled:
945		return "WEP";
946	case Ndis802_11Encryption2Enabled:
947		return "TKIP";
948	case Ndis802_11Encryption3Enabled:
949		return "AES";
950	case Ndis802_11Encryption4Enabled:
951		return "TKIPAES";
952	default:
953		return "UNKNOW";
954	}
955}
956