1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
6 * Purpose: rf function code
13 * IFRFbWriteEmbedded - Embedded write RF register via MAC
26 #define BY_AL2230_REG_LEN 23 /* 24bit */
27 #define CB_AL2230_INIT_SEQ 15
28 #define SWITCH_CHANNEL_DELAY_AL2230 200 /* us */
29 #define AL2230_PWR_IDX_LEN 64
31 #define BY_AL7230_REG_LEN 23 /* 24bit */
32 #define CB_AL7230_INIT_SEQ 16
33 #define SWITCH_CHANNEL_DELAY_AL7230 200 /* us */
34 #define AL7230_PWR_IDX_LEN 64
36 static const unsigned long al2230_init_table[CB_AL2230_INIT_SEQ] = {
37 0x03F79000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
38 0x03333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
39 0x01A00200 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
40 0x00FFF300 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
41 0x0005A400 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
42 0x0F4DC500 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
43 0x0805B600 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
44 0x0146C700 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
45 0x00068800 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
46 0x0403B900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
47 0x00DBBA00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
48 0x00099B00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
49 0x0BDFFC00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
50 0x00000D00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
51 0x00580F00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW
54 static const unsigned long al2230_channel_table0[CB_MAX_CHANNEL] = {
55 0x03F79000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 1, Tf = 2412MHz */
56 0x03F79000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 2, Tf = 2417MHz */
57 0x03E79000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 3, Tf = 2422MHz */
58 0x03E79000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 4, Tf = 2427MHz */
59 0x03F7A000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 5, Tf = 2432MHz */
60 0x03F7A000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 6, Tf = 2437MHz */
61 0x03E7A000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 7, Tf = 2442MHz */
62 0x03E7A000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 8, Tf = 2447MHz */
63 0x03F7B000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 9, Tf = 2452MHz */
64 0x03F7B000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 10, Tf = 2457MHz */
65 0x03E7B000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 11, Tf = 2462MHz */
66 0x03E7B000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 12, Tf = 2467MHz */
67 0x03F7C000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 13, Tf = 2472MHz */
68 0x03E7C000 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW /* channel = 14, Tf = 2412M */
71 static const unsigned long al2230_channel_table1[CB_MAX_CHANNEL] = {
72 0x03333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 1, Tf = 2412MHz */
73 0x0B333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 2, Tf = 2417MHz */
74 0x03333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 3, Tf = 2422MHz */
75 0x0B333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 4, Tf = 2427MHz */
76 0x03333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 5, Tf = 2432MHz */
77 0x0B333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 6, Tf = 2437MHz */
78 0x03333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 7, Tf = 2442MHz */
79 0x0B333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 8, Tf = 2447MHz */
80 0x03333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 9, Tf = 2452MHz */
81 0x0B333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 10, Tf = 2457MHz */
82 0x03333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 11, Tf = 2462MHz */
83 0x0B333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 12, Tf = 2467MHz */
84 0x03333100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW, /* channel = 13, Tf = 2472MHz */
85 0x06666100 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW /* channel = 14, Tf = 2412M */
88 static unsigned long al2230_power_table[AL2230_PWR_IDX_LEN] = {
89 0x04040900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
90 0x04041900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
91 0x04042900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
92 0x04043900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
93 0x04044900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
94 0x04045900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
95 0x04046900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
96 0x04047900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
97 0x04048900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
98 0x04049900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
99 0x0404A900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
100 0x0404B900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
101 0x0404C900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
102 0x0404D900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
103 0x0404E900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
104 0x0404F900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
105 0x04050900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
106 0x04051900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
107 0x04052900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
108 0x04053900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
109 0x04054900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
110 0x04055900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
111 0x04056900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
112 0x04057900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
113 0x04058900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
114 0x04059900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
115 0x0405A900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
116 0x0405B900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
117 0x0405C900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
118 0x0405D900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
119 0x0405E900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
120 0x0405F900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
121 0x04060900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
122 0x04061900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
123 0x04062900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
124 0x04063900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
125 0x04064900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
126 0x04065900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
127 0x04066900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
128 0x04067900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
129 0x04068900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
130 0x04069900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
131 0x0406A900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
132 0x0406B900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
133 0x0406C900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
134 0x0406D900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
135 0x0406E900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
136 0x0406F900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
137 0x04070900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
138 0x04071900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
139 0x04072900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
140 0x04073900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
141 0x04074900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
142 0x04075900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
143 0x04076900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
144 0x04077900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
145 0x04078900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
146 0x04079900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
147 0x0407A900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
148 0x0407B900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
149 0x0407C900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
150 0x0407D900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
151 0x0407E900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW,
152 0x0407F900 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW
156 * Description: Write to IF/RF, by embedded programming
160 * iobase - I/O base address
161 * dwData - data to write
165 * Return Value: true if succeeded; false if failed.
168 bool IFRFbWriteEmbedded(struct vnt_private *priv, unsigned long dwData)
170 void __iomem *iobase = priv->port_offset;
172 unsigned long dwValue;
174 VNSvOutPortD(iobase + MAC_REG_IFREGCTL, dwData);
176 /* W_MAX_TIMEOUT is the timeout period */
177 for (ww = 0; ww < W_MAX_TIMEOUT; ww++) {
178 dwValue = ioread32(iobase + MAC_REG_IFREGCTL);
179 if (dwValue & IFREGCTL_DONE)
183 if (ww == W_MAX_TIMEOUT)
190 * Description: AIROHA IFRF chip init function
194 * iobase - I/O base address
198 * Return Value: true if succeeded; false if failed.
201 static bool RFbAL2230Init(struct vnt_private *priv)
203 void __iomem *iobase = priv->port_offset;
209 /* 3-wire control for normal mode */
210 iowrite8(0, iobase + MAC_REG_SOFTPWRCTL);
212 MACvWordRegBitsOn(iobase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPECTI |
213 SOFTPWRCTL_TXPEINV));
215 MACvWordRegBitsOff(iobase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3);
217 /* patch abnormal AL2230 frequency output */
218 IFRFbWriteEmbedded(priv, (0x07168700 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW));
220 for (ii = 0; ii < CB_AL2230_INIT_SEQ; ii++)
221 ret &= IFRFbWriteEmbedded(priv, al2230_init_table[ii]);
222 MACvTimer0MicroSDelay(priv, 30); /* delay 30 us */
225 MACvWordRegBitsOn(iobase, MAC_REG_SOFTPWRCTL, SOFTPWRCTL_SWPE3);
227 MACvTimer0MicroSDelay(priv, 150);/* 150us */
228 ret &= IFRFbWriteEmbedded(priv, (0x00d80f00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW));
229 MACvTimer0MicroSDelay(priv, 30);/* 30us */
230 ret &= IFRFbWriteEmbedded(priv, (0x00780f00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW));
231 MACvTimer0MicroSDelay(priv, 30);/* 30us */
232 ret &= IFRFbWriteEmbedded(priv,
233 al2230_init_table[CB_AL2230_INIT_SEQ - 1]);
235 MACvWordRegBitsOn(iobase, MAC_REG_SOFTPWRCTL, (SOFTPWRCTL_SWPE3 |
238 SOFTPWRCTL_TXPEINV));
240 /* 3-wire control for power saving mode */
241 iowrite8(PSSIG_WPE3 | PSSIG_WPE2, iobase + MAC_REG_PSPWRSIG);
246 static bool RFbAL2230SelectChannel(struct vnt_private *priv, unsigned char byChannel)
248 void __iomem *iobase = priv->port_offset;
253 ret &= IFRFbWriteEmbedded(priv, al2230_channel_table0[byChannel - 1]);
254 ret &= IFRFbWriteEmbedded(priv, al2230_channel_table1[byChannel - 1]);
256 /* Set Channel[7] = 0 to tell H/W channel is changing now. */
257 iowrite8(byChannel & 0x7F, iobase + MAC_REG_CHANNEL);
258 MACvTimer0MicroSDelay(priv, SWITCH_CHANNEL_DELAY_AL2230);
259 /* Set Channel[7] = 1 to tell H/W channel change is done. */
260 iowrite8(byChannel | 0x80, iobase + MAC_REG_CHANNEL);
266 * Description: RF init function
275 * Return Value: true if succeeded; false if failed.
278 bool RFbInit(struct vnt_private *priv)
282 switch (priv->byRFType) {
285 priv->max_pwr_level = AL2230_PWR_IDX_LEN;
286 ret = RFbAL2230Init(priv);
299 * Description: Select channel
304 * byChannel - Channel number
308 * Return Value: true if succeeded; false if failed.
311 bool RFbSelectChannel(struct vnt_private *priv, unsigned char byRFType,
319 ret = RFbAL2230SelectChannel(priv, byChannel);
321 /*{{ RobertYu: 20050104 */
333 * Description: Write WakeProgSyn
337 * priv - Device Structure
339 * channel - Channel number
341 * Return Value: true if succeeded; false if failed.
344 bool rf_write_wake_prog_syn(struct vnt_private *priv, unsigned char rf_type,
347 void __iomem *iobase = priv->port_offset;
349 unsigned char init_count = 0;
350 unsigned char sleep_count = 0;
351 unsigned short idx = MISCFIFO_SYNDATA_IDX;
353 VNSvOutPortW(iobase + MAC_REG_MISCFFNDEX, 0);
358 if (channel > CB_MAX_CHANNEL_24G)
361 /* Init Reg + Channel Reg (2) */
362 init_count = CB_AL2230_INIT_SEQ + 2;
365 for (i = 0; i < CB_AL2230_INIT_SEQ; i++)
366 MACvSetMISCFifo(priv, idx++, al2230_init_table[i]);
368 MACvSetMISCFifo(priv, idx++, al2230_channel_table0[channel - 1]);
369 MACvSetMISCFifo(priv, idx++, al2230_channel_table1[channel - 1]);
372 /* Need to check, PLLON need to be low for channel setting */
381 MACvSetMISCFifo(priv, MISCFIFO_SYNINFO_IDX, (unsigned long)MAKEWORD(sleep_count, init_count));
387 * Description: Set Tx power
391 * iobase - I/O base address
392 * dwRFPowerTable - RF Tx Power Setting
396 * Return Value: true if succeeded; false if failed.
399 bool RFbSetPower(struct vnt_private *priv, unsigned int rate, u16 uCH)
402 unsigned char byPwr = 0;
403 unsigned char byDec = 0;
405 if (priv->dwDiagRefCount != 0)
408 if ((uCH < 1) || (uCH > CB_MAX_CHANNEL))
416 if (uCH > CB_MAX_CHANNEL_24G)
419 byPwr = priv->abyCCKPwrTbl[uCH];
425 byPwr = priv->abyOFDMPwrTbl[uCH];
428 if (byDec >= priv->max_pwr_level)
429 byDec = priv->max_pwr_level - 1;
437 byPwr = priv->abyOFDMPwrTbl[uCH];
441 if (priv->byCurPwr == byPwr)
444 ret = RFbRawSetPower(priv, byPwr, rate);
446 priv->byCurPwr = byPwr;
452 * Description: Set Tx power
456 * iobase - I/O base address
457 * dwRFPowerTable - RF Tx Power Setting
461 * Return Value: true if succeeded; false if failed.
465 bool RFbRawSetPower(struct vnt_private *priv, unsigned char byPwr,
470 if (byPwr >= priv->max_pwr_level)
473 switch (priv->byRFType) {
475 ret &= IFRFbWriteEmbedded(priv, al2230_power_table[byPwr]);
476 if (rate <= RATE_11M)
477 ret &= IFRFbWriteEmbedded(priv, 0x0001B400 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW);
479 ret &= IFRFbWriteEmbedded(priv, 0x0005A400 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW);
484 ret &= IFRFbWriteEmbedded(priv, al2230_power_table[byPwr]);
485 if (rate <= RATE_11M) {
486 ret &= IFRFbWriteEmbedded(priv, 0x040C1400 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW);
487 ret &= IFRFbWriteEmbedded(priv, 0x00299B00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW);
489 ret &= IFRFbWriteEmbedded(priv, 0x0005A400 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW);
490 ret &= IFRFbWriteEmbedded(priv, 0x00099B00 + (BY_AL2230_REG_LEN << 3) + IFREGCTL_REGW);
503 * Routine Description:
504 * Translate RSSI to dBm
508 * priv - The adapter to be translated
509 * byCurrRSSI - RSSI to be translated
511 * pdwdbm - Translated dbm number
517 RFvRSSITodBm(struct vnt_private *priv, unsigned char byCurrRSSI, long *pldBm)
519 unsigned char byIdx = (((byCurrRSSI & 0xC0) >> 6) & 0x03);
520 long b = (byCurrRSSI & 0x3F);
522 unsigned char abyAIROHARF[4] = {0, 18, 0, 40};
524 switch (priv->byRFType) {
527 a = abyAIROHARF[byIdx];
533 *pldBm = -1 * (a + b * 2);