root/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8225.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rtl8225_write
  2. rtl8225_read
  3. rtl8225_rf_set_tx_power
  4. rtl8225_rf_init
  5. rtl8225z2_rf_set_tx_power
  6. rtl8225z2_rf_init
  7. rtl8225_rf_stop
  8. rtl8225_rf_set_channel
  9. rtl8180_detect_rf

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

/* [<][>][^][v][top][bottom][index][help] */