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