Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[linux-btrfs-devel.git] / drivers / staging / rtl8187se / r8185b_init.c
blob4b0b830f9ab6d9aad8dbaec0fb4c0636c1e896c3
1 /*++
2 Copyright (c) Realtek Semiconductor Corp. All rights reserved.
4 Module Name:
5 r8185b_init.c
7 Abstract:
8 Hardware Initialization and Hardware IO for RTL8185B
10 Major Change History:
11 When Who What
12 ---------- --------------- -------------------------------
13 2006-11-15 Xiong Created
15 Notes:
16 This file is ported from RTL8185B Windows driver.
19 --*/
21 /*--------------------------Include File------------------------------------*/
22 #include <linux/spinlock.h>
23 #include "r8180_hw.h"
24 #include "r8180.h"
25 #include "r8180_rtl8225.h" /* RTL8225 Radio frontend */
26 #include "r8180_93cx6.h" /* Card EEPROM */
27 #include "r8180_wx.h"
29 #include "ieee80211/dot11d.h"
32 /* #define CONFIG_RTL8180_IO_MAP */
34 #define TC_3W_POLL_MAX_TRY_CNT 5
35 static 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},
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},
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},
72 /* PAGA 0: */
73 {0x5e, 0x00}, {0x9f, 0x03}
77 static u8 ZEBRA_AGC[] = {
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
89 static 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
97 static 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 */
102 /* 0x00 */
103 0x10, 0x0F, 0x0A, 0x0C, 0x14, 0xFA, 0xFF, 0x50,
104 0x00, 0x50, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00,
105 /* 0x10 */
106 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xA8, 0x26,
107 0x32, 0x33, 0x06, 0xA5, 0x6F, 0x55, 0xC8, 0xBB,
108 /* 0x20 */
109 0x0A, 0xE1, 0x2C, 0x4A, 0x86, 0x83, 0x34, 0x00,
110 0x4F, 0x24, 0x6F, 0xC2, 0x03, 0x40, 0x80, 0x00,
111 /* 0x30 */
112 0xC0, 0xC1, 0x58, 0xF1, 0x00, 0xC4, 0x90, 0x3e,
113 0xD8, 0x3C, 0x7B, 0x10, 0x10
116 /* ---------------------------------------------------------------
117 * Hardware IO
118 * the code is ported from Windows source code
119 ----------------------------------------------------------------*/
121 void
122 PlatformIOWrite1Byte(
123 struct net_device *dev,
124 u32 offset,
125 u8 data
128 write_nic_byte(dev, offset, data);
129 read_nic_byte(dev, offset); /* To make sure write operation is completed, 2005.11.09, by rcnjko. */
133 void
134 PlatformIOWrite2Byte(
135 struct net_device *dev,
136 u32 offset,
137 u16 data
140 write_nic_word(dev, offset, data);
141 read_nic_word(dev, offset); /* To make sure write operation is completed, 2005.11.09, by rcnjko. */
145 u8 PlatformIORead1Byte(struct net_device *dev, u32 offset);
147 void
148 PlatformIOWrite4Byte(
149 struct net_device *dev,
150 u32 offset,
151 u32 data
154 /* {by amy 080312 */
155 if (offset == PhyAddr) {
156 /* For Base Band configuration. */
157 unsigned char cmdByte;
158 unsigned long dataBytes;
159 unsigned char idx;
160 u8 u1bTmp;
162 cmdByte = (u8)(data & 0x000000ff);
163 dataBytes = data>>8;
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.
173 /* NdisAcquireSpinLock( &(pDevice->IoSpinLock) ); */
175 for (idx = 0; idx < 30; idx++) {
176 /* Make sure command bit is clear before access it. */
177 u1bTmp = PlatformIORead1Byte(dev, PhyAddr);
178 if ((u1bTmp & BIT7) == 0)
179 break;
180 else
181 mdelay(10);
184 for (idx = 0; idx < 3; idx++)
185 PlatformIOWrite1Byte(dev, offset+1+idx, ((u8 *)&dataBytes)[idx]);
187 write_nic_byte(dev, offset, cmdByte);
189 /* NdisReleaseSpinLock( &(pDevice->IoSpinLock) ); */
191 /* by amy 080312} */
192 else {
193 write_nic_dword(dev, offset, data);
194 read_nic_dword(dev, offset); /* To make sure write operation is completed, 2005.11.09, by rcnjko. */
199 PlatformIORead1Byte(
200 struct net_device *dev,
201 u32 offset
204 u8 data = 0;
206 data = read_nic_byte(dev, offset);
209 return data;
213 PlatformIORead2Byte(
214 struct net_device *dev,
215 u32 offset
218 u16 data = 0;
220 data = read_nic_word(dev, offset);
223 return data;
227 PlatformIORead4Byte(
228 struct net_device *dev,
229 u32 offset
232 u32 data = 0;
234 data = read_nic_dword(dev, offset);
237 return data;
240 void SetOutputEnableOfRfPins(struct net_device *dev)
242 write_nic_word(dev, RFPinsEnable, 0x1bff);
245 static int
246 HwHSSIThreeWire(
247 struct net_device *dev,
248 u8 *pDataBuf,
249 u8 nDataBufBitCnt,
250 int bSI,
251 int bWrite
254 int bResult = 1;
255 u8 TryCnt;
256 u8 u1bTmp;
258 do {
259 /* Check if WE and RE are cleared. */
260 for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) {
261 u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
262 if ((u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0)
263 break;
265 udelay(10);
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;
274 /* RTL8187S HSSI Read/Write Function */
275 u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
277 if (bSI)
278 u1bTmp |= RF_SW_CFG_SI; /* reg08[1]=1 Serial Interface(SI) */
280 else
281 u1bTmp &= ~RF_SW_CFG_SI; /* reg08[1]=0 Parallel Interface(PI) */
284 write_nic_byte(dev, RF_SW_CONFIG, u1bTmp);
286 if (bSI) {
287 /* jong: HW SI read must set reg84[3]=0. */
288 u1bTmp = read_nic_byte(dev, RFPinsSelect);
289 u1bTmp &= ~BIT3;
290 write_nic_byte(dev, RFPinsSelect, u1bTmp);
292 /* Fill up data buffer for write operation. */
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 {
302 int idx;
303 int ByteCnt = nDataBufBitCnt / 8;
304 /* printk("%d\n",nDataBufBitCnt); */
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;
315 if (nDataBufBitCnt > 64) {
316 printk(KERN_ERR "rtl8187se: HwThreeWire():"
317 " nDataBufBitCnt(%d) should <= 64!!!\n",
318 nDataBufBitCnt);
319 dump_stack();
320 nDataBufBitCnt = 64;
323 for (idx = 0; idx < ByteCnt; idx++)
324 write_nic_byte(dev, (SW_3W_DB0+idx), *(pDataBuf+idx));
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);
337 /* Set up command: WE or RE. */
338 if (bWrite)
339 write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_WE);
341 else
342 write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_RE);
345 /* Check if DONE is set. */
346 for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) {
347 u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
348 if ((u1bTmp & SW_3W_CMD1_DONE) != 0)
349 break;
351 udelay(10);
354 write_nic_byte(dev, SW_3W_CMD1, 0);
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);
366 *((u16 *)pDataBuf) &= 0x0FFF;
369 } while (0);
371 return bResult;
374 void
375 RF_WriteReg(struct net_device *dev, u8 offset, u32 data)
377 u32 data2Write;
378 u8 len;
380 /* Pure HW 3-wire. */
381 data2Write = (data << 4) | (u32)(offset & 0x0f);
382 len = 16;
384 HwHSSIThreeWire(dev, (u8 *)(&data2Write), len, 1, 1);
387 u32 RF_ReadReg(struct net_device *dev, u8 offset)
389 u32 data2Write;
390 u8 wlen;
391 u32 dataRead;
393 data2Write = ((u32)(offset & 0x0f));
394 wlen = 16;
395 HwHSSIThreeWire(dev, (u8 *)(&data2Write), wlen, 1, 0);
396 dataRead = data2Write;
398 return dataRead;
402 /* by Owen on 04/07/14 for writing BB register successfully */
403 void
404 WriteBBPortUchar(
405 struct net_device *dev,
406 u32 Data
409 /* u8 TimeoutCounter; */
410 u8 RegisterContent;
411 u8 UCharData;
413 UCharData = (u8)((Data & 0x0000ff00) >> 8);
414 PlatformIOWrite4Byte(dev, PhyAddr, Data);
415 /* for(TimeoutCounter = 10; TimeoutCounter > 0; TimeoutCounter--) */
417 PlatformIOWrite4Byte(dev, PhyAddr, Data & 0xffffff7f);
418 RegisterContent = PlatformIORead1Byte(dev, PhyDataR);
419 /*if(UCharData == RegisterContent) */
420 /* break; */
425 ReadBBPortUchar(
426 struct net_device *dev,
427 u32 addr
430 /*u8 TimeoutCounter; */
431 u8 RegisterContent;
433 PlatformIOWrite4Byte(dev, PhyAddr, addr & 0xffffff7f);
434 RegisterContent = PlatformIORead1Byte(dev, PhyDataR);
436 return RegisterContent;
438 /* {by amy 080312 */
440 Description:
441 Perform Antenna settings with antenna diversity on 87SE.
442 Created by Roger, 2008.01.25.
444 bool
445 SetAntennaConfig87SE(
446 struct net_device *dev,
447 u8 DefaultAnt, /* 0: Main, 1: Aux. */
448 bool bAntDiversity /* 1:Enable, 0: Disable. */
451 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
452 bool bAntennaSwitched = true;
454 /* printk("SetAntennaConfig87SE(): DefaultAnt(%d), bAntDiversity(%d)\n", DefaultAnt, bAntDiversity); */
456 /* Threshold for antenna diversity. */
457 write_phy_cck(dev, 0x0c, 0x09); /* Reg0c : 09 */
459 if (bAntDiversity) { /* Enable Antenna Diversity. */
460 if (DefaultAnt == 1) { /* aux antenna */
462 /* Mac register, aux antenna */
463 write_nic_byte(dev, ANTSEL, 0x00);
465 /* Config CCK RX antenna. */
466 write_phy_cck(dev, 0x11, 0xbb); /* Reg11 : bb */
467 write_phy_cck(dev, 0x01, 0xc7); /* Reg01 : c7 */
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 */
474 write_nic_byte(dev, ANTSEL, 0x03);
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 */
480 /* Config OFDM RX antenna. */
481 write_phy_ofdm(dev, 0x0d, 0x5c); /* Reg0d : 5c */
482 write_phy_ofdm(dev, 0x18, 0xb2); /* Reg18 : b2 */
484 } else {
485 /* Disable Antenna Diversity. */
486 if (DefaultAnt == 1) { /* aux Antenna */
487 /* Mac register, aux antenna */
488 write_nic_byte(dev, ANTSEL, 0x00);
490 /* Config CCK RX antenna. */
491 write_phy_cck(dev, 0x11, 0xbb); /* Reg11 : bb */
492 write_phy_cck(dev, 0x01, 0x47); /* Reg01 : 47 */
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 */
499 write_nic_byte(dev, ANTSEL, 0x03);
501 /* Config CCK RX antenna. */
502 write_phy_cck(dev, 0x11, 0x9b); /* Reg11 : 9b */
503 write_phy_cck(dev, 0x01, 0x47); /* Reg01 : 47 */
505 /* Config OFDM RX antenna. */
506 write_phy_ofdm(dev, 0x0D, 0x5c); /* Reg0d : 5c */
507 write_phy_ofdm(dev, 0x18, 0x32); /*Reg18 : 32 */
510 priv->CurrAntennaIndex = DefaultAnt; /* Update default settings. */
511 return bAntennaSwitched;
513 /* by amy 080312 */
515 ---------------------------------------------------------------
516 * Hardware Initialization.
517 * the code is ported from Windows source code
518 ----------------------------------------------------------------*/
520 void
521 ZEBRA_Config_85BASIC_HardCode(
522 struct net_device *dev
526 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
527 u32 i;
528 u32 addr, data;
529 u32 u4bRegOffset, u4bRegValue, u4bRF23, u4bRF24;
530 u8 u1b24E;
531 int d_cut = 0;
535 =============================================================================
536 87S_PCIE :: RADIOCFG.TXT
537 =============================================================================
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);
546 if (u4bRF23 == 0x818 && u4bRF24 == 0x70C) {
547 d_cut = 1;
548 printk(KERN_INFO "rtl8187se: card type changed from C- to D-cut\n");
551 /* Page0 : reg0-reg15 */
553 RF_WriteReg(dev, 0x00, 0x009f); mdelay(1);/* 1 */
555 RF_WriteReg(dev, 0x01, 0x06e0); mdelay(1);
557 RF_WriteReg(dev, 0x02, 0x004d); mdelay(1);/* 2 */
559 RF_WriteReg(dev, 0x03, 0x07f1); mdelay(1);/* 3 */
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);
575 /* Page1 : reg16-reg30 */
576 RF_WriteReg(dev, 0x00, 0x013f); mdelay(1);
578 RF_WriteReg(dev, 0x03, 0x0806); mdelay(1);
580 RF_WriteReg(dev, 0x04, 0x03a7); mdelay(1);
581 RF_WriteReg(dev, 0x05, 0x059b); mdelay(1);
582 RF_WriteReg(dev, 0x06, 0x0081); mdelay(1);
585 RF_WriteReg(dev, 0x07, 0x01A0); mdelay(1);
586 /* Don't write RF23/RF24 to make a difference between 87S C cut and D cut. asked by SD3 stevenl. */
587 RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1);
588 RF_WriteReg(dev, 0x0b, 0x0418); mdelay(1);
590 if (d_cut) {
591 RF_WriteReg(dev, 0x0c, 0x0fbe); mdelay(1);
592 RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1);
593 RF_WriteReg(dev, 0x0e, 0x0807); mdelay(1); /* RX LO buffer */
594 } else {
595 RF_WriteReg(dev, 0x0c, 0x0fbe); mdelay(1);
596 RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1);
597 RF_WriteReg(dev, 0x0e, 0x0806); mdelay(1); /* RX LO buffer */
600 RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1);
602 RF_WriteReg(dev, 0x00, 0x01d7); mdelay(1); /* 6 */
604 RF_WriteReg(dev, 0x03, 0x0e00); mdelay(1);
605 RF_WriteReg(dev, 0x04, 0x0e50); mdelay(1);
606 for (i = 0; i <= 36; i++) {
607 RF_WriteReg(dev, 0x01, i); mdelay(1);
608 RF_WriteReg(dev, 0x02, ZEBRA_RF_RX_GAIN_TABLE[i]); mdelay(1);
611 RF_WriteReg(dev, 0x05, 0x0203); mdelay(1); /* 203, 343 */
612 RF_WriteReg(dev, 0x06, 0x0200); mdelay(1); /* 400 */
614 RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); /* switch to reg16-reg30, and HSSI disable 137 */
615 mdelay(10); /* Deay 10 ms. */ /* 0xfd */
617 RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); /* Z4 synthesizer loop filter setting, 392 */
618 mdelay(10); /* Deay 10 ms. */ /* 0xfd */
620 RF_WriteReg(dev, 0x00, 0x0037); mdelay(1); /* switch to reg0-reg15, and HSSI disable */
621 mdelay(10); /* Deay 10 ms. */ /* 0xfd */
623 RF_WriteReg(dev, 0x04, 0x0160); mdelay(1); /* CBC on, Tx Rx disable, High gain */
624 mdelay(10); /* Deay 10 ms. */ /* 0xfd */
626 RF_WriteReg(dev, 0x07, 0x0080); mdelay(1); /* Z4 setted channel 1 */
627 mdelay(10); /* Deay 10 ms. */ /* 0xfd */
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 */
634 RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); /* switch to reg16-reg30 137, and HSSI disable 137 */
635 mdelay(10); /* Deay 10 ms. */ /* 0xfd */
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);
642 /* DAC calibration off 20070702 */
643 RF_WriteReg(dev, 0x06, 0x00c1); mdelay(1);
644 RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1);
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);
654 printk("ZEBRA_Config_85BASIC_HardCode(): (%02x)\n",
655 (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) | BIT11 | BIT9);
656 } else {
657 /* using default value. Xin=6, Xout=6. */
658 RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1);
660 /* by amy 080312 */
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 */
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. */
676 u1b24E = read_nic_byte(dev, 0x24E);
677 write_nic_byte(dev, 0x24E, (u1b24E & (~(BIT5|BIT6))));
679 /*=============================================================================
681 =============================================================================
682 CCKCONF.TXT
683 =============================================================================
685 /* [POWER SAVE] Power Saving Parameters by jong. 2007-11-27
686 CCK reg0x00[7]=1'b1 :power saving for TX (default)
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
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);
700 /* power control */
701 write_nic_byte(dev, CCK_TXAGC, 0x10);
702 write_nic_byte(dev, OFDM_TXAGC, 0x1B);
703 write_nic_byte(dev, ANTSEL, 0x03);
708 =============================================================================
709 AGC.txt
710 =============================================================================
713 write_phy_ofdm(dev, 0x00, 0x12);
715 for (i = 0; i < 128; i++) {
717 data = ZEBRA_AGC[i+1];
718 data = data << 8;
719 data = data | 0x0000008F;
721 addr = i + 0x80; /* enable writing AGC table */
722 addr = addr << 8;
723 addr = addr | 0x0000008E;
725 WriteBBPortUchar(dev, data);
726 WriteBBPortUchar(dev, addr);
727 WriteBBPortUchar(dev, 0x0000008E);
730 PlatformIOWrite4Byte(dev, PhyAddr, 0x00001080); /* Annie, 2006-05-05 */
733 =============================================================================
735 =============================================================================
736 OFDMCONF.TXT
737 =============================================================================
740 for (i = 0; i < 60; i++) {
741 u4bRegOffset = i;
742 u4bRegValue = OFDM_CONFIG[i];
744 WriteBBPortUchar(dev,
745 (0x00000080 |
746 (u4bRegOffset & 0x7f) |
747 ((u4bRegValue & 0xff) << 8)));
751 =============================================================================
752 by amy for antenna
753 =============================================================================
755 /* {by amy 080312 */
756 /* Config Sw/Hw Combinational Antenna Diversity. Added by Roger, 2008.02.26. */
757 SetAntennaConfig87SE(dev, priv->bDefaultAntenna1, priv->bSwAntennaDiverity);
758 /* by amy 080312} */
759 /* by amy for antenna */
763 void
764 UpdateInitialGain(
765 struct net_device *dev
768 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
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
776 priv->InitialGain = priv->InitialGainBackUp;
777 return;
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;
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;
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;
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;
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;
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;
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);
821 break;
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;
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);
833 break;
837 Description:
838 Tx Power tracking mechanism routine on 87SE.
839 Created by Roger, 2007.12.11.
841 void
842 InitTxPwrTracking87SE(
843 struct net_device *dev
846 u32 u4bRfReg;
848 u4bRfReg = RF_ReadReg(dev, 0x02);
850 /* Enable Thermal meter indication. */
851 RF_WriteReg(dev, 0x02, u4bRfReg|PWR_METER_EN); mdelay(1);
854 void
855 PhyConfig8185(
856 struct net_device *dev
859 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
860 write_nic_dword(dev, RCR, priv->ReceiveConfig);
861 priv->RFProgType = read_nic_byte(dev, CONFIG4) & 0x03;
862 /* RF config */
863 ZEBRA_Config_85BASIC_HardCode(dev);
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)
868 priv->InitialGain = 4;
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.
876 if (priv->bTxPowerTrack)
877 InitTxPwrTracking87SE(dev);
879 /* by amy 080312} */
880 priv->InitialGainBackUp = priv->InitialGain;
881 UpdateInitialGain(dev);
883 return;
886 void
887 HwConfigureRTL8185(
888 struct net_device *dev
891 /* RTL8185_TODO: Determine Retrylimit, TxAGC, AutoRateFallback control. */
892 u8 bUNIVERSAL_CONTROL_RL = 0;
893 u8 bUNIVERSAL_CONTROL_AGC = 1;
894 u8 bUNIVERSAL_CONTROL_ANT = 1;
895 u8 bAUTO_RATE_FALLBACK_CTL = 1;
896 u8 val8;
897 write_nic_word(dev, BRSR, 0x0fff);
898 /* Retry limit */
899 val8 = read_nic_byte(dev, CW_CONF);
901 if (bUNIVERSAL_CONTROL_RL)
902 val8 = val8 & 0xfd;
903 else
904 val8 = val8 | 0x02;
906 write_nic_byte(dev, CW_CONF, val8);
908 /* Tx AGC */
909 val8 = read_nic_byte(dev, TXAGC_CTL);
910 if (bUNIVERSAL_CONTROL_AGC) {
911 write_nic_byte(dev, CCK_TXAGC, 128);
912 write_nic_byte(dev, OFDM_TXAGC, 128);
913 val8 = val8 & 0xfe;
914 } else {
915 val8 = val8 | 0x01 ;
919 write_nic_byte(dev, TXAGC_CTL, val8);
921 /* Tx Antenna including Feedback control */
922 val8 = read_nic_byte(dev, TXAGC_CTL);
924 if (bUNIVERSAL_CONTROL_ANT) {
925 write_nic_byte(dev, ANTSEL, 0x00);
926 val8 = val8 & 0xfd;
927 } else {
928 val8 = val8 & (val8|0x02); /* xiong-2006-11-15 */
931 write_nic_byte(dev, TXAGC_CTL, val8);
933 /* Auto Rate fallback control */
934 val8 = read_nic_byte(dev, RATE_FALLBACK);
935 val8 &= 0x7c;
936 if (bAUTO_RATE_FALLBACK_CTL) {
937 val8 |= RATE_FALLBACK_CTL_ENABLE | RATE_FALLBACK_CTL_AUTO_STEP1;
939 /* <RJ_TODO_8185B> We shall set up the ARFR according to user's setting. */
940 PlatformIOWrite2Byte(dev, ARFR, 0x0fff); /* set 1M ~ 54Mbps. */
942 write_nic_byte(dev, RATE_FALLBACK, val8);
945 static void
946 MacConfig_85BASIC_HardCode(
947 struct net_device *dev)
950 ============================================================================
951 MACREG.TXT
952 ============================================================================
954 int nLinesRead = 0;
956 u32 u4bRegOffset, u4bRegValue, u4bPageIndex = 0;
957 int i;
959 nLinesRead = sizeof(MAC_REG_TABLE)/2;
961 for (i = 0; i < nLinesRead; i++) { /* nLinesRead=101 */
962 u4bRegOffset = MAC_REG_TABLE[i][0];
963 u4bRegValue = MAC_REG_TABLE[i][1];
965 if (u4bRegOffset == 0x5e)
966 u4bPageIndex = u4bRegValue;
968 else
969 u4bRegOffset |= (u4bPageIndex << 8);
971 write_nic_byte(dev, u4bRegOffset, (u8)u4bRegValue);
973 /* ============================================================================ */
976 static void
977 MacConfig_85BASIC(
978 struct net_device *dev)
981 u8 u1DA;
982 MacConfig_85BASIC_HardCode(dev);
984 /* ============================================================================ */
986 /* Follow TID_AC_MAP of WMac. */
987 write_nic_word(dev, TID_AC_MAP, 0xfa50);
989 /* Interrupt Migration, Jong suggested we use set 0x0000 first, 2005.12.14, by rcnjko. */
990 write_nic_word(dev, IntMig, 0x0000);
992 /* Prevent TPC to cause CRC error. Added by Annie, 2006-06-10. */
993 PlatformIOWrite4Byte(dev, 0x1F0, 0x00000000);
994 PlatformIOWrite4Byte(dev, 0x1F4, 0x00000000);
995 PlatformIOWrite1Byte(dev, 0x1F8, 0x00);
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. */
1000 /* Enable DA10 TX power saving */
1001 u1DA = read_nic_byte(dev, PHYPR);
1002 write_nic_byte(dev, PHYPR, (u1DA | BIT2));
1004 /* POWER: */
1005 write_nic_word(dev, 0x360, 0x1000);
1006 write_nic_word(dev, 0x362, 0x1000);
1008 /* AFE. */
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);
1016 write_nic_word(dev, 0x37E, 0x00EC); /*+edward */
1017 write_nic_byte(dev, 0x24E, 0x01);
1021 GetSupportedWirelessMode8185(
1022 struct net_device *dev
1025 u8 btSupportedWirelessMode = 0;
1027 btSupportedWirelessMode = (WIRELESS_MODE_B | WIRELESS_MODE_G);
1028 return btSupportedWirelessMode;
1031 void
1032 ActUpdateChannelAccessSetting(
1033 struct net_device *dev,
1034 WIRELESS_MODE WirelessMode,
1035 PCHANNEL_ACCESS_SETTING ChnlAccessSetting
1038 struct r8180_priv *priv = ieee80211_priv(dev);
1039 struct ieee80211_device *ieee = priv->ieee80211;
1040 AC_CODING eACI;
1041 AC_PARAM AcParam;
1042 u8 bFollowLegacySetting = 0;
1043 u8 u1bAIFS;
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.
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.
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. */
1062 write_nic_byte(dev, SIFS, ChnlAccessSetting->SIFS_Timer);
1063 write_nic_byte(dev, SLOT, ChnlAccessSetting->SlotTimeTimer); /* Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29. */
1065 u1bAIFS = aSifsTime + (2 * ChnlAccessSetting->SlotTimeTimer);
1067 write_nic_byte(dev, EIFS, ChnlAccessSetting->EIFS_Timer);
1069 write_nic_byte(dev, AckTimeOutReg, 0x5B); /* <RJ_EXPR_QOS> Suggested by wcchu, it is the default value of EIFS register, 2005.12.08. */
1071 { /* Legacy 802.11. */
1072 bFollowLegacySetting = 1;
1076 /* this setting is copied from rtl8187B. xiong-2006-11-13 */
1077 if (bFollowLegacySetting) {
1080 Follow 802.11 seeting to AC parameter, all AC shall use the same parameter.
1081 2005.12.01, by rcnjko.
1083 AcParam.longData = 0;
1084 AcParam.f.AciAifsn.f.AIFSN = 2; /* Follow 802.11 DIFS. */
1085 AcParam.f.AciAifsn.f.ACM = 0;
1086 AcParam.f.Ecw.f.ECWmin = ChnlAccessSetting->CWminIndex; /* Follow 802.11 CWmin. */
1087 AcParam.f.Ecw.f.ECWmax = ChnlAccessSetting->CWmaxIndex; /* Follow 802.11 CWmax. */
1088 AcParam.f.TXOPLimit = 0;
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)
1093 AcParam.f.TXOPLimit = 0x01FF;
1094 /* For 87SE with Intel 4965 Ad-Hoc mode have poor throughput (19MB) */
1095 if (ieee->iw_mode == IW_MODE_ADHOC)
1096 AcParam.f.TXOPLimit = 0x0020;
1098 for (eACI = 0; eACI < AC_MAX; eACI++) {
1099 AcParam.f.AciAifsn.f.ACI = (u8)eACI;
1101 PAC_PARAM pAcParam = (PAC_PARAM)(&AcParam);
1102 AC_CODING eACI;
1103 u8 u1bAIFS;
1104 u32 u4bAcParam;
1106 /* Retrive paramters to udpate. */
1107 eACI = pAcParam->f.AciAifsn.f.ACI;
1108 u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * ChnlAccessSetting->SlotTimeTimer + aSifsTime;
1109 u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) |
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));
1114 switch (eACI) {
1115 case AC1_BK:
1116 /* write_nic_dword(dev, AC_BK_PARAM, u4bAcParam); */
1117 break;
1119 case AC0_BE:
1120 /* write_nic_dword(dev, AC_BK_PARAM, u4bAcParam); */
1121 break;
1123 case AC2_VI:
1124 /* write_nic_dword(dev, AC_BK_PARAM, u4bAcParam); */
1125 break;
1127 case AC3_VO:
1128 /* write_nic_dword(dev, AC_BK_PARAM, u4bAcParam); */
1129 break;
1131 default:
1132 DMESGW("SetHwReg8185(): invalid ACI: %d !\n", eACI);
1133 break;
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. */
1139 PACI_AIFSN pAciAifsn = (PACI_AIFSN)(&pAcParam->f.AciAifsn);
1140 AC_CODING eACI = pAciAifsn->f.ACI;
1142 /*modified Joseph */
1143 /*for 8187B AsynIORead issue */
1144 u8 AcmCtrl = 0;
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;
1152 case AC2_VI:
1153 AcmCtrl |= (VIQ_ACM_EN|VIQ_ACM_CTL|ACM_HW_EN); /* or 0x42 */
1154 break;
1156 case AC3_VO:
1157 AcmCtrl |= (VOQ_ACM_EN|VOQ_ACM_CTL|ACM_HW_EN); /* or 0x84 */
1158 break;
1160 default:
1161 DMESGW("SetHwReg8185(): [HW_VAR_ACM_CTRL] ACM set failed: eACI is %d\n", eACI);
1162 break;
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;
1171 case AC2_VI:
1172 AcmCtrl &= ((~VIQ_ACM_EN) & (~VIQ_ACM_CTL) & (~ACM_HW_EN)); /* and 0xBD */
1173 break;
1175 case AC3_VO:
1176 AcmCtrl &= ((~VOQ_ACM_EN) & (~VOQ_ACM_CTL) & (~ACM_HW_EN)); /* and 0x7B */
1177 break;
1179 default:
1180 break;
1183 write_nic_byte(dev, ACM_CONTROL, 0);
1190 void
1191 ActSetWirelessMode8185(
1192 struct net_device *dev,
1193 u8 btWirelessMode
1196 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1197 struct ieee80211_device *ieee = priv->ieee80211;
1198 u8 btSupportedWirelessMode = GetSupportedWirelessMode8185(dev);
1200 if ((btWirelessMode & btSupportedWirelessMode) == 0) {
1201 /* Don't switch to unsupported wireless mode, 2006.02.15, by rcnjko. */
1202 DMESGW("ActSetWirelessMode8185(): WirelessMode(%d) is not supported (%d)!\n",
1203 btWirelessMode, btSupportedWirelessMode);
1204 return;
1207 /* 1. Assign wireless mode to swtich if necessary. */
1208 if (btWirelessMode == WIRELESS_MODE_AUTO) {
1209 if ((btSupportedWirelessMode & WIRELESS_MODE_A)) {
1210 btWirelessMode = WIRELESS_MODE_A;
1211 } else if (btSupportedWirelessMode & WIRELESS_MODE_G) {
1212 btWirelessMode = WIRELESS_MODE_G;
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;
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. */
1228 ieee->mode = (WIRELESS_MODE)btWirelessMode;
1230 /* 3. Change related setting. */
1231 if( ieee->mode == WIRELESS_MODE_A ) {
1232 DMESG("WIRELESS_MODE_A\n");
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");
1238 ActUpdateChannelAccessSetting( dev, ieee->mode, &priv->ChannelAccessSetting);
1241 void rtl8185b_irq_enable(struct net_device *dev)
1243 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1245 priv->irq_enabled = 1;
1246 write_nic_dword(dev, IMR, priv->IntrMask);
1248 /* by amy for power save */
1249 void
1250 DrvIFIndicateDisassociation(
1251 struct net_device *dev,
1252 u16 reason
1255 /* nothing is needed after disassociation request. */
1257 void
1258 MgntDisconnectIBSS(
1259 struct net_device *dev
1262 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1263 u8 i;
1265 DrvIFIndicateDisassociation(dev, unspec_reason);
1267 for (i = 0; i < 6 ; i++)
1268 priv->ieee80211->current_network.bssid[i] = 0x55;
1272 priv->ieee80211->state = IEEE80211_NOLINK;
1274 Stop Beacon.
1276 Vista add a Adhoc profile, HW radio off until OID_DOT11_RESET_REQUEST
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.
1280 Disable Beacon Queue Own bit, suggested by jong */
1281 ieee80211_stop_send_beacons(priv->ieee80211);
1283 priv->ieee80211->link_change(dev);
1284 notify_wx_assoc_event(priv->ieee80211);
1286 void
1287 MlmeDisassociateRequest(
1288 struct net_device *dev,
1289 u8 *asSta,
1290 u8 asRsn
1293 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1294 u8 i;
1296 SendDisassociation(priv->ieee80211, asSta, asRsn);
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. */
1301 DrvIFIndicateDisassociation(dev, unspec_reason);
1305 for (i = 0; i < 6; i++)
1306 priv->ieee80211->current_network.bssid[i] = 0x22;
1308 ieee80211_disassociate(priv->ieee80211);
1313 void
1314 MgntDisconnectAP(
1315 struct net_device *dev,
1316 u8 asRsn
1319 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1322 Commented out by rcnjko, 2005.01.27:
1323 I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE().
1325 2004/09/15, kcwu, the key should be cleared, or the new handshaking will not success
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);
1331 priv->ieee80211->state = IEEE80211_NOLINK;
1333 bool
1334 MgntDisconnect(
1335 struct net_device *dev,
1336 u8 asRsn
1339 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1341 Schedule an workitem to wake up for ps mode, 070109, by rcnjko.
1344 if (IS_DOT11D_ENABLE(priv->ieee80211))
1345 Dot11d_Reset(priv->ieee80211);
1346 /* In adhoc mode, update beacon frame. */
1347 if (priv->ieee80211->state == IEEE80211_LINKED) {
1348 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1349 MgntDisconnectIBSS(dev);
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. */
1357 MgntDisconnectAP(dev, asRsn);
1359 /* Inidicate Disconnect, 2005.02.23, by rcnjko. */
1361 return true;
1364 Description:
1365 Chang RF Power State.
1366 Note that, only MgntActSet_RF_State() is allowed to set HW_VAR_RF_STATE.
1368 Assumption:
1369 PASSIVE LEVEL.
1371 bool
1372 SetRFPowerState(
1373 struct net_device *dev,
1374 RT_RF_POWER_STATE eRFPowerState
1377 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1378 bool bResult = false;
1380 if (eRFPowerState == priv->eRFPowerState)
1381 return bResult;
1383 bResult = SetZebraRFPowerState8185(dev, eRFPowerState);
1385 return bResult;
1387 void
1388 HalEnableRx8185Dummy(
1389 struct net_device *dev
1393 void
1394 HalDisableRx8185Dummy(
1395 struct net_device *dev
1400 bool
1401 MgntActSet_RF_State(
1402 struct net_device *dev,
1403 RT_RF_POWER_STATE StateToSet,
1404 u32 ChangeSource
1407 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1408 bool bActionAllowed = false;
1409 bool bConnectBySSID = false;
1410 RT_RF_POWER_STATE rtState;
1411 u16 RFWaitCounter = 0;
1412 unsigned long flag;
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.
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 */
1426 /* Wait too long, return FALSE to avoid to be stuck here. */
1427 if (RFWaitCounter > 1000) { /* 1sec */
1428 printk("MgntActSet_RF_State(): Wait too long to set RF\n");
1429 /* TODO: Reset RF state? */
1430 return false;
1433 } else {
1434 priv->RFChangeInProgress = true;
1435 spin_unlock_irqrestore(&priv->rf_ps_lock, flag);
1436 break;
1439 rtState = priv->eRFPowerState;
1441 switch (StateToSet) {
1442 case eRfOn:
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.
1447 priv->RfOffReason &= (~ChangeSource);
1449 if (!priv->RfOffReason) {
1450 priv->RfOffReason = 0;
1451 bActionAllowed = true;
1453 if (rtState == eRfOff && ChangeSource >= RF_CHANGE_BY_HW && !priv->bInHctTest)
1454 bConnectBySSID = true;
1456 } else
1458 break;
1460 case eRfOff:
1461 /* 070125, rcnjko: we always keep connected in AP mode. */
1463 if (priv->RfOffReason > RF_CHANGE_BY_IPS) {
1465 060808, Annie:
1466 Disconnect to current BSS when radio off. Asked by QuanTa.
1468 Calling MgntDisconnect() instead of MgntActSet_802_11_DISASSOCIATE(),
1469 because we do NOT need to set ssid to dummy ones.
1471 MgntDisconnect(dev, disas_lv_ss);
1473 /* Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI. */
1476 priv->RfOffReason |= ChangeSource;
1477 bActionAllowed = true;
1478 break;
1479 case eRfSleep:
1480 priv->RfOffReason |= ChangeSource;
1481 bActionAllowed = true;
1482 break;
1483 default:
1484 break;
1487 if (bActionAllowed) {
1488 /* Config HW to the specified mode. */
1489 SetRFPowerState(dev, StateToSet);
1491 /* Turn on RF. */
1492 if (StateToSet == eRfOn) {
1493 HalEnableRx8185Dummy(dev);
1494 if (bConnectBySSID) {
1495 /* by amy not supported */
1498 /* Turn off RF. */
1499 else if (StateToSet == eRfOff)
1500 HalDisableRx8185Dummy(dev);
1504 /* Release RF spinlock */
1505 spin_lock_irqsave(&priv->rf_ps_lock, flag);
1506 priv->RFChangeInProgress = false;
1507 spin_unlock_irqrestore(&priv->rf_ps_lock, flag);
1508 return bActionAllowed;
1510 void
1511 InactivePowerSave(
1512 struct net_device *dev
1515 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
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.
1523 priv->bSwRfProcessing = true;
1525 MgntActSet_RF_State(dev, priv->eInactivePowerState, RF_CHANGE_BY_IPS);
1528 To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
1531 priv->bSwRfProcessing = false;
1535 Description:
1536 Enter the inactive power save mode. RF will be off
1538 void
1539 IPSEnter(
1540 struct net_device *dev
1543 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1544 RT_RF_POWER_STATE rtState;
1545 if (priv->bInactivePs) {
1546 rtState = priv->eRFPowerState;
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)
1556 if (rtState == eRfOn && !priv->bSwRfProcessing
1557 && (priv->ieee80211->state != IEEE80211_LINKED)) {
1558 priv->eInactivePowerState = eRfOff;
1559 InactivePowerSave(dev);
1563 void
1564 IPSLeave(
1565 struct net_device *dev
1568 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1569 RT_RF_POWER_STATE rtState;
1570 if (priv->bInactivePs) {
1571 rtState = priv->eRFPowerState;
1572 if ((rtState == eRfOff || rtState == eRfSleep) && (!priv->bSwRfProcessing) && priv->RfOffReason <= RF_CHANGE_BY_IPS) {
1573 priv->eInactivePowerState = eRfOn;
1574 InactivePowerSave(dev);
1579 void rtl8185b_adapter_start(struct net_device *dev)
1581 struct r8180_priv *priv = ieee80211_priv(dev);
1582 struct ieee80211_device *ieee = priv->ieee80211;
1584 u8 SupportedWirelessMode;
1585 u8 InitWirelessMode;
1586 u8 bInvalidWirelessMode = 0;
1587 u8 tmpu8;
1588 u8 btCR9346;
1589 u8 TmpU1b;
1590 u8 btPSR;
1592 write_nic_byte(dev, 0x24e, (BIT5|BIT6|BIT0));
1593 rtl8180_reset(dev);
1595 priv->dma_poll_mask = 0;
1596 priv->dma_poll_stop_mask = 0;
1598 HwConfigureRTL8185(dev);
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' */
1602 write_nic_word(dev, BcnItv, 100);
1603 write_nic_word(dev, AtimWnd, 2);
1604 PlatformIOWrite2Byte(dev, FEMR, 0xFFFF);
1605 write_nic_byte(dev, WPA_CONFIG, 0);
1606 MacConfig_85BASIC(dev);
1607 /* Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07, by rcnjko. */
1608 /* BT_DEMO_BOARD type */
1609 PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x569a);
1612 -----------------------------------------------------------------------------
1613 Set up PHY related.
1614 -----------------------------------------------------------------------------
1616 /* Enable Config3.PARAM_En to revise AnaaParm. */
1617 write_nic_byte(dev, CR9346, 0xc0); /* enable config register write */
1618 tmpu8 = read_nic_byte(dev, CONFIG3);
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. */
1622 write_nic_dword(dev, ANAPARAM2, ANAPARM2_ASIC_ON);
1623 write_nic_dword(dev, ANAPARAM, ANAPARM_ASIC_ON);
1624 write_nic_word(dev, ANAPARAM3, 0x0010);
1626 write_nic_byte(dev, CONFIG3, tmpu8);
1627 write_nic_byte(dev, CR9346, 0x00);
1628 /* enable EEM0 and EEM1 in 9346CR */
1629 btCR9346 = read_nic_byte(dev, CR9346);
1630 write_nic_byte(dev, CR9346, (btCR9346 | 0xC0));
1632 /* B cut use LED1 to control HW RF on/off */
1633 TmpU1b = read_nic_byte(dev, CONFIG5);
1634 TmpU1b = TmpU1b & ~BIT3;
1635 write_nic_byte(dev, CONFIG5, TmpU1b);
1637 /* disable EEM0 and EEM1 in 9346CR */
1638 btCR9346 &= ~(0xC0);
1639 write_nic_byte(dev, CR9346, btCR9346);
1641 /* Enable Led (suggested by Jong) */
1642 /* B-cut RF Radio on/off 5e[3]=0 */
1643 btPSR = read_nic_byte(dev, PSR);
1644 write_nic_byte(dev, PSR, (btPSR | BIT3));
1645 /* setup initial timing for RFE. */
1646 write_nic_word(dev, RFPinsOutput, 0x0480);
1647 SetOutputEnableOfRfPins(dev);
1648 write_nic_word(dev, RFPinsSelect, 0x2488);
1650 /* PHY config. */
1651 PhyConfig8185(dev);
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.
1658 SupportedWirelessMode = GetSupportedWirelessMode8185(dev);
1659 if ((ieee->mode != WIRELESS_MODE_B) &&
1660 (ieee->mode != WIRELESS_MODE_G) &&
1661 (ieee->mode != WIRELESS_MODE_A) &&
1662 (ieee->mode != WIRELESS_MODE_AUTO)) {
1663 /* It should be one of B, G, A, or AUTO. */
1664 bInvalidWirelessMode = 1;
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) {
1670 bInvalidWirelessMode = 1;
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)) {
1678 InitWirelessMode = WIRELESS_MODE_A;
1679 } else if ((SupportedWirelessMode & WIRELESS_MODE_G)) {
1680 InitWirelessMode = WIRELESS_MODE_G;
1681 } else if ((SupportedWirelessMode & WIRELESS_MODE_B)) {
1682 InitWirelessMode = WIRELESS_MODE_B;
1683 } else {
1684 DMESGW("InitializeAdapter8185(): No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n",
1685 SupportedWirelessMode);
1686 InitWirelessMode = WIRELESS_MODE_B;
1689 /* Initialize RegWirelessMode if it is not a valid one. */
1690 if (bInvalidWirelessMode)
1691 ieee->mode = (WIRELESS_MODE)InitWirelessMode;
1693 } else {
1694 /* One of B, G, A. */
1695 InitWirelessMode = ieee->mode;
1697 /* by amy for power save */
1698 priv->eRFPowerState = eRfOff;
1699 priv->RfOffReason = 0;
1701 MgntActSet_RF_State(dev, eRfOn, 0);
1704 If inactive power mode is enabled, disable rf while in disconnected state.
1706 if (priv->bInactivePs)
1707 MgntActSet_RF_State(dev , eRfOff, RF_CHANGE_BY_IPS);
1709 /* by amy for power save */
1711 ActSetWirelessMode8185(dev, (u8)(InitWirelessMode));
1713 /* ----------------------------------------------------------------------------- */
1715 rtl8185b_irq_enable(dev);
1717 netif_start_queue(dev);
1720 void rtl8185b_rx_enable(struct net_device *dev)
1722 u8 cmd;
1723 /* for now we accept data, management & ctl frame*/
1724 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1727 if (dev->flags & IFF_PROMISC)
1728 DMESG("NIC in promisc mode");
1730 if (priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
1731 dev->flags & IFF_PROMISC) {
1732 priv->ReceiveConfig = priv->ReceiveConfig & (~RCR_APM);
1733 priv->ReceiveConfig = priv->ReceiveConfig | RCR_AAP;
1736 if (priv->ieee80211->iw_mode == IW_MODE_MONITOR)
1737 priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACF | RCR_APWRMGT | RCR_AICV;
1740 if (priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
1741 priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACRC32;
1743 write_nic_dword(dev, RCR, priv->ReceiveConfig);
1745 fix_rx_fifo(dev);
1747 cmd = read_nic_byte(dev, CMD);
1748 write_nic_byte(dev, CMD, cmd | (1<<CMD_RX_ENABLE_SHIFT));
1752 void rtl8185b_tx_enable(struct net_device *dev)
1754 u8 cmd;
1755 u8 byte;
1756 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
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);
1763 fix_tx_fifo(dev);
1765 cmd = read_nic_byte(dev, CMD);
1766 write_nic_byte(dev, CMD, cmd | (1<<CMD_TX_ENABLE_SHIFT));