Fix common misspellings
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / rtl8187se / r8185b_init.c
CommitLineData
c8d86be3
GKH
1/*++
2Copyright (c) Realtek Semiconductor Corp. All rights reserved.
3
4Module Name:
3742e3d7 5 r8185b_init.c
c8d86be3
GKH
6
7Abstract:
3742e3d7 8 Hardware Initialization and Hardware IO for RTL8185B
c8d86be3
GKH
9
10Major Change History:
3742e3d7
TD
11 When Who What
12 ---------- --------------- -------------------------------
c8d86be3
GKH
13 2006-11-15 Xiong Created
14
15Notes:
16 This file is ported from RTL8185B Windows driver.
17
18
19--*/
20
21/*--------------------------Include File------------------------------------*/
22#include <linux/spinlock.h>
23#include "r8180_hw.h"
24#include "r8180.h"
c8d86be3 25#include "r8180_rtl8225.h" /* RTL8225 Radio frontend */
c8d86be3
GKH
26#include "r8180_93cx6.h" /* Card EEPROM */
27#include "r8180_wx.h"
28
fd9b8d6e 29#include "ieee80211/dot11d.h"
c8d86be3 30
c8d86be3 31
3742e3d7 32/* #define CONFIG_RTL8180_IO_MAP */
c8d86be3
GKH
33
34#define TC_3W_POLL_MAX_TRY_CNT 5
3742e3d7
TD
35static u8 MAC_REG_TABLE[][2] = {
36 /*PAGA 0: */
37 /* 0x34(BRSR), 0xBE(RATE_FALLBACK_CTL), 0x1E0(ARFR) would set in HwConfigureRTL8185() */
38 /* 0x272(RFSW_CTRL), 0x1CE(AESMSK_QC) set in InitializeAdapter8185(). */
39 /* 0x1F0~0x1F8 set in MacConfig_85BASIC() */
40 {0x08, 0xae}, {0x0a, 0x72}, {0x5b, 0x42},
41 {0x84, 0x88}, {0x85, 0x24}, {0x88, 0x54}, {0x8b, 0xb8}, {0x8c, 0x03},
42 {0x8d, 0x40}, {0x8e, 0x00}, {0x8f, 0x00}, {0x5b, 0x18}, {0x91, 0x03},
43 {0x94, 0x0F}, {0x95, 0x32},
44 {0x96, 0x00}, {0x97, 0x07}, {0xb4, 0x22}, {0xdb, 0x00},
45 {0xf0, 0x32}, {0xf1, 0x32}, {0xf2, 0x00}, {0xf3, 0x00}, {0xf4, 0x32},
46 {0xf5, 0x43}, {0xf6, 0x00}, {0xf7, 0x00}, {0xf8, 0x46}, {0xf9, 0xa4},
47 {0xfa, 0x00}, {0xfb, 0x00}, {0xfc, 0x96}, {0xfd, 0xa4}, {0xfe, 0x00},
48 {0xff, 0x00},
49
50 /*PAGE 1: */
51 /* For Flextronics system Logo PCIHCT failure: */
52 /* 0x1C4~0x1CD set no-zero value to avoid PCI configuration space 0x45[7]=1 */
53 {0x5e, 0x01},
54 {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x04}, {0x5b, 0x00}, {0x60, 0x24},
55 {0x61, 0x97}, {0x62, 0xF0}, {0x63, 0x09}, {0x80, 0x0F}, {0x81, 0xFF},
56 {0x82, 0xFF}, {0x83, 0x03},
57 {0xC4, 0x22}, {0xC5, 0x22}, {0xC6, 0x22}, {0xC7, 0x22}, {0xC8, 0x22}, /* lzm add 080826 */
58 {0xC9, 0x22}, {0xCA, 0x22}, {0xCB, 0x22}, {0xCC, 0x22}, {0xCD, 0x22},/* lzm add 080826 */
59 {0xe2, 0x00},
60
61
62 /* PAGE 2: */
63 {0x5e, 0x02},
64 {0x0c, 0x04}, {0x4c, 0x30}, {0x4d, 0x08}, {0x50, 0x05}, {0x51, 0xf5},
65 {0x52, 0x04}, {0x53, 0xa0}, {0x54, 0xff}, {0x55, 0xff}, {0x56, 0xff},
66 {0x57, 0xff}, {0x58, 0x08}, {0x59, 0x08}, {0x5a, 0x08}, {0x5b, 0x08},
67 {0x60, 0x08}, {0x61, 0x08}, {0x62, 0x08}, {0x63, 0x08}, {0x64, 0x2f},
68 {0x8c, 0x3f}, {0x8d, 0x3f}, {0x8e, 0x3f},
69 {0x8f, 0x3f}, {0xc4, 0xff}, {0xc5, 0xff}, {0xc6, 0xff}, {0xc7, 0xff},
70 {0xc8, 0x00}, {0xc9, 0x00}, {0xca, 0x80}, {0xcb, 0x00},
71
72 /* PAGA 0: */
73 {0x5e, 0x00}, {0x9f, 0x03}
74 };
75
76
77static u8 ZEBRA_AGC[] = {
c8d86be3 78 0,
3742e3d7
TD
79 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72,
80 0x71, 0x70, 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A, 0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62,
81 0x48, 0x47, 0x46, 0x45, 0x44, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x08, 0x07,
82 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x15, 0x16,
84 0x17, 0x17, 0x18, 0x18, 0x19, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e,
85 0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x24,
86 0x24, 0x25, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F
c8d86be3
GKH
87 };
88
3742e3d7
TD
89static u32 ZEBRA_RF_RX_GAIN_TABLE[] = {
90 0x0096, 0x0076, 0x0056, 0x0036, 0x0016, 0x01f6, 0x01d6, 0x01b6,
91 0x0196, 0x0176, 0x00F7, 0x00D7, 0x00B7, 0x0097, 0x0077, 0x0057,
92 0x0037, 0x00FB, 0x00DB, 0x00BB, 0x00FF, 0x00E3, 0x00C3, 0x00A3,
93 0x0083, 0x0063, 0x0043, 0x0023, 0x0003, 0x01E3, 0x01C3, 0x01A3,
94 0x0183, 0x0163, 0x0143, 0x0123, 0x0103
c8d86be3
GKH
95 };
96
3742e3d7
TD
97static u8 OFDM_CONFIG[] = {
98 /* OFDM reg0x06[7:0]=0xFF: Enable power saving mode in RX */
99 /* OFDM reg0x3C[4]=1'b1: Enable RX power saving mode */
100 /* ofdm 0x3a = 0x7b ,(original : 0xfb) For ECS shielding room TP test */
c8d86be3 101
3742e3d7 102 /* 0x00 */
c8d86be3
GKH
103 0x10, 0x0F, 0x0A, 0x0C, 0x14, 0xFA, 0xFF, 0x50,
104 0x00, 0x50, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00,
3742e3d7 105 /* 0x10 */
c8d86be3
GKH
106 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xA8, 0x26,
107 0x32, 0x33, 0x06, 0xA5, 0x6F, 0x55, 0xC8, 0xBB,
3742e3d7 108 /* 0x20 */
c8d86be3
GKH
109 0x0A, 0xE1, 0x2C, 0x4A, 0x86, 0x83, 0x34, 0x00,
110 0x4F, 0x24, 0x6F, 0xC2, 0x03, 0x40, 0x80, 0x00,
3742e3d7 111 /* 0x30 */
c8d86be3
GKH
112 0xC0, 0xC1, 0x58, 0xF1, 0x00, 0xC4, 0x90, 0x3e,
113 0xD8, 0x3C, 0x7B, 0x10, 0x10
114 };
c8d86be3 115
3742e3d7
TD
116/* ---------------------------------------------------------------
117 * Hardware IO
118 * the code is ported from Windows source code
119 ----------------------------------------------------------------*/
c8d86be3
GKH
120
121void
122PlatformIOWrite1Byte(
123 struct net_device *dev,
124 u32 offset,
125 u8 data
126 )
127{
c8d86be3 128 write_nic_byte(dev, offset, data);
3742e3d7 129 read_nic_byte(dev, offset); /* To make sure write operation is completed, 2005.11.09, by rcnjko. */
c8d86be3 130
c8d86be3
GKH
131}
132
133void
134PlatformIOWrite2Byte(
135 struct net_device *dev,
136 u32 offset,
137 u16 data
138 )
139{
c8d86be3 140 write_nic_word(dev, offset, data);
3742e3d7 141 read_nic_word(dev, offset); /* To make sure write operation is completed, 2005.11.09, by rcnjko. */
c8d86be3
GKH
142
143
c8d86be3
GKH
144}
145u8 PlatformIORead1Byte(struct net_device *dev, u32 offset);
146
147void
148PlatformIOWrite4Byte(
149 struct net_device *dev,
150 u32 offset,
151 u32 data
152 )
153{
3742e3d7
TD
154/* {by amy 080312 */
155if (offset == PhyAddr) {
156/* For Base Band configuration. */
c8d86be3
GKH
157 unsigned char cmdByte;
158 unsigned long dataBytes;
159 unsigned char idx;
160 u8 u1bTmp;
161
162 cmdByte = (u8)(data & 0x000000ff);
163 dataBytes = data>>8;
164
3742e3d7
TD
165 /*
166 071010, rcnjko:
167 The critical section is only BB read/write race condition.
168 Assumption:
169 1. We assume NO one will access BB at DIRQL, otherwise, system will crash for
170 acquiring the spinlock in such context.
171 2. PlatformIOWrite4Byte() MUST NOT be recursive.
172 */
173/* NdisAcquireSpinLock( &(pDevice->IoSpinLock) ); */
174
175 for (idx = 0; idx < 30; idx++) {
176 /* Make sure command bit is clear before access it. */
c8d86be3 177 u1bTmp = PlatformIORead1Byte(dev, PhyAddr);
3742e3d7 178 if ((u1bTmp & BIT7) == 0)
c8d86be3
GKH
179 break;
180 else
181 mdelay(10);
182 }
183
3742e3d7
TD
184 for (idx = 0; idx < 3; idx++)
185 PlatformIOWrite1Byte(dev, offset+1+idx, ((u8 *)&dataBytes)[idx]);
186
c8d86be3
GKH
187 write_nic_byte(dev, offset, cmdByte);
188
3742e3d7 189/* NdisReleaseSpinLock( &(pDevice->IoSpinLock) ); */
c8d86be3 190 }
3742e3d7
TD
191/* by amy 080312} */
192 else {
c8d86be3 193 write_nic_dword(dev, offset, data);
3742e3d7 194 read_nic_dword(dev, offset); /* To make sure write operation is completed, 2005.11.09, by rcnjko. */
c8d86be3 195 }
c8d86be3
GKH
196}
197
198u8
199PlatformIORead1Byte(
200 struct net_device *dev,
201 u32 offset
202 )
203{
204 u8 data = 0;
205
c8d86be3
GKH
206 data = read_nic_byte(dev, offset);
207
c8d86be3
GKH
208
209 return data;
210}
211
212u16
213PlatformIORead2Byte(
214 struct net_device *dev,
215 u32 offset
216 )
217{
218 u16 data = 0;
219
c8d86be3
GKH
220 data = read_nic_word(dev, offset);
221
c8d86be3
GKH
222
223 return data;
224}
225
226u32
227PlatformIORead4Byte(
228 struct net_device *dev,
229 u32 offset
230 )
231{
232 u32 data = 0;
233
c8d86be3
GKH
234 data = read_nic_dword(dev, offset);
235
c8d86be3
GKH
236
237 return data;
238}
239
8daba6b9 240void SetOutputEnableOfRfPins(struct net_device *dev)
c8d86be3 241{
8daba6b9 242 write_nic_word(dev, RFPinsEnable, 0x1bff);
c8d86be3
GKH
243}
244
cd18964a 245static int
c8d86be3
GKH
246HwHSSIThreeWire(
247 struct net_device *dev,
248 u8 *pDataBuf,
249 u8 nDataBufBitCnt,
250 int bSI,
251 int bWrite
252 )
253{
254 int bResult = 1;
255 u8 TryCnt;
256 u8 u1bTmp;
257
3742e3d7
TD
258 do {
259 /* Check if WE and RE are cleared. */
260 for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) {
c8d86be3 261 u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
3742e3d7 262 if ((u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0)
c8d86be3 263 break;
3742e3d7 264
c8d86be3
GKH
265 udelay(10);
266 }
f36d83a8
LF
267 if (TryCnt == TC_3W_POLL_MAX_TRY_CNT) {
268 printk(KERN_ERR "rtl8187se: HwThreeWire(): CmdReg:"
269 " %#X RE|WE bits are not clear!!\n", u1bTmp);
270 dump_stack();
271 return 0;
272 }
c8d86be3 273
3742e3d7 274 /* RTL8187S HSSI Read/Write Function */
c8d86be3
GKH
275 u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
276
3742e3d7
TD
277 if (bSI)
278 u1bTmp |= RF_SW_CFG_SI; /* reg08[1]=1 Serial Interface(SI) */
279
280 else
281 u1bTmp &= ~RF_SW_CFG_SI; /* reg08[1]=0 Parallel Interface(PI) */
282
c8d86be3
GKH
283
284 write_nic_byte(dev, RF_SW_CONFIG, u1bTmp);
285
3742e3d7
TD
286 if (bSI) {
287 /* jong: HW SI read must set reg84[3]=0. */
c8d86be3
GKH
288 u1bTmp = read_nic_byte(dev, RFPinsSelect);
289 u1bTmp &= ~BIT3;
3742e3d7 290 write_nic_byte(dev, RFPinsSelect, u1bTmp);
c8d86be3 291 }
3742e3d7
TD
292 /* Fill up data buffer for write operation. */
293
294 if (bWrite) {
295 if (nDataBufBitCnt == 16) {
296 write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf));
297 } else if (nDataBufBitCnt == 64) {
298 /* RTL8187S shouldn't enter this case */
299 write_nic_dword(dev, SW_3W_DB0, *((u32 *)pDataBuf));
300 write_nic_dword(dev, SW_3W_DB1, *((u32 *)(pDataBuf + 4)));
301 } else {
c8d86be3
GKH
302 int idx;
303 int ByteCnt = nDataBufBitCnt / 8;
3742e3d7 304 /* printk("%d\n",nDataBufBitCnt); */
f36d83a8
LF
305 if ((nDataBufBitCnt % 8) != 0) {
306 printk(KERN_ERR "rtl8187se: "
307 "HwThreeWire(): nDataBufBitCnt(%d)"
308 " should be multiple of 8!!!\n",
309 nDataBufBitCnt);
310 dump_stack();
311 nDataBufBitCnt += 8;
312 nDataBufBitCnt &= ~7;
313 }
314
315 if (nDataBufBitCnt > 64) {
316 printk(KERN_ERR "rtl8187se: HwThreeWire():"
317 " nDataBufBitCnt(%d) should <= 64!!!\n",
318 nDataBufBitCnt);
319 dump_stack();
320 nDataBufBitCnt = 64;
321 }
c8d86be3 322
3742e3d7 323 for (idx = 0; idx < ByteCnt; idx++)
c8d86be3 324 write_nic_byte(dev, (SW_3W_DB0+idx), *(pDataBuf+idx));
3742e3d7 325
c8d86be3 326 }
3742e3d7
TD
327 } else { /* read */
328 if (bSI) {
329 /* SI - reg274[3:0] : RF register's Address */
330 write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf));
331 } else {
332 /* PI - reg274[15:12] : RF register's Address */
333 write_nic_word(dev, SW_3W_DB0, (*((u16 *)pDataBuf)) << 12);
c8d86be3
GKH
334 }
335 }
336
3742e3d7
TD
337 /* Set up command: WE or RE. */
338 if (bWrite)
c8d86be3 339 write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_WE);
3742e3d7 340
c8d86be3 341 else
c8d86be3 342 write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_RE);
c8d86be3 343
3742e3d7
TD
344
345 /* Check if DONE is set. */
346 for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) {
c8d86be3 347 u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
3742e3d7 348 if ((u1bTmp & SW_3W_CMD1_DONE) != 0)
c8d86be3 349 break;
3742e3d7 350
c8d86be3
GKH
351 udelay(10);
352 }
353
354 write_nic_byte(dev, SW_3W_CMD1, 0);
355
3742e3d7
TD
356 /* Read back data for read operation. */
357 if (bWrite == 0) {
358 if (bSI) {
359 /* Serial Interface : reg363_362[11:0] */
360 *((u16 *)pDataBuf) = read_nic_word(dev, SI_DATA_READ) ;
361 } else {
362 /* Parallel Interface : reg361_360[11:0] */
363 *((u16 *)pDataBuf) = read_nic_word(dev, PI_DATA_READ);
c8d86be3
GKH
364 }
365
3742e3d7 366 *((u16 *)pDataBuf) &= 0x0FFF;
c8d86be3
GKH
367 }
368
3742e3d7 369 } while (0);
c8d86be3
GKH
370
371 return bResult;
372}
c8d86be3
GKH
373
374void
8daba6b9 375RF_WriteReg(struct net_device *dev, u8 offset, u32 data)
c8d86be3 376{
8daba6b9
LF
377 u32 data2Write;
378 u8 len;
c8d86be3 379
8daba6b9
LF
380 /* Pure HW 3-wire. */
381 data2Write = (data << 4) | (u32)(offset & 0x0f);
382 len = 16;
c8d86be3 383
8daba6b9 384 HwHSSIThreeWire(dev, (u8 *)(&data2Write), len, 1, 1);
c8d86be3
GKH
385}
386
8daba6b9 387u32 RF_ReadReg(struct net_device *dev, u8 offset)
c8d86be3 388{
8daba6b9
LF
389 u32 data2Write;
390 u8 wlen;
391 u32 dataRead;
c8d86be3 392
8daba6b9
LF
393 data2Write = ((u32)(offset & 0x0f));
394 wlen = 16;
395 HwHSSIThreeWire(dev, (u8 *)(&data2Write), wlen, 1, 0);
396 dataRead = data2Write;
c8d86be3
GKH
397
398 return dataRead;
399}
400
401
3742e3d7 402/* by Owen on 04/07/14 for writing BB register successfully */
c8d86be3
GKH
403void
404WriteBBPortUchar(
405 struct net_device *dev,
406 u32 Data
407 )
408{
3742e3d7 409 /* u8 TimeoutCounter; */
c8d86be3
GKH
410 u8 RegisterContent;
411 u8 UCharData;
412
413 UCharData = (u8)((Data & 0x0000ff00) >> 8);
414 PlatformIOWrite4Byte(dev, PhyAddr, Data);
3742e3d7 415 /* for(TimeoutCounter = 10; TimeoutCounter > 0; TimeoutCounter--) */
c8d86be3
GKH
416 {
417 PlatformIOWrite4Byte(dev, PhyAddr, Data & 0xffffff7f);
418 RegisterContent = PlatformIORead1Byte(dev, PhyDataR);
3742e3d7
TD
419 /*if(UCharData == RegisterContent) */
420 /* break; */
c8d86be3
GKH
421 }
422}
423
424u8
425ReadBBPortUchar(
426 struct net_device *dev,
427 u32 addr
428 )
429{
3742e3d7 430 /*u8 TimeoutCounter; */
c8d86be3
GKH
431 u8 RegisterContent;
432
433 PlatformIOWrite4Byte(dev, PhyAddr, addr & 0xffffff7f);
434 RegisterContent = PlatformIORead1Byte(dev, PhyDataR);
435
436 return RegisterContent;
437}
3742e3d7
TD
438/* {by amy 080312 */
439/*
440 Description:
441 Perform Antenna settings with antenna diversity on 87SE.
442 Created by Roger, 2008.01.25.
443*/
c8d86be3
GKH
444bool
445SetAntennaConfig87SE(
446 struct net_device *dev,
3742e3d7
TD
447 u8 DefaultAnt, /* 0: Main, 1: Aux. */
448 bool bAntDiversity /* 1:Enable, 0: Disable. */
c8d86be3
GKH
449)
450{
451 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
452 bool bAntennaSwitched = true;
453
3742e3d7 454 /* printk("SetAntennaConfig87SE(): DefaultAnt(%d), bAntDiversity(%d)\n", DefaultAnt, bAntDiversity); */
c8d86be3 455
3742e3d7
TD
456 /* Threshold for antenna diversity. */
457 write_phy_cck(dev, 0x0c, 0x09); /* Reg0c : 09 */
c8d86be3 458
3742e3d7
TD
459 if (bAntDiversity) { /* Enable Antenna Diversity. */
460 if (DefaultAnt == 1) { /* aux antenna */
461
462 /* Mac register, aux antenna */
c8d86be3
GKH
463 write_nic_byte(dev, ANTSEL, 0x00);
464
3742e3d7
TD
465 /* Config CCK RX antenna. */
466 write_phy_cck(dev, 0x11, 0xbb); /* Reg11 : bb */
467 write_phy_cck(dev, 0x01, 0xc7); /* Reg01 : c7 */
c8d86be3 468
3742e3d7
TD
469 /* Config OFDM RX antenna. */
470 write_phy_ofdm(dev, 0x0D, 0x54); /* Reg0d : 54 */
471 write_phy_ofdm(dev, 0x18, 0xb2); /* Reg18 : b2 */
472 } else { /* use main antenna */
473 /* Mac register, main antenna */
c8d86be3 474 write_nic_byte(dev, ANTSEL, 0x03);
3742e3d7
TD
475 /* base band */
476 /* Config CCK RX antenna. */
477 write_phy_cck(dev, 0x11, 0x9b); /* Reg11 : 9b */
478 write_phy_cck(dev, 0x01, 0xc7); /* Reg01 : c7 */
479
480 /* Config OFDM RX antenna. */
481 write_phy_ofdm(dev, 0x0d, 0x5c); /* Reg0d : 5c */
482 write_phy_ofdm(dev, 0x18, 0xb2); /* Reg18 : b2 */
c8d86be3 483 }
3742e3d7
TD
484 } else {
485 /* Disable Antenna Diversity. */
486 if (DefaultAnt == 1) { /* aux Antenna */
487 /* Mac register, aux antenna */
c8d86be3
GKH
488 write_nic_byte(dev, ANTSEL, 0x00);
489
3742e3d7
TD
490 /* Config CCK RX antenna. */
491 write_phy_cck(dev, 0x11, 0xbb); /* Reg11 : bb */
492 write_phy_cck(dev, 0x01, 0x47); /* Reg01 : 47 */
c8d86be3 493
3742e3d7
TD
494 /* Config OFDM RX antenna. */
495 write_phy_ofdm(dev, 0x0D, 0x54); /* Reg0d : 54 */
496 write_phy_ofdm(dev, 0x18, 0x32); /* Reg18 : 32 */
497 } else { /* main Antenna */
498 /* Mac register, main antenna */
c8d86be3
GKH
499 write_nic_byte(dev, ANTSEL, 0x03);
500
3742e3d7
TD
501 /* Config CCK RX antenna. */
502 write_phy_cck(dev, 0x11, 0x9b); /* Reg11 : 9b */
503 write_phy_cck(dev, 0x01, 0x47); /* Reg01 : 47 */
c8d86be3 504
3742e3d7
TD
505 /* Config OFDM RX antenna. */
506 write_phy_ofdm(dev, 0x0D, 0x5c); /* Reg0d : 5c */
507 write_phy_ofdm(dev, 0x18, 0x32); /*Reg18 : 32 */
c8d86be3
GKH
508 }
509 }
3742e3d7 510 priv->CurrAntennaIndex = DefaultAnt; /* Update default settings. */
c8d86be3
GKH
511 return bAntennaSwitched;
512}
3742e3d7
TD
513/* by amy 080312 */
514/*
515---------------------------------------------------------------
516 * Hardware Initialization.
517 * the code is ported from Windows source code
518----------------------------------------------------------------*/
c8d86be3
GKH
519
520void
521ZEBRA_Config_85BASIC_HardCode(
522 struct net_device *dev
523 )
524{
525
526 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
527 u32 i;
3742e3d7 528 u32 addr, data;
c8d86be3 529 u32 u4bRegOffset, u4bRegValue, u4bRF23, u4bRF24;
3742e3d7 530 u8 u1b24E;
d44eb889 531 int d_cut = 0;
c8d86be3 532
c8d86be3 533
3742e3d7
TD
534/*
535=============================================================================
536 87S_PCIE :: RADIOCFG.TXT
537=============================================================================
538*/
c8d86be3
GKH
539
540
3742e3d7
TD
541 /* Page1 : reg16-reg30 */
542 RF_WriteReg(dev, 0x00, 0x013f); mdelay(1); /* switch to page1 */
543 u4bRF23 = RF_ReadReg(dev, 0x08); mdelay(1);
544 u4bRF24 = RF_ReadReg(dev, 0x09); mdelay(1);
c8d86be3 545
d44eb889
LF
546 if (u4bRF23 == 0x818 && u4bRF24 == 0x70C) {
547 d_cut = 1;
548 printk(KERN_INFO "rtl8187se: card type changed from C- to D-cut\n");
549 }
c8d86be3 550
3742e3d7 551 /* Page0 : reg0-reg15 */
c8d86be3 552
3742e3d7 553 RF_WriteReg(dev, 0x00, 0x009f); mdelay(1);/* 1 */
c8d86be3
GKH
554
555 RF_WriteReg(dev, 0x01, 0x06e0); mdelay(1);
556
3742e3d7 557 RF_WriteReg(dev, 0x02, 0x004d); mdelay(1);/* 2 */
c8d86be3 558
3742e3d7 559 RF_WriteReg(dev, 0x03, 0x07f1); mdelay(1);/* 3 */
c8d86be3
GKH
560
561 RF_WriteReg(dev, 0x04, 0x0975); mdelay(1);
562 RF_WriteReg(dev, 0x05, 0x0c72); mdelay(1);
563 RF_WriteReg(dev, 0x06, 0x0ae6); mdelay(1);
564 RF_WriteReg(dev, 0x07, 0x00ca); mdelay(1);
565 RF_WriteReg(dev, 0x08, 0x0e1c); mdelay(1);
566 RF_WriteReg(dev, 0x09, 0x02f0); mdelay(1);
567 RF_WriteReg(dev, 0x0a, 0x09d0); mdelay(1);
568 RF_WriteReg(dev, 0x0b, 0x01ba); mdelay(1);
569 RF_WriteReg(dev, 0x0c, 0x0640); mdelay(1);
570 RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1);
571 RF_WriteReg(dev, 0x0e, 0x0020); mdelay(1);
572 RF_WriteReg(dev, 0x0f, 0x0990); mdelay(1);
573
574
3742e3d7 575 /* Page1 : reg16-reg30 */
c8d86be3
GKH
576 RF_WriteReg(dev, 0x00, 0x013f); mdelay(1);
577
578 RF_WriteReg(dev, 0x03, 0x0806); mdelay(1);
579
d44eb889
LF
580 RF_WriteReg(dev, 0x04, 0x03a7); mdelay(1);
581 RF_WriteReg(dev, 0x05, 0x059b); mdelay(1);
582 RF_WriteReg(dev, 0x06, 0x0081); mdelay(1);
c8d86be3
GKH
583
584
585 RF_WriteReg(dev, 0x07, 0x01A0); mdelay(1);
3742e3d7 586/* Don't write RF23/RF24 to make a difference between 87S C cut and D cut. asked by SD3 stevenl. */
c8d86be3
GKH
587 RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1);
588 RF_WriteReg(dev, 0x0b, 0x0418); mdelay(1);
589
d44eb889 590 if (d_cut) {
c8d86be3
GKH
591 RF_WriteReg(dev, 0x0c, 0x0fbe); mdelay(1);
592 RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1);
3742e3d7
TD
593 RF_WriteReg(dev, 0x0e, 0x0807); mdelay(1); /* RX LO buffer */
594 } else {
c8d86be3
GKH
595 RF_WriteReg(dev, 0x0c, 0x0fbe); mdelay(1);
596 RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1);
3742e3d7 597 RF_WriteReg(dev, 0x0e, 0x0806); mdelay(1); /* RX LO buffer */
c8d86be3
GKH
598 }
599
600 RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1);
601
3742e3d7 602 RF_WriteReg(dev, 0x00, 0x01d7); mdelay(1); /* 6 */
c8d86be3
GKH
603
604 RF_WriteReg(dev, 0x03, 0x0e00); mdelay(1);
605 RF_WriteReg(dev, 0x04, 0x0e50); mdelay(1);
3742e3d7 606 for (i = 0; i <= 36; i++) {
c8d86be3
GKH
607 RF_WriteReg(dev, 0x01, i); mdelay(1);
608 RF_WriteReg(dev, 0x02, ZEBRA_RF_RX_GAIN_TABLE[i]); mdelay(1);
c8d86be3
GKH
609 }
610
3742e3d7
TD
611 RF_WriteReg(dev, 0x05, 0x0203); mdelay(1); /* 203, 343 */
612 RF_WriteReg(dev, 0x06, 0x0200); mdelay(1); /* 400 */
c8d86be3 613
3742e3d7
TD
614 RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); /* switch to reg16-reg30, and HSSI disable 137 */
615 mdelay(10); /* Deay 10 ms. */ /* 0xfd */
c8d86be3 616
3742e3d7
TD
617 RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); /* Z4 synthesizer loop filter setting, 392 */
618 mdelay(10); /* Deay 10 ms. */ /* 0xfd */
c8d86be3 619
3742e3d7
TD
620 RF_WriteReg(dev, 0x00, 0x0037); mdelay(1); /* switch to reg0-reg15, and HSSI disable */
621 mdelay(10); /* Deay 10 ms. */ /* 0xfd */
c8d86be3 622
3742e3d7
TD
623 RF_WriteReg(dev, 0x04, 0x0160); mdelay(1); /* CBC on, Tx Rx disable, High gain */
624 mdelay(10); /* Deay 10 ms. */ /* 0xfd */
c8d86be3 625
3742e3d7
TD
626 RF_WriteReg(dev, 0x07, 0x0080); mdelay(1); /* Z4 setted channel 1 */
627 mdelay(10); /* Deay 10 ms. */ /* 0xfd */
c8d86be3 628
3742e3d7
TD
629 RF_WriteReg(dev, 0x02, 0x088D); mdelay(1); /* LC calibration */
630 mdelay(200); /* Deay 200 ms. */ /* 0xfd */
631 mdelay(10); /* Deay 10 ms. */ /* 0xfd */
632 mdelay(10); /* Deay 10 ms. */ /* 0xfd */
c8d86be3 633
3742e3d7
TD
634 RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); /* switch to reg16-reg30 137, and HSSI disable 137 */
635 mdelay(10); /* Deay 10 ms. */ /* 0xfd */
c8d86be3
GKH
636
637 RF_WriteReg(dev, 0x07, 0x0000); mdelay(1);
638 RF_WriteReg(dev, 0x07, 0x0180); mdelay(1);
639 RF_WriteReg(dev, 0x07, 0x0220); mdelay(1);
640 RF_WriteReg(dev, 0x07, 0x03E0); mdelay(1);
641
3742e3d7 642 /* DAC calibration off 20070702 */
c8d86be3
GKH
643 RF_WriteReg(dev, 0x06, 0x00c1); mdelay(1);
644 RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1);
3742e3d7
TD
645/* {by amy 080312 */
646 /* For crystal calibration, added by Roger, 2007.12.11. */
647 if (priv->bXtalCalibration) { /* reg 30. */
648 /* enable crystal calibration.
649 RF Reg[30], (1)Xin:[12:9], Xout:[8:5], addr[4:0].
650 (2)PA Pwr delay timer[15:14], default: 2.4us, set BIT15=0
651 (3)RF signal on/off when calibration[13], default: on, set BIT13=0.
652 So we should minus 4 BITs offset. */
653 RF_WriteReg(dev, 0x0f, (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) | BIT11 | BIT9); mdelay(1);
c8d86be3 654 printk("ZEBRA_Config_85BASIC_HardCode(): (%02x)\n",
3742e3d7
TD
655 (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) | BIT11 | BIT9);
656 } else {
657 /* using default value. Xin=6, Xout=6. */
c8d86be3
GKH
658 RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1);
659 }
3742e3d7
TD
660/* by amy 080312 */
661
662 RF_WriteReg(dev, 0x00, 0x00bf); mdelay(1); /* switch to reg0-reg15, and HSSI enable */
663 RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1); /* Rx BB start calibration, 00c//+edward */
664 RF_WriteReg(dev, 0x02, 0x004d); mdelay(1); /* temperature meter off */
665 RF_WriteReg(dev, 0x04, 0x0975); mdelay(1); /* Rx mode */
666 mdelay(10); /* Deay 10 ms.*/ /* 0xfe */
667 mdelay(10); /* Deay 10 ms.*/ /* 0xfe */
668 mdelay(10); /* Deay 10 ms.*/ /* 0xfe */
669 RF_WriteReg(dev, 0x00, 0x0197); mdelay(1); /* Rx mode*/ /*+edward */
670 RF_WriteReg(dev, 0x05, 0x05ab); mdelay(1); /* Rx mode*/ /*+edward */
671 RF_WriteReg(dev, 0x00, 0x009f); mdelay(1); /* Rx mode*/ /*+edward */
672
673 RF_WriteReg(dev, 0x01, 0x0000); mdelay(1); /* Rx mode*/ /*+edward */
674 RF_WriteReg(dev, 0x02, 0x0000); mdelay(1); /* Rx mode*/ /*+edward */
675 /* power save parameters. */
c8d86be3
GKH
676 u1b24E = read_nic_byte(dev, 0x24E);
677 write_nic_byte(dev, 0x24E, (u1b24E & (~(BIT5|BIT6))));
678
3742e3d7 679 /*=============================================================================
c8d86be3 680
3742e3d7
TD
681 =============================================================================
682 CCKCONF.TXT
683 =============================================================================
684 */
c8d86be3 685 /* [POWER SAVE] Power Saving Parameters by jong. 2007-11-27
3742e3d7 686 CCK reg0x00[7]=1'b1 :power saving for TX (default)
c8d86be3
GKH
687 CCK reg0x00[6]=1'b1: power saving for RX (default)
688 CCK reg0x06[4]=1'b1: turn off channel estimation related circuits if not doing channel estimation.
689 CCK reg0x06[3]=1'b1: turn off unused circuits before cca = 1
690 CCK reg0x06[2]=1'b1: turn off cck's circuit if macrst =0
691 */
5521a513 692
3742e3d7
TD
693 write_phy_cck(dev, 0x00, 0xc8);
694 write_phy_cck(dev, 0x06, 0x1c);
695 write_phy_cck(dev, 0x10, 0x78);
696 write_phy_cck(dev, 0x2e, 0xd0);
697 write_phy_cck(dev, 0x2f, 0x06);
698 write_phy_cck(dev, 0x01, 0x46);
c8d86be3 699
3742e3d7 700 /* power control */
c8d86be3
GKH
701 write_nic_byte(dev, CCK_TXAGC, 0x10);
702 write_nic_byte(dev, OFDM_TXAGC, 0x1B);
703 write_nic_byte(dev, ANTSEL, 0x03);
c8d86be3
GKH
704
705
706
3742e3d7
TD
707 /*
708 =============================================================================
709 AGC.txt
710 =============================================================================
711 */
c8d86be3 712
c8d86be3 713 write_phy_ofdm(dev, 0x00, 0x12);
c8d86be3 714
3742e3d7 715 for (i = 0; i < 128; i++) {
c8d86be3
GKH
716
717 data = ZEBRA_AGC[i+1];
718 data = data << 8;
719 data = data | 0x0000008F;
720
3742e3d7 721 addr = i + 0x80; /* enable writing AGC table */
c8d86be3
GKH
722 addr = addr << 8;
723 addr = addr | 0x0000008E;
724
725 WriteBBPortUchar(dev, data);
726 WriteBBPortUchar(dev, addr);
727 WriteBBPortUchar(dev, 0x0000008E);
728 }
729
3742e3d7 730 PlatformIOWrite4Byte(dev, PhyAddr, 0x00001080); /* Annie, 2006-05-05 */
c8d86be3 731
3742e3d7
TD
732 /*
733 =============================================================================
c8d86be3 734
3742e3d7
TD
735 =============================================================================
736 OFDMCONF.TXT
737 =============================================================================
738 */
c8d86be3 739
3742e3d7
TD
740 for (i = 0; i < 60; i++) {
741 u4bRegOffset = i;
742 u4bRegValue = OFDM_CONFIG[i];
c8d86be3 743
c8d86be3
GKH
744 WriteBBPortUchar(dev,
745 (0x00000080 |
746 (u4bRegOffset & 0x7f) |
747 ((u4bRegValue & 0xff) << 8)));
748 }
749
3742e3d7
TD
750 /*
751 =============================================================================
752 by amy for antenna
753 =============================================================================
754 */
755/* {by amy 080312 */
756 /* Config Sw/Hw Combinational Antenna Diversity. Added by Roger, 2008.02.26. */
c8d86be3 757 SetAntennaConfig87SE(dev, priv->bDefaultAntenna1, priv->bSwAntennaDiverity);
3742e3d7
TD
758/* by amy 080312} */
759/* by amy for antenna */
c8d86be3
GKH
760}
761
762
763void
764UpdateInitialGain(
765 struct net_device *dev
766 )
767{
768 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
c8d86be3 769
3742e3d7
TD
770 /* lzm add 080826 */
771 if (priv->eRFPowerState != eRfOn) {
772 /* Don't access BB/RF under disable PLL situation.
773 RT_TRACE(COMP_DIG, DBG_LOUD, ("UpdateInitialGain - pHalData->eRFPowerState!=eRfOn\n"));
774 Back to the original state
775 */
776 priv->InitialGain = priv->InitialGainBackUp;
c8d86be3
GKH
777 return;
778 }
779
8daba6b9
LF
780 switch (priv->InitialGain) {
781 case 1: /* m861dBm */
782 write_phy_ofdm(dev, 0x17, 0x26); mdelay(1);
783 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
784 write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
785 break;
c8d86be3 786
8daba6b9
LF
787 case 2: /* m862dBm */
788 write_phy_ofdm(dev, 0x17, 0x36); mdelay(1);
789 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
790 write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
791 break;
c8d86be3 792
8daba6b9
LF
793 case 3: /* m863dBm */
794 write_phy_ofdm(dev, 0x17, 0x36); mdelay(1);
795 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
796 write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
797 break;
c8d86be3 798
8daba6b9
LF
799 case 4: /* m864dBm */
800 write_phy_ofdm(dev, 0x17, 0x46); mdelay(1);
801 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
802 write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
803 break;
c8d86be3 804
8daba6b9
LF
805 case 5: /* m82dBm */
806 write_phy_ofdm(dev, 0x17, 0x46); mdelay(1);
807 write_phy_ofdm(dev, 0x24, 0x96); mdelay(1);
808 write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
809 break;
c8d86be3 810
8daba6b9
LF
811 case 6: /* m78dBm */
812 write_phy_ofdm(dev, 0x17, 0x56); mdelay(1);
813 write_phy_ofdm(dev, 0x24, 0x96); mdelay(1);
814 write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
815 break;
c8d86be3 816
8daba6b9
LF
817 case 7: /* m74dBm */
818 write_phy_ofdm(dev, 0x17, 0x56); mdelay(1);
819 write_phy_ofdm(dev, 0x24, 0xa6); mdelay(1);
820 write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
c8d86be3
GKH
821 break;
822
8daba6b9
LF
823 case 8:
824 write_phy_ofdm(dev, 0x17, 0x66); mdelay(1);
825 write_phy_ofdm(dev, 0x24, 0xb6); mdelay(1);
826 write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
827 break;
c8d86be3 828
8daba6b9
LF
829 default: /* MP */
830 write_phy_ofdm(dev, 0x17, 0x26); mdelay(1);
831 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
832 write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
c8d86be3
GKH
833 break;
834 }
835}
3742e3d7
TD
836/*
837 Description:
838 Tx Power tracking mechanism routine on 87SE.
839 Created by Roger, 2007.12.11.
840*/
c8d86be3
GKH
841void
842InitTxPwrTracking87SE(
843 struct net_device *dev
844)
845{
c8d86be3
GKH
846 u32 u4bRfReg;
847
848 u4bRfReg = RF_ReadReg(dev, 0x02);
849
3742e3d7 850 /* Enable Thermal meter indication. */
c8d86be3
GKH
851 RF_WriteReg(dev, 0x02, u4bRfReg|PWR_METER_EN); mdelay(1);
852}
853
c8d86be3
GKH
854void
855PhyConfig8185(
856 struct net_device *dev
857 )
858{
859 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
3742e3d7 860 write_nic_dword(dev, RCR, priv->ReceiveConfig);
c8d86be3 861 priv->RFProgType = read_nic_byte(dev, CONFIG4) & 0x03;
8daba6b9
LF
862 /* RF config */
863 ZEBRA_Config_85BASIC_HardCode(dev);
3742e3d7
TD
864/* {by amy 080312 */
865 /* Set default initial gain state to 4, approved by SD3 DZ, by Bruce, 2007-06-06. */
866 if (priv->bDigMechanism) {
867 if (priv->InitialGain == 0)
c8d86be3 868 priv->InitialGain = 4;
c8d86be3
GKH
869 }
870
3742e3d7
TD
871 /*
872 Enable thermal meter indication to implement TxPower tracking on 87SE.
873 We initialize thermal meter here to avoid unsuccessful configuration.
874 Added by Roger, 2007.12.11.
875 */
876 if (priv->bTxPowerTrack)
c8d86be3
GKH
877 InitTxPwrTracking87SE(dev);
878
3742e3d7
TD
879/* by amy 080312} */
880 priv->InitialGainBackUp = priv->InitialGain;
c8d86be3
GKH
881 UpdateInitialGain(dev);
882
883 return;
884}
885
c8d86be3
GKH
886void
887HwConfigureRTL8185(
888 struct net_device *dev
889 )
890{
3742e3d7
TD
891 /* RTL8185_TODO: Determine Retrylimit, TxAGC, AutoRateFallback control. */
892 u8 bUNIVERSAL_CONTROL_RL = 0;
c8d86be3
GKH
893 u8 bUNIVERSAL_CONTROL_AGC = 1;
894 u8 bUNIVERSAL_CONTROL_ANT = 1;
895 u8 bAUTO_RATE_FALLBACK_CTL = 1;
896 u8 val8;
3742e3d7
TD
897 write_nic_word(dev, BRSR, 0x0fff);
898 /* Retry limit */
c8d86be3
GKH
899 val8 = read_nic_byte(dev, CW_CONF);
900
3742e3d7 901 if (bUNIVERSAL_CONTROL_RL)
c8d86be3
GKH
902 val8 = val8 & 0xfd;
903 else
904 val8 = val8 | 0x02;
905
906 write_nic_byte(dev, CW_CONF, val8);
907
3742e3d7 908 /* Tx AGC */
c8d86be3 909 val8 = read_nic_byte(dev, TXAGC_CTL);
3742e3d7 910 if (bUNIVERSAL_CONTROL_AGC) {
c8d86be3
GKH
911 write_nic_byte(dev, CCK_TXAGC, 128);
912 write_nic_byte(dev, OFDM_TXAGC, 128);
913 val8 = val8 & 0xfe;
3742e3d7 914 } else {
c8d86be3
GKH
915 val8 = val8 | 0x01 ;
916 }
917
918
919 write_nic_byte(dev, TXAGC_CTL, val8);
920
3742e3d7
TD
921 /* Tx Antenna including Feedback control */
922 val8 = read_nic_byte(dev, TXAGC_CTL);
c8d86be3 923
3742e3d7 924 if (bUNIVERSAL_CONTROL_ANT) {
c8d86be3
GKH
925 write_nic_byte(dev, ANTSEL, 0x00);
926 val8 = val8 & 0xfd;
3742e3d7
TD
927 } else {
928 val8 = val8 & (val8|0x02); /* xiong-2006-11-15 */
c8d86be3
GKH
929 }
930
931 write_nic_byte(dev, TXAGC_CTL, val8);
932
3742e3d7 933 /* Auto Rate fallback control */
c8d86be3
GKH
934 val8 = read_nic_byte(dev, RATE_FALLBACK);
935 val8 &= 0x7c;
3742e3d7 936 if (bAUTO_RATE_FALLBACK_CTL) {
c8d86be3
GKH
937 val8 |= RATE_FALLBACK_CTL_ENABLE | RATE_FALLBACK_CTL_AUTO_STEP1;
938
3742e3d7
TD
939 /* <RJ_TODO_8185B> We shall set up the ARFR according to user's setting. */
940 PlatformIOWrite2Byte(dev, ARFR, 0x0fff); /* set 1M ~ 54Mbps. */
c8d86be3
GKH
941 }
942 write_nic_byte(dev, RATE_FALLBACK, val8);
943}
944
c8d86be3
GKH
945static void
946MacConfig_85BASIC_HardCode(
947 struct net_device *dev)
948{
3742e3d7
TD
949 /*
950 ============================================================================
951 MACREG.TXT
952 ============================================================================
953 */
c8d86be3
GKH
954 int nLinesRead = 0;
955
3742e3d7 956 u32 u4bRegOffset, u4bRegValue, u4bPageIndex = 0;
c8d86be3
GKH
957 int i;
958
3742e3d7
TD
959 nLinesRead = sizeof(MAC_REG_TABLE)/2;
960
961 for (i = 0; i < nLinesRead; i++) { /* nLinesRead=101 */
962 u4bRegOffset = MAC_REG_TABLE[i][0];
963 u4bRegValue = MAC_REG_TABLE[i][1];
964
965 if (u4bRegOffset == 0x5e)
966 u4bPageIndex = u4bRegValue;
967
968 else
969 u4bRegOffset |= (u4bPageIndex << 8);
c8d86be3 970
c8d86be3
GKH
971 write_nic_byte(dev, u4bRegOffset, (u8)u4bRegValue);
972 }
3742e3d7 973 /* ============================================================================ */
c8d86be3
GKH
974}
975
c8d86be3
GKH
976static void
977MacConfig_85BASIC(
978 struct net_device *dev)
979{
980
3742e3d7 981 u8 u1DA;
c8d86be3
GKH
982 MacConfig_85BASIC_HardCode(dev);
983
3742e3d7 984 /* ============================================================================ */
c8d86be3 985
3742e3d7 986 /* Follow TID_AC_MAP of WMac. */
c8d86be3
GKH
987 write_nic_word(dev, TID_AC_MAP, 0xfa50);
988
3742e3d7 989 /* Interrupt Migration, Jong suggested we use set 0x0000 first, 2005.12.14, by rcnjko. */
c8d86be3
GKH
990 write_nic_word(dev, IntMig, 0x0000);
991
3742e3d7 992 /* Prevent TPC to cause CRC error. Added by Annie, 2006-06-10. */
c8d86be3
GKH
993 PlatformIOWrite4Byte(dev, 0x1F0, 0x00000000);
994 PlatformIOWrite4Byte(dev, 0x1F4, 0x00000000);
995 PlatformIOWrite1Byte(dev, 0x1F8, 0x00);
996
3742e3d7
TD
997 /* Asked for by SD3 CM Lin, 2006.06.27, by rcnjko. */
998 /* power save parameter based on "87SE power save parameters 20071127.doc", as follow. */
c8d86be3 999
3742e3d7 1000 /* Enable DA10 TX power saving */
c8d86be3 1001 u1DA = read_nic_byte(dev, PHYPR);
3742e3d7 1002 write_nic_byte(dev, PHYPR, (u1DA | BIT2));
c8d86be3 1003
3742e3d7 1004 /* POWER: */
c8d86be3
GKH
1005 write_nic_word(dev, 0x360, 0x1000);
1006 write_nic_word(dev, 0x362, 0x1000);
1007
3742e3d7 1008 /* AFE. */
c8d86be3
GKH
1009 write_nic_word(dev, 0x370, 0x0560);
1010 write_nic_word(dev, 0x372, 0x0560);
1011 write_nic_word(dev, 0x374, 0x0DA4);
1012 write_nic_word(dev, 0x376, 0x0DA4);
1013 write_nic_word(dev, 0x378, 0x0560);
1014 write_nic_word(dev, 0x37A, 0x0560);
1015 write_nic_word(dev, 0x37C, 0x00EC);
3742e3d7
TD
1016 write_nic_word(dev, 0x37E, 0x00EC); /*+edward */
1017 write_nic_byte(dev, 0x24E, 0x01);
c8d86be3
GKH
1018}
1019
c8d86be3
GKH
1020u8
1021GetSupportedWirelessMode8185(
1022 struct net_device *dev
1023)
1024{
1025 u8 btSupportedWirelessMode = 0;
c8d86be3 1026
8daba6b9 1027 btSupportedWirelessMode = (WIRELESS_MODE_B | WIRELESS_MODE_G);
c8d86be3
GKH
1028 return btSupportedWirelessMode;
1029}
1030
1031void
1032ActUpdateChannelAccessSetting(
1033 struct net_device *dev,
1034 WIRELESS_MODE WirelessMode,
1035 PCHANNEL_ACCESS_SETTING ChnlAccessSetting
1036 )
1037{
1038 struct r8180_priv *priv = ieee80211_priv(dev);
1039 struct ieee80211_device *ieee = priv->ieee80211;
1040 AC_CODING eACI;
1041 AC_PARAM AcParam;
c8d86be3
GKH
1042 u8 bFollowLegacySetting = 0;
1043 u8 u1bAIFS;
1044
3742e3d7
TD
1045 /*
1046 <RJ_TODO_8185B>
1047 TODO: We still don't know how to set up these registers, just follow WMAC to
1048 verify 8185B FPAG.
1049
1050 <RJ_TODO_8185B>
1051 Jong said CWmin/CWmax register are not functional in 8185B,
1052 so we shall fill channel access realted register into AC parameter registers,
1053 even in nQBss.
1054 */
1055 ChnlAccessSetting->SIFS_Timer = 0x22; /* Suggested by Jong, 2005.12.08. */
1056 ChnlAccessSetting->DIFS_Timer = 0x1C; /* 2006.06.02, by rcnjko. */
1057 ChnlAccessSetting->SlotTimeTimer = 9; /* 2006.06.02, by rcnjko. */
1058 ChnlAccessSetting->EIFS_Timer = 0x5B; /* Suggested by wcchu, it is the default value of EIFS register, 2005.12.08. */
1059 ChnlAccessSetting->CWminIndex = 3; /* 2006.06.02, by rcnjko. */
1060 ChnlAccessSetting->CWmaxIndex = 7; /* 2006.06.02, by rcnjko. */
c8d86be3
GKH
1061
1062 write_nic_byte(dev, SIFS, ChnlAccessSetting->SIFS_Timer);
3742e3d7 1063 write_nic_byte(dev, SLOT, ChnlAccessSetting->SlotTimeTimer); /* Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29. */
c8d86be3 1064
3742e3d7 1065 u1bAIFS = aSifsTime + (2 * ChnlAccessSetting->SlotTimeTimer);
c8d86be3 1066
c8d86be3
GKH
1067 write_nic_byte(dev, EIFS, ChnlAccessSetting->EIFS_Timer);
1068
3742e3d7 1069 write_nic_byte(dev, AckTimeOutReg, 0x5B); /* <RJ_EXPR_QOS> Suggested by wcchu, it is the default value of EIFS register, 2005.12.08. */
c8d86be3 1070
3742e3d7 1071 { /* Legacy 802.11. */
c8d86be3
GKH
1072 bFollowLegacySetting = 1;
1073
1074 }
1075
3742e3d7
TD
1076 /* this setting is copied from rtl8187B. xiong-2006-11-13 */
1077 if (bFollowLegacySetting) {
c8d86be3 1078
3742e3d7
TD
1079 /*
1080 Follow 802.11 seeting to AC parameter, all AC shall use the same parameter.
1081 2005.12.01, by rcnjko.
1082 */
c8d86be3 1083 AcParam.longData = 0;
3742e3d7 1084 AcParam.f.AciAifsn.f.AIFSN = 2; /* Follow 802.11 DIFS. */
c8d86be3 1085 AcParam.f.AciAifsn.f.ACM = 0;
3742e3d7
TD
1086 AcParam.f.Ecw.f.ECWmin = ChnlAccessSetting->CWminIndex; /* Follow 802.11 CWmin. */
1087 AcParam.f.Ecw.f.ECWmax = ChnlAccessSetting->CWmaxIndex; /* Follow 802.11 CWmax. */
c8d86be3
GKH
1088 AcParam.f.TXOPLimit = 0;
1089
3742e3d7
TD
1090 /* lzm reserved 080826 */
1091 /* For turbo mode setting. port from 87B by Isaiah 2008-08-01 */
1092 if (ieee->current_network.Turbo_Enable == 1)
c8d86be3 1093 AcParam.f.TXOPLimit = 0x01FF;
3742e3d7 1094 /* For 87SE with Intel 4965 Ad-Hoc mode have poor throughput (19MB) */
c8d86be3
GKH
1095 if (ieee->iw_mode == IW_MODE_ADHOC)
1096 AcParam.f.TXOPLimit = 0x0020;
c8d86be3 1097
3742e3d7 1098 for (eACI = 0; eACI < AC_MAX; eACI++) {
c8d86be3
GKH
1099 AcParam.f.AciAifsn.f.ACI = (u8)eACI;
1100 {
1101 PAC_PARAM pAcParam = (PAC_PARAM)(&AcParam);
1102 AC_CODING eACI;
1103 u8 u1bAIFS;
1104 u32 u4bAcParam;
1105
3742e3d7 1106 /* Retrive paramters to udpate. */
c8d86be3
GKH
1107 eACI = pAcParam->f.AciAifsn.f.ACI;
1108 u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * ChnlAccessSetting->SlotTimeTimer + aSifsTime;
3742e3d7 1109 u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) |
c8d86be3
GKH
1110 (((u32)(pAcParam->f.Ecw.f.ECWmax)) << AC_PARAM_ECW_MAX_OFFSET) |
1111 (((u32)(pAcParam->f.Ecw.f.ECWmin)) << AC_PARAM_ECW_MIN_OFFSET) |
1112 (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET));
1113
3742e3d7
TD
1114 switch (eACI) {
1115 case AC1_BK:
1116 /* write_nic_dword(dev, AC_BK_PARAM, u4bAcParam); */
1117 break;
c8d86be3 1118
3742e3d7
TD
1119 case AC0_BE:
1120 /* write_nic_dword(dev, AC_BK_PARAM, u4bAcParam); */
1121 break;
c8d86be3 1122
3742e3d7
TD
1123 case AC2_VI:
1124 /* write_nic_dword(dev, AC_BK_PARAM, u4bAcParam); */
1125 break;
c8d86be3 1126
3742e3d7
TD
1127 case AC3_VO:
1128 /* write_nic_dword(dev, AC_BK_PARAM, u4bAcParam); */
1129 break;
c8d86be3 1130
3742e3d7
TD
1131 default:
1132 DMESGW("SetHwReg8185(): invalid ACI: %d !\n", eACI);
1133 break;
c8d86be3
GKH
1134 }
1135
3742e3d7
TD
1136 /* Cehck ACM bit. */
1137 /* If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13. */
c8d86be3
GKH
1138 {
1139 PACI_AIFSN pAciAifsn = (PACI_AIFSN)(&pAcParam->f.AciAifsn);
1140 AC_CODING eACI = pAciAifsn->f.ACI;
1141
3742e3d7
TD
1142 /*modified Joseph */
1143 /*for 8187B AsynIORead issue */
c8d86be3 1144 u8 AcmCtrl = 0;
3742e3d7
TD
1145 if (pAciAifsn->f.ACM) {
1146 /* ACM bit is 1. */
1147 switch (eACI) {
1148 case AC0_BE:
1149 AcmCtrl |= (BEQ_ACM_EN|BEQ_ACM_CTL|ACM_HW_EN); /* or 0x21 */
1150 break;
1151
1152 case AC2_VI:
1153 AcmCtrl |= (VIQ_ACM_EN|VIQ_ACM_CTL|ACM_HW_EN); /* or 0x42 */
1154 break;
1155
1156 case AC3_VO:
1157 AcmCtrl |= (VOQ_ACM_EN|VOQ_ACM_CTL|ACM_HW_EN); /* or 0x84 */
1158 break;
1159
1160 default:
1161 DMESGW("SetHwReg8185(): [HW_VAR_ACM_CTRL] ACM set failed: eACI is %d\n", eACI);
1162 break;
c8d86be3 1163 }
3742e3d7
TD
1164 } else {
1165 /* ACM bit is 0. */
1166 switch (eACI) {
1167 case AC0_BE:
1168 AcmCtrl &= ((~BEQ_ACM_EN) & (~BEQ_ACM_CTL) & (~ACM_HW_EN)); /* and 0xDE */
1169 break;
1170
1171 case AC2_VI:
1172 AcmCtrl &= ((~VIQ_ACM_EN) & (~VIQ_ACM_CTL) & (~ACM_HW_EN)); /* and 0xBD */
1173 break;
1174
1175 case AC3_VO:
1176 AcmCtrl &= ((~VOQ_ACM_EN) & (~VOQ_ACM_CTL) & (~ACM_HW_EN)); /* and 0x7B */
1177 break;
1178
1179 default:
1180 break;
c8d86be3
GKH
1181 }
1182 }
c8d86be3
GKH
1183 write_nic_byte(dev, ACM_CONTROL, 0);
1184 }
1185 }
1186 }
c8d86be3
GKH
1187 }
1188}
1189
1190void
1191ActSetWirelessMode8185(
1192 struct net_device *dev,
1193 u8 btWirelessMode
1194 )
1195{
1196 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1197 struct ieee80211_device *ieee = priv->ieee80211;
c8d86be3
GKH
1198 u8 btSupportedWirelessMode = GetSupportedWirelessMode8185(dev);
1199
3742e3d7
TD
1200 if ((btWirelessMode & btSupportedWirelessMode) == 0) {
1201 /* Don't switch to unsupported wireless mode, 2006.02.15, by rcnjko. */
c8d86be3
GKH
1202 DMESGW("ActSetWirelessMode8185(): WirelessMode(%d) is not supported (%d)!\n",
1203 btWirelessMode, btSupportedWirelessMode);
1204 return;
1205 }
1206
3742e3d7
TD
1207 /* 1. Assign wireless mode to swtich if necessary. */
1208 if (btWirelessMode == WIRELESS_MODE_AUTO) {
1209 if ((btSupportedWirelessMode & WIRELESS_MODE_A)) {
c8d86be3 1210 btWirelessMode = WIRELESS_MODE_A;
3742e3d7
TD
1211 } else if (btSupportedWirelessMode & WIRELESS_MODE_G) {
1212 btWirelessMode = WIRELESS_MODE_G;
1213
1214 } else if ((btSupportedWirelessMode & WIRELESS_MODE_B)) {
1215 btWirelessMode = WIRELESS_MODE_B;
1216 } else {
1217 DMESGW("ActSetWirelessMode8185(): No valid wireless mode supported, btSupportedWirelessMode(%x)!!!\n",
1218 btSupportedWirelessMode);
1219 btWirelessMode = WIRELESS_MODE_B;
c8d86be3
GKH
1220 }
1221 }
1222
8daba6b9
LF
1223 /* 2. Swtich band: RF or BB specific actions,
1224 * for example, refresh tables in omc8255, or change initial gain if necessary.
1225 * Nothing to do for Zebra to switch band.
1226 * Update current wireless mode if we swtich to specified band successfully. */
3742e3d7 1227
8daba6b9 1228 ieee->mode = (WIRELESS_MODE)btWirelessMode;
c8d86be3 1229
3742e3d7
TD
1230 /* 3. Change related setting. */
1231 if( ieee->mode == WIRELESS_MODE_A ) {
c8d86be3 1232 DMESG("WIRELESS_MODE_A\n");
3742e3d7
TD
1233 } else if( ieee->mode == WIRELESS_MODE_B ) {
1234 DMESG("WIRELESS_MODE_B\n");
1235 } else if( ieee->mode == WIRELESS_MODE_G ) {
1236 DMESG("WIRELESS_MODE_G\n");
c8d86be3 1237 }
c8d86be3
GKH
1238 ActUpdateChannelAccessSetting( dev, ieee->mode, &priv->ChannelAccessSetting);
1239}
1240
1241void rtl8185b_irq_enable(struct net_device *dev)
1242{
1243 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1244
1245 priv->irq_enabled = 1;
1246 write_nic_dword(dev, IMR, priv->IntrMask);
1247}
3742e3d7 1248/* by amy for power save */
c8d86be3
GKH
1249void
1250DrvIFIndicateDisassociation(
1251 struct net_device *dev,
1252 u16 reason
1253 )
1254{
3742e3d7
TD
1255 /* nothing is needed after disassociation request. */
1256 }
c8d86be3
GKH
1257void
1258MgntDisconnectIBSS(
1259 struct net_device *dev
1260)
1261{
1262 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1263 u8 i;
1264
c8d86be3 1265 DrvIFIndicateDisassociation(dev, unspec_reason);
c8d86be3 1266
3742e3d7
TD
1267 for (i = 0; i < 6 ; i++)
1268 priv->ieee80211->current_network.bssid[i] = 0x55;
c8d86be3 1269
c8d86be3 1270
c8d86be3 1271
3742e3d7
TD
1272 priv->ieee80211->state = IEEE80211_NOLINK;
1273 /*
1274 Stop Beacon.
1275
25985edc 1276 Vista add a Adhoc profile, HW radio off until OID_DOT11_RESET_REQUEST
3742e3d7
TD
1277 Driver would set MSR=NO_LINK, then HW Radio ON, MgntQueue Stuck.
1278 Because Bcn DMA isn't complete, mgnt queue would stuck until Bcn packet send.
1279
1280 Disable Beacon Queue Own bit, suggested by jong */
c8d86be3
GKH
1281 ieee80211_stop_send_beacons(priv->ieee80211);
1282
1283 priv->ieee80211->link_change(dev);
1284 notify_wx_assoc_event(priv->ieee80211);
c8d86be3
GKH
1285}
1286void
1287MlmeDisassociateRequest(
1288 struct net_device *dev,
3742e3d7
TD
1289 u8 *asSta,
1290 u8 asRsn
c8d86be3
GKH
1291 )
1292{
1293 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1294 u8 i;
1295
3742e3d7 1296 SendDisassociation(priv->ieee80211, asSta, asRsn);
c8d86be3 1297
3742e3d7
TD
1298 if (memcmp(priv->ieee80211->current_network.bssid, asSta, 6) == 0) {
1299 /*ShuChen TODO: change media status. */
1300 /*ShuChen TODO: What to do when disassociate. */
c8d86be3
GKH
1301 DrvIFIndicateDisassociation(dev, unspec_reason);
1302
1303
3742e3d7
TD
1304
1305 for (i = 0; i < 6; i++)
1306 priv->ieee80211->current_network.bssid[i] = 0x22;
1307
c8d86be3 1308 ieee80211_disassociate(priv->ieee80211);
c8d86be3
GKH
1309 }
1310
1311}
1312
1313void
1314MgntDisconnectAP(
1315 struct net_device *dev,
1316 u8 asRsn
1317)
1318{
1319 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1320
3742e3d7
TD
1321 /*
1322 Commented out by rcnjko, 2005.01.27:
1323 I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE().
1324
1325 2004/09/15, kcwu, the key should be cleared, or the new handshaking will not success
c8d86be3 1326
3742e3d7
TD
1327 In WPA WPA2 need to Clear all key ... because new key will set after new handshaking.
1328 2004.10.11, by rcnjko. */
1329 MlmeDisassociateRequest(dev, priv->ieee80211->current_network.bssid, asRsn);
c8d86be3
GKH
1330
1331 priv->ieee80211->state = IEEE80211_NOLINK;
c8d86be3
GKH
1332}
1333bool
1334MgntDisconnect(
1335 struct net_device *dev,
1336 u8 asRsn
1337)
1338{
1339 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
3742e3d7
TD
1340 /*
1341 Schedule an workitem to wake up for ps mode, 070109, by rcnjko.
1342 */
c8d86be3 1343
3742e3d7 1344 if (IS_DOT11D_ENABLE(priv->ieee80211))
c8d86be3 1345 Dot11d_Reset(priv->ieee80211);
3742e3d7
TD
1346 /* In adhoc mode, update beacon frame. */
1347 if (priv->ieee80211->state == IEEE80211_LINKED) {
1348 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
c8d86be3 1349 MgntDisconnectIBSS(dev);
3742e3d7
TD
1350
1351 if (priv->ieee80211->iw_mode == IW_MODE_INFRA) {
1352 /* We clear key here instead of MgntDisconnectAP() because that
1353 MgntActSet_802_11_DISASSOCIATE() is an interface called by OS,
1354 e.g. OID_802_11_DISASSOCIATE in Windows while as MgntDisconnectAP() is
1355 used to handle disassociation related things to AP, e.g. send Disassoc
1356 frame to AP. 2005.01.27, by rcnjko. */
c8d86be3
GKH
1357 MgntDisconnectAP(dev, asRsn);
1358 }
3742e3d7 1359 /* Inidicate Disconnect, 2005.02.23, by rcnjko. */
c8d86be3 1360 }
c8d86be3
GKH
1361 return true;
1362}
3742e3d7
TD
1363/*
1364 Description:
1365 Chang RF Power State.
1366 Note that, only MgntActSet_RF_State() is allowed to set HW_VAR_RF_STATE.
1367
1368 Assumption:
1369 PASSIVE LEVEL.
1370*/
c8d86be3
GKH
1371bool
1372SetRFPowerState(
1373 struct net_device *dev,
1374 RT_RF_POWER_STATE eRFPowerState
1375 )
1376{
1377 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1378 bool bResult = false;
1379
3742e3d7 1380 if (eRFPowerState == priv->eRFPowerState)
c8d86be3 1381 return bResult;
c8d86be3 1382
8daba6b9 1383 bResult = SetZebraRFPowerState8185(dev, eRFPowerState);
c8d86be3
GKH
1384
1385 return bResult;
1386}
1387void
1388HalEnableRx8185Dummy(
1389 struct net_device *dev
1390 )
1391{
1392}
1393void
1394HalDisableRx8185Dummy(
1395 struct net_device *dev
1396 )
1397{
1398}
1399
1400bool
1401MgntActSet_RF_State(
1402 struct net_device *dev,
1403 RT_RF_POWER_STATE StateToSet,
1404 u32 ChangeSource
1405 )
1406{
1407 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1408 bool bActionAllowed = false;
1409 bool bConnectBySSID = false;
3742e3d7 1410 RT_RF_POWER_STATE rtState;
c8d86be3
GKH
1411 u16 RFWaitCounter = 0;
1412 unsigned long flag;
3742e3d7
TD
1413 /*
1414 Prevent the race condition of RF state change. By Bruce, 2007-11-28.
1415 Only one thread can change the RF state at one time, and others should wait to be executed.
1416 */
1417 while (true) {
1418 spin_lock_irqsave(&priv->rf_ps_lock, flag);
1419 if (priv->RFChangeInProgress) {
1420 spin_unlock_irqrestore(&priv->rf_ps_lock, flag);
1421 /* Set RF after the previous action is done. */
1422 while (priv->RFChangeInProgress) {
1423 RFWaitCounter++;
1424 udelay(1000); /* 1 ms */
1425
1426 /* Wait too long, return FALSE to avoid to be stuck here. */
1427 if (RFWaitCounter > 1000) { /* 1sec */
c8d86be3 1428 printk("MgntActSet_RF_State(): Wait too long to set RF\n");
3742e3d7 1429 /* TODO: Reset RF state? */
c8d86be3
GKH
1430 return false;
1431 }
1432 }
3742e3d7 1433 } else {
c8d86be3 1434 priv->RFChangeInProgress = true;
3742e3d7 1435 spin_unlock_irqrestore(&priv->rf_ps_lock, flag);
c8d86be3
GKH
1436 break;
1437 }
1438 }
c8d86be3
GKH
1439 rtState = priv->eRFPowerState;
1440
3742e3d7 1441 switch (StateToSet) {
c8d86be3 1442 case eRfOn:
3742e3d7
TD
1443 /*
1444 Turn On RF no matter the IPS setting because we need to update the RF state to Ndis under Vista, or
1445 the Windows does not allow the driver to perform site survey any more. By Bruce, 2007-10-02.
1446 */
c8d86be3
GKH
1447 priv->RfOffReason &= (~ChangeSource);
1448
3742e3d7 1449 if (!priv->RfOffReason) {
c8d86be3
GKH
1450 priv->RfOffReason = 0;
1451 bActionAllowed = true;
1452
3742e3d7 1453 if (rtState == eRfOff && ChangeSource >= RF_CHANGE_BY_HW && !priv->bInHctTest)
c8d86be3 1454 bConnectBySSID = true;
3742e3d7
TD
1455
1456 } else
1457 ;
c8d86be3
GKH
1458 break;
1459
1460 case eRfOff:
3742e3d7 1461 /* 070125, rcnjko: we always keep connected in AP mode. */
c8d86be3 1462
3742e3d7
TD
1463 if (priv->RfOffReason > RF_CHANGE_BY_IPS) {
1464 /*
1465 060808, Annie:
1466 Disconnect to current BSS when radio off. Asked by QuanTa.
1467
1468 Calling MgntDisconnect() instead of MgntActSet_802_11_DISASSOCIATE(),
1469 because we do NOT need to set ssid to dummy ones.
1470 */
1471 MgntDisconnect(dev, disas_lv_ss);
1472
1473 /* Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI. */
c8d86be3
GKH
1474 }
1475
c8d86be3
GKH
1476 priv->RfOffReason |= ChangeSource;
1477 bActionAllowed = true;
1478 break;
c8d86be3
GKH
1479 case eRfSleep:
1480 priv->RfOffReason |= ChangeSource;
1481 bActionAllowed = true;
1482 break;
c8d86be3
GKH
1483 default:
1484 break;
1485 }
1486
3742e3d7
TD
1487 if (bActionAllowed) {
1488 /* Config HW to the specified mode. */
c8d86be3
GKH
1489 SetRFPowerState(dev, StateToSet);
1490
3742e3d7
TD
1491 /* Turn on RF. */
1492 if (StateToSet == eRfOn) {
c8d86be3 1493 HalEnableRx8185Dummy(dev);
3742e3d7
TD
1494 if (bConnectBySSID) {
1495 /* by amy not supported */
c8d86be3
GKH
1496 }
1497 }
3742e3d7
TD
1498 /* Turn off RF. */
1499 else if (StateToSet == eRfOff)
c8d86be3 1500 HalDisableRx8185Dummy(dev);
3742e3d7 1501
c8d86be3 1502 }
c8d86be3 1503
3742e3d7
TD
1504 /* Release RF spinlock */
1505 spin_lock_irqsave(&priv->rf_ps_lock, flag);
c8d86be3 1506 priv->RFChangeInProgress = false;
3742e3d7 1507 spin_unlock_irqrestore(&priv->rf_ps_lock, flag);
c8d86be3
GKH
1508 return bActionAllowed;
1509}
1510void
1511InactivePowerSave(
1512 struct net_device *dev
1513 )
1514{
1515 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
3742e3d7
TD
1516 /*
1517 This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
1518 is really scheduled.
1519 The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
1520 previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
1521 blocks the IPS procedure of switching RF.
1522 */
c8d86be3
GKH
1523 priv->bSwRfProcessing = true;
1524
1525 MgntActSet_RF_State(dev, priv->eInactivePowerState, RF_CHANGE_BY_IPS);
1526
3742e3d7
TD
1527 /*
1528 To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
1529 */
c8d86be3 1530
c8d86be3
GKH
1531 priv->bSwRfProcessing = false;
1532}
1533
3742e3d7
TD
1534/*
1535 Description:
1536 Enter the inactive power save mode. RF will be off
1537*/
c8d86be3
GKH
1538void
1539IPSEnter(
1540 struct net_device *dev
1541 )
1542{
1543 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1544 RT_RF_POWER_STATE rtState;
3742e3d7 1545 if (priv->bInactivePs) {
c8d86be3
GKH
1546 rtState = priv->eRFPowerState;
1547
3742e3d7
TD
1548 /*
1549 Do not enter IPS in the following conditions:
1550 (1) RF is already OFF or Sleep
1551 (2) bSwRfProcessing (indicates the IPS is still under going)
1552 (3) Connectted (only disconnected can trigger IPS)
1553 (4) IBSS (send Beacon)
1554 (5) AP mode (send Beacon)
1555 */
c8d86be3 1556 if (rtState == eRfOn && !priv->bSwRfProcessing
3742e3d7 1557 && (priv->ieee80211->state != IEEE80211_LINKED)) {
c8d86be3
GKH
1558 priv->eInactivePowerState = eRfOff;
1559 InactivePowerSave(dev);
1560 }
1561 }
c8d86be3
GKH
1562}
1563void
1564IPSLeave(
1565 struct net_device *dev
1566 )
1567{
1568 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1569 RT_RF_POWER_STATE rtState;
3742e3d7 1570 if (priv->bInactivePs) {
c8d86be3 1571 rtState = priv->eRFPowerState;
3742e3d7 1572 if ((rtState == eRfOff || rtState == eRfSleep) && (!priv->bSwRfProcessing) && priv->RfOffReason <= RF_CHANGE_BY_IPS) {
c8d86be3
GKH
1573 priv->eInactivePowerState = eRfOn;
1574 InactivePowerSave(dev);
1575 }
1576 }
c8d86be3 1577}
cd18964a 1578
c8d86be3
GKH
1579void rtl8185b_adapter_start(struct net_device *dev)
1580{
3742e3d7 1581 struct r8180_priv *priv = ieee80211_priv(dev);
c8d86be3
GKH
1582 struct ieee80211_device *ieee = priv->ieee80211;
1583
1584 u8 SupportedWirelessMode;
1585 u8 InitWirelessMode;
1586 u8 bInvalidWirelessMode = 0;
c8d86be3 1587 u8 tmpu8;
c8d86be3
GKH
1588 u8 btCR9346;
1589 u8 TmpU1b;
1590 u8 btPSR;
1591
3742e3d7 1592 write_nic_byte(dev, 0x24e, (BIT5|BIT6|BIT0));
c8d86be3
GKH
1593 rtl8180_reset(dev);
1594
1595 priv->dma_poll_mask = 0;
1596 priv->dma_poll_stop_mask = 0;
1597
c8d86be3 1598 HwConfigureRTL8185(dev);
3742e3d7
TD
1599 write_nic_dword(dev, MAC0, ((u32 *)dev->dev_addr)[0]);
1600 write_nic_word(dev, MAC4, ((u32 *)dev->dev_addr)[1] & 0xffff);
1601 write_nic_byte(dev, MSR, read_nic_byte(dev, MSR) & 0xf3); /* default network type to 'No Link' */
c8d86be3
GKH
1602 write_nic_word(dev, BcnItv, 100);
1603 write_nic_word(dev, AtimWnd, 2);
c8d86be3 1604 PlatformIOWrite2Byte(dev, FEMR, 0xFFFF);
c8d86be3 1605 write_nic_byte(dev, WPA_CONFIG, 0);
c8d86be3 1606 MacConfig_85BASIC(dev);
3742e3d7
TD
1607 /* Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07, by rcnjko. */
1608 /* BT_DEMO_BOARD type */
c8d86be3 1609 PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x569a);
c8d86be3 1610
3742e3d7
TD
1611 /*
1612 -----------------------------------------------------------------------------
1613 Set up PHY related.
1614 -----------------------------------------------------------------------------
1615 */
1616 /* Enable Config3.PARAM_En to revise AnaaParm. */
1617 write_nic_byte(dev, CR9346, 0xc0); /* enable config register write */
c8d86be3 1618 tmpu8 = read_nic_byte(dev, CONFIG3);
3742e3d7
TD
1619 write_nic_byte(dev, CONFIG3, (tmpu8 | CONFIG3_PARM_En));
1620 /* Turn on Analog power. */
1621 /* Asked for by William, otherwise, MAC 3-wire can't work, 2006.06.27, by rcnjko. */
c8d86be3
GKH
1622 write_nic_dword(dev, ANAPARAM2, ANAPARM2_ASIC_ON);
1623 write_nic_dword(dev, ANAPARAM, ANAPARM_ASIC_ON);
c8d86be3 1624 write_nic_word(dev, ANAPARAM3, 0x0010);
c8d86be3
GKH
1625
1626 write_nic_byte(dev, CONFIG3, tmpu8);
1627 write_nic_byte(dev, CR9346, 0x00);
3742e3d7 1628 /* enable EEM0 and EEM1 in 9346CR */
c8d86be3 1629 btCR9346 = read_nic_byte(dev, CR9346);
3742e3d7 1630 write_nic_byte(dev, CR9346, (btCR9346 | 0xC0));
c8d86be3 1631
3742e3d7 1632 /* B cut use LED1 to control HW RF on/off */
c8d86be3
GKH
1633 TmpU1b = read_nic_byte(dev, CONFIG5);
1634 TmpU1b = TmpU1b & ~BIT3;
3742e3d7 1635 write_nic_byte(dev, CONFIG5, TmpU1b);
c8d86be3 1636
3742e3d7 1637 /* disable EEM0 and EEM1 in 9346CR */
c8d86be3
GKH
1638 btCR9346 &= ~(0xC0);
1639 write_nic_byte(dev, CR9346, btCR9346);
1640
3742e3d7
TD
1641 /* Enable Led (suggested by Jong) */
1642 /* B-cut RF Radio on/off 5e[3]=0 */
c8d86be3
GKH
1643 btPSR = read_nic_byte(dev, PSR);
1644 write_nic_byte(dev, PSR, (btPSR | BIT3));
3742e3d7 1645 /* setup initial timing for RFE. */
c8d86be3
GKH
1646 write_nic_word(dev, RFPinsOutput, 0x0480);
1647 SetOutputEnableOfRfPins(dev);
1648 write_nic_word(dev, RFPinsSelect, 0x2488);
1649
3742e3d7 1650 /* PHY config. */
c8d86be3
GKH
1651 PhyConfig8185(dev);
1652
3742e3d7
TD
1653 /*
1654 We assume RegWirelessMode has already been initialized before,
1655 however, we has to validate the wireless mode here and provide a
1656 reasonable initialized value if necessary. 2005.01.13, by rcnjko.
1657 */
c8d86be3 1658 SupportedWirelessMode = GetSupportedWirelessMode8185(dev);
3742e3d7 1659 if ((ieee->mode != WIRELESS_MODE_B) &&
c8d86be3
GKH
1660 (ieee->mode != WIRELESS_MODE_G) &&
1661 (ieee->mode != WIRELESS_MODE_A) &&
3742e3d7
TD
1662 (ieee->mode != WIRELESS_MODE_AUTO)) {
1663 /* It should be one of B, G, A, or AUTO. */
c8d86be3 1664 bInvalidWirelessMode = 1;
3742e3d7
TD
1665 } else {
1666 /* One of B, G, A, or AUTO. */
1667 /* Check if the wireless mode is supported by RF. */
1668 if ((ieee->mode != WIRELESS_MODE_AUTO) &&
1669 (ieee->mode & SupportedWirelessMode) == 0) {
c8d86be3
GKH
1670 bInvalidWirelessMode = 1;
1671 }
1672 }
1673
3742e3d7
TD
1674 if (bInvalidWirelessMode || ieee->mode == WIRELESS_MODE_AUTO) {
1675 /* Auto or other invalid value. */
1676 /* Assigne a wireless mode to initialize. */
1677 if ((SupportedWirelessMode & WIRELESS_MODE_A)) {
c8d86be3 1678 InitWirelessMode = WIRELESS_MODE_A;
3742e3d7 1679 } else if ((SupportedWirelessMode & WIRELESS_MODE_G)) {
c8d86be3 1680 InitWirelessMode = WIRELESS_MODE_G;
3742e3d7 1681 } else if ((SupportedWirelessMode & WIRELESS_MODE_B)) {
c8d86be3 1682 InitWirelessMode = WIRELESS_MODE_B;
3742e3d7 1683 } else {
c8d86be3
GKH
1684 DMESGW("InitializeAdapter8185(): No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n",
1685 SupportedWirelessMode);
1686 InitWirelessMode = WIRELESS_MODE_B;
1687 }
1688
3742e3d7
TD
1689 /* Initialize RegWirelessMode if it is not a valid one. */
1690 if (bInvalidWirelessMode)
c8d86be3 1691 ieee->mode = (WIRELESS_MODE)InitWirelessMode;
3742e3d7
TD
1692
1693 } else {
1694 /* One of B, G, A. */
c8d86be3
GKH
1695 InitWirelessMode = ieee->mode;
1696 }
3742e3d7 1697/* by amy for power save */
c8d86be3
GKH
1698 priv->eRFPowerState = eRfOff;
1699 priv->RfOffReason = 0;
1700 {
c8d86be3 1701 MgntActSet_RF_State(dev, eRfOn, 0);
c8d86be3 1702 }
3742e3d7
TD
1703 /*
1704 If inactive power mode is enabled, disable rf while in disconnected state.
1705 */
c8d86be3 1706 if (priv->bInactivePs)
3742e3d7
TD
1707 MgntActSet_RF_State(dev , eRfOff, RF_CHANGE_BY_IPS);
1708
1709/* by amy for power save */
c8d86be3
GKH
1710
1711 ActSetWirelessMode8185(dev, (u8)(InitWirelessMode));
1712
3742e3d7 1713 /* ----------------------------------------------------------------------------- */
c8d86be3
GKH
1714
1715 rtl8185b_irq_enable(dev);
1716
1717 netif_start_queue(dev);
3742e3d7 1718 }
c8d86be3 1719
c8d86be3
GKH
1720void rtl8185b_rx_enable(struct net_device *dev)
1721{
1722 u8 cmd;
c8d86be3
GKH
1723 /* for now we accept data, management & ctl frame*/
1724 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
c8d86be3 1725
c8d86be3 1726
3742e3d7
TD
1727 if (dev->flags & IFF_PROMISC)
1728 DMESG("NIC in promisc mode");
1729
1730 if (priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
1731 dev->flags & IFF_PROMISC) {
1732 priv->ReceiveConfig = priv->ReceiveConfig & (~RCR_APM);
c8d86be3
GKH
1733 priv->ReceiveConfig = priv->ReceiveConfig | RCR_AAP;
1734 }
1735
3742e3d7 1736 if (priv->ieee80211->iw_mode == IW_MODE_MONITOR)
c8d86be3 1737 priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACF | RCR_APWRMGT | RCR_AICV;
c8d86be3 1738
3742e3d7
TD
1739
1740 if (priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
c8d86be3
GKH
1741 priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACRC32;
1742
1743 write_nic_dword(dev, RCR, priv->ReceiveConfig);
1744
1745 fix_rx_fifo(dev);
1746
3742e3d7
TD
1747 cmd = read_nic_byte(dev, CMD);
1748 write_nic_byte(dev, CMD, cmd | (1<<CMD_RX_ENABLE_SHIFT));
c8d86be3
GKH
1749
1750}
1751
1752void rtl8185b_tx_enable(struct net_device *dev)
1753{
1754 u8 cmd;
c8d86be3 1755 u8 byte;
c8d86be3
GKH
1756 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1757
c8d86be3
GKH
1758 write_nic_dword(dev, TCR, priv->TransmitConfig);
1759 byte = read_nic_byte(dev, MSR);
1760 byte |= MSR_LINK_ENEDCA;
1761 write_nic_byte(dev, MSR, byte);
1762
1763 fix_tx_fifo(dev);
1764
3742e3d7
TD
1765 cmd = read_nic_byte(dev, CMD);
1766 write_nic_byte(dev, CMD, cmd | (1<<CMD_TX_ENABLE_SHIFT));
c8d86be3
GKH
1767}
1768