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