iPXE
rtl8185_rtl8225.c
Go to the documentation of this file.
00001 /*
00002  * Radio tuning for RTL8225 on RTL8185
00003  *
00004  * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
00005  * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
00006  *
00007  * Modified slightly for iPXE, June 2009 by Joshua Oreman
00008  *
00009  * Based on the r8180 driver, which is:
00010  * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al.
00011  *
00012  * Thanks to Realtek for their support!
00013  *
00014  * This program is free software; you can redistribute it and/or modify
00015  * it under the terms of the GNU General Public License version 2 as
00016  * published by the Free Software Foundation.
00017  */
00018 
00019 #include <unistd.h>
00020 #include <ipxe/pci.h>
00021 #include <ipxe/net80211.h>
00022 
00023 #include "rtl818x.h"
00024 
00025 FILE_LICENCE(GPL2_ONLY);
00026 
00027 #define RTL8225_ANAPARAM_ON     0xa0000b59
00028 #define RTL8225_ANAPARAM2_ON    0x860dec11
00029 #define RTL8225_ANAPARAM_OFF    0xa00beb59
00030 #define RTL8225_ANAPARAM2_OFF   0x840dec11
00031 
00032 #define min(a,b) (((a)<(b))?(a):(b))
00033 
00034 static inline void rtl8225_write_phy_ofdm(struct net80211_device *dev,
00035                                           u8 addr, u8 data)
00036 {
00037         rtl818x_write_phy(dev, addr, data);
00038 }
00039 
00040 static inline void rtl8225_write_phy_cck(struct net80211_device *dev,
00041                                          u8 addr, u8 data)
00042 {
00043         rtl818x_write_phy(dev, addr, data | 0x10000);
00044 }
00045 
00046 static void rtl8225_write(struct net80211_device *dev, u8 addr, u16 data)
00047 {
00048         struct rtl818x_priv *priv = dev->priv;
00049         u16 reg80, reg84, reg82;
00050         u32 bangdata;
00051         int i;
00052 
00053         bangdata = (data << 4) | (addr & 0xf);
00054 
00055         reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput) & 0xfff3;
00056         reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
00057 
00058         rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x7);
00059 
00060         reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect);
00061         rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x7 | 0x400);
00062         rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00063         udelay(10);
00064 
00065         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
00066         rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00067         udelay(2);
00068         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
00069         rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00070         udelay(10);
00071 
00072         for (i = 15; i >= 0; i--) {
00073                 u16 reg = ( reg80 | ( ( bangdata >> i ) & 1 ) );
00074 
00075                 if (i & 1)
00076                         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
00077 
00078                 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
00079                 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1));
00080 
00081                 if (!(i & 1))
00082                         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
00083         }
00084 
00085         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
00086         rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00087         udelay(10);
00088 
00089         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
00090         rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x400);
00091         rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
00092 }
00093 
00094 static u16 rtl8225_read(struct net80211_device *dev, u8 addr)
00095 {
00096         struct rtl818x_priv *priv = dev->priv;
00097         u16 reg80, reg82, reg84, out;
00098         int i;
00099 
00100         reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput);
00101         reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable);
00102         reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect) | 0x400;
00103 
00104         reg80 &= ~0xF;
00105 
00106         rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x000F);
00107         rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x000F);
00108 
00109         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2));
00110         rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00111         udelay(4);
00112         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80);
00113         rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00114         udelay(5);
00115 
00116         for (i = 4; i >= 0; i--) {
00117                 u16 reg = reg80 | ((addr >> i) & 1);
00118 
00119                 if (!(i & 1)) {
00120                         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
00121                         rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00122                         udelay(1);
00123                 }
00124 
00125                 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
00126                                   reg | (1 << 1));
00127                 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00128                 udelay(2);
00129                 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
00130                                   reg | (1 << 1));
00131                 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00132                 udelay(2);
00133 
00134                 if (i & 1) {
00135                         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
00136                         rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00137                         udelay(1);
00138                 }
00139         }
00140 
00141         rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x000E);
00142         rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x040E);
00143         rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00144         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
00145                           reg80 | (1 << 3) | (1 << 1));
00146         rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00147         udelay(2);
00148         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
00149                           reg80 | (1 << 3));
00150         rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00151         udelay(2);
00152         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
00153                           reg80 | (1 << 3));
00154         rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00155         udelay(2);
00156 
00157         out = 0;
00158         for (i = 11; i >= 0; i--) {
00159                 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
00160                                   reg80 | (1 << 3));
00161                 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00162                 udelay(1);
00163                 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
00164                                   reg80 | (1 << 3) | (1 << 1));
00165                 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00166                 udelay(2);
00167                 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
00168                                   reg80 | (1 << 3) | (1 << 1));
00169                 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00170                 udelay(2);
00171                 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
00172                                   reg80 | (1 << 3) | (1 << 1));
00173                 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00174                 udelay(2);
00175 
00176                 if (rtl818x_ioread16(priv, &priv->map->RFPinsInput) & (1 << 1))
00177                         out |= 1 << i;
00178 
00179                 rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
00180                                   reg80 | (1 << 3));
00181                 rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00182                 udelay(2);
00183         }
00184 
00185         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput,
00186                           reg80 | (1 << 3) | (1 << 2));
00187         rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00188         udelay(2);
00189 
00190         rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82);
00191         rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84);
00192         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x03A0);
00193 
00194         return out;
00195 }
00196 
00197 static const u16 rtl8225bcd_rxgain[] = {
00198         0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
00199         0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
00200         0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
00201         0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
00202         0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
00203         0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
00204         0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
00205         0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
00206         0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
00207         0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
00208         0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
00209         0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
00210 };
00211 
00212 static const u8 rtl8225_agc[] = {
00213         0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
00214         0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96,
00215         0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e,
00216         0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86,
00217         0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e,
00218         0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36,
00219         0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e,
00220         0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26,
00221         0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e,
00222         0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16,
00223         0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
00224         0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06,
00225         0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01,
00226         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
00227         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
00228         0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
00229 };
00230 
00231 static const u8 rtl8225_gain[] = {
00232         0x23, 0x88, 0x7c, 0xa5, /* -82dbm */
00233         0x23, 0x88, 0x7c, 0xb5, /* -82dbm */
00234         0x23, 0x88, 0x7c, 0xc5, /* -82dbm */
00235         0x33, 0x80, 0x79, 0xc5, /* -78dbm */
00236         0x43, 0x78, 0x76, 0xc5, /* -74dbm */
00237         0x53, 0x60, 0x73, 0xc5, /* -70dbm */
00238         0x63, 0x58, 0x70, 0xc5, /* -66dbm */
00239 };
00240 
00241 static const u8 rtl8225_threshold[] = {
00242         0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd
00243 };
00244 
00245 static const u8 rtl8225_tx_gain_cck_ofdm[] = {
00246         0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e
00247 };
00248 
00249 static const u8 rtl8225_tx_power_cck[] = {
00250         0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02,
00251         0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02,
00252         0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02,
00253         0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02,
00254         0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03,
00255         0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03
00256 };
00257 
00258 static const u8 rtl8225_tx_power_cck_ch14[] = {
00259         0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00,
00260         0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00,
00261         0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00,
00262         0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00,
00263         0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00,
00264         0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00
00265 };
00266 
00267 static const u8 rtl8225_tx_power_ofdm[] = {
00268         0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4
00269 };
00270 
00271 static const u32 rtl8225_chan[] = {
00272         0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c,
00273         0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72
00274 };
00275 
00276 static void rtl8225_rf_set_tx_power(struct net80211_device *dev, int channel)
00277 {
00278         struct rtl818x_priv *priv = dev->priv;
00279         u8 cck_power, ofdm_power;
00280         const u8 *tmp;
00281         u32 reg;
00282         int i;
00283 
00284         cck_power = priv->txpower[channel - 1] & 0xFF;
00285         ofdm_power = priv->txpower[channel - 1] >> 8;
00286 
00287         cck_power = min(cck_power, (u8)35);
00288         ofdm_power = min(ofdm_power, (u8)35);
00289 
00290         rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK,
00291                          rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1);
00292 
00293         if (channel == 14)
00294                 tmp = &rtl8225_tx_power_cck_ch14[(cck_power % 6) * 8];
00295         else
00296                 tmp = &rtl8225_tx_power_cck[(cck_power % 6) * 8];
00297 
00298         for (i = 0; i < 8; i++)
00299                 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
00300 
00301         mdelay(1); /* FIXME: optional? */
00302 
00303         /* anaparam2 on */
00304         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
00305         reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
00306         rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
00307         rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON);
00308         rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
00309         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
00310 
00311         rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM,
00312                          rtl8225_tx_gain_cck_ofdm[ofdm_power/6] >> 1);
00313 
00314         tmp = &rtl8225_tx_power_ofdm[ofdm_power % 6];
00315 
00316         rtl8225_write_phy_ofdm(dev, 5, *tmp);
00317         rtl8225_write_phy_ofdm(dev, 7, *tmp);
00318 
00319         mdelay(1);
00320 }
00321 
00322 static void rtl8225_rf_init(struct net80211_device *dev)
00323 {
00324         struct rtl818x_priv *priv = dev->priv;
00325         unsigned int i;
00326 
00327         rtl818x_set_anaparam(priv, RTL8225_ANAPARAM_ON);
00328 
00329         /* host_pci_init */
00330         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
00331         rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
00332         rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488);
00333         rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
00334         rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00335         mdelay(200);    /* FIXME: ehh?? */
00336         rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0xFF & ~(1 << 6));
00337 
00338         rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x000a8008);
00339 
00340         /* TODO: check if we need really to change BRSR to do RF config */
00341         rtl818x_ioread16(priv, &priv->map->BRSR);
00342         rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF);
00343         rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044);
00344         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
00345         rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44);
00346         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
00347 
00348         rtl8225_write(dev, 0x0, 0x067);
00349         rtl8225_write(dev, 0x1, 0xFE0);
00350         rtl8225_write(dev, 0x2, 0x44D);
00351         rtl8225_write(dev, 0x3, 0x441);
00352         rtl8225_write(dev, 0x4, 0x8BE);
00353         rtl8225_write(dev, 0x5, 0xBF0);         /* TODO: minipci */
00354         rtl8225_write(dev, 0x6, 0xAE6);
00355         rtl8225_write(dev, 0x7, rtl8225_chan[0]);
00356         rtl8225_write(dev, 0x8, 0x01F);
00357         rtl8225_write(dev, 0x9, 0x334);
00358         rtl8225_write(dev, 0xA, 0xFD4);
00359         rtl8225_write(dev, 0xB, 0x391);
00360         rtl8225_write(dev, 0xC, 0x050);
00361         rtl8225_write(dev, 0xD, 0x6DB);
00362         rtl8225_write(dev, 0xE, 0x029);
00363         rtl8225_write(dev, 0xF, 0x914); mdelay(1);
00364 
00365         rtl8225_write(dev, 0x2, 0xC4D); mdelay(100);
00366 
00367         rtl8225_write(dev, 0x0, 0x127);
00368 
00369         for (i = 0; i < ARRAY_SIZE(rtl8225bcd_rxgain); i++) {
00370                 rtl8225_write(dev, 0x1, i + 1);
00371                 rtl8225_write(dev, 0x2, rtl8225bcd_rxgain[i]);
00372         }
00373 
00374         rtl8225_write(dev, 0x0, 0x027);
00375         rtl8225_write(dev, 0x0, 0x22F);
00376         rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
00377 
00378         for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
00379                 rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
00380                 mdelay(1);
00381                 rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
00382                 mdelay(1);
00383         }
00384 
00385         mdelay(1);
00386 
00387         rtl8225_write_phy_ofdm(dev, 0x00, 0x01); mdelay(1);
00388         rtl8225_write_phy_ofdm(dev, 0x01, 0x02); mdelay(1);
00389         rtl8225_write_phy_ofdm(dev, 0x02, 0x62); mdelay(1);
00390         rtl8225_write_phy_ofdm(dev, 0x03, 0x00); mdelay(1);
00391         rtl8225_write_phy_ofdm(dev, 0x04, 0x00); mdelay(1);
00392         rtl8225_write_phy_ofdm(dev, 0x05, 0x00); mdelay(1);
00393         rtl8225_write_phy_ofdm(dev, 0x06, 0x00); mdelay(1);
00394         rtl8225_write_phy_ofdm(dev, 0x07, 0x00); mdelay(1);
00395         rtl8225_write_phy_ofdm(dev, 0x08, 0x00); mdelay(1);
00396         rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); mdelay(1);
00397         rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); mdelay(1);
00398         rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); mdelay(1);
00399         rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); mdelay(1);
00400         rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); mdelay(1);
00401         rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); mdelay(1);
00402         rtl8225_write_phy_ofdm(dev, 0x10, 0x84); mdelay(1);
00403         rtl8225_write_phy_ofdm(dev, 0x11, 0x03); mdelay(1);
00404         rtl8225_write_phy_ofdm(dev, 0x12, 0x20); mdelay(1);
00405         rtl8225_write_phy_ofdm(dev, 0x13, 0x20); mdelay(1);
00406         rtl8225_write_phy_ofdm(dev, 0x14, 0x00); mdelay(1);
00407         rtl8225_write_phy_ofdm(dev, 0x15, 0x40); mdelay(1);
00408         rtl8225_write_phy_ofdm(dev, 0x16, 0x00); mdelay(1);
00409         rtl8225_write_phy_ofdm(dev, 0x17, 0x40); mdelay(1);
00410         rtl8225_write_phy_ofdm(dev, 0x18, 0xef); mdelay(1);
00411         rtl8225_write_phy_ofdm(dev, 0x19, 0x19); mdelay(1);
00412         rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1);
00413         rtl8225_write_phy_ofdm(dev, 0x1b, 0x76); mdelay(1);
00414         rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); mdelay(1);
00415         rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); mdelay(1);
00416         rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1);
00417         rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); mdelay(1);
00418         rtl8225_write_phy_ofdm(dev, 0x21, 0x27); mdelay(1);
00419         rtl8225_write_phy_ofdm(dev, 0x22, 0x16); mdelay(1);
00420         rtl8225_write_phy_ofdm(dev, 0x24, 0x46); mdelay(1);
00421         rtl8225_write_phy_ofdm(dev, 0x25, 0x20); mdelay(1);
00422         rtl8225_write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);
00423         rtl8225_write_phy_ofdm(dev, 0x27, 0x88); mdelay(1);
00424 
00425         rtl8225_write_phy_cck(dev, 0x00, 0x98); mdelay(1);
00426         rtl8225_write_phy_cck(dev, 0x03, 0x20); mdelay(1);
00427         rtl8225_write_phy_cck(dev, 0x04, 0x7e); mdelay(1);
00428         rtl8225_write_phy_cck(dev, 0x05, 0x12); mdelay(1);
00429         rtl8225_write_phy_cck(dev, 0x06, 0xfc); mdelay(1);
00430         rtl8225_write_phy_cck(dev, 0x07, 0x78); mdelay(1);
00431         rtl8225_write_phy_cck(dev, 0x08, 0x2e); mdelay(1);
00432         rtl8225_write_phy_cck(dev, 0x10, 0x93); mdelay(1);
00433         rtl8225_write_phy_cck(dev, 0x11, 0x88); mdelay(1);
00434         rtl8225_write_phy_cck(dev, 0x12, 0x47); mdelay(1);
00435         rtl8225_write_phy_cck(dev, 0x13, 0xd0);
00436         rtl8225_write_phy_cck(dev, 0x19, 0x00);
00437         rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
00438         rtl8225_write_phy_cck(dev, 0x1b, 0x08);
00439         rtl8225_write_phy_cck(dev, 0x40, 0x86);
00440         rtl8225_write_phy_cck(dev, 0x41, 0x8d); mdelay(1);
00441         rtl8225_write_phy_cck(dev, 0x42, 0x15); mdelay(1);
00442         rtl8225_write_phy_cck(dev, 0x43, 0x18); mdelay(1);
00443         rtl8225_write_phy_cck(dev, 0x44, 0x1f); mdelay(1);
00444         rtl8225_write_phy_cck(dev, 0x45, 0x1e); mdelay(1);
00445         rtl8225_write_phy_cck(dev, 0x46, 0x1a); mdelay(1);
00446         rtl8225_write_phy_cck(dev, 0x47, 0x15); mdelay(1);
00447         rtl8225_write_phy_cck(dev, 0x48, 0x10); mdelay(1);
00448         rtl8225_write_phy_cck(dev, 0x49, 0x0a); mdelay(1);
00449         rtl8225_write_phy_cck(dev, 0x4a, 0x05); mdelay(1);
00450         rtl8225_write_phy_cck(dev, 0x4b, 0x02); mdelay(1);
00451         rtl8225_write_phy_cck(dev, 0x4c, 0x05); mdelay(1);
00452 
00453         rtl818x_iowrite8(priv, &priv->map->TESTR, 0x0D); mdelay(1);
00454 
00455         rtl8225_rf_set_tx_power(dev, 1);
00456 
00457         /* RX antenna default to A */
00458         rtl8225_write_phy_cck(dev, 0x10, 0x9b); mdelay(1);      /* B: 0xDB */
00459         rtl8225_write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);     /* B: 0x10 */
00460 
00461         rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);   /* B: 0x00 */
00462         mdelay(1);
00463         rtl818x_iowrite32(priv, (u32 *)((u8 *)priv->map + 0x94), 0x15c00002);
00464         rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
00465 
00466         rtl8225_write(dev, 0x0c, 0x50);
00467         /* set OFDM initial gain */
00468         rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[4 * 4]);
00469         rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[4 * 4 + 1]);
00470         rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[4 * 4 + 2]);
00471         rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[4 * 4 + 3]);
00472         /* set CCK threshold */
00473         rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[0]);
00474 }
00475 
00476 static const u8 rtl8225z2_tx_power_cck_ch14[] = {
00477         0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00
00478 };
00479 
00480 static const u8 rtl8225z2_tx_power_cck_B[] = {
00481         0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x04
00482 };
00483 
00484 static const u8 rtl8225z2_tx_power_cck_A[] = {
00485         0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04
00486 };
00487 
00488 static const u8 rtl8225z2_tx_power_cck[] = {
00489         0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04
00490 };
00491 
00492 static void rtl8225z2_rf_set_tx_power(struct net80211_device *dev, int channel)
00493 {
00494         struct rtl818x_priv *priv = dev->priv;
00495         u8 cck_power, ofdm_power;
00496         const u8 *tmp;
00497         int i;
00498 
00499         cck_power = priv->txpower[channel - 1] & 0xFF;
00500         ofdm_power = priv->txpower[channel - 1] >> 8;
00501 
00502         if (channel == 14)
00503                 tmp = rtl8225z2_tx_power_cck_ch14;
00504         else if (cck_power == 12)
00505                 tmp = rtl8225z2_tx_power_cck_B;
00506         else if (cck_power == 13)
00507                 tmp = rtl8225z2_tx_power_cck_A;
00508         else
00509                 tmp = rtl8225z2_tx_power_cck;
00510 
00511         for (i = 0; i < 8; i++)
00512                 rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++);
00513 
00514         cck_power = min(cck_power, (u8)35);
00515         if (cck_power == 13 || cck_power == 14)
00516                 cck_power = 12;
00517         if (cck_power >= 15)
00518                 cck_power -= 2;
00519 
00520         rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, cck_power);
00521         rtl818x_ioread8(priv, &priv->map->TX_GAIN_CCK);
00522         mdelay(1);
00523 
00524         ofdm_power = min(ofdm_power, (u8)35);
00525         rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, ofdm_power);
00526 
00527         rtl8225_write_phy_ofdm(dev, 2, 0x62);
00528         rtl8225_write_phy_ofdm(dev, 5, 0x00);
00529         rtl8225_write_phy_ofdm(dev, 6, 0x40);
00530         rtl8225_write_phy_ofdm(dev, 7, 0x00);
00531         rtl8225_write_phy_ofdm(dev, 8, 0x40);
00532 
00533         mdelay(1);
00534 }
00535 
00536 static const u16 rtl8225z2_rxgain[] = {
00537         0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0008, 0x0009,
00538         0x000a, 0x000b, 0x0102, 0x0103, 0x0104, 0x0105, 0x0140, 0x0141,
00539         0x0142, 0x0143, 0x0144, 0x0145, 0x0180, 0x0181, 0x0182, 0x0183,
00540         0x0184, 0x0185, 0x0188, 0x0189, 0x018a, 0x018b, 0x0243, 0x0244,
00541         0x0245, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0288,
00542         0x0289, 0x028a, 0x028b, 0x028c, 0x0342, 0x0343, 0x0344, 0x0345,
00543         0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0388, 0x0389,
00544         0x038a, 0x038b, 0x038c, 0x038d, 0x0390, 0x0391, 0x0392, 0x0393,
00545         0x0394, 0x0395, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d,
00546         0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9,
00547         0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
00548         0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
00549 };
00550 
00551 static void rtl8225z2_rf_init(struct net80211_device *dev)
00552 {
00553         struct rtl818x_priv *priv = dev->priv;
00554         unsigned int i;
00555 
00556         rtl818x_set_anaparam(priv, RTL8225_ANAPARAM_ON);
00557 
00558         /* host_pci_init */
00559         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
00560         rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
00561         rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488);
00562         rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0);
00563         rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00564         mdelay(200);    /* FIXME: ehh?? */
00565         rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0xFF & ~(1 << 6));
00566 
00567         rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00088008);
00568 
00569         /* TODO: check if we need really to change BRSR to do RF config */
00570         rtl818x_ioread16(priv, &priv->map->BRSR);
00571         rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF);
00572         rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044);
00573         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
00574         rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44);
00575         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
00576 
00577         rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
00578 
00579         rtl8225_write(dev, 0x0, 0x0B7); mdelay(1);
00580         rtl8225_write(dev, 0x1, 0xEE0); mdelay(1);
00581         rtl8225_write(dev, 0x2, 0x44D); mdelay(1);
00582         rtl8225_write(dev, 0x3, 0x441); mdelay(1);
00583         rtl8225_write(dev, 0x4, 0x8C3); mdelay(1);
00584         rtl8225_write(dev, 0x5, 0xC72); mdelay(1);
00585         rtl8225_write(dev, 0x6, 0x0E6); mdelay(1);
00586         rtl8225_write(dev, 0x7, 0x82A); mdelay(1);
00587         rtl8225_write(dev, 0x8, 0x03F); mdelay(1);
00588         rtl8225_write(dev, 0x9, 0x335); mdelay(1);
00589         rtl8225_write(dev, 0xa, 0x9D4); mdelay(1);
00590         rtl8225_write(dev, 0xb, 0x7BB); mdelay(1);
00591         rtl8225_write(dev, 0xc, 0x850); mdelay(1);
00592         rtl8225_write(dev, 0xd, 0xCDF); mdelay(1);
00593         rtl8225_write(dev, 0xe, 0x02B); mdelay(1);
00594         rtl8225_write(dev, 0xf, 0x114); mdelay(100);
00595 
00596         if (!(rtl8225_read(dev, 6) & (1 << 7))) {
00597                 rtl8225_write(dev, 0x02, 0x0C4D);
00598                 mdelay(200);
00599                 rtl8225_write(dev, 0x02, 0x044D);
00600                 mdelay(100);
00601                 /* TODO: readd calibration failure message when the calibration
00602                    check works */
00603         }
00604 
00605         rtl8225_write(dev, 0x0, 0x1B7);
00606         rtl8225_write(dev, 0x3, 0x002);
00607         rtl8225_write(dev, 0x5, 0x004);
00608 
00609         for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
00610                 rtl8225_write(dev, 0x1, i + 1);
00611                 rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]);
00612         }
00613 
00614         rtl8225_write(dev, 0x0, 0x0B7); mdelay(100);
00615         rtl8225_write(dev, 0x2, 0xC4D);
00616 
00617         mdelay(200);
00618         rtl8225_write(dev, 0x2, 0x44D);
00619         mdelay(100);
00620 
00621         rtl8225_write(dev, 0x00, 0x2BF);
00622         rtl8225_write(dev, 0xFF, 0xFFFF);
00623 
00624         rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
00625 
00626         for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
00627                 rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]);
00628                 mdelay(1);
00629                 rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i);
00630                 mdelay(1);
00631         }
00632 
00633         mdelay(1);
00634 
00635         rtl8225_write_phy_ofdm(dev, 0x00, 0x01); mdelay(1);
00636         rtl8225_write_phy_ofdm(dev, 0x01, 0x02); mdelay(1);
00637         rtl8225_write_phy_ofdm(dev, 0x02, 0x62); mdelay(1);
00638         rtl8225_write_phy_ofdm(dev, 0x03, 0x00); mdelay(1);
00639         rtl8225_write_phy_ofdm(dev, 0x04, 0x00); mdelay(1);
00640         rtl8225_write_phy_ofdm(dev, 0x05, 0x00); mdelay(1);
00641         rtl8225_write_phy_ofdm(dev, 0x06, 0x40); mdelay(1);
00642         rtl8225_write_phy_ofdm(dev, 0x07, 0x00); mdelay(1);
00643         rtl8225_write_phy_ofdm(dev, 0x08, 0x40); mdelay(1);
00644         rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); mdelay(1);
00645         rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); mdelay(1);
00646         rtl8225_write_phy_ofdm(dev, 0x18, 0xef); mdelay(1);
00647         rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); mdelay(1);
00648         rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); mdelay(1);
00649         rtl8225_write_phy_ofdm(dev, 0x0d, 0x43);
00650         rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); mdelay(1);
00651         rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); mdelay(1);
00652         rtl8225_write_phy_ofdm(dev, 0x10, 0x84); mdelay(1);
00653         rtl8225_write_phy_ofdm(dev, 0x11, 0x06); mdelay(1);
00654         rtl8225_write_phy_ofdm(dev, 0x12, 0x20); mdelay(1);
00655         rtl8225_write_phy_ofdm(dev, 0x13, 0x20); mdelay(1);
00656         rtl8225_write_phy_ofdm(dev, 0x14, 0x00); mdelay(1);
00657         rtl8225_write_phy_ofdm(dev, 0x15, 0x40); mdelay(1);
00658         rtl8225_write_phy_ofdm(dev, 0x16, 0x00); mdelay(1);
00659         rtl8225_write_phy_ofdm(dev, 0x17, 0x40); mdelay(1);
00660         rtl8225_write_phy_ofdm(dev, 0x18, 0xef); mdelay(1);
00661         rtl8225_write_phy_ofdm(dev, 0x19, 0x19); mdelay(1);
00662         rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1);
00663         rtl8225_write_phy_ofdm(dev, 0x1b, 0x11); mdelay(1);
00664         rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); mdelay(1);
00665         rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5); mdelay(1);
00666         rtl8225_write_phy_ofdm(dev, 0x1e, 0xb3); mdelay(1);
00667         rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1);
00668         rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); mdelay(1);
00669         rtl8225_write_phy_ofdm(dev, 0x21, 0x27); mdelay(1);
00670         rtl8225_write_phy_ofdm(dev, 0x22, 0x16); mdelay(1);
00671         rtl8225_write_phy_ofdm(dev, 0x23, 0x80); mdelay(1); /* FIXME: not needed? */
00672         rtl8225_write_phy_ofdm(dev, 0x24, 0x46); mdelay(1);
00673         rtl8225_write_phy_ofdm(dev, 0x25, 0x20); mdelay(1);
00674         rtl8225_write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);
00675         rtl8225_write_phy_ofdm(dev, 0x27, 0x88); mdelay(1);
00676 
00677         rtl8225_write_phy_cck(dev, 0x00, 0x98); mdelay(1);
00678         rtl8225_write_phy_cck(dev, 0x03, 0x20); mdelay(1);
00679         rtl8225_write_phy_cck(dev, 0x04, 0x7e); mdelay(1);
00680         rtl8225_write_phy_cck(dev, 0x05, 0x12); mdelay(1);
00681         rtl8225_write_phy_cck(dev, 0x06, 0xfc); mdelay(1);
00682         rtl8225_write_phy_cck(dev, 0x07, 0x78); mdelay(1);
00683         rtl8225_write_phy_cck(dev, 0x08, 0x2e); mdelay(1);
00684         rtl8225_write_phy_cck(dev, 0x10, 0x93); mdelay(1);
00685         rtl8225_write_phy_cck(dev, 0x11, 0x88); mdelay(1);
00686         rtl8225_write_phy_cck(dev, 0x12, 0x47); mdelay(1);
00687         rtl8225_write_phy_cck(dev, 0x13, 0xd0);
00688         rtl8225_write_phy_cck(dev, 0x19, 0x00);
00689         rtl8225_write_phy_cck(dev, 0x1a, 0xa0);
00690         rtl8225_write_phy_cck(dev, 0x1b, 0x08);
00691         rtl8225_write_phy_cck(dev, 0x40, 0x86);
00692         rtl8225_write_phy_cck(dev, 0x41, 0x8a); mdelay(1);
00693         rtl8225_write_phy_cck(dev, 0x42, 0x15); mdelay(1);
00694         rtl8225_write_phy_cck(dev, 0x43, 0x18); mdelay(1);
00695         rtl8225_write_phy_cck(dev, 0x44, 0x36); mdelay(1);
00696         rtl8225_write_phy_cck(dev, 0x45, 0x35); mdelay(1);
00697         rtl8225_write_phy_cck(dev, 0x46, 0x2e); mdelay(1);
00698         rtl8225_write_phy_cck(dev, 0x47, 0x25); mdelay(1);
00699         rtl8225_write_phy_cck(dev, 0x48, 0x1c); mdelay(1);
00700         rtl8225_write_phy_cck(dev, 0x49, 0x12); mdelay(1);
00701         rtl8225_write_phy_cck(dev, 0x4a, 0x09); mdelay(1);
00702         rtl8225_write_phy_cck(dev, 0x4b, 0x04); mdelay(1);
00703         rtl8225_write_phy_cck(dev, 0x4c, 0x05); mdelay(1);
00704 
00705         rtl818x_iowrite8(priv, (u8 *)priv->map + 0x5B, 0x0D); mdelay(1);
00706 
00707         rtl8225z2_rf_set_tx_power(dev, 1);
00708 
00709         /* RX antenna default to A */
00710         rtl8225_write_phy_cck(dev, 0x10, 0x9b); mdelay(1);      /* B: 0xDB */
00711         rtl8225_write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);     /* B: 0x10 */
00712 
00713         rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);   /* B: 0x00 */
00714         mdelay(1);
00715         rtl818x_iowrite32(priv, (u32 *)((u8 *)priv->map + 0x94), 0x15c00002);
00716         rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
00717 }
00718 
00719 static void rtl8225x_rf_init(struct net80211_device *dev)
00720 {
00721         struct rtl818x_priv *priv = dev->priv;
00722         u16 reg8, reg9;
00723 
00724         rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
00725         rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488);
00726         rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF);
00727         rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00728         mdelay(100);
00729 
00730         rtl8225_write(dev, 0, 0x1B7);
00731 
00732         reg8 = rtl8225_read(dev, 8);
00733         reg9 = rtl8225_read(dev, 9);
00734 
00735         rtl8225_write(dev, 0, 0x0B7);
00736 
00737         if (reg8 != 0x588 || reg9 != 0x700) {
00738                 priv->rf_flag = 0;
00739                 rtl8225_rf_init(dev);
00740         } else {
00741                 priv->rf_flag = 1;
00742                 rtl8225z2_rf_init(dev);
00743         }
00744 }
00745 
00746 static void rtl8225_rf_stop(struct net80211_device *dev)
00747 {
00748         struct rtl818x_priv *priv = dev->priv;
00749         u8 reg;
00750 
00751         rtl8225_write(dev, 0x4, 0x1f); mdelay(1);
00752 
00753         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
00754         reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
00755         rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
00756         rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_OFF);
00757         rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_OFF);
00758         rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
00759         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
00760 }
00761 
00762 static void rtl8225_rf_set_channel(struct net80211_device *dev,
00763                                    struct net80211_channel *channelp)
00764 {
00765         struct rtl818x_priv *priv = dev->priv;
00766         int chan = channelp->channel_nr;
00767 
00768         if (priv->rf_flag)
00769                 rtl8225z2_rf_set_tx_power(dev, chan);
00770         else
00771                 rtl8225_rf_set_tx_power(dev, chan);
00772 
00773         rtl8225_write(dev, 0x7, rtl8225_chan[chan - 1]);
00774         mdelay(10);
00775 }
00776 
00777 static void rtl8225_rf_conf_erp(struct net80211_device *dev)
00778 {
00779         struct rtl818x_priv *priv = dev->priv;
00780 
00781         if (dev->phy_flags & NET80211_PHY_USE_SHORT_SLOT) {
00782                 rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9);
00783                 rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22);
00784                 rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14);
00785                 rtl818x_iowrite8(priv, &priv->map->EIFS, 81);
00786                 rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0x73);
00787         } else {
00788                 rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14);
00789                 rtl818x_iowrite8(priv, &priv->map->SIFS, 0x44);
00790                 rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24);
00791                 rtl818x_iowrite8(priv, &priv->map->EIFS, 81);
00792                 rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5);
00793         }
00794 }
00795 
00796 struct rtl818x_rf_ops rtl8225_ops __rtl818x_rf_driver = {
00797         .name           = "rtl8225",
00798         .id             = 9,
00799         .init           = rtl8225x_rf_init,
00800         .stop           = rtl8225_rf_stop,
00801         .set_chan       = rtl8225_rf_set_channel,
00802         .conf_erp       = rtl8225_rf_conf_erp,
00803 };