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