1 /* 2 * Radio tuning for RTL8225 on RTL8185 3 * 4 * Copyright 2007 Michael Wu <flamingice (at) sourmilk.net> 5 * Copyright 2007 Andrea Merello <andreamrl (at) tiscali.it> 6 * 7 * Modified slightly for gPXE, June 2009 by Joshua Oreman 8 * 9 * Based on the r8180 driver, which is: 10 * Copyright 2005 Andrea Merello <andreamrl (at) tiscali.it>, et al. 11 * 12 * Thanks to Realtek for their support! 13 * 14 * This program is free software; you can redistribute it and/or modify 15 * it under the terms of the GNU General Public License version 2 as 16 * published by the Free Software Foundation. 17 */ 18 19 #include <unistd.h> 20 #include <gpxe/pci.h> 21 #include <gpxe/net80211.h> 22 23 #include "rtl818x.h" 24 25 FILE_LICENCE(GPL2_ONLY); 26 27 #define RTL8225_ANAPARAM_ON 0xa0000b59 28 #define RTL8225_ANAPARAM2_ON 0x860dec11 29 #define RTL8225_ANAPARAM_OFF 0xa00beb59 30 #define RTL8225_ANAPARAM2_OFF 0x840dec11 31 32 #define min(a,b) (((a)<(b))?(a):(b)) 33 #define ARRAY_SIZE(a) (int)(sizeof(a)/sizeof((a)[0])) 34 35 static inline void rtl8225_write_phy_ofdm(struct net80211_device *dev, 36 u8 addr, u8 data) 37 { 38 rtl818x_write_phy(dev, addr, data); 39 } 40 41 static inline void rtl8225_write_phy_cck(struct net80211_device *dev, 42 u8 addr, u8 data) 43 { 44 rtl818x_write_phy(dev, addr, data | 0x10000); 45 } 46 47 static void rtl8225_write(struct net80211_device *dev, u8 addr, u16 data) 48 { 49 struct rtl818x_priv *priv = dev->priv; 50 u16 reg80, reg84, reg82; 51 u32 bangdata; 52 int i; 53 54 bangdata = (data << 4) | (addr & 0xf); 55 56 reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput) & 0xfff3; 57 reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); 58 59 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x7); 60 61 reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect); 62 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x7 | 0x400); 63 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 64 udelay(10); 65 66 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); 67 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 68 udelay(2); 69 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); 70 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 71 udelay(10); 72 73 for (i = 15; i >= 0; i--) { 74 u16 reg = reg80 | !!(bangdata & (1 << i)); 75 76 if (i & 1) 77 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); 78 79 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1)); 80 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1)); 81 82 if (!(i & 1)) 83 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); 84 } 85 86 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); 87 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 88 udelay(10); 89 90 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); 91 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x400); 92 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); 93 } 94 95 static u16 rtl8225_read(struct net80211_device *dev, u8 addr) 96 { 97 struct rtl818x_priv *priv = dev->priv; 98 u16 reg80, reg82, reg84, out; 99 int i; 100 101 reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput); 102 reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); 103 reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect) | 0x400; 104 105 reg80 &= ~0xF; 106 107 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x000F); 108 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x000F); 109 110 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); 111 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 112 udelay(4); 113 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); 114 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 115 udelay(5); 116 117 for (i = 4; i >= 0; i--) { 118 u16 reg = reg80 | ((addr >> i) & 1); 119 120 if (!(i & 1)) { 121 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); 122 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 123 udelay(1); 124 } 125 126 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 127 reg | (1 << 1)); 128 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 129 udelay(2); 130 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 131 reg | (1 << 1)); 132 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 133 udelay(2); 134 135 if (i & 1) { 136 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); 137 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 138 udelay(1); 139 } 140 } 141 142 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x000E); 143 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x040E); 144 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 145 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 146 reg80 | (1 << 3) | (1 << 1)); 147 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 148 udelay(2); 149 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 150 reg80 | (1 << 3)); 151 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 152 udelay(2); 153 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 154 reg80 | (1 << 3)); 155 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 156 udelay(2); 157 158 out = 0; 159 for (i = 11; i >= 0; i--) { 160 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 161 reg80 | (1 << 3)); 162 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 163 udelay(1); 164 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 165 reg80 | (1 << 3) | (1 << 1)); 166 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 167 udelay(2); 168 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 169 reg80 | (1 << 3) | (1 << 1)); 170 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 171 udelay(2); 172 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 173 reg80 | (1 << 3) | (1 << 1)); 174 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 175 udelay(2); 176 177 if (rtl818x_ioread16(priv, &priv->map->RFPinsInput) & (1 << 1)) 178 out |= 1 << i; 179 180 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 181 reg80 | (1 << 3)); 182 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 183 udelay(2); 184 } 185 186 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 187 reg80 | (1 << 3) | (1 << 2)); 188 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 189 udelay(2); 190 191 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82); 192 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84); 193 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x03A0); 194 195 return out; 196 } 197 198 static const u16 rtl8225bcd_rxgain[] = { 199 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409, 200 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541, 201 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583, 202 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644, 203 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688, 204 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745, 205 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789, 206 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793, 207 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d, 208 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9, 209 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3, 210 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb 211 }; 212 213 static const u8 rtl8225_agc[] = { 214 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 215 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96, 216 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e, 217 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, 218 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, 219 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36, 220 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e, 221 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 222 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, 223 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, 224 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, 225 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 226 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 227 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 228 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 229 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 230 }; 231 232 static const u8 rtl8225_gain[] = { 233 0x23, 0x88, 0x7c, 0xa5, /* -82dbm */ 234 0x23, 0x88, 0x7c, 0xb5, /* -82dbm */ 235 0x23, 0x88, 0x7c, 0xc5, /* -82dbm */ 236 0x33, 0x80, 0x79, 0xc5, /* -78dbm */ 237 0x43, 0x78, 0x76, 0xc5, /* -74dbm */ 238 0x53, 0x60, 0x73, 0xc5, /* -70dbm */ 239 0x63, 0x58, 0x70, 0xc5, /* -66dbm */ 240 }; 241 242 static const u8 rtl8225_threshold[] = { 243 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd 244 }; 245 246 static const u8 rtl8225_tx_gain_cck_ofdm[] = { 247 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e 248 }; 249 250 static const u8 rtl8225_tx_power_cck[] = { 251 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02, 252 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02, 253 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02, 254 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02, 255 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03, 256 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03 257 }; 258 259 static const u8 rtl8225_tx_power_cck_ch14[] = { 260 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00, 261 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00, 262 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00, 263 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00, 264 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, 265 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00 266 }; 267 268 static const u8 rtl8225_tx_power_ofdm[] = { 269 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4 270 }; 271 272 static const u32 rtl8225_chan[] = { 273 0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c, 274 0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72 275 }; 276 277 static void rtl8225_rf_set_tx_power(struct net80211_device *dev, int channel) 278 { 279 struct rtl818x_priv *priv = dev->priv; 280 u8 cck_power, ofdm_power; 281 const u8 *tmp; 282 u32 reg; 283 int i; 284 285 cck_power = priv->txpower[channel - 1] & 0xFF; 286 ofdm_power = priv->txpower[channel - 1] >> 8; 287 288 cck_power = min(cck_power, (u8)35); 289 ofdm_power = min(ofdm_power, (u8)35); 290 291 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 292 rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1); 293 294 if (channel == 14) 295 tmp = &rtl8225_tx_power_cck_ch14[(cck_power % 6) * 8]; 296 else 297 tmp = &rtl8225_tx_power_cck[(cck_power % 6) * 8]; 298 299 for (i = 0; i < 8; i++) 300 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); 301 302 mdelay(1); /* FIXME: optional? */ 303 304 /* anaparam2 on */ 305 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 306 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); 307 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE); 308 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON); 309 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); 310 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 311 312 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 313 rtl8225_tx_gain_cck_ofdm[ofdm_power/6] >> 1); 314 315 tmp = &rtl8225_tx_power_ofdm[ofdm_power % 6]; 316 317 rtl8225_write_phy_ofdm(dev, 5, *tmp); 318 rtl8225_write_phy_ofdm(dev, 7, *tmp); 319 320 mdelay(1); 321 } 322 323 static void rtl8225_rf_init(struct net80211_device *dev) 324 { 325 struct rtl818x_priv *priv = dev->priv; 326 int i; 327 328 rtl818x_set_anaparam(priv, RTL8225_ANAPARAM_ON); 329 330 /* host_pci_init */ 331 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480); 332 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); 333 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488); 334 rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); 335 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 336 mdelay(200); /* FIXME: ehh?? */ 337 rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0xFF & ~(1 << 6)); 338 339 rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x000a8008); 340 341 /* TODO: check if we need really to change BRSR to do RF config */ 342 rtl818x_ioread16(priv, &priv->map->BRSR); 343 rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF); 344 rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044); 345 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 346 rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44); 347 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 348 349 rtl8225_write(dev, 0x0, 0x067); 350 rtl8225_write(dev, 0x1, 0xFE0); 351 rtl8225_write(dev, 0x2, 0x44D); 352 rtl8225_write(dev, 0x3, 0x441); 353 rtl8225_write(dev, 0x4, 0x8BE); 354 rtl8225_write(dev, 0x5, 0xBF0); /* TODO: minipci */ 355 rtl8225_write(dev, 0x6, 0xAE6); 356 rtl8225_write(dev, 0x7, rtl8225_chan[0]); 357 rtl8225_write(dev, 0x8, 0x01F); 358 rtl8225_write(dev, 0x9, 0x334); 359 rtl8225_write(dev, 0xA, 0xFD4); 360 rtl8225_write(dev, 0xB, 0x391); 361 rtl8225_write(dev, 0xC, 0x050); 362 rtl8225_write(dev, 0xD, 0x6DB); 363 rtl8225_write(dev, 0xE, 0x029); 364 rtl8225_write(dev, 0xF, 0x914); mdelay(1); 365 366 rtl8225_write(dev, 0x2, 0xC4D); mdelay(100); 367 368 rtl8225_write(dev, 0x0, 0x127); 369 370 for (i = 0; i < ARRAY_SIZE(rtl8225bcd_rxgain); i++) { 371 rtl8225_write(dev, 0x1, i + 1); 372 rtl8225_write(dev, 0x2, rtl8225bcd_rxgain[i]); 373 } 374 375 rtl8225_write(dev, 0x0, 0x027); 376 rtl8225_write(dev, 0x0, 0x22F); 377 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); 378 379 for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) { 380 rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]); 381 mdelay(1); 382 rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i); 383 mdelay(1); 384 } 385 386 mdelay(1); 387 388 rtl8225_write_phy_ofdm(dev, 0x00, 0x01); mdelay(1); 389 rtl8225_write_phy_ofdm(dev, 0x01, 0x02); mdelay(1); 390 rtl8225_write_phy_ofdm(dev, 0x02, 0x62); mdelay(1); 391 rtl8225_write_phy_ofdm(dev, 0x03, 0x00); mdelay(1); 392 rtl8225_write_phy_ofdm(dev, 0x04, 0x00); mdelay(1); 393 rtl8225_write_phy_ofdm(dev, 0x05, 0x00); mdelay(1); 394 rtl8225_write_phy_ofdm(dev, 0x06, 0x00); mdelay(1); 395 rtl8225_write_phy_ofdm(dev, 0x07, 0x00); mdelay(1); 396 rtl8225_write_phy_ofdm(dev, 0x08, 0x00); mdelay(1); 397 rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); mdelay(1); 398 rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); mdelay(1); 399 rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); mdelay(1); 400 rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); mdelay(1); 401 rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); mdelay(1); 402 rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); mdelay(1); 403 rtl8225_write_phy_ofdm(dev, 0x10, 0x84); mdelay(1); 404 rtl8225_write_phy_ofdm(dev, 0x11, 0x03); mdelay(1); 405 rtl8225_write_phy_ofdm(dev, 0x12, 0x20); mdelay(1); 406 rtl8225_write_phy_ofdm(dev, 0x13, 0x20); mdelay(1); 407 rtl8225_write_phy_ofdm(dev, 0x14, 0x00); mdelay(1); 408 rtl8225_write_phy_ofdm(dev, 0x15, 0x40); mdelay(1); 409 rtl8225_write_phy_ofdm(dev, 0x16, 0x00); mdelay(1); 410 rtl8225_write_phy_ofdm(dev, 0x17, 0x40); mdelay(1); 411 rtl8225_write_phy_ofdm(dev, 0x18, 0xef); mdelay(1); 412 rtl8225_write_phy_ofdm(dev, 0x19, 0x19); mdelay(1); 413 rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1); 414 rtl8225_write_phy_ofdm(dev, 0x1b, 0x76); mdelay(1); 415 rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); mdelay(1); 416 rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); mdelay(1); 417 rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1); 418 rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); mdelay(1); 419 rtl8225_write_phy_ofdm(dev, 0x21, 0x27); mdelay(1); 420 rtl8225_write_phy_ofdm(dev, 0x22, 0x16); mdelay(1); 421 rtl8225_write_phy_ofdm(dev, 0x24, 0x46); mdelay(1); 422 rtl8225_write_phy_ofdm(dev, 0x25, 0x20); mdelay(1); 423 rtl8225_write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); 424 rtl8225_write_phy_ofdm(dev, 0x27, 0x88); mdelay(1); 425 426 rtl8225_write_phy_cck(dev, 0x00, 0x98); mdelay(1); 427 rtl8225_write_phy_cck(dev, 0x03, 0x20); mdelay(1); 428 rtl8225_write_phy_cck(dev, 0x04, 0x7e); mdelay(1); 429 rtl8225_write_phy_cck(dev, 0x05, 0x12); mdelay(1); 430 rtl8225_write_phy_cck(dev, 0x06, 0xfc); mdelay(1); 431 rtl8225_write_phy_cck(dev, 0x07, 0x78); mdelay(1); 432 rtl8225_write_phy_cck(dev, 0x08, 0x2e); mdelay(1); 433 rtl8225_write_phy_cck(dev, 0x10, 0x93); mdelay(1); 434 rtl8225_write_phy_cck(dev, 0x11, 0x88); mdelay(1); 435 rtl8225_write_phy_cck(dev, 0x12, 0x47); mdelay(1); 436 rtl8225_write_phy_cck(dev, 0x13, 0xd0); 437 rtl8225_write_phy_cck(dev, 0x19, 0x00); 438 rtl8225_write_phy_cck(dev, 0x1a, 0xa0); 439 rtl8225_write_phy_cck(dev, 0x1b, 0x08); 440 rtl8225_write_phy_cck(dev, 0x40, 0x86); 441 rtl8225_write_phy_cck(dev, 0x41, 0x8d); mdelay(1); 442 rtl8225_write_phy_cck(dev, 0x42, 0x15); mdelay(1); 443 rtl8225_write_phy_cck(dev, 0x43, 0x18); mdelay(1); 444 rtl8225_write_phy_cck(dev, 0x44, 0x1f); mdelay(1); 445 rtl8225_write_phy_cck(dev, 0x45, 0x1e); mdelay(1); 446 rtl8225_write_phy_cck(dev, 0x46, 0x1a); mdelay(1); 447 rtl8225_write_phy_cck(dev, 0x47, 0x15); mdelay(1); 448 rtl8225_write_phy_cck(dev, 0x48, 0x10); mdelay(1); 449 rtl8225_write_phy_cck(dev, 0x49, 0x0a); mdelay(1); 450 rtl8225_write_phy_cck(dev, 0x4a, 0x05); mdelay(1); 451 rtl8225_write_phy_cck(dev, 0x4b, 0x02); mdelay(1); 452 rtl8225_write_phy_cck(dev, 0x4c, 0x05); mdelay(1); 453 454 rtl818x_iowrite8(priv, &priv->map->TESTR, 0x0D); mdelay(1); 455 456 rtl8225_rf_set_tx_power(dev, 1); 457 458 /* RX antenna default to A */ 459 rtl8225_write_phy_cck(dev, 0x10, 0x9b); mdelay(1); /* B: 0xDB */ 460 rtl8225_write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); /* B: 0x10 */ 461 462 rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */ 463 mdelay(1); 464 rtl818x_iowrite32(priv, (u32 *)((u8 *)priv->map + 0x94), 0x15c00002); 465 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); 466 467 rtl8225_write(dev, 0x0c, 0x50); 468 /* set OFDM initial gain */ 469 rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[4 * 4]); 470 rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[4 * 4 + 1]); 471 rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[4 * 4 + 2]); 472 rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[4 * 4 + 3]); 473 /* set CCK threshold */ 474 rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[0]); 475 } 476 477 static const u8 rtl8225z2_tx_power_cck_ch14[] = { 478 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00 479 }; 480 481 static const u8 rtl8225z2_tx_power_cck_B[] = { 482 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x04 483 }; 484 485 static const u8 rtl8225z2_tx_power_cck_A[] = { 486 0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04 487 }; 488 489 static const u8 rtl8225z2_tx_power_cck[] = { 490 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04 491 }; 492 493 static void rtl8225z2_rf_set_tx_power(struct net80211_device *dev, int channel) 494 { 495 struct rtl818x_priv *priv = dev->priv; 496 u8 cck_power, ofdm_power; 497 const u8 *tmp; 498 int i; 499 500 cck_power = priv->txpower[channel - 1] & 0xFF; 501 ofdm_power = priv->txpower[channel - 1] >> 8; 502 503 if (channel == 14) 504 tmp = rtl8225z2_tx_power_cck_ch14; 505 else if (cck_power == 12) 506 tmp = rtl8225z2_tx_power_cck_B; 507 else if (cck_power == 13) 508 tmp = rtl8225z2_tx_power_cck_A; 509 else 510 tmp = rtl8225z2_tx_power_cck; 511 512 for (i = 0; i < 8; i++) 513 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); 514 515 cck_power = min(cck_power, (u8)35); 516 if (cck_power == 13 || cck_power == 14) 517 cck_power = 12; 518 if (cck_power >= 15) 519 cck_power -= 2; 520 521 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, cck_power); 522 rtl818x_ioread8(priv, &priv->map->TX_GAIN_CCK); 523 mdelay(1); 524 525 ofdm_power = min(ofdm_power, (u8)35); 526 rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, ofdm_power); 527 528 rtl8225_write_phy_ofdm(dev, 2, 0x62); 529 rtl8225_write_phy_ofdm(dev, 5, 0x00); 530 rtl8225_write_phy_ofdm(dev, 6, 0x40); 531 rtl8225_write_phy_ofdm(dev, 7, 0x00); 532 rtl8225_write_phy_ofdm(dev, 8, 0x40); 533 534 mdelay(1); 535 } 536 537 static const u16 rtl8225z2_rxgain[] = { 538 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0008, 0x0009, 539 0x000a, 0x000b, 0x0102, 0x0103, 0x0104, 0x0105, 0x0140, 0x0141, 540 0x0142, 0x0143, 0x0144, 0x0145, 0x0180, 0x0181, 0x0182, 0x0183, 541 0x0184, 0x0185, 0x0188, 0x0189, 0x018a, 0x018b, 0x0243, 0x0244, 542 0x0245, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0288, 543 0x0289, 0x028a, 0x028b, 0x028c, 0x0342, 0x0343, 0x0344, 0x0345, 544 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0388, 0x0389, 545 0x038a, 0x038b, 0x038c, 0x038d, 0x0390, 0x0391, 0x0392, 0x0393, 546 0x0394, 0x0395, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 547 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9, 548 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3, 549 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb 550 }; 551 552 static void rtl8225z2_rf_init(struct net80211_device *dev) 553 { 554 struct rtl818x_priv *priv = dev->priv; 555 int i; 556 557 rtl818x_set_anaparam(priv, RTL8225_ANAPARAM_ON); 558 559 /* host_pci_init */ 560 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480); 561 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); 562 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488); 563 rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); 564 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 565 mdelay(200); /* FIXME: ehh?? */ 566 rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0xFF & ~(1 << 6)); 567 568 rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00088008); 569 570 /* TODO: check if we need really to change BRSR to do RF config */ 571 rtl818x_ioread16(priv, &priv->map->BRSR); 572 rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF); 573 rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044); 574 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 575 rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44); 576 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 577 578 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); 579 580 rtl8225_write(dev, 0x0, 0x0B7); mdelay(1); 581 rtl8225_write(dev, 0x1, 0xEE0); mdelay(1); 582 rtl8225_write(dev, 0x2, 0x44D); mdelay(1); 583 rtl8225_write(dev, 0x3, 0x441); mdelay(1); 584 rtl8225_write(dev, 0x4, 0x8C3); mdelay(1); 585 rtl8225_write(dev, 0x5, 0xC72); mdelay(1); 586 rtl8225_write(dev, 0x6, 0x0E6); mdelay(1); 587 rtl8225_write(dev, 0x7, 0x82A); mdelay(1); 588 rtl8225_write(dev, 0x8, 0x03F); mdelay(1); 589 rtl8225_write(dev, 0x9, 0x335); mdelay(1); 590 rtl8225_write(dev, 0xa, 0x9D4); mdelay(1); 591 rtl8225_write(dev, 0xb, 0x7BB); mdelay(1); 592 rtl8225_write(dev, 0xc, 0x850); mdelay(1); 593 rtl8225_write(dev, 0xd, 0xCDF); mdelay(1); 594 rtl8225_write(dev, 0xe, 0x02B); mdelay(1); 595 rtl8225_write(dev, 0xf, 0x114); mdelay(100); 596 597 if (!(rtl8225_read(dev, 6) & (1 << 7))) { 598 rtl8225_write(dev, 0x02, 0x0C4D); 599 mdelay(200); 600 rtl8225_write(dev, 0x02, 0x044D); 601 mdelay(100); 602 /* TODO: readd calibration failure message when the calibration 603 check works */ 604 } 605 606 rtl8225_write(dev, 0x0, 0x1B7); 607 rtl8225_write(dev, 0x3, 0x002); 608 rtl8225_write(dev, 0x5, 0x004); 609 610 for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) { 611 rtl8225_write(dev, 0x1, i + 1); 612 rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]); 613 } 614 615 rtl8225_write(dev, 0x0, 0x0B7); mdelay(100); 616 rtl8225_write(dev, 0x2, 0xC4D); 617 618 mdelay(200); 619 rtl8225_write(dev, 0x2, 0x44D); 620 mdelay(100); 621 622 rtl8225_write(dev, 0x00, 0x2BF); 623 rtl8225_write(dev, 0xFF, 0xFFFF); 624 625 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); 626 627 for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) { 628 rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]); 629 mdelay(1); 630 rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i); 631 mdelay(1); 632 } 633 634 mdelay(1); 635 636 rtl8225_write_phy_ofdm(dev, 0x00, 0x01); mdelay(1); 637 rtl8225_write_phy_ofdm(dev, 0x01, 0x02); mdelay(1); 638 rtl8225_write_phy_ofdm(dev, 0x02, 0x62); mdelay(1); 639 rtl8225_write_phy_ofdm(dev, 0x03, 0x00); mdelay(1); 640 rtl8225_write_phy_ofdm(dev, 0x04, 0x00); mdelay(1); 641 rtl8225_write_phy_ofdm(dev, 0x05, 0x00); mdelay(1); 642 rtl8225_write_phy_ofdm(dev, 0x06, 0x40); mdelay(1); 643 rtl8225_write_phy_ofdm(dev, 0x07, 0x00); mdelay(1); 644 rtl8225_write_phy_ofdm(dev, 0x08, 0x40); mdelay(1); 645 rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); mdelay(1); 646 rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); mdelay(1); 647 rtl8225_write_phy_ofdm(dev, 0x18, 0xef); mdelay(1); 648 rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); mdelay(1); 649 rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); mdelay(1); 650 rtl8225_write_phy_ofdm(dev, 0x0d, 0x43); 651 rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); mdelay(1); 652 rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); mdelay(1); 653 rtl8225_write_phy_ofdm(dev, 0x10, 0x84); mdelay(1); 654 rtl8225_write_phy_ofdm(dev, 0x11, 0x06); mdelay(1); 655 rtl8225_write_phy_ofdm(dev, 0x12, 0x20); mdelay(1); 656 rtl8225_write_phy_ofdm(dev, 0x13, 0x20); mdelay(1); 657 rtl8225_write_phy_ofdm(dev, 0x14, 0x00); mdelay(1); 658 rtl8225_write_phy_ofdm(dev, 0x15, 0x40); mdelay(1); 659 rtl8225_write_phy_ofdm(dev, 0x16, 0x00); mdelay(1); 660 rtl8225_write_phy_ofdm(dev, 0x17, 0x40); mdelay(1); 661 rtl8225_write_phy_ofdm(dev, 0x18, 0xef); mdelay(1); 662 rtl8225_write_phy_ofdm(dev, 0x19, 0x19); mdelay(1); 663 rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1); 664 rtl8225_write_phy_ofdm(dev, 0x1b, 0x11); mdelay(1); 665 rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); mdelay(1); 666 rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5); mdelay(1); 667 rtl8225_write_phy_ofdm(dev, 0x1e, 0xb3); mdelay(1); 668 rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1); 669 rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); mdelay(1); 670 rtl8225_write_phy_ofdm(dev, 0x21, 0x27); mdelay(1); 671 rtl8225_write_phy_ofdm(dev, 0x22, 0x16); mdelay(1); 672 rtl8225_write_phy_ofdm(dev, 0x23, 0x80); mdelay(1); /* FIXME: not needed? */ 673 rtl8225_write_phy_ofdm(dev, 0x24, 0x46); mdelay(1); 674 rtl8225_write_phy_ofdm(dev, 0x25, 0x20); mdelay(1); 675 rtl8225_write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); 676 rtl8225_write_phy_ofdm(dev, 0x27, 0x88); mdelay(1); 677 678 rtl8225_write_phy_cck(dev, 0x00, 0x98); mdelay(1); 679 rtl8225_write_phy_cck(dev, 0x03, 0x20); mdelay(1); 680 rtl8225_write_phy_cck(dev, 0x04, 0x7e); mdelay(1); 681 rtl8225_write_phy_cck(dev, 0x05, 0x12); mdelay(1); 682 rtl8225_write_phy_cck(dev, 0x06, 0xfc); mdelay(1); 683 rtl8225_write_phy_cck(dev, 0x07, 0x78); mdelay(1); 684 rtl8225_write_phy_cck(dev, 0x08, 0x2e); mdelay(1); 685 rtl8225_write_phy_cck(dev, 0x10, 0x93); mdelay(1); 686 rtl8225_write_phy_cck(dev, 0x11, 0x88); mdelay(1); 687 rtl8225_write_phy_cck(dev, 0x12, 0x47); mdelay(1); 688 rtl8225_write_phy_cck(dev, 0x13, 0xd0); 689 rtl8225_write_phy_cck(dev, 0x19, 0x00); 690 rtl8225_write_phy_cck(dev, 0x1a, 0xa0); 691 rtl8225_write_phy_cck(dev, 0x1b, 0x08); 692 rtl8225_write_phy_cck(dev, 0x40, 0x86); 693 rtl8225_write_phy_cck(dev, 0x41, 0x8a); mdelay(1); 694 rtl8225_write_phy_cck(dev, 0x42, 0x15); mdelay(1); 695 rtl8225_write_phy_cck(dev, 0x43, 0x18); mdelay(1); 696 rtl8225_write_phy_cck(dev, 0x44, 0x36); mdelay(1); 697 rtl8225_write_phy_cck(dev, 0x45, 0x35); mdelay(1); 698 rtl8225_write_phy_cck(dev, 0x46, 0x2e); mdelay(1); 699 rtl8225_write_phy_cck(dev, 0x47, 0x25); mdelay(1); 700 rtl8225_write_phy_cck(dev, 0x48, 0x1c); mdelay(1); 701 rtl8225_write_phy_cck(dev, 0x49, 0x12); mdelay(1); 702 rtl8225_write_phy_cck(dev, 0x4a, 0x09); mdelay(1); 703 rtl8225_write_phy_cck(dev, 0x4b, 0x04); mdelay(1); 704 rtl8225_write_phy_cck(dev, 0x4c, 0x05); mdelay(1); 705 706 rtl818x_iowrite8(priv, (u8 *)priv->map + 0x5B, 0x0D); mdelay(1); 707 708 rtl8225z2_rf_set_tx_power(dev, 1); 709 710 /* RX antenna default to A */ 711 rtl8225_write_phy_cck(dev, 0x10, 0x9b); mdelay(1); /* B: 0xDB */ 712 rtl8225_write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); /* B: 0x10 */ 713 714 rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */ 715 mdelay(1); 716 rtl818x_iowrite32(priv, (u32 *)((u8 *)priv->map + 0x94), 0x15c00002); 717 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); 718 } 719 720 static void rtl8225x_rf_init(struct net80211_device *dev) 721 { 722 struct rtl818x_priv *priv = dev->priv; 723 u16 reg8, reg9; 724 725 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480); 726 rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488); 727 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); 728 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 729 mdelay(100); 730 731 rtl8225_write(dev, 0, 0x1B7); 732 733 reg8 = rtl8225_read(dev, 8); 734 reg9 = rtl8225_read(dev, 9); 735 736 rtl8225_write(dev, 0, 0x0B7); 737 738 if (reg8 != 0x588 || reg9 != 0x700) { 739 priv->rf_flag = 0; 740 rtl8225_rf_init(dev); 741 } else { 742 priv->rf_flag = 1; 743 rtl8225z2_rf_init(dev); 744 } 745 } 746 747 static void rtl8225_rf_stop(struct net80211_device *dev) 748 { 749 struct rtl818x_priv *priv = dev->priv; 750 u8 reg; 751 752 rtl8225_write(dev, 0x4, 0x1f); mdelay(1); 753 754 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 755 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); 756 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE); 757 rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_OFF); 758 rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_OFF); 759 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); 760 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 761 } 762 763 static void rtl8225_rf_set_channel(struct net80211_device *dev, 764 struct net80211_channel *channelp) 765 { 766 struct rtl818x_priv *priv = dev->priv; 767 int chan = channelp->channel_nr; 768 769 if (priv->rf_flag) 770 rtl8225z2_rf_set_tx_power(dev, chan); 771 else 772 rtl8225_rf_set_tx_power(dev, chan); 773 774 rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]); 775 mdelay(10); 776 } 777 778 static void rtl8225_rf_conf_erp(struct net80211_device *dev) 779 { 780 struct rtl818x_priv *priv = dev->priv; 781 782 if (dev->phy_flags & NET80211_PHY_USE_SHORT_SLOT) { 783 rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9); 784 rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22); 785 rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14); 786 rtl818x_iowrite8(priv, &priv->map->EIFS, 81); 787 rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0x73); 788 } else { 789 rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14); 790 rtl818x_iowrite8(priv, &priv->map->SIFS, 0x44); 791 rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24); 792 rtl818x_iowrite8(priv, &priv->map->EIFS, 81); 793 rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5); 794 } 795 } 796 797 struct rtl818x_rf_ops rtl8225_ops __rtl818x_rf_driver = { 798 .name = "rtl8225", 799 .id = 9, 800 .init = rtl8225x_rf_init, 801 .stop = rtl8225_rf_stop, 802 .set_chan = rtl8225_rf_set_channel, 803 .conf_erp = rtl8225_rf_conf_erp, 804 }; 805