Commit | Line | Data |
---|---|---|
2865d42c | 1 | /****************************************************************************** |
2865d42c | 2 | * |
cf3e6881 | 3 | * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. |
2865d42c | 4 | * |
cf3e6881 AB |
5 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of version 2 of the GNU General Public License as | |
7 | * published by the Free Software Foundation. | |
2865d42c | 8 | * |
cf3e6881 AB |
9 | * This program is distributed in the hope that it will be useful, but WITHOUT |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
12 | * more details. | |
2865d42c | 13 | * |
cf3e6881 AB |
14 | * You should have received a copy of the GNU General Public License along with |
15 | * this program; if not, write to the Free Software Foundation, Inc., | |
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | |
2865d42c | 17 | * |
cf3e6881 AB |
18 | * Modifications for inclusion into the Linux staging tree are |
19 | * Copyright(c) 2010 Larry Finger. All rights reserved. | |
2865d42c | 20 | * |
cf3e6881 AB |
21 | * Contact information: |
22 | * WLAN FAE <wlanfae@realtek.com> | |
23 | * Larry Finger <Larry.Finger@lwfinger.net> | |
24 | * | |
25 | ******************************************************************************/ | |
2865d42c LF |
26 | #define _RTL871X_MP_C_ |
27 | ||
28 | #include "osdep_service.h" | |
29 | #include "drv_types.h" | |
30 | #include "rtl871x_mp_phy_regdef.h" | |
31 | #include "rtl8712_cmd.h" | |
32 | ||
33 | static void _init_mp_priv_(struct mp_priv *pmp_priv) | |
34 | { | |
35 | pmp_priv->mode = _LOOPBOOK_MODE_; | |
36 | pmp_priv->curr_ch = 1; | |
37 | pmp_priv->curr_modem = MIXED_PHY; | |
38 | pmp_priv->curr_rateidx = 0; | |
39 | pmp_priv->curr_txpoweridx = 0x14; | |
40 | pmp_priv->antenna_tx = ANTENNA_A; | |
41 | pmp_priv->antenna_rx = ANTENNA_AB; | |
42 | pmp_priv->check_mp_pkt = 0; | |
43 | pmp_priv->tx_pktcount = 0; | |
44 | pmp_priv->rx_pktcount = 0; | |
45 | pmp_priv->rx_crcerrpktcount = 0; | |
46 | } | |
47 | ||
48 | static int init_mp_priv(struct mp_priv *pmp_priv) | |
49 | { | |
50 | int i, res; | |
51 | struct mp_xmit_frame *pmp_xmitframe; | |
52 | ||
53 | _init_mp_priv_(pmp_priv); | |
54 | _init_queue(&pmp_priv->free_mp_xmitqueue); | |
55 | pmp_priv->pallocated_mp_xmitframe_buf = NULL; | |
56 | pmp_priv->pallocated_mp_xmitframe_buf = _malloc(NR_MP_XMITFRAME * | |
57 | sizeof(struct mp_xmit_frame) + 4); | |
58 | if (pmp_priv->pallocated_mp_xmitframe_buf == NULL) { | |
59 | res = _FAIL; | |
60 | goto _exit_init_mp_priv; | |
61 | } | |
62 | pmp_priv->pmp_xmtframe_buf = pmp_priv->pallocated_mp_xmitframe_buf + | |
63 | 4 - | |
64 | ((addr_t)(pmp_priv->pallocated_mp_xmitframe_buf) & 3); | |
65 | pmp_xmitframe = (struct mp_xmit_frame *)pmp_priv->pmp_xmtframe_buf; | |
66 | for (i = 0; i < NR_MP_XMITFRAME; i++) { | |
67 | _init_listhead(&(pmp_xmitframe->list)); | |
68 | list_insert_tail(&(pmp_xmitframe->list), | |
69 | &(pmp_priv->free_mp_xmitqueue.queue)); | |
70 | pmp_xmitframe->pkt = NULL; | |
71 | pmp_xmitframe->frame_tag = MP_FRAMETAG; | |
72 | pmp_xmitframe->padapter = pmp_priv->papdater; | |
73 | pmp_xmitframe++; | |
74 | } | |
75 | pmp_priv->free_mp_xmitframe_cnt = NR_MP_XMITFRAME; | |
76 | res = _SUCCESS; | |
77 | _exit_init_mp_priv: | |
78 | return res; | |
79 | } | |
80 | ||
81 | static int free_mp_priv(struct mp_priv *pmp_priv) | |
82 | { | |
83 | int res = 0; | |
84 | kfree(pmp_priv->pallocated_mp_xmitframe_buf); | |
85 | return res; | |
86 | } | |
87 | ||
88 | void mp871xinit(struct _adapter *padapter) | |
89 | { | |
90 | struct mp_priv *pmppriv = &padapter->mppriv; | |
91 | ||
92 | pmppriv->papdater = padapter; | |
93 | init_mp_priv(pmppriv); | |
94 | } | |
95 | ||
96 | void mp871xdeinit(struct _adapter *padapter) | |
97 | { | |
98 | struct mp_priv *pmppriv = &padapter->mppriv; | |
99 | ||
100 | free_mp_priv(pmppriv); | |
101 | } | |
102 | ||
103 | /* | |
104 | * Special for bb and rf reg read/write | |
105 | */ | |
106 | static u32 fw_iocmd_read(struct _adapter *pAdapter, struct IOCMD_STRUCT iocmd) | |
107 | { | |
108 | u32 cmd32 = 0, val32 = 0; | |
109 | u8 iocmd_class = iocmd.cmdclass; | |
110 | u16 iocmd_value = iocmd.value; | |
111 | u8 iocmd_idx = iocmd.index; | |
112 | ||
113 | cmd32 = (iocmd_class << 24) | (iocmd_value << 8) | iocmd_idx ; | |
114 | if (r8712_fw_cmd(pAdapter, cmd32)) | |
115 | r8712_fw_cmd_data(pAdapter, &val32, 1); | |
116 | else | |
117 | val32 = 0; | |
118 | return val32; | |
119 | } | |
120 | ||
121 | static u8 fw_iocmd_write(struct _adapter *pAdapter, | |
122 | struct IOCMD_STRUCT iocmd, u32 value) | |
123 | { | |
124 | u32 cmd32 = 0; | |
125 | u8 iocmd_class = iocmd.cmdclass; | |
126 | u32 iocmd_value = iocmd.value; | |
127 | u8 iocmd_idx = iocmd.index; | |
128 | ||
129 | r8712_fw_cmd_data(pAdapter, &value, 0); | |
130 | msleep(100); | |
131 | cmd32 = (iocmd_class << 24) | (iocmd_value << 8) | iocmd_idx ; | |
132 | return r8712_fw_cmd(pAdapter, cmd32); | |
133 | } | |
134 | ||
135 | /* offset : 0X800~0XFFF */ | |
136 | u32 r8712_bb_reg_read(struct _adapter *pAdapter, u16 offset) | |
137 | { | |
138 | u8 shift = offset & 0x0003; /* 4 byte access */ | |
139 | u16 bb_addr = offset & 0x0FFC; /* 4 byte access */ | |
140 | u32 bb_val = 0; | |
141 | struct IOCMD_STRUCT iocmd; | |
142 | ||
143 | iocmd.cmdclass = IOCMD_CLASS_BB_RF; | |
144 | iocmd.value = bb_addr; | |
145 | iocmd.index = IOCMD_BB_READ_IDX; | |
146 | bb_val = fw_iocmd_read(pAdapter, iocmd); | |
147 | if (shift != 0) { | |
148 | u32 bb_val2 = 0; | |
149 | bb_val >>= (shift * 8); | |
150 | iocmd.value += 4; | |
151 | bb_val2 = fw_iocmd_read(pAdapter, iocmd); | |
152 | bb_val2 <<= ((4 - shift) * 8); | |
153 | bb_val |= bb_val2; | |
154 | } | |
155 | return bb_val; | |
156 | } | |
157 | ||
158 | /* offset : 0X800~0XFFF */ | |
159 | u8 r8712_bb_reg_write(struct _adapter *pAdapter, u16 offset, u32 value) | |
160 | { | |
161 | u8 shift = offset & 0x0003; /* 4 byte access */ | |
162 | u16 bb_addr = offset & 0x0FFC; /* 4 byte access */ | |
163 | struct IOCMD_STRUCT iocmd; | |
164 | ||
165 | iocmd.cmdclass = IOCMD_CLASS_BB_RF; | |
166 | iocmd.value = bb_addr; | |
167 | iocmd.index = IOCMD_BB_WRITE_IDX; | |
168 | if (shift != 0) { | |
169 | u32 oldValue = 0; | |
170 | u32 newValue = value; | |
171 | ||
172 | oldValue = r8712_bb_reg_read(pAdapter, iocmd.value); | |
173 | oldValue &= (0xFFFFFFFF >> ((4 - shift) * 8)); | |
174 | value = oldValue | (newValue << (shift * 8)); | |
175 | if (fw_iocmd_write(pAdapter, iocmd, value) == false) | |
176 | return false; | |
177 | iocmd.value += 4; | |
178 | oldValue = r8712_bb_reg_read(pAdapter, iocmd.value); | |
179 | oldValue &= (0xFFFFFFFF << (shift * 8)); | |
180 | value = oldValue | (newValue >> ((4 - shift) * 8)); | |
181 | } | |
182 | return fw_iocmd_write(pAdapter, iocmd, value); | |
183 | } | |
184 | ||
185 | /* offset : 0x00 ~ 0xFF */ | |
186 | u32 r8712_rf_reg_read(struct _adapter *pAdapter, u8 path, u8 offset) | |
187 | { | |
188 | u16 rf_addr = (path << 8) | offset; | |
189 | u32 rf_data; | |
190 | struct IOCMD_STRUCT iocmd; | |
191 | ||
192 | iocmd.cmdclass = IOCMD_CLASS_BB_RF ; | |
193 | iocmd.value = rf_addr ; | |
194 | iocmd.index = IOCMD_RF_READ_IDX; | |
195 | rf_data = fw_iocmd_read(pAdapter, iocmd); | |
196 | return rf_data; | |
197 | } | |
198 | ||
199 | u8 r8712_rf_reg_write(struct _adapter *pAdapter, u8 path, u8 offset, u32 value) | |
200 | { | |
201 | u16 rf_addr = (path << 8) | offset; | |
202 | struct IOCMD_STRUCT iocmd; | |
203 | ||
204 | iocmd.cmdclass = IOCMD_CLASS_BB_RF; | |
205 | iocmd.value = rf_addr; | |
206 | iocmd.index = IOCMD_RF_WRIT_IDX; | |
207 | return fw_iocmd_write(pAdapter, iocmd, value); | |
208 | } | |
209 | ||
210 | static u32 bitshift(u32 bitmask) | |
211 | { | |
212 | u32 i; | |
213 | ||
214 | for (i = 0; i <= 31; i++) | |
215 | if (((bitmask>>i) & 0x1) == 1) | |
216 | break; | |
217 | return i; | |
218 | } | |
219 | ||
16e53729 | 220 | static u32 get_bb_reg(struct _adapter *pAdapter, u16 offset, u32 bitmask) |
2865d42c LF |
221 | { |
222 | u32 org_value, bit_shift, new_value; | |
223 | ||
224 | org_value = r8712_bb_reg_read(pAdapter, offset); | |
225 | bit_shift = bitshift(bitmask); | |
226 | new_value = (org_value & bitmask) >> bit_shift; | |
227 | return new_value; | |
228 | } | |
229 | ||
2657c30e JM |
230 | static u8 set_bb_reg(struct _adapter *pAdapter, |
231 | u16 offset, | |
232 | u32 bitmask, | |
233 | u32 value) | |
2865d42c LF |
234 | { |
235 | u32 org_value, bit_shift, new_value; | |
236 | ||
237 | if (bitmask != bMaskDWord) { | |
238 | org_value = r8712_bb_reg_read(pAdapter, offset); | |
239 | bit_shift = bitshift(bitmask); | |
240 | new_value = ((org_value & (~bitmask)) | (value << bit_shift)); | |
241 | } else | |
242 | new_value = value; | |
243 | return r8712_bb_reg_write(pAdapter, offset, new_value); | |
244 | } | |
245 | ||
246 | static u32 get_rf_reg(struct _adapter *pAdapter, u8 path, u8 offset, | |
247 | u32 bitmask) | |
248 | { | |
249 | u32 org_value, bit_shift, new_value; | |
250 | ||
251 | org_value = r8712_rf_reg_read(pAdapter, path, offset); | |
252 | bit_shift = bitshift(bitmask); | |
253 | new_value = (org_value & bitmask) >> bit_shift; | |
254 | return new_value; | |
255 | } | |
256 | ||
257 | static u8 set_rf_reg(struct _adapter *pAdapter, u8 path, u8 offset, u32 bitmask, | |
258 | u32 value) | |
259 | { | |
260 | u32 org_value, bit_shift, new_value; | |
261 | ||
262 | if (bitmask != bMaskDWord) { | |
263 | org_value = r8712_rf_reg_read(pAdapter, path, offset); | |
264 | bit_shift = bitshift(bitmask); | |
265 | new_value = ((org_value & (~bitmask)) | (value << bit_shift)); | |
266 | } else | |
267 | new_value = value; | |
268 | return r8712_rf_reg_write(pAdapter, path, offset, new_value); | |
269 | } | |
270 | ||
271 | /* | |
272 | * SetChannel | |
273 | * Description | |
274 | * Use H2C command to change channel, | |
275 | * not only modify rf register, but also other setting need to be done. | |
276 | */ | |
277 | void r8712_SetChannel(struct _adapter *pAdapter) | |
278 | { | |
279 | struct cmd_priv *pcmdpriv = &pAdapter->cmdpriv; | |
280 | struct cmd_obj *pcmd = NULL; | |
281 | struct SetChannel_parm *pparm = NULL; | |
282 | u16 code = GEN_CMD_CODE(_SetChannel); | |
283 | ||
284 | pcmd = (struct cmd_obj *)_malloc(sizeof(struct cmd_obj)); | |
285 | if (pcmd == NULL) | |
286 | return; | |
287 | pparm = (struct SetChannel_parm *)_malloc(sizeof(struct | |
288 | SetChannel_parm)); | |
289 | if (pparm == NULL) { | |
40083865 | 290 | kfree(pcmd); |
2865d42c LF |
291 | return; |
292 | } | |
293 | pparm->curr_ch = pAdapter->mppriv.curr_ch; | |
294 | init_h2fwcmd_w_parm_no_rsp(pcmd, pparm, code); | |
295 | r8712_enqueue_cmd(pcmdpriv, pcmd); | |
296 | } | |
297 | ||
298 | static void SetCCKTxPower(struct _adapter *pAdapter, u8 TxPower) | |
299 | { | |
300 | u16 TxAGC = 0; | |
301 | ||
302 | TxAGC = TxPower; | |
303 | set_bb_reg(pAdapter, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC); | |
304 | } | |
305 | ||
306 | static void SetOFDMTxPower(struct _adapter *pAdapter, u8 TxPower) | |
307 | { | |
308 | u32 TxAGC = 0; | |
309 | ||
310 | TxAGC |= ((TxPower<<24)|(TxPower<<16)|(TxPower<<8)|TxPower); | |
311 | set_bb_reg(pAdapter, rTxAGC_Rate18_06, bTxAGCRate18_06, TxAGC); | |
312 | set_bb_reg(pAdapter, rTxAGC_Rate54_24, bTxAGCRate54_24, TxAGC); | |
313 | set_bb_reg(pAdapter, rTxAGC_Mcs03_Mcs00, bTxAGCRateMCS3_MCS0, TxAGC); | |
314 | set_bb_reg(pAdapter, rTxAGC_Mcs07_Mcs04, bTxAGCRateMCS7_MCS4, TxAGC); | |
315 | set_bb_reg(pAdapter, rTxAGC_Mcs11_Mcs08, bTxAGCRateMCS11_MCS8, TxAGC); | |
316 | set_bb_reg(pAdapter, rTxAGC_Mcs15_Mcs12, bTxAGCRateMCS15_MCS12, TxAGC); | |
317 | } | |
318 | ||
319 | void r8712_SetTxPower(struct _adapter *pAdapter) | |
320 | { | |
321 | u8 TxPower = pAdapter->mppriv.curr_txpoweridx; | |
322 | SetCCKTxPower(pAdapter, TxPower); | |
323 | SetOFDMTxPower(pAdapter, TxPower); | |
324 | } | |
325 | ||
326 | void r8712_SetTxAGCOffset(struct _adapter *pAdapter, u32 ulTxAGCOffset) | |
327 | { | |
328 | u32 TxAGCOffset_B, TxAGCOffset_C, TxAGCOffset_D, tmpAGC; | |
329 | ||
330 | TxAGCOffset_B = (ulTxAGCOffset&0x000000ff); | |
331 | TxAGCOffset_C = ((ulTxAGCOffset&0x0000ff00)>>8); | |
332 | TxAGCOffset_D = ((ulTxAGCOffset&0x00ff0000)>>16); | |
333 | tmpAGC = (TxAGCOffset_D<<8 | TxAGCOffset_C<<4 | TxAGCOffset_B); | |
334 | set_bb_reg(pAdapter, rFPGA0_TxGainStage, | |
335 | (bXBTxAGC|bXCTxAGC|bXDTxAGC), tmpAGC); | |
336 | } | |
337 | ||
338 | void r8712_SetDataRate(struct _adapter *pAdapter) | |
339 | { | |
340 | u8 path = RF_PATH_A; | |
341 | u8 offset = RF_SYN_G2; | |
342 | u32 value; | |
343 | ||
344 | value = (pAdapter->mppriv.curr_rateidx < 4) ? 0x4440 : 0xF200; | |
345 | r8712_rf_reg_write(pAdapter, path, offset, value); | |
346 | } | |
347 | ||
348 | void r8712_SwitchBandwidth(struct _adapter *pAdapter) | |
349 | { | |
350 | /* 3 1.Set MAC register : BWOPMODE bit2:1 20MhzBW */ | |
351 | u8 regBwOpMode = 0; | |
352 | u8 Bandwidth = pAdapter->mppriv.curr_bandwidth; | |
353 | ||
354 | regBwOpMode = r8712_read8(pAdapter, 0x10250203); | |
355 | if (Bandwidth == HT_CHANNEL_WIDTH_20) | |
356 | regBwOpMode |= BIT(2); | |
357 | else | |
358 | regBwOpMode &= ~(BIT(2)); | |
359 | r8712_write8(pAdapter, 0x10250203, regBwOpMode); | |
360 | /* 3 2.Set PHY related register */ | |
361 | switch (Bandwidth) { | |
362 | /* 20 MHz channel*/ | |
363 | case HT_CHANNEL_WIDTH_20: | |
364 | set_bb_reg(pAdapter, rFPGA0_RFMOD, bRFMOD, 0x0); | |
365 | set_bb_reg(pAdapter, rFPGA1_RFMOD, bRFMOD, 0x0); | |
366 | /* Use PHY_REG.txt default value. Do not need to change. | |
367 | * Correct the tx power for CCK rate in 40M. | |
368 | * It is set in Tx descriptor for 8192x series | |
369 | */ | |
370 | set_bb_reg(pAdapter, rFPGA0_AnalogParameter2, bMaskDWord, 0x58); | |
371 | break; | |
372 | /* 40 MHz channel*/ | |
373 | case HT_CHANNEL_WIDTH_40: | |
374 | set_bb_reg(pAdapter, rFPGA0_RFMOD, bRFMOD, 0x1); | |
375 | set_bb_reg(pAdapter, rFPGA1_RFMOD, bRFMOD, 0x1); | |
376 | /* Use PHY_REG.txt default value. Do not need to change. | |
377 | * Correct the tx power for CCK rate in 40M. | |
378 | * Set Control channel to upper or lower. These settings are | |
379 | * required only for 40MHz */ | |
380 | set_bb_reg(pAdapter, rCCK0_System, bCCKSideBand, | |
381 | (HAL_PRIME_CHNL_OFFSET_DONT_CARE>>1)); | |
382 | set_bb_reg(pAdapter, rOFDM1_LSTF, 0xC00, | |
383 | HAL_PRIME_CHNL_OFFSET_DONT_CARE); | |
384 | set_bb_reg(pAdapter, rFPGA0_AnalogParameter2, bMaskDWord, 0x18); | |
385 | break; | |
386 | default: | |
387 | break; | |
388 | } | |
389 | ||
390 | /* 3 3.Set RF related register */ | |
391 | switch (Bandwidth) { | |
392 | case HT_CHANNEL_WIDTH_20: | |
393 | set_rf_reg(pAdapter, RF_PATH_A, RF_CHNLBW, | |
394 | BIT(10) | BIT(11), 0x01); | |
395 | break; | |
396 | case HT_CHANNEL_WIDTH_40: | |
397 | set_rf_reg(pAdapter, RF_PATH_A, RF_CHNLBW, | |
398 | BIT(10) | BIT(11), 0x00); | |
399 | break; | |
400 | default: | |
401 | break; | |
402 | } | |
403 | } | |
404 | /*------------------------------Define structure----------------------------*/ | |
405 | struct R_ANTENNA_SELECT_OFDM { | |
406 | u32 r_tx_antenna:4; | |
407 | u32 r_ant_l:4; | |
408 | u32 r_ant_non_ht:4; | |
409 | u32 r_ant_ht1:4; | |
410 | u32 r_ant_ht2:4; | |
411 | u32 r_ant_ht_s1:4; | |
412 | u32 r_ant_non_ht_s1:4; | |
413 | u32 OFDM_TXSC:2; | |
414 | u32 Reserved:2; | |
415 | }; | |
416 | ||
417 | struct R_ANTENNA_SELECT_CCK { | |
418 | u8 r_cckrx_enable_2:2; | |
419 | u8 r_cckrx_enable:2; | |
420 | u8 r_ccktx_enable:4; | |
421 | }; | |
422 | ||
423 | void r8712_SwitchAntenna(struct _adapter *pAdapter) | |
424 | { | |
425 | u32 ofdm_tx_en_val = 0, ofdm_tx_ant_sel_val = 0; | |
426 | u8 ofdm_rx_ant_sel_val = 0; | |
427 | u8 cck_ant_select_val = 0; | |
428 | u32 cck_ant_sel_val = 0; | |
429 | struct R_ANTENNA_SELECT_CCK *p_cck_txrx; | |
430 | ||
431 | p_cck_txrx = (struct R_ANTENNA_SELECT_CCK *)&cck_ant_select_val; | |
432 | ||
433 | switch (pAdapter->mppriv.antenna_tx) { | |
434 | case ANTENNA_A: | |
435 | /* From SD3 Willis suggestion !!! Set RF A=TX and B as standby*/ | |
436 | set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 2); | |
437 | set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 1); | |
438 | ofdm_tx_en_val = 0x3; | |
439 | ofdm_tx_ant_sel_val = 0x11111111;/* Power save */ | |
440 | p_cck_txrx->r_ccktx_enable = 0x8; | |
441 | break; | |
442 | case ANTENNA_B: | |
443 | set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 1); | |
444 | set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 2); | |
445 | ofdm_tx_en_val = 0x3; | |
446 | ofdm_tx_ant_sel_val = 0x22222222;/* Power save */ | |
447 | p_cck_txrx->r_ccktx_enable = 0x4; | |
448 | break; | |
449 | case ANTENNA_AB: /* For 8192S */ | |
450 | set_bb_reg(pAdapter, rFPGA0_XA_HSSIParameter2, 0xe, 2); | |
451 | set_bb_reg(pAdapter, rFPGA0_XB_HSSIParameter2, 0xe, 2); | |
452 | ofdm_tx_en_val = 0x3; | |
453 | ofdm_tx_ant_sel_val = 0x3321333; /* Disable Power save */ | |
454 | p_cck_txrx->r_ccktx_enable = 0xC; | |
455 | break; | |
456 | default: | |
457 | break; | |
458 | } | |
459 | /*OFDM Tx*/ | |
460 | set_bb_reg(pAdapter, rFPGA1_TxInfo, 0xffffffff, ofdm_tx_ant_sel_val); | |
461 | /*OFDM Tx*/ | |
462 | set_bb_reg(pAdapter, rFPGA0_TxInfo, 0x0000000f, ofdm_tx_en_val); | |
463 | switch (pAdapter->mppriv.antenna_rx) { | |
464 | case ANTENNA_A: | |
465 | ofdm_rx_ant_sel_val = 0x1; /* A */ | |
466 | p_cck_txrx->r_cckrx_enable = 0x0; /* default: A */ | |
467 | p_cck_txrx->r_cckrx_enable_2 = 0x0; /* option: A */ | |
468 | break; | |
469 | case ANTENNA_B: | |
470 | ofdm_rx_ant_sel_val = 0x2; /* B */ | |
471 | p_cck_txrx->r_cckrx_enable = 0x1; /* default: B */ | |
472 | p_cck_txrx->r_cckrx_enable_2 = 0x1; /* option: B */ | |
473 | break; | |
474 | case ANTENNA_AB: | |
475 | ofdm_rx_ant_sel_val = 0x3; /* AB */ | |
476 | p_cck_txrx->r_cckrx_enable = 0x0; /* default:A */ | |
477 | p_cck_txrx->r_cckrx_enable_2 = 0x1; /* option:B */ | |
478 | break; | |
479 | default: | |
480 | break; | |
481 | } | |
482 | /*OFDM Rx*/ | |
483 | set_bb_reg(pAdapter, rOFDM0_TRxPathEnable, 0x0000000f, | |
484 | ofdm_rx_ant_sel_val); | |
485 | /*OFDM Rx*/ | |
486 | set_bb_reg(pAdapter, rOFDM1_TRxPathEnable, 0x0000000f, | |
487 | ofdm_rx_ant_sel_val); | |
488 | ||
489 | cck_ant_sel_val = cck_ant_select_val; | |
490 | /*CCK TxRx*/ | |
491 | set_bb_reg(pAdapter, rCCK0_AFESetting, bMaskByte3, cck_ant_sel_val); | |
492 | } | |
493 | ||
494 | void r8712_SetCrystalCap(struct _adapter *pAdapter) | |
495 | { | |
496 | set_bb_reg(pAdapter, rFPGA0_AnalogParameter1, bXtalCap, | |
497 | pAdapter->mppriv.curr_crystalcap); | |
498 | } | |
499 | ||
500 | static void TriggerRFThermalMeter(struct _adapter *pAdapter) | |
501 | { | |
502 | /* 0x24: RF Reg[6:5] */ | |
503 | set_rf_reg(pAdapter, RF_PATH_A, RF_T_METER, bRFRegOffsetMask, 0x60); | |
504 | } | |
505 | ||
506 | static u32 ReadRFThermalMeter(struct _adapter *pAdapter) | |
507 | { | |
508 | u32 ThermalValue = 0; | |
509 | ||
510 | /* 0x24: RF Reg[4:0] */ | |
511 | ThermalValue = get_rf_reg(pAdapter, RF_PATH_A, RF_T_METER, 0x1F); | |
512 | return ThermalValue; | |
513 | } | |
514 | ||
515 | void r8712_GetThermalMeter(struct _adapter *pAdapter, u32 *value) | |
516 | { | |
517 | TriggerRFThermalMeter(pAdapter); | |
518 | msleep(1000); | |
519 | *value = ReadRFThermalMeter(pAdapter); | |
520 | } | |
521 | ||
522 | void r8712_SetSingleCarrierTx(struct _adapter *pAdapter, u8 bStart) | |
523 | { | |
524 | if (bStart) { /* Start Single Carrier. */ | |
525 | /* 1. if OFDM block on? */ | |
526 | if (!get_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn)) | |
527 | /*set OFDM block on*/ | |
528 | set_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn, bEnable); | |
529 | /* 2. set CCK test mode off, set to CCK normal mode */ | |
530 | set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, bDisable); | |
531 | /* 3. turn on scramble setting */ | |
532 | set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, bEnable); | |
533 | /* 4. Turn On Single Carrier Tx and off the other test modes. */ | |
534 | set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); | |
535 | set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bEnable); | |
536 | set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); | |
537 | } else { /* Stop Single Carrier.*/ | |
538 | /* Turn off all test modes.*/ | |
539 | set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); | |
540 | set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, | |
541 | bDisable); | |
542 | set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); | |
543 | msleep(20); | |
544 | /*BB Reset*/ | |
545 | set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); | |
546 | set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); | |
547 | } | |
548 | } | |
549 | ||
550 | void r8712_SetSingleToneTx(struct _adapter *pAdapter, u8 bStart) | |
551 | { | |
552 | u8 rfPath = pAdapter->mppriv.curr_rfpath; | |
553 | switch (pAdapter->mppriv.antenna_tx) { | |
554 | case ANTENNA_B: | |
555 | rfPath = RF_PATH_B; | |
556 | break; | |
557 | case ANTENNA_A: | |
558 | default: | |
559 | rfPath = RF_PATH_A; | |
560 | break; | |
561 | } | |
562 | if (bStart) { /* Start Single Tone.*/ | |
563 | set_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn, bDisable); | |
564 | set_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn, bDisable); | |
565 | set_rf_reg(pAdapter, rfPath, RF_TX_G2, bRFRegOffsetMask, | |
566 | 0xd4000); | |
567 | msleep(100); | |
568 | /* PAD all on.*/ | |
569 | set_rf_reg(pAdapter, rfPath, RF_AC, bRFRegOffsetMask, 0x2001f); | |
570 | msleep(100); | |
571 | } else { /* Stop Single Tone.*/ | |
572 | set_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn, bEnable); | |
573 | set_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn, bEnable); | |
574 | set_rf_reg(pAdapter, rfPath, RF_TX_G2, bRFRegOffsetMask, | |
575 | 0x54000); | |
576 | msleep(100); | |
577 | /* PAD all on.*/ | |
578 | set_rf_reg(pAdapter, rfPath, RF_AC, bRFRegOffsetMask, 0x30000); | |
579 | msleep(100); | |
580 | } | |
581 | } | |
582 | ||
583 | void r8712_SetCarrierSuppressionTx(struct _adapter *pAdapter, u8 bStart) | |
584 | { | |
585 | if (bStart) { /* Start Carrier Suppression.*/ | |
586 | if (pAdapter->mppriv.curr_rateidx <= MPT_RATE_11M) { | |
587 | /* 1. if CCK block on? */ | |
588 | if (!get_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn)) { | |
589 | /*set CCK block on*/ | |
590 | set_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn, | |
591 | bEnable); | |
592 | } | |
593 | /* Turn Off All Test Mode */ | |
594 | set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, | |
595 | bDisable); | |
596 | set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, | |
597 | bDisable); | |
598 | set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, | |
599 | bDisable); | |
600 | /*transmit mode*/ | |
601 | set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, 0x2); | |
602 | /*turn off scramble setting*/ | |
603 | set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, | |
604 | bDisable); | |
605 | /*Set CCK Tx Test Rate*/ | |
606 | /*Set FTxRate to 1Mbps*/ | |
607 | set_bb_reg(pAdapter, rCCK0_System, bCCKTxRate, 0x0); | |
608 | } | |
609 | } else { /* Stop Carrier Suppression. */ | |
610 | if (pAdapter->mppriv.curr_rateidx <= MPT_RATE_11M) { | |
611 | /*normal mode*/ | |
612 | set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, 0x0); | |
613 | /*turn on scramble setting*/ | |
614 | set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, | |
615 | bEnable); | |
616 | /*BB Reset*/ | |
617 | set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); | |
618 | set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); | |
619 | } | |
620 | } | |
621 | } | |
622 | ||
623 | static void SetCCKContinuousTx(struct _adapter *pAdapter, u8 bStart) | |
624 | { | |
625 | u32 cckrate; | |
626 | ||
627 | if (bStart) { | |
628 | /* 1. if CCK block on? */ | |
629 | if (!get_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn)) { | |
630 | /*set CCK block on*/ | |
631 | set_bb_reg(pAdapter, rFPGA0_RFMOD, bCCKEn, bEnable); | |
632 | } | |
633 | /* Turn Off All Test Mode */ | |
634 | set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); | |
635 | set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable); | |
636 | set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); | |
637 | /*Set CCK Tx Test Rate*/ | |
638 | cckrate = pAdapter->mppriv.curr_rateidx; | |
639 | set_bb_reg(pAdapter, rCCK0_System, bCCKTxRate, cckrate); | |
640 | /*transmit mode*/ | |
641 | set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, 0x2); | |
642 | /*turn on scramble setting*/ | |
643 | set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, bEnable); | |
644 | } else { | |
645 | /*normal mode*/ | |
646 | set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, 0x0); | |
647 | /*turn on scramble setting*/ | |
648 | set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, bEnable); | |
649 | /*BB Reset*/ | |
650 | set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); | |
651 | set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); | |
652 | } | |
653 | } /* mpt_StartCckContTx */ | |
654 | ||
655 | static void SetOFDMContinuousTx(struct _adapter *pAdapter, u8 bStart) | |
656 | { | |
657 | if (bStart) { | |
658 | /* 1. if OFDM block on? */ | |
659 | if (!get_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn)) { | |
660 | /*set OFDM block on*/ | |
661 | set_bb_reg(pAdapter, rFPGA0_RFMOD, bOFDMEn, bEnable); | |
662 | } | |
663 | /* 2. set CCK test mode off, set to CCK normal mode*/ | |
664 | set_bb_reg(pAdapter, rCCK0_System, bCCKBBMode, bDisable); | |
665 | /* 3. turn on scramble setting */ | |
666 | set_bb_reg(pAdapter, rCCK0_System, bCCKScramble, bEnable); | |
667 | /* 4. Turn On Continue Tx and turn off the other test modes.*/ | |
668 | set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bEnable); | |
669 | set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, bDisable); | |
670 | set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); | |
671 | } else { | |
672 | set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMContinueTx, bDisable); | |
673 | set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleCarrier, | |
674 | bDisable); | |
675 | set_bb_reg(pAdapter, rOFDM1_LSTF, bOFDMSingleTone, bDisable); | |
676 | msleep(20); | |
677 | /*BB Reset*/ | |
678 | set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x0); | |
679 | set_bb_reg(pAdapter, rPMAC_Reset, bBBResetB, 0x1); | |
680 | } | |
681 | } /* mpt_StartOfdmContTx */ | |
682 | ||
683 | void r8712_SetContinuousTx(struct _adapter *pAdapter, u8 bStart) | |
684 | { | |
685 | /* ADC turn off [bit24-21] adc port0 ~ port1 */ | |
686 | if (bStart) { | |
687 | r8712_bb_reg_write(pAdapter, rRx_Wait_CCCA, | |
688 | r8712_bb_reg_read(pAdapter, | |
689 | rRx_Wait_CCCA) & 0xFE1FFFFF); | |
690 | msleep(100); | |
691 | } | |
692 | if (pAdapter->mppriv.curr_rateidx <= MPT_RATE_11M) | |
693 | SetCCKContinuousTx(pAdapter, bStart); | |
694 | else if ((pAdapter->mppriv.curr_rateidx >= MPT_RATE_6M) && | |
695 | (pAdapter->mppriv.curr_rateidx <= MPT_RATE_MCS15)) | |
696 | SetOFDMContinuousTx(pAdapter, bStart); | |
697 | /* ADC turn on [bit24-21] adc port0 ~ port1 */ | |
698 | if (!bStart) | |
699 | r8712_bb_reg_write(pAdapter, rRx_Wait_CCCA, | |
700 | r8712_bb_reg_read(pAdapter, | |
701 | rRx_Wait_CCCA) | 0x01E00000); | |
702 | } | |
703 | ||
704 | void r8712_ResetPhyRxPktCount(struct _adapter *pAdapter) | |
705 | { | |
706 | u32 i, phyrx_set = 0; | |
707 | ||
708 | for (i = OFDM_PPDU_BIT; i <= HT_MPDU_FAIL_BIT; i++) { | |
709 | phyrx_set = 0; | |
710 | phyrx_set |= (i << 28); /*select*/ | |
711 | phyrx_set |= 0x08000000; /* set counter to zero*/ | |
712 | r8712_write32(pAdapter, RXERR_RPT, phyrx_set); | |
713 | } | |
714 | } | |
715 | ||
716 | static u32 GetPhyRxPktCounts(struct _adapter *pAdapter, u32 selbit) | |
717 | { | |
718 | /*selection*/ | |
719 | u32 phyrx_set = 0, count = 0; | |
720 | u32 SelectBit; | |
721 | ||
722 | SelectBit = selbit << 28; | |
723 | phyrx_set |= (SelectBit & 0xF0000000); | |
724 | r8712_write32(pAdapter, RXERR_RPT, phyrx_set); | |
725 | /*Read packet count*/ | |
726 | count = r8712_read32(pAdapter, RXERR_RPT) & RPTMaxCount; | |
727 | return count; | |
728 | } | |
729 | ||
730 | u32 r8712_GetPhyRxPktReceived(struct _adapter *pAdapter) | |
731 | { | |
732 | u32 OFDM_cnt = 0, CCK_cnt = 0, HT_cnt = 0; | |
733 | ||
734 | OFDM_cnt = GetPhyRxPktCounts(pAdapter, OFDM_MPDU_OK_BIT); | |
735 | CCK_cnt = GetPhyRxPktCounts(pAdapter, CCK_MPDU_OK_BIT); | |
736 | HT_cnt = GetPhyRxPktCounts(pAdapter, HT_MPDU_OK_BIT); | |
737 | return OFDM_cnt + CCK_cnt + HT_cnt; | |
738 | } | |
739 | ||
740 | u32 r8712_GetPhyRxPktCRC32Error(struct _adapter *pAdapter) | |
741 | { | |
742 | u32 OFDM_cnt = 0, CCK_cnt = 0, HT_cnt = 0; | |
743 | ||
744 | OFDM_cnt = GetPhyRxPktCounts(pAdapter, OFDM_MPDU_FAIL_BIT); | |
745 | CCK_cnt = GetPhyRxPktCounts(pAdapter, CCK_MPDU_FAIL_BIT); | |
746 | HT_cnt = GetPhyRxPktCounts(pAdapter, HT_MPDU_FAIL_BIT); | |
747 | return OFDM_cnt + CCK_cnt + HT_cnt; | |
748 | } |