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 
rtl8225_write(struct ieee80211_hw * dev,u8 addr,u16 data)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 
rtl8225_read(struct ieee80211_hw * dev,u8 addr)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 
rtl8225_rf_set_tx_power(struct ieee80211_hw * dev,int channel)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 
rtl8225_rf_init(struct ieee80211_hw * dev)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 
rtl8225z2_rf_set_tx_power(struct ieee80211_hw * dev,int channel)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 
rtl8225z2_rf_init(struct ieee80211_hw * dev)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 
rtl8225_rf_stop(struct ieee80211_hw * dev)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 
rtl8225_rf_set_channel(struct ieee80211_hw * dev,struct ieee80211_conf * conf)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 
rtl8225_rf_conf_erp(struct ieee80211_hw * dev,struct ieee80211_bss_conf * info)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 
rtl8180_detect_rf(struct ieee80211_hw * dev)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 }
792