2 * Copyright (c) Realtek Semiconductor Corp. All rights reserved.
8 * Hardware Initialization and Hardware IO for RTL8185B
10 * Major Change History:
12 * ---------- --------------- -------------------------------
13 * 2006-11-15 Xiong Created
16 * This file is ported from RTL8185B Windows driver.
21 /*--------------------------Include File------------------------------------*/
22 #include <linux/spinlock.h>
25 #include "r8180_rtl8225.h" /* RTL8225 Radio frontend */
26 #include "r8180_93cx6.h" /* Card EEPROM */
28 #include "ieee80211/dot11d.h"
29 /* #define CONFIG_RTL8180_IO_MAP */
30 #define TC_3W_POLL_MAX_TRY_CNT 5
32 static u8 MAC_REG_TABLE[][2] = {
34 /* 0x34(BRSR), 0xBE(RATE_FALLBACK_CTL), 0x1E0(ARFR) would set in HwConfigureRTL8185() */
35 /* 0x272(RFSW_CTRL), 0x1CE(AESMSK_QC) set in InitializeAdapter8185(). */
36 /* 0x1F0~0x1F8 set in MacConfig_85BASIC() */
37 {0x08, 0xae}, {0x0a, 0x72}, {0x5b, 0x42},
38 {0x84, 0x88}, {0x85, 0x24}, {0x88, 0x54}, {0x8b, 0xb8}, {0x8c, 0x03},
39 {0x8d, 0x40}, {0x8e, 0x00}, {0x8f, 0x00}, {0x5b, 0x18}, {0x91, 0x03},
40 {0x94, 0x0F}, {0x95, 0x32},
41 {0x96, 0x00}, {0x97, 0x07}, {0xb4, 0x22}, {0xdb, 0x00},
42 {0xf0, 0x32}, {0xf1, 0x32}, {0xf2, 0x00}, {0xf3, 0x00}, {0xf4, 0x32},
43 {0xf5, 0x43}, {0xf6, 0x00}, {0xf7, 0x00}, {0xf8, 0x46}, {0xf9, 0xa4},
44 {0xfa, 0x00}, {0xfb, 0x00}, {0xfc, 0x96}, {0xfd, 0xa4}, {0xfe, 0x00},
48 /* For Flextronics system Logo PCIHCT failure: */
49 /* 0x1C4~0x1CD set no-zero value to avoid PCI configuration space 0x45[7]=1 */
51 {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x04}, {0x5b, 0x00}, {0x60, 0x24},
52 {0x61, 0x97}, {0x62, 0xF0}, {0x63, 0x09}, {0x80, 0x0F}, {0x81, 0xFF},
53 {0x82, 0xFF}, {0x83, 0x03},
54 {0xC4, 0x22}, {0xC5, 0x22}, {0xC6, 0x22}, {0xC7, 0x22}, {0xC8, 0x22}, /* lzm add 080826 */
55 {0xC9, 0x22}, {0xCA, 0x22}, {0xCB, 0x22}, {0xCC, 0x22}, {0xCD, 0x22}, /* lzm add 080826 */
61 {0x0c, 0x04}, {0x4c, 0x30}, {0x4d, 0x08}, {0x50, 0x05}, {0x51, 0xf5},
62 {0x52, 0x04}, {0x53, 0xa0}, {0x54, 0xff}, {0x55, 0xff}, {0x56, 0xff},
63 {0x57, 0xff}, {0x58, 0x08}, {0x59, 0x08}, {0x5a, 0x08}, {0x5b, 0x08},
64 {0x60, 0x08}, {0x61, 0x08}, {0x62, 0x08}, {0x63, 0x08}, {0x64, 0x2f},
65 {0x8c, 0x3f}, {0x8d, 0x3f}, {0x8e, 0x3f},
66 {0x8f, 0x3f}, {0xc4, 0xff}, {0xc5, 0xff}, {0xc6, 0xff}, {0xc7, 0xff},
67 {0xc8, 0x00}, {0xc9, 0x00}, {0xca, 0x80}, {0xcb, 0x00},
70 {0x5e, 0x00}, {0x9f, 0x03}
74 static u8 ZEBRA_AGC[] = {
76 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72,
77 0x71, 0x70, 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A, 0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62,
78 0x48, 0x47, 0x46, 0x45, 0x44, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x08, 0x07,
79 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x15, 0x16,
81 0x17, 0x17, 0x18, 0x18, 0x19, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e,
82 0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x23, 0x23, 0x24,
83 0x24, 0x25, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F
86 static u32 ZEBRA_RF_RX_GAIN_TABLE[] = {
87 0x0096, 0x0076, 0x0056, 0x0036, 0x0016, 0x01f6, 0x01d6, 0x01b6,
88 0x0196, 0x0176, 0x00F7, 0x00D7, 0x00B7, 0x0097, 0x0077, 0x0057,
89 0x0037, 0x00FB, 0x00DB, 0x00BB, 0x00FF, 0x00E3, 0x00C3, 0x00A3,
90 0x0083, 0x0063, 0x0043, 0x0023, 0x0003, 0x01E3, 0x01C3, 0x01A3,
91 0x0183, 0x0163, 0x0143, 0x0123, 0x0103
94 static u8 OFDM_CONFIG[] = {
95 /* OFDM reg0x06[7:0]=0xFF: Enable power saving mode in RX */
96 /* OFDM reg0x3C[4]=1'b1: Enable RX power saving mode */
97 /* ofdm 0x3a = 0x7b ,(original : 0xfb) For ECS shielding room TP test */
99 0x10, 0x0F, 0x0A, 0x0C, 0x14, 0xFA, 0xFF, 0x50,
100 0x00, 0x50, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00,
102 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xA8, 0x26,
103 0x32, 0x33, 0x06, 0xA5, 0x6F, 0x55, 0xC8, 0xBB,
105 0x0A, 0xE1, 0x2C, 0x4A, 0x86, 0x83, 0x34, 0x00,
106 0x4F, 0x24, 0x6F, 0xC2, 0x03, 0x40, 0x80, 0x00,
108 0xC0, 0xC1, 0x58, 0xF1, 0x00, 0xC4, 0x90, 0x3e,
109 0xD8, 0x3C, 0x7B, 0x10, 0x10
112 /*---------------------------------------------------------------
114 * the code is ported from Windows source code
115 *---------------------------------------------------------------
118 void PlatformIOWrite1Byte(struct net_device *dev, u32 offset, u8 data)
120 write_nic_byte(dev, offset, data);
121 read_nic_byte(dev, offset); /* To make sure write operation is completed, 2005.11.09, by rcnjko. */
124 void PlatformIOWrite2Byte(struct net_device *dev, u32 offset, u16 data)
126 write_nic_word(dev, offset, data);
127 read_nic_word(dev, offset); /* To make sure write operation is completed, 2005.11.09, by rcnjko. */
130 u8 PlatformIORead1Byte(struct net_device *dev, u32 offset);
132 void PlatformIOWrite4Byte(struct net_device *dev, u32 offset, u32 data)
134 if (offset == PhyAddr) {
135 /* For Base Band configuration. */
136 unsigned char cmdByte;
137 unsigned long dataBytes;
141 cmdByte = (u8)(data & 0x000000ff);
146 * The critical section is only BB read/write race condition.
148 * 1. We assume NO one will access BB at DIRQL, otherwise, system will crash for
149 * acquiring the spinlock in such context.
150 * 2. PlatformIOWrite4Byte() MUST NOT be recursive.
152 /* NdisAcquireSpinLock( &(pDevice->IoSpinLock) ); */
154 for (idx = 0; idx < 30; idx++) {
155 /* Make sure command bit is clear before access it. */
156 u1bTmp = PlatformIORead1Byte(dev, PhyAddr);
157 if ((u1bTmp & BIT7) == 0)
163 for (idx = 0; idx < 3; idx++)
164 PlatformIOWrite1Byte(dev, offset+1+idx, ((u8 *)&dataBytes)[idx]);
166 write_nic_byte(dev, offset, cmdByte);
168 /* NdisReleaseSpinLock( &(pDevice->IoSpinLock) ); */
170 write_nic_dword(dev, offset, data);
171 read_nic_dword(dev, offset); /* To make sure write operation is completed, 2005.11.09, by rcnjko. */
175 u8 PlatformIORead1Byte(struct net_device *dev, u32 offset)
179 data = read_nic_byte(dev, offset);
185 u16 PlatformIORead2Byte(struct net_device *dev, u32 offset)
189 data = read_nic_word(dev, offset);
195 u32 PlatformIORead4Byte(struct net_device *dev, u32 offset)
199 data = read_nic_dword(dev, offset);
205 void SetOutputEnableOfRfPins(struct net_device *dev)
207 write_nic_word(dev, RFPinsEnable, 0x1bff);
210 static int HwHSSIThreeWire(struct net_device *dev,
221 /* Check if WE and RE are cleared. */
222 for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) {
223 u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
224 if ((u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0)
229 if (TryCnt == TC_3W_POLL_MAX_TRY_CNT) {
230 printk(KERN_ERR "rtl8187se: HwThreeWire(): CmdReg:"
231 " %#X RE|WE bits are not clear!!\n", u1bTmp);
236 /* RTL8187S HSSI Read/Write Function */
237 u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
240 u1bTmp |= RF_SW_CFG_SI; /* reg08[1]=1 Serial Interface(SI) */
243 u1bTmp &= ~RF_SW_CFG_SI; /* reg08[1]=0 Parallel Interface(PI) */
246 write_nic_byte(dev, RF_SW_CONFIG, u1bTmp);
249 /* jong: HW SI read must set reg84[3]=0. */
250 u1bTmp = read_nic_byte(dev, RFPinsSelect);
252 write_nic_byte(dev, RFPinsSelect, u1bTmp);
254 /* Fill up data buffer for write operation. */
257 if (nDataBufBitCnt == 16) {
258 write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf));
259 } else if (nDataBufBitCnt == 64) {
260 /* RTL8187S shouldn't enter this case */
261 write_nic_dword(dev, SW_3W_DB0, *((u32 *)pDataBuf));
262 write_nic_dword(dev, SW_3W_DB1, *((u32 *)(pDataBuf + 4)));
265 int ByteCnt = nDataBufBitCnt / 8;
266 /* printk("%d\n",nDataBufBitCnt); */
267 if ((nDataBufBitCnt % 8) != 0) {
268 printk(KERN_ERR "rtl8187se: "
269 "HwThreeWire(): nDataBufBitCnt(%d)"
270 " should be multiple of 8!!!\n",
274 nDataBufBitCnt &= ~7;
277 if (nDataBufBitCnt > 64) {
278 printk(KERN_ERR "rtl8187se: HwThreeWire():"
279 " nDataBufBitCnt(%d) should <= 64!!!\n",
285 for (idx = 0; idx < ByteCnt; idx++)
286 write_nic_byte(dev, (SW_3W_DB0+idx), *(pDataBuf+idx));
291 /* SI - reg274[3:0] : RF register's Address */
292 write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf));
294 /* PI - reg274[15:12] : RF register's Address */
295 write_nic_word(dev, SW_3W_DB0, (*((u16 *)pDataBuf)) << 12);
299 /* Set up command: WE or RE. */
301 write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_WE);
304 write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_RE);
307 /* Check if DONE is set. */
308 for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) {
309 u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
310 if ((u1bTmp & SW_3W_CMD1_DONE) != 0)
316 write_nic_byte(dev, SW_3W_CMD1, 0);
318 /* Read back data for read operation. */
321 /* Serial Interface : reg363_362[11:0] */
322 *((u16 *)pDataBuf) = read_nic_word(dev, SI_DATA_READ) ;
324 /* Parallel Interface : reg361_360[11:0] */
325 *((u16 *)pDataBuf) = read_nic_word(dev, PI_DATA_READ);
328 *((u16 *)pDataBuf) &= 0x0FFF;
336 void RF_WriteReg(struct net_device *dev, u8 offset, u32 data)
341 /* Pure HW 3-wire. */
342 data2Write = (data << 4) | (u32)(offset & 0x0f);
345 HwHSSIThreeWire(dev, (u8 *)(&data2Write), len, 1, 1);
348 u32 RF_ReadReg(struct net_device *dev, u8 offset)
354 data2Write = ((u32)(offset & 0x0f));
356 HwHSSIThreeWire(dev, (u8 *)(&data2Write), wlen, 1, 0);
357 dataRead = data2Write;
363 /* by Owen on 04/07/14 for writing BB register successfully */
364 void WriteBBPortUchar(struct net_device *dev, u32 Data)
366 /* u8 TimeoutCounter; */
370 UCharData = (u8)((Data & 0x0000ff00) >> 8);
371 PlatformIOWrite4Byte(dev, PhyAddr, Data);
372 /* for(TimeoutCounter = 10; TimeoutCounter > 0; TimeoutCounter--) */
374 PlatformIOWrite4Byte(dev, PhyAddr, Data & 0xffffff7f);
375 RegisterContent = PlatformIORead1Byte(dev, PhyDataR);
376 /*if(UCharData == RegisterContent) */
381 u8 ReadBBPortUchar(struct net_device *dev, u32 addr)
383 /*u8 TimeoutCounter; */
386 PlatformIOWrite4Byte(dev, PhyAddr, addr & 0xffffff7f);
387 RegisterContent = PlatformIORead1Byte(dev, PhyDataR);
389 return RegisterContent;
393 * Perform Antenna settings with antenna diversity on 87SE.
394 * Created by Roger, 2008.01.25.
396 bool SetAntennaConfig87SE(struct net_device *dev,
397 u8 DefaultAnt, /* 0: Main, 1: Aux. */
398 bool bAntDiversity) /* 1:Enable, 0: Disable. */
400 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
401 bool bAntennaSwitched = true;
403 /* printk("SetAntennaConfig87SE(): DefaultAnt(%d), bAntDiversity(%d)\n", DefaultAnt, bAntDiversity); */
405 /* Threshold for antenna diversity. */
406 write_phy_cck(dev, 0x0c, 0x09); /* Reg0c : 09 */
408 if (bAntDiversity) { /* Enable Antenna Diversity. */
409 if (DefaultAnt == 1) { /* aux antenna */
411 /* Mac register, aux antenna */
412 write_nic_byte(dev, ANTSEL, 0x00);
414 /* Config CCK RX antenna. */
415 write_phy_cck(dev, 0x11, 0xbb); /* Reg11 : bb */
416 write_phy_cck(dev, 0x01, 0xc7); /* Reg01 : c7 */
418 /* Config OFDM RX antenna. */
419 write_phy_ofdm(dev, 0x0D, 0x54); /* Reg0d : 54 */
420 write_phy_ofdm(dev, 0x18, 0xb2); /* Reg18 : b2 */
421 } else { /* use main antenna */
422 /* Mac register, main antenna */
423 write_nic_byte(dev, ANTSEL, 0x03);
425 /* Config CCK RX antenna. */
426 write_phy_cck(dev, 0x11, 0x9b); /* Reg11 : 9b */
427 write_phy_cck(dev, 0x01, 0xc7); /* Reg01 : c7 */
429 /* Config OFDM RX antenna. */
430 write_phy_ofdm(dev, 0x0d, 0x5c); /* Reg0d : 5c */
431 write_phy_ofdm(dev, 0x18, 0xb2); /* Reg18 : b2 */
434 /* Disable Antenna Diversity. */
435 if (DefaultAnt == 1) { /* aux Antenna */
436 /* Mac register, aux antenna */
437 write_nic_byte(dev, ANTSEL, 0x00);
439 /* Config CCK RX antenna. */
440 write_phy_cck(dev, 0x11, 0xbb); /* Reg11 : bb */
441 write_phy_cck(dev, 0x01, 0x47); /* Reg01 : 47 */
443 /* Config OFDM RX antenna. */
444 write_phy_ofdm(dev, 0x0D, 0x54); /* Reg0d : 54 */
445 write_phy_ofdm(dev, 0x18, 0x32); /* Reg18 : 32 */
446 } else { /* main Antenna */
447 /* Mac register, main antenna */
448 write_nic_byte(dev, ANTSEL, 0x03);
450 /* Config CCK RX antenna. */
451 write_phy_cck(dev, 0x11, 0x9b); /* Reg11 : 9b */
452 write_phy_cck(dev, 0x01, 0x47); /* Reg01 : 47 */
454 /* Config OFDM RX antenna. */
455 write_phy_ofdm(dev, 0x0D, 0x5c); /* Reg0d : 5c */
456 write_phy_ofdm(dev, 0x18, 0x32); /*Reg18 : 32 */
459 priv->CurrAntennaIndex = DefaultAnt; /* Update default settings. */
460 return bAntennaSwitched;
463 *--------------------------------------------------------------
464 * Hardware Initialization.
465 * the code is ported from Windows source code
466 *--------------------------------------------------------------
469 void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev)
472 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
475 u32 u4bRegOffset, u4bRegValue, u4bRF23, u4bRF24;
481 *===========================================================================
482 * 87S_PCIE :: RADIOCFG.TXT
483 *===========================================================================
487 /* Page1 : reg16-reg30 */
488 RF_WriteReg(dev, 0x00, 0x013f); mdelay(1); /* switch to page1 */
489 u4bRF23 = RF_ReadReg(dev, 0x08); mdelay(1);
490 u4bRF24 = RF_ReadReg(dev, 0x09); mdelay(1);
492 if (u4bRF23 == 0x818 && u4bRF24 == 0x70C) {
494 printk(KERN_INFO "rtl8187se: card type changed from C- to D-cut\n");
497 /* Page0 : reg0-reg15 */
499 RF_WriteReg(dev, 0x00, 0x009f); mdelay(1);/* 1 */
500 RF_WriteReg(dev, 0x01, 0x06e0); mdelay(1);
501 RF_WriteReg(dev, 0x02, 0x004d); mdelay(1);/* 2 */
502 RF_WriteReg(dev, 0x03, 0x07f1); mdelay(1);/* 3 */
503 RF_WriteReg(dev, 0x04, 0x0975); mdelay(1);
504 RF_WriteReg(dev, 0x05, 0x0c72); mdelay(1);
505 RF_WriteReg(dev, 0x06, 0x0ae6); mdelay(1);
506 RF_WriteReg(dev, 0x07, 0x00ca); mdelay(1);
507 RF_WriteReg(dev, 0x08, 0x0e1c); mdelay(1);
508 RF_WriteReg(dev, 0x09, 0x02f0); mdelay(1);
509 RF_WriteReg(dev, 0x0a, 0x09d0); mdelay(1);
510 RF_WriteReg(dev, 0x0b, 0x01ba); mdelay(1);
511 RF_WriteReg(dev, 0x0c, 0x0640); mdelay(1);
512 RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1);
513 RF_WriteReg(dev, 0x0e, 0x0020); mdelay(1);
514 RF_WriteReg(dev, 0x0f, 0x0990); mdelay(1);
516 /* Page1 : reg16-reg30 */
517 RF_WriteReg(dev, 0x00, 0x013f); mdelay(1);
518 RF_WriteReg(dev, 0x03, 0x0806); mdelay(1);
519 RF_WriteReg(dev, 0x04, 0x03a7); mdelay(1);
520 RF_WriteReg(dev, 0x05, 0x059b); mdelay(1);
521 RF_WriteReg(dev, 0x06, 0x0081); mdelay(1);
522 RF_WriteReg(dev, 0x07, 0x01A0); mdelay(1);
523 /* Don't write RF23/RF24 to make a difference between 87S C cut and D cut. asked by SD3 stevenl. */
524 RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1);
525 RF_WriteReg(dev, 0x0b, 0x0418); mdelay(1);
528 RF_WriteReg(dev, 0x0c, 0x0fbe); mdelay(1);
529 RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1);
530 RF_WriteReg(dev, 0x0e, 0x0807); mdelay(1); /* RX LO buffer */
532 RF_WriteReg(dev, 0x0c, 0x0fbe); mdelay(1);
533 RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1);
534 RF_WriteReg(dev, 0x0e, 0x0806); mdelay(1); /* RX LO buffer */
537 RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1);
538 RF_WriteReg(dev, 0x00, 0x01d7); mdelay(1); /* 6 */
539 RF_WriteReg(dev, 0x03, 0x0e00); mdelay(1);
540 RF_WriteReg(dev, 0x04, 0x0e50); mdelay(1);
542 for (i = 0; i <= 36; i++) {
543 RF_WriteReg(dev, 0x01, i); mdelay(1);
544 RF_WriteReg(dev, 0x02, ZEBRA_RF_RX_GAIN_TABLE[i]); mdelay(1);
547 RF_WriteReg(dev, 0x05, 0x0203); mdelay(1); /* 203, 343 */
548 RF_WriteReg(dev, 0x06, 0x0200); mdelay(1); /* 400 */
549 RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); /* switch to reg16-reg30, and HSSI disable 137 */
550 mdelay(10); /* Deay 10 ms. */ /* 0xfd */
552 RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); /* Z4 synthesizer loop filter setting, 392 */
553 mdelay(10); /* Deay 10 ms. */ /* 0xfd */
555 RF_WriteReg(dev, 0x00, 0x0037); mdelay(1); /* switch to reg0-reg15, and HSSI disable */
556 mdelay(10); /* Deay 10 ms. */ /* 0xfd */
558 RF_WriteReg(dev, 0x04, 0x0160); mdelay(1); /* CBC on, Tx Rx disable, High gain */
559 mdelay(10); /* Deay 10 ms. */ /* 0xfd */
561 RF_WriteReg(dev, 0x07, 0x0080); mdelay(1); /* Z4 setted channel 1 */
562 mdelay(10); /* Deay 10 ms. */ /* 0xfd */
564 RF_WriteReg(dev, 0x02, 0x088D); mdelay(1); /* LC calibration */
565 mdelay(200); /* Deay 200 ms. */ /* 0xfd */
566 mdelay(10); /* Deay 10 ms. */ /* 0xfd */
567 mdelay(10); /* Deay 10 ms. */ /* 0xfd */
569 RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); /* switch to reg16-reg30 137, and HSSI disable 137 */
570 mdelay(10); /* Deay 10 ms. */ /* 0xfd */
572 RF_WriteReg(dev, 0x07, 0x0000); mdelay(1);
573 RF_WriteReg(dev, 0x07, 0x0180); mdelay(1);
574 RF_WriteReg(dev, 0x07, 0x0220); mdelay(1);
575 RF_WriteReg(dev, 0x07, 0x03E0); mdelay(1);
577 /* DAC calibration off 20070702 */
578 RF_WriteReg(dev, 0x06, 0x00c1); mdelay(1);
579 RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1);
580 /* For crystal calibration, added by Roger, 2007.12.11. */
581 if (priv->bXtalCalibration) { /* reg 30. */
583 * enable crystal calibration.
584 * RF Reg[30], (1)Xin:[12:9], Xout:[8:5], addr[4:0].
585 * (2)PA Pwr delay timer[15:14], default: 2.4us, set BIT15=0
586 * (3)RF signal on/off when calibration[13], default: on, set BIT13=0.
587 * So we should minus 4 BITs offset.
589 RF_WriteReg(dev, 0x0f, (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) | BIT11 | BIT9); mdelay(1);
590 printk("ZEBRA_Config_85BASIC_HardCode(): (%02x)\n",
591 (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) | BIT11 | BIT9);
593 /* using default value. Xin=6, Xout=6. */
594 RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1);
597 RF_WriteReg(dev, 0x00, 0x00bf); mdelay(1); /* switch to reg0-reg15, and HSSI enable */
598 RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1); /* Rx BB start calibration, 00c//+edward */
599 RF_WriteReg(dev, 0x02, 0x004d); mdelay(1); /* temperature meter off */
600 RF_WriteReg(dev, 0x04, 0x0975); mdelay(1); /* Rx mode */
601 mdelay(10); /* Deay 10 ms.*/ /* 0xfe */
602 mdelay(10); /* Deay 10 ms.*/ /* 0xfe */
603 mdelay(10); /* Deay 10 ms.*/ /* 0xfe */
604 RF_WriteReg(dev, 0x00, 0x0197); mdelay(1); /* Rx mode*/ /*+edward */
605 RF_WriteReg(dev, 0x05, 0x05ab); mdelay(1); /* Rx mode*/ /*+edward */
606 RF_WriteReg(dev, 0x00, 0x009f); mdelay(1); /* Rx mode*/ /*+edward */
607 RF_WriteReg(dev, 0x01, 0x0000); mdelay(1); /* Rx mode*/ /*+edward */
608 RF_WriteReg(dev, 0x02, 0x0000); mdelay(1); /* Rx mode*/ /*+edward */
609 /* power save parameters. */
610 u1b24E = read_nic_byte(dev, 0x24E);
611 write_nic_byte(dev, 0x24E, (u1b24E & (~(BIT5|BIT6))));
613 /*=============================================================================
615 *===========================================================================
617 *===========================================================================
619 * [POWER SAVE] Power Saving Parameters by jong. 2007-11-27
620 * CCK reg0x00[7]=1'b1 :power saving for TX (default)
621 * CCK reg0x00[6]=1'b1: power saving for RX (default)
622 * CCK reg0x06[4]=1'b1: turn off channel estimation related circuits if not doing channel estimation.
623 * CCK reg0x06[3]=1'b1: turn off unused circuits before cca = 1
624 * CCK reg0x06[2]=1'b1: turn off cck's circuit if macrst =0
627 write_phy_cck(dev, 0x00, 0xc8);
628 write_phy_cck(dev, 0x06, 0x1c);
629 write_phy_cck(dev, 0x10, 0x78);
630 write_phy_cck(dev, 0x2e, 0xd0);
631 write_phy_cck(dev, 0x2f, 0x06);
632 write_phy_cck(dev, 0x01, 0x46);
635 write_nic_byte(dev, CCK_TXAGC, 0x10);
636 write_nic_byte(dev, OFDM_TXAGC, 0x1B);
637 write_nic_byte(dev, ANTSEL, 0x03);
642 *===========================================================================
644 *===========================================================================
647 write_phy_ofdm(dev, 0x00, 0x12);
649 for (i = 0; i < 128; i++) {
651 data = ZEBRA_AGC[i+1];
653 data = data | 0x0000008F;
655 addr = i + 0x80; /* enable writing AGC table */
657 addr = addr | 0x0000008E;
659 WriteBBPortUchar(dev, data);
660 WriteBBPortUchar(dev, addr);
661 WriteBBPortUchar(dev, 0x0000008E);
664 PlatformIOWrite4Byte(dev, PhyAddr, 0x00001080); /* Annie, 2006-05-05 */
667 *===========================================================================
669 *===========================================================================
671 *===========================================================================
674 for (i = 0; i < 60; i++) {
676 u4bRegValue = OFDM_CONFIG[i];
678 WriteBBPortUchar(dev,
680 (u4bRegOffset & 0x7f) |
681 ((u4bRegValue & 0xff) << 8)));
685 *===========================================================================
687 *===========================================================================
689 /* Config Sw/Hw Combinational Antenna Diversity. Added by Roger, 2008.02.26. */
690 SetAntennaConfig87SE(dev, priv->bDefaultAntenna1, priv->bSwAntennaDiverity);
694 void UpdateInitialGain(struct net_device *dev)
696 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
699 if (priv->eRFPowerState != eRfOn) {
700 /* Don't access BB/RF under disable PLL situation.
701 * RT_TRACE(COMP_DIG, DBG_LOUD, ("UpdateInitialGain - pHalData->eRFPowerState!=eRfOn\n"));
702 * Back to the original state
704 priv->InitialGain = priv->InitialGainBackUp;
708 switch (priv->InitialGain) {
709 case 1: /* m861dBm */
710 write_phy_ofdm(dev, 0x17, 0x26); mdelay(1);
711 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
712 write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
715 case 2: /* m862dBm */
716 write_phy_ofdm(dev, 0x17, 0x36); mdelay(1);
717 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
718 write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
721 case 3: /* m863dBm */
722 write_phy_ofdm(dev, 0x17, 0x36); mdelay(1);
723 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
724 write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
727 case 4: /* m864dBm */
728 write_phy_ofdm(dev, 0x17, 0x46); mdelay(1);
729 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
730 write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
734 write_phy_ofdm(dev, 0x17, 0x46); mdelay(1);
735 write_phy_ofdm(dev, 0x24, 0x96); mdelay(1);
736 write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
740 write_phy_ofdm(dev, 0x17, 0x56); mdelay(1);
741 write_phy_ofdm(dev, 0x24, 0x96); mdelay(1);
742 write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
746 write_phy_ofdm(dev, 0x17, 0x56); mdelay(1);
747 write_phy_ofdm(dev, 0x24, 0xa6); mdelay(1);
748 write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
752 write_phy_ofdm(dev, 0x17, 0x66); mdelay(1);
753 write_phy_ofdm(dev, 0x24, 0xb6); mdelay(1);
754 write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
758 write_phy_ofdm(dev, 0x17, 0x26); mdelay(1);
759 write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
760 write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
766 * Tx Power tracking mechanism routine on 87SE.
767 * Created by Roger, 2007.12.11.
769 void InitTxPwrTracking87SE(struct net_device *dev)
773 u4bRfReg = RF_ReadReg(dev, 0x02);
775 /* Enable Thermal meter indication. */
776 RF_WriteReg(dev, 0x02, u4bRfReg|PWR_METER_EN); mdelay(1);
779 void PhyConfig8185(struct net_device *dev)
781 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
782 write_nic_dword(dev, RCR, priv->ReceiveConfig);
783 priv->RFProgType = read_nic_byte(dev, CONFIG4) & 0x03;
785 ZEBRA_Config_85BASIC_HardCode(dev);
786 /* Set default initial gain state to 4, approved by SD3 DZ, by Bruce, 2007-06-06. */
787 if (priv->bDigMechanism) {
788 if (priv->InitialGain == 0)
789 priv->InitialGain = 4;
793 * Enable thermal meter indication to implement TxPower tracking on 87SE.
794 * We initialize thermal meter here to avoid unsuccessful configuration.
795 * Added by Roger, 2007.12.11.
797 if (priv->bTxPowerTrack)
798 InitTxPwrTracking87SE(dev);
800 priv->InitialGainBackUp = priv->InitialGain;
801 UpdateInitialGain(dev);
806 void HwConfigureRTL8185(struct net_device *dev)
808 /* RTL8185_TODO: Determine Retrylimit, TxAGC, AutoRateFallback control. */
809 u8 bUNIVERSAL_CONTROL_RL = 0;
810 u8 bUNIVERSAL_CONTROL_AGC = 1;
811 u8 bUNIVERSAL_CONTROL_ANT = 1;
812 u8 bAUTO_RATE_FALLBACK_CTL = 1;
814 write_nic_word(dev, BRSR, 0x0fff);
816 val8 = read_nic_byte(dev, CW_CONF);
818 if (bUNIVERSAL_CONTROL_RL)
823 write_nic_byte(dev, CW_CONF, val8);
826 val8 = read_nic_byte(dev, TXAGC_CTL);
827 if (bUNIVERSAL_CONTROL_AGC) {
828 write_nic_byte(dev, CCK_TXAGC, 128);
829 write_nic_byte(dev, OFDM_TXAGC, 128);
836 write_nic_byte(dev, TXAGC_CTL, val8);
838 /* Tx Antenna including Feedback control */
839 val8 = read_nic_byte(dev, TXAGC_CTL);
841 if (bUNIVERSAL_CONTROL_ANT) {
842 write_nic_byte(dev, ANTSEL, 0x00);
845 val8 = val8 & (val8|0x02); /* xiong-2006-11-15 */
848 write_nic_byte(dev, TXAGC_CTL, val8);
850 /* Auto Rate fallback control */
851 val8 = read_nic_byte(dev, RATE_FALLBACK);
853 if (bAUTO_RATE_FALLBACK_CTL) {
854 val8 |= RATE_FALLBACK_CTL_ENABLE | RATE_FALLBACK_CTL_AUTO_STEP1;
856 /* <RJ_TODO_8185B> We shall set up the ARFR according to user's setting. */
857 PlatformIOWrite2Byte(dev, ARFR, 0x0fff); /* set 1M ~ 54Mbps. */
859 write_nic_byte(dev, RATE_FALLBACK, val8);
862 static void MacConfig_85BASIC_HardCode(struct net_device *dev)
865 *==========================================================================
867 *==========================================================================
870 u32 u4bRegOffset, u4bRegValue, u4bPageIndex = 0;
873 nLinesRead = sizeof(MAC_REG_TABLE)/2;
875 for (i = 0; i < nLinesRead; i++) { /* nLinesRead=101 */
876 u4bRegOffset = MAC_REG_TABLE[i][0];
877 u4bRegValue = MAC_REG_TABLE[i][1];
879 if (u4bRegOffset == 0x5e)
880 u4bPageIndex = u4bRegValue;
882 u4bRegOffset |= (u4bPageIndex << 8);
884 write_nic_byte(dev, u4bRegOffset, (u8)u4bRegValue);
886 /* ============================================================================ */
889 static void MacConfig_85BASIC(struct net_device *dev)
893 MacConfig_85BASIC_HardCode(dev);
895 /* ============================================================================ */
897 /* Follow TID_AC_MAP of WMac. */
898 write_nic_word(dev, TID_AC_MAP, 0xfa50);
900 /* Interrupt Migration, Jong suggested we use set 0x0000 first, 2005.12.14, by rcnjko. */
901 write_nic_word(dev, IntMig, 0x0000);
903 /* Prevent TPC to cause CRC error. Added by Annie, 2006-06-10. */
904 PlatformIOWrite4Byte(dev, 0x1F0, 0x00000000);
905 PlatformIOWrite4Byte(dev, 0x1F4, 0x00000000);
906 PlatformIOWrite1Byte(dev, 0x1F8, 0x00);
908 /* Asked for by SD3 CM Lin, 2006.06.27, by rcnjko. */
909 /* power save parameter based on "87SE power save parameters 20071127.doc", as follow. */
911 /* Enable DA10 TX power saving */
912 u1DA = read_nic_byte(dev, PHYPR);
913 write_nic_byte(dev, PHYPR, (u1DA | BIT2));
916 write_nic_word(dev, 0x360, 0x1000);
917 write_nic_word(dev, 0x362, 0x1000);
920 write_nic_word(dev, 0x370, 0x0560);
921 write_nic_word(dev, 0x372, 0x0560);
922 write_nic_word(dev, 0x374, 0x0DA4);
923 write_nic_word(dev, 0x376, 0x0DA4);
924 write_nic_word(dev, 0x378, 0x0560);
925 write_nic_word(dev, 0x37A, 0x0560);
926 write_nic_word(dev, 0x37C, 0x00EC);
927 write_nic_word(dev, 0x37E, 0x00EC); /* +edward */
928 write_nic_byte(dev, 0x24E, 0x01);
931 u8 GetSupportedWirelessMode8185(struct net_device *dev)
933 u8 btSupportedWirelessMode = 0;
935 btSupportedWirelessMode = (WIRELESS_MODE_B | WIRELESS_MODE_G);
936 return btSupportedWirelessMode;
939 void ActUpdateChannelAccessSetting(struct net_device *dev,
940 WIRELESS_MODE WirelessMode,
941 PCHANNEL_ACCESS_SETTING ChnlAccessSetting)
943 struct r8180_priv *priv = ieee80211_priv(dev);
944 struct ieee80211_device *ieee = priv->ieee80211;
947 u8 bFollowLegacySetting = 0;
952 * TODO: We still don't know how to set up these registers, just follow WMAC to
956 * Jong said CWmin/CWmax register are not functional in 8185B,
957 * so we shall fill channel access realted register into AC parameter registers,
960 ChnlAccessSetting->SIFS_Timer = 0x22; /* Suggested by Jong, 2005.12.08. */
961 ChnlAccessSetting->DIFS_Timer = 0x1C; /* 2006.06.02, by rcnjko. */
962 ChnlAccessSetting->SlotTimeTimer = 9; /* 2006.06.02, by rcnjko. */
963 ChnlAccessSetting->EIFS_Timer = 0x5B; /* Suggested by wcchu, it is the default value of EIFS register, 2005.12.08. */
964 ChnlAccessSetting->CWminIndex = 3; /* 2006.06.02, by rcnjko. */
965 ChnlAccessSetting->CWmaxIndex = 7; /* 2006.06.02, by rcnjko. */
967 write_nic_byte(dev, SIFS, ChnlAccessSetting->SIFS_Timer);
968 write_nic_byte(dev, SLOT, ChnlAccessSetting->SlotTimeTimer); /* Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29. */
970 u1bAIFS = aSifsTime + (2 * ChnlAccessSetting->SlotTimeTimer);
972 write_nic_byte(dev, EIFS, ChnlAccessSetting->EIFS_Timer);
974 write_nic_byte(dev, AckTimeOutReg, 0x5B); /* <RJ_EXPR_QOS> Suggested by wcchu, it is the default value of EIFS register, 2005.12.08. */
976 { /* Legacy 802.11. */
977 bFollowLegacySetting = 1;
981 /* this setting is copied from rtl8187B. xiong-2006-11-13 */
982 if (bFollowLegacySetting) {
985 * Follow 802.11 seeting to AC parameter, all AC shall use the same parameter.
986 * 2005.12.01, by rcnjko.
988 AcParam.longData = 0;
989 AcParam.f.AciAifsn.f.AIFSN = 2; /* Follow 802.11 DIFS. */
990 AcParam.f.AciAifsn.f.ACM = 0;
991 AcParam.f.Ecw.f.ECWmin = ChnlAccessSetting->CWminIndex; /* Follow 802.11 CWmin. */
992 AcParam.f.Ecw.f.ECWmax = ChnlAccessSetting->CWmaxIndex; /* Follow 802.11 CWmax. */
993 AcParam.f.TXOPLimit = 0;
995 /* lzm reserved 080826 */
996 /* For turbo mode setting. port from 87B by Isaiah 2008-08-01 */
997 if (ieee->current_network.Turbo_Enable == 1)
998 AcParam.f.TXOPLimit = 0x01FF;
999 /* For 87SE with Intel 4965 Ad-Hoc mode have poor throughput (19MB) */
1000 if (ieee->iw_mode == IW_MODE_ADHOC)
1001 AcParam.f.TXOPLimit = 0x0020;
1003 for (eACI = 0; eACI < AC_MAX; eACI++) {
1004 AcParam.f.AciAifsn.f.ACI = (u8)eACI;
1006 PAC_PARAM pAcParam = (PAC_PARAM)(&AcParam);
1011 /* Retrieve paramters to update. */
1012 eACI = pAcParam->f.AciAifsn.f.ACI;
1013 u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * ChnlAccessSetting->SlotTimeTimer + aSifsTime;
1014 u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) |
1015 (((u32)(pAcParam->f.Ecw.f.ECWmax)) << AC_PARAM_ECW_MAX_OFFSET) |
1016 (((u32)(pAcParam->f.Ecw.f.ECWmin)) << AC_PARAM_ECW_MIN_OFFSET) |
1017 (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET));
1021 /* write_nic_dword(dev, AC_BK_PARAM, u4bAcParam); */
1025 /* write_nic_dword(dev, AC_BK_PARAM, u4bAcParam); */
1029 /* write_nic_dword(dev, AC_BK_PARAM, u4bAcParam); */
1033 /* write_nic_dword(dev, AC_BK_PARAM, u4bAcParam); */
1037 DMESGW("SetHwReg8185(): invalid ACI: %d !\n", eACI);
1041 /* Cehck ACM bit. */
1042 /* If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13. */
1044 PACI_AIFSN pAciAifsn = (PACI_AIFSN)(&pAcParam->f.AciAifsn);
1045 AC_CODING eACI = pAciAifsn->f.ACI;
1047 /*for 8187B AsynIORead issue */
1049 if (pAciAifsn->f.ACM) {
1053 AcmCtrl |= (BEQ_ACM_EN|BEQ_ACM_CTL|ACM_HW_EN); /* or 0x21 */
1057 AcmCtrl |= (VIQ_ACM_EN|VIQ_ACM_CTL|ACM_HW_EN); /* or 0x42 */
1061 AcmCtrl |= (VOQ_ACM_EN|VOQ_ACM_CTL|ACM_HW_EN); /* or 0x84 */
1065 DMESGW("SetHwReg8185(): [HW_VAR_ACM_CTRL] ACM set failed: eACI is %d\n", eACI);
1072 AcmCtrl &= ((~BEQ_ACM_EN) & (~BEQ_ACM_CTL) & (~ACM_HW_EN)); /* and 0xDE */
1076 AcmCtrl &= ((~VIQ_ACM_EN) & (~VIQ_ACM_CTL) & (~ACM_HW_EN)); /* and 0xBD */
1080 AcmCtrl &= ((~VOQ_ACM_EN) & (~VOQ_ACM_CTL) & (~ACM_HW_EN)); /* and 0x7B */
1087 write_nic_byte(dev, ACM_CONTROL, 0);
1094 void ActSetWirelessMode8185(struct net_device *dev, u8 btWirelessMode)
1096 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1097 struct ieee80211_device *ieee = priv->ieee80211;
1098 u8 btSupportedWirelessMode = GetSupportedWirelessMode8185(dev);
1100 if ((btWirelessMode & btSupportedWirelessMode) == 0) {
1101 /* Don't switch to unsupported wireless mode, 2006.02.15, by rcnjko. */
1102 DMESGW("ActSetWirelessMode8185(): WirelessMode(%d) is not supported (%d)!\n",
1103 btWirelessMode, btSupportedWirelessMode);
1107 /* 1. Assign wireless mode to switch if necessary. */
1108 if (btWirelessMode == WIRELESS_MODE_AUTO) {
1109 if ((btSupportedWirelessMode & WIRELESS_MODE_A)) {
1110 btWirelessMode = WIRELESS_MODE_A;
1111 } else if (btSupportedWirelessMode & WIRELESS_MODE_G) {
1112 btWirelessMode = WIRELESS_MODE_G;
1114 } else if ((btSupportedWirelessMode & WIRELESS_MODE_B)) {
1115 btWirelessMode = WIRELESS_MODE_B;
1117 DMESGW("ActSetWirelessMode8185(): No valid wireless mode supported, btSupportedWirelessMode(%x)!!!\n",
1118 btSupportedWirelessMode);
1119 btWirelessMode = WIRELESS_MODE_B;
1124 * 2. Swtich band: RF or BB specific actions,
1125 * for example, refresh tables in omc8255, or change initial gain if necessary.
1126 * Nothing to do for Zebra to switch band.
1127 * Update current wireless mode if we switch to specified band successfully.
1130 ieee->mode = (WIRELESS_MODE)btWirelessMode;
1132 /* 3. Change related setting. */
1133 if( ieee->mode == WIRELESS_MODE_A ) {
1134 DMESG("WIRELESS_MODE_A\n");
1135 } else if( ieee->mode == WIRELESS_MODE_B ) {
1136 DMESG("WIRELESS_MODE_B\n");
1137 } else if( ieee->mode == WIRELESS_MODE_G ) {
1138 DMESG("WIRELESS_MODE_G\n");
1140 ActUpdateChannelAccessSetting( dev, ieee->mode, &priv->ChannelAccessSetting);
1143 void rtl8185b_irq_enable(struct net_device *dev)
1145 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1147 priv->irq_enabled = 1;
1148 write_nic_dword(dev, IMR, priv->IntrMask);
1151 void DrvIFIndicateDisassociation(struct net_device *dev, u16 reason)
1153 /* nothing is needed after disassociation request. */
1156 void MgntDisconnectIBSS(struct net_device *dev)
1158 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1161 DrvIFIndicateDisassociation(dev, unspec_reason);
1163 for (i = 0; i < 6 ; i++)
1164 priv->ieee80211->current_network.bssid[i] = 0x55;
1168 priv->ieee80211->state = IEEE80211_NOLINK;
1172 * Vista add a Adhoc profile, HW radio off until OID_DOT11_RESET_REQUEST
1173 * Driver would set MSR=NO_LINK, then HW Radio ON, MgntQueue Stuck.
1174 * Because Bcn DMA isn't complete, mgnt queue would stuck until Bcn packet send.
1176 * Disable Beacon Queue Own bit, suggested by jong
1178 ieee80211_stop_send_beacons(priv->ieee80211);
1180 priv->ieee80211->link_change(dev);
1181 notify_wx_assoc_event(priv->ieee80211);
1184 void MlmeDisassociateRequest(struct net_device *dev, u8 *asSta, u8 asRsn)
1186 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1189 SendDisassociation(priv->ieee80211, asSta, asRsn);
1191 if (memcmp(priv->ieee80211->current_network.bssid, asSta, 6) == 0) {
1192 /* ShuChen TODO: change media status. */
1193 /* ShuChen TODO: What to do when disassociate. */
1194 DrvIFIndicateDisassociation(dev, unspec_reason);
1196 for (i = 0; i < 6; i++)
1197 priv->ieee80211->current_network.bssid[i] = 0x22;
1199 ieee80211_disassociate(priv->ieee80211);
1203 void MgntDisconnectAP(struct net_device *dev, u8 asRsn)
1205 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1208 * Commented out by rcnjko, 2005.01.27:
1209 * I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE().
1211 * 2004/09/15, kcwu, the key should be cleared, or the new handshaking will not success
1213 * In WPA WPA2 need to Clear all key ... because new key will set after new handshaking.
1214 * 2004.10.11, by rcnjko.
1216 MlmeDisassociateRequest(dev, priv->ieee80211->current_network.bssid, asRsn);
1218 priv->ieee80211->state = IEEE80211_NOLINK;
1221 bool MgntDisconnect(struct net_device *dev, u8 asRsn)
1223 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1225 * Schedule an workitem to wake up for ps mode, 070109, by rcnjko.
1228 if (IS_DOT11D_ENABLE(priv->ieee80211))
1229 Dot11d_Reset(priv->ieee80211);
1230 /* In adhoc mode, update beacon frame. */
1231 if (priv->ieee80211->state == IEEE80211_LINKED) {
1232 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
1233 MgntDisconnectIBSS(dev);
1235 if (priv->ieee80211->iw_mode == IW_MODE_INFRA) {
1237 * We clear key here instead of MgntDisconnectAP() because that
1238 * MgntActSet_802_11_DISASSOCIATE() is an interface called by OS,
1239 * e.g. OID_802_11_DISASSOCIATE in Windows while as MgntDisconnectAP() is
1240 * used to handle disassociation related things to AP, e.g. send Disassoc
1241 * frame to AP. 2005.01.27, by rcnjko.
1243 MgntDisconnectAP(dev, asRsn);
1245 /* Indicate Disconnect, 2005.02.23, by rcnjko. */
1251 * Chang RF Power State.
1252 * Note that, only MgntActSet_RF_State() is allowed to set HW_VAR_RF_STATE.
1257 bool SetRFPowerState(struct net_device *dev, RT_RF_POWER_STATE eRFPowerState)
1259 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1260 bool bResult = false;
1262 if (eRFPowerState == priv->eRFPowerState)
1265 bResult = SetZebraRFPowerState8185(dev, eRFPowerState);
1270 void HalEnableRx8185Dummy(struct net_device *dev)
1274 void HalDisableRx8185Dummy(struct net_device *dev)
1278 bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, u32 ChangeSource)
1280 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1281 bool bActionAllowed = false;
1282 bool bConnectBySSID = false;
1283 RT_RF_POWER_STATE rtState;
1284 u16 RFWaitCounter = 0;
1287 * Prevent the race condition of RF state change. By Bruce, 2007-11-28.
1288 * Only one thread can change the RF state at one time, and others should wait to be executed.
1291 spin_lock_irqsave(&priv->rf_ps_lock, flag);
1292 if (priv->RFChangeInProgress) {
1293 spin_unlock_irqrestore(&priv->rf_ps_lock, flag);
1294 /* Set RF after the previous action is done. */
1295 while (priv->RFChangeInProgress) {
1297 udelay(1000); /* 1 ms */
1299 /* Wait too long, return FALSE to avoid to be stuck here. */
1300 if (RFWaitCounter > 1000) { /* 1sec */
1301 printk("MgntActSet_RF_State(): Wait too long to set RF\n");
1302 /* TODO: Reset RF state? */
1307 priv->RFChangeInProgress = true;
1308 spin_unlock_irqrestore(&priv->rf_ps_lock, flag);
1312 rtState = priv->eRFPowerState;
1314 switch (StateToSet) {
1317 * Turn On RF no matter the IPS setting because we need to update the RF state to Ndis under Vista, or
1318 * the Windows does not allow the driver to perform site survey any more. By Bruce, 2007-10-02.
1320 priv->RfOffReason &= (~ChangeSource);
1322 if (!priv->RfOffReason) {
1323 priv->RfOffReason = 0;
1324 bActionAllowed = true;
1326 if (rtState == eRfOff && ChangeSource >= RF_CHANGE_BY_HW && !priv->bInHctTest)
1327 bConnectBySSID = true;
1334 /* 070125, rcnjko: we always keep connected in AP mode. */
1336 if (priv->RfOffReason > RF_CHANGE_BY_IPS) {
1339 * Disconnect to current BSS when radio off. Asked by QuanTa.
1341 * Calling MgntDisconnect() instead of MgntActSet_802_11_DISASSOCIATE(),
1342 * because we do NOT need to set ssid to dummy ones.
1344 MgntDisconnect(dev, disas_lv_ss);
1345 /* Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI. */
1348 priv->RfOffReason |= ChangeSource;
1349 bActionAllowed = true;
1352 priv->RfOffReason |= ChangeSource;
1353 bActionAllowed = true;
1359 if (bActionAllowed) {
1360 /* Config HW to the specified mode. */
1361 SetRFPowerState(dev, StateToSet);
1364 if (StateToSet == eRfOn) {
1365 HalEnableRx8185Dummy(dev);
1366 if (bConnectBySSID) {
1367 /* by amy not supported */
1371 else if (StateToSet == eRfOff)
1372 HalDisableRx8185Dummy(dev);
1376 /* Release RF spinlock */
1377 spin_lock_irqsave(&priv->rf_ps_lock, flag);
1378 priv->RFChangeInProgress = false;
1379 spin_unlock_irqrestore(&priv->rf_ps_lock, flag);
1380 return bActionAllowed;
1383 void InactivePowerSave(struct net_device *dev)
1385 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1387 * This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
1388 * is really scheduled.
1389 * The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
1390 * previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
1391 * blocks the IPS procedure of switching RF.
1393 priv->bSwRfProcessing = true;
1395 MgntActSet_RF_State(dev, priv->eInactivePowerState, RF_CHANGE_BY_IPS);
1398 * To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
1401 priv->bSwRfProcessing = false;
1406 * Enter the inactive power save mode. RF will be off
1408 void IPSEnter(struct net_device *dev)
1410 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1411 RT_RF_POWER_STATE rtState;
1412 if (priv->bInactivePs) {
1413 rtState = priv->eRFPowerState;
1416 * Do not enter IPS in the following conditions:
1417 * (1) RF is already OFF or Sleep
1418 * (2) bSwRfProcessing (indicates the IPS is still under going)
1419 * (3) Connected (only disconnected can trigger IPS)
1420 * (4) IBSS (send Beacon)
1421 * (5) AP mode (send Beacon)
1423 if (rtState == eRfOn && !priv->bSwRfProcessing
1424 && (priv->ieee80211->state != IEEE80211_LINKED)) {
1425 priv->eInactivePowerState = eRfOff;
1426 InactivePowerSave(dev);
1430 void IPSLeave(struct net_device *dev)
1432 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1433 RT_RF_POWER_STATE rtState;
1434 if (priv->bInactivePs) {
1435 rtState = priv->eRFPowerState;
1436 if ((rtState == eRfOff || rtState == eRfSleep) && (!priv->bSwRfProcessing) && priv->RfOffReason <= RF_CHANGE_BY_IPS) {
1437 priv->eInactivePowerState = eRfOn;
1438 InactivePowerSave(dev);
1443 void rtl8185b_adapter_start(struct net_device *dev)
1445 struct r8180_priv *priv = ieee80211_priv(dev);
1446 struct ieee80211_device *ieee = priv->ieee80211;
1448 u8 SupportedWirelessMode;
1449 u8 InitWirelessMode;
1450 u8 bInvalidWirelessMode = 0;
1456 write_nic_byte(dev, 0x24e, (BIT5|BIT6|BIT0));
1459 priv->dma_poll_mask = 0;
1460 priv->dma_poll_stop_mask = 0;
1462 HwConfigureRTL8185(dev);
1463 write_nic_dword(dev, MAC0, ((u32 *)dev->dev_addr)[0]);
1464 write_nic_word(dev, MAC4, ((u32 *)dev->dev_addr)[1] & 0xffff);
1465 write_nic_byte(dev, MSR, read_nic_byte(dev, MSR) & 0xf3); /* default network type to 'No Link' */
1466 write_nic_word(dev, BcnItv, 100);
1467 write_nic_word(dev, AtimWnd, 2);
1468 PlatformIOWrite2Byte(dev, FEMR, 0xFFFF);
1469 write_nic_byte(dev, WPA_CONFIG, 0);
1470 MacConfig_85BASIC(dev);
1471 /* Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07, by rcnjko. */
1472 /* BT_DEMO_BOARD type */
1473 PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x569a);
1476 *---------------------------------------------------------------------------
1477 * Set up PHY related.
1478 *---------------------------------------------------------------------------
1480 /* Enable Config3.PARAM_En to revise AnaaParm. */
1481 write_nic_byte(dev, CR9346, 0xc0); /* enable config register write */
1482 tmpu8 = read_nic_byte(dev, CONFIG3);
1483 write_nic_byte(dev, CONFIG3, (tmpu8 | CONFIG3_PARM_En));
1484 /* Turn on Analog power. */
1485 /* Asked for by William, otherwise, MAC 3-wire can't work, 2006.06.27, by rcnjko. */
1486 write_nic_dword(dev, ANAPARAM2, ANAPARM2_ASIC_ON);
1487 write_nic_dword(dev, ANAPARAM, ANAPARM_ASIC_ON);
1488 write_nic_word(dev, ANAPARAM3, 0x0010);
1490 write_nic_byte(dev, CONFIG3, tmpu8);
1491 write_nic_byte(dev, CR9346, 0x00);
1492 /* enable EEM0 and EEM1 in 9346CR */
1493 btCR9346 = read_nic_byte(dev, CR9346);
1494 write_nic_byte(dev, CR9346, (btCR9346 | 0xC0));
1496 /* B cut use LED1 to control HW RF on/off */
1497 TmpU1b = read_nic_byte(dev, CONFIG5);
1498 TmpU1b = TmpU1b & ~BIT3;
1499 write_nic_byte(dev, CONFIG5, TmpU1b);
1501 /* disable EEM0 and EEM1 in 9346CR */
1502 btCR9346 &= ~(0xC0);
1503 write_nic_byte(dev, CR9346, btCR9346);
1505 /* Enable Led (suggested by Jong) */
1506 /* B-cut RF Radio on/off 5e[3]=0 */
1507 btPSR = read_nic_byte(dev, PSR);
1508 write_nic_byte(dev, PSR, (btPSR | BIT3));
1509 /* setup initial timing for RFE. */
1510 write_nic_word(dev, RFPinsOutput, 0x0480);
1511 SetOutputEnableOfRfPins(dev);
1512 write_nic_word(dev, RFPinsSelect, 0x2488);
1518 * We assume RegWirelessMode has already been initialized before,
1519 * however, we has to validate the wireless mode here and provide a
1520 * reasonable initialized value if necessary. 2005.01.13, by rcnjko.
1522 SupportedWirelessMode = GetSupportedWirelessMode8185(dev);
1523 if ((ieee->mode != WIRELESS_MODE_B) &&
1524 (ieee->mode != WIRELESS_MODE_G) &&
1525 (ieee->mode != WIRELESS_MODE_A) &&
1526 (ieee->mode != WIRELESS_MODE_AUTO)) {
1527 /* It should be one of B, G, A, or AUTO. */
1528 bInvalidWirelessMode = 1;
1530 /* One of B, G, A, or AUTO. */
1531 /* Check if the wireless mode is supported by RF. */
1532 if ((ieee->mode != WIRELESS_MODE_AUTO) &&
1533 (ieee->mode & SupportedWirelessMode) == 0) {
1534 bInvalidWirelessMode = 1;
1538 if (bInvalidWirelessMode || ieee->mode == WIRELESS_MODE_AUTO) {
1539 /* Auto or other invalid value. */
1540 /* Assigne a wireless mode to initialize. */
1541 if ((SupportedWirelessMode & WIRELESS_MODE_A)) {
1542 InitWirelessMode = WIRELESS_MODE_A;
1543 } else if ((SupportedWirelessMode & WIRELESS_MODE_G)) {
1544 InitWirelessMode = WIRELESS_MODE_G;
1545 } else if ((SupportedWirelessMode & WIRELESS_MODE_B)) {
1546 InitWirelessMode = WIRELESS_MODE_B;
1548 DMESGW("InitializeAdapter8185(): No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n",
1549 SupportedWirelessMode);
1550 InitWirelessMode = WIRELESS_MODE_B;
1553 /* Initialize RegWirelessMode if it is not a valid one. */
1554 if (bInvalidWirelessMode)
1555 ieee->mode = (WIRELESS_MODE)InitWirelessMode;
1558 /* One of B, G, A. */
1559 InitWirelessMode = ieee->mode;
1561 priv->eRFPowerState = eRfOff;
1562 priv->RfOffReason = 0;
1564 MgntActSet_RF_State(dev, eRfOn, 0);
1567 * If inactive power mode is enabled, disable rf while in disconnected state.
1569 if (priv->bInactivePs)
1570 MgntActSet_RF_State(dev , eRfOff, RF_CHANGE_BY_IPS);
1572 ActSetWirelessMode8185(dev, (u8)(InitWirelessMode));
1574 /* ----------------------------------------------------------------------------- */
1576 rtl8185b_irq_enable(dev);
1578 netif_start_queue(dev);
1581 void rtl8185b_rx_enable(struct net_device *dev)
1584 /* for now we accept data, management & ctl frame*/
1585 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1588 if (dev->flags & IFF_PROMISC)
1589 DMESG("NIC in promisc mode");
1591 if (priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
1592 dev->flags & IFF_PROMISC) {
1593 priv->ReceiveConfig = priv->ReceiveConfig & (~RCR_APM);
1594 priv->ReceiveConfig = priv->ReceiveConfig | RCR_AAP;
1597 if (priv->ieee80211->iw_mode == IW_MODE_MONITOR)
1598 priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACF | RCR_APWRMGT | RCR_AICV;
1601 if (priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
1602 priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACRC32;
1604 write_nic_dword(dev, RCR, priv->ReceiveConfig);
1608 cmd = read_nic_byte(dev, CMD);
1609 write_nic_byte(dev, CMD, cmd | (1<<CMD_RX_ENABLE_SHIFT));
1613 void rtl8185b_tx_enable(struct net_device *dev)
1617 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1619 write_nic_dword(dev, TCR, priv->TransmitConfig);
1620 byte = read_nic_byte(dev, MSR);
1621 byte |= MSR_LINK_ENEDCA;
1622 write_nic_byte(dev, MSR, byte);
1626 cmd = read_nic_byte(dev, CMD);
1627 write_nic_byte(dev, CMD, cmd | (1<<CMD_TX_ENABLE_SHIFT));