source: bootcd/isolinux/syslinux-6.03/gpxe/src/drivers/net/rtl818x/rtl8185_rtl8225.c

Last change on this file was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

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