1 1.17 chs /* $NetBSD: rtwphy.c,v 1.17 2019/11/10 21:16:35 chs Exp $ */ 2 1.1 dyoung /*- 3 1.1 dyoung * Copyright (c) 2004, 2005 David Young. All rights reserved. 4 1.1 dyoung * 5 1.1 dyoung * Programmed for NetBSD by David Young. 6 1.1 dyoung * 7 1.1 dyoung * Redistribution and use in source and binary forms, with or without 8 1.1 dyoung * modification, are permitted provided that the following conditions 9 1.1 dyoung * are met: 10 1.1 dyoung * 1. Redistributions of source code must retain the above copyright 11 1.1 dyoung * notice, this list of conditions and the following disclaimer. 12 1.1 dyoung * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 dyoung * notice, this list of conditions and the following disclaimer in the 14 1.1 dyoung * documentation and/or other materials provided with the distribution. 15 1.1 dyoung * 16 1.1 dyoung * THIS SOFTWARE IS PROVIDED BY David Young ``AS IS'' AND ANY 17 1.1 dyoung * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 18 1.1 dyoung * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 19 1.1 dyoung * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David 20 1.1 dyoung * Young BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 1.1 dyoung * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 22 1.1 dyoung * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 1.1 dyoung * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 1.1 dyoung * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 1.1 dyoung * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 1.1 dyoung * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 27 1.1 dyoung * OF SUCH DAMAGE. 28 1.1 dyoung */ 29 1.1 dyoung /* 30 1.1 dyoung * Control the Philips SA2400 RF front-end and the baseband processor 31 1.1 dyoung * built into the Realtek RTL8180. 32 1.1 dyoung */ 33 1.1 dyoung 34 1.1 dyoung #include <sys/cdefs.h> 35 1.17 chs __KERNEL_RCSID(0, "$NetBSD: rtwphy.c,v 1.17 2019/11/10 21:16:35 chs Exp $"); 36 1.1 dyoung 37 1.1 dyoung #include <sys/param.h> 38 1.1 dyoung #include <sys/systm.h> 39 1.1 dyoung #include <sys/types.h> 40 1.14 tsutsui #include <sys/device.h> 41 1.1 dyoung 42 1.13 ad #include <sys/bus.h> 43 1.1 dyoung 44 1.1 dyoung #include <net/if.h> 45 1.1 dyoung #include <net/if_media.h> 46 1.1 dyoung #include <net/if_ether.h> 47 1.1 dyoung 48 1.6 dyoung #include <net80211/ieee80211_netbsd.h> 49 1.6 dyoung #include <net80211/ieee80211_radiotap.h> 50 1.1 dyoung #include <net80211/ieee80211_var.h> 51 1.1 dyoung 52 1.1 dyoung #include <dev/ic/rtwreg.h> 53 1.1 dyoung #include <dev/ic/max2820reg.h> 54 1.1 dyoung #include <dev/ic/sa2400reg.h> 55 1.1 dyoung #include <dev/ic/rtwvar.h> 56 1.1 dyoung #include <dev/ic/rtwphyio.h> 57 1.1 dyoung #include <dev/ic/rtwphy.h> 58 1.1 dyoung 59 1.1 dyoung static int rtw_max2820_pwrstate(struct rtw_rf *, enum rtw_pwrstate); 60 1.1 dyoung static int rtw_sa2400_pwrstate(struct rtw_rf *, enum rtw_pwrstate); 61 1.1 dyoung 62 1.8 dyoung #define GCT_WRITE(__gr, __addr, __val, __label) \ 63 1.8 dyoung do { \ 64 1.8 dyoung if (rtw_rfbus_write(&(__gr)->gr_bus, RTW_RFCHIPID_GCT, \ 65 1.8 dyoung (__addr), (__val)) == -1) \ 66 1.8 dyoung goto __label; \ 67 1.8 dyoung } while(0) 68 1.8 dyoung 69 1.1 dyoung static int 70 1.1 dyoung rtw_bbp_preinit(struct rtw_regs *regs, u_int antatten0, int dflantb, 71 1.1 dyoung u_int freq) 72 1.1 dyoung { 73 1.1 dyoung u_int antatten = antatten0; 74 1.1 dyoung if (dflantb) 75 1.1 dyoung antatten |= RTW_BBP_ANTATTEN_DFLANTB; 76 1.1 dyoung if (freq == 2484) /* channel 14 */ 77 1.1 dyoung antatten |= RTW_BBP_ANTATTEN_CHAN14; 78 1.1 dyoung return rtw_bbp_write(regs, RTW_BBP_ANTATTEN, antatten); 79 1.1 dyoung } 80 1.1 dyoung 81 1.1 dyoung static int 82 1.1 dyoung rtw_bbp_init(struct rtw_regs *regs, struct rtw_bbpset *bb, int antdiv, 83 1.4 dyoung int dflantb, uint8_t cs_threshold, u_int freq) 84 1.1 dyoung { 85 1.1 dyoung int rc; 86 1.4 dyoung uint32_t sys2, sys3; 87 1.1 dyoung 88 1.1 dyoung sys2 = bb->bb_sys2; 89 1.1 dyoung if (antdiv) 90 1.1 dyoung sys2 |= RTW_BBP_SYS2_ANTDIV; 91 1.1 dyoung sys3 = bb->bb_sys3 | 92 1.10 dyoung __SHIFTIN(cs_threshold, RTW_BBP_SYS3_CSTHRESH_MASK); 93 1.1 dyoung 94 1.1 dyoung #define RTW_BBP_WRITE_OR_RETURN(reg, val) \ 95 1.1 dyoung if ((rc = rtw_bbp_write(regs, reg, val)) != 0) \ 96 1.1 dyoung return rc; 97 1.1 dyoung 98 1.1 dyoung RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS1, bb->bb_sys1); 99 1.1 dyoung RTW_BBP_WRITE_OR_RETURN(RTW_BBP_TXAGC, bb->bb_txagc); 100 1.1 dyoung RTW_BBP_WRITE_OR_RETURN(RTW_BBP_LNADET, bb->bb_lnadet); 101 1.1 dyoung RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCINI, bb->bb_ifagcini); 102 1.1 dyoung RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCLIMIT, bb->bb_ifagclimit); 103 1.1 dyoung RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCDET, bb->bb_ifagcdet); 104 1.1 dyoung 105 1.1 dyoung if ((rc = rtw_bbp_preinit(regs, bb->bb_antatten, dflantb, freq)) != 0) 106 1.1 dyoung return rc; 107 1.1 dyoung 108 1.1 dyoung RTW_BBP_WRITE_OR_RETURN(RTW_BBP_TRL, bb->bb_trl); 109 1.1 dyoung RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS2, sys2); 110 1.1 dyoung RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS3, sys3); 111 1.1 dyoung RTW_BBP_WRITE_OR_RETURN(RTW_BBP_CHESTLIM, bb->bb_chestlim); 112 1.1 dyoung RTW_BBP_WRITE_OR_RETURN(RTW_BBP_CHSQLIM, bb->bb_chsqlim); 113 1.1 dyoung return 0; 114 1.1 dyoung } 115 1.1 dyoung 116 1.1 dyoung static int 117 1.4 dyoung rtw_sa2400_txpower(struct rtw_rf *rf, uint8_t opaque_txpower) 118 1.1 dyoung { 119 1.1 dyoung struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf; 120 1.1 dyoung struct rtw_rfbus *bus = &sa->sa_bus; 121 1.1 dyoung 122 1.1 dyoung return rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_TX, 123 1.1 dyoung opaque_txpower); 124 1.1 dyoung } 125 1.1 dyoung 126 1.1 dyoung /* make sure we're using the same settings as the reference driver */ 127 1.1 dyoung static void 128 1.4 dyoung verify_syna(u_int freq, uint32_t val) 129 1.1 dyoung { 130 1.16 nisimura #ifdef DIAGNOSTIC 131 1.4 dyoung uint32_t expected_val = ~val; 132 1.1 dyoung 133 1.1 dyoung switch (freq) { 134 1.1 dyoung case 2412: 135 1.1 dyoung expected_val = 0x0000096c; /* ch 1 */ 136 1.1 dyoung break; 137 1.1 dyoung case 2417: 138 1.1 dyoung expected_val = 0x00080970; /* ch 2 */ 139 1.1 dyoung break; 140 1.1 dyoung case 2422: 141 1.1 dyoung expected_val = 0x00100974; /* ch 3 */ 142 1.1 dyoung break; 143 1.1 dyoung case 2427: 144 1.1 dyoung expected_val = 0x00180978; /* ch 4 */ 145 1.1 dyoung break; 146 1.1 dyoung case 2432: 147 1.1 dyoung expected_val = 0x00000980; /* ch 5 */ 148 1.1 dyoung break; 149 1.1 dyoung case 2437: 150 1.1 dyoung expected_val = 0x00080984; /* ch 6 */ 151 1.1 dyoung break; 152 1.1 dyoung case 2442: 153 1.1 dyoung expected_val = 0x00100988; /* ch 7 */ 154 1.1 dyoung break; 155 1.1 dyoung case 2447: 156 1.1 dyoung expected_val = 0x0018098c; /* ch 8 */ 157 1.1 dyoung break; 158 1.1 dyoung case 2452: 159 1.1 dyoung expected_val = 0x00000994; /* ch 9 */ 160 1.1 dyoung break; 161 1.1 dyoung case 2457: 162 1.1 dyoung expected_val = 0x00080998; /* ch 10 */ 163 1.1 dyoung break; 164 1.1 dyoung case 2462: 165 1.1 dyoung expected_val = 0x0010099c; /* ch 11 */ 166 1.1 dyoung break; 167 1.1 dyoung case 2467: 168 1.1 dyoung expected_val = 0x001809a0; /* ch 12 */ 169 1.1 dyoung break; 170 1.1 dyoung case 2472: 171 1.1 dyoung expected_val = 0x000009a8; /* ch 13 */ 172 1.1 dyoung break; 173 1.1 dyoung case 2484: 174 1.1 dyoung expected_val = 0x000009b4; /* ch 14 */ 175 1.1 dyoung break; 176 1.1 dyoung } 177 1.1 dyoung KASSERT(val == expected_val); 178 1.16 nisimura #endif 179 1.1 dyoung } 180 1.1 dyoung 181 1.1 dyoung /* freq is in MHz */ 182 1.1 dyoung static int 183 1.1 dyoung rtw_sa2400_tune(struct rtw_rf *rf, u_int freq) 184 1.1 dyoung { 185 1.1 dyoung struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf; 186 1.1 dyoung struct rtw_rfbus *bus = &sa->sa_bus; 187 1.1 dyoung int rc; 188 1.4 dyoung uint32_t syna, synb, sync; 189 1.1 dyoung 190 1.1 dyoung /* XO = 44MHz, R = 11, hence N is in units of XO / R = 4MHz. 191 1.1 dyoung * 192 1.1 dyoung * The channel spacing (5MHz) is not divisible by 4MHz, so 193 1.1 dyoung * we set the fractional part of N to compensate. 194 1.1 dyoung */ 195 1.1 dyoung int n = freq / 4, nf = (freq % 4) * 2; 196 1.1 dyoung 197 1.10 dyoung syna = __SHIFTIN(nf, SA2400_SYNA_NF_MASK) | __SHIFTIN(n, SA2400_SYNA_N_MASK); 198 1.1 dyoung verify_syna(freq, syna); 199 1.1 dyoung 200 1.1 dyoung /* Divide the 44MHz crystal down to 4MHz. Set the fractional 201 1.1 dyoung * compensation charge pump value to agree with the fractional 202 1.1 dyoung * modulus. 203 1.1 dyoung */ 204 1.10 dyoung synb = __SHIFTIN(11, SA2400_SYNB_R_MASK) | SA2400_SYNB_L_NORMAL | 205 1.1 dyoung SA2400_SYNB_ON | SA2400_SYNB_ONE | 206 1.10 dyoung __SHIFTIN(80, SA2400_SYNB_FC_MASK); /* agrees w/ SA2400_SYNA_FM = 0 */ 207 1.1 dyoung 208 1.1 dyoung sync = SA2400_SYNC_CP_NORMAL; 209 1.1 dyoung 210 1.1 dyoung if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_SYNA, 211 1.1 dyoung syna)) != 0) 212 1.1 dyoung return rc; 213 1.1 dyoung if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_SYNB, 214 1.1 dyoung synb)) != 0) 215 1.1 dyoung return rc; 216 1.1 dyoung if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_SYNC, 217 1.1 dyoung sync)) != 0) 218 1.1 dyoung return rc; 219 1.1 dyoung return rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_SYND, 0x0); 220 1.1 dyoung } 221 1.1 dyoung 222 1.1 dyoung static int 223 1.1 dyoung rtw_sa2400_pwrstate(struct rtw_rf *rf, enum rtw_pwrstate power) 224 1.1 dyoung { 225 1.1 dyoung struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf; 226 1.1 dyoung struct rtw_rfbus *bus = &sa->sa_bus; 227 1.4 dyoung uint32_t opmode; 228 1.2 dyoung opmode = SA2400_OPMODE_DEFAULTS; 229 1.1 dyoung switch (power) { 230 1.1 dyoung case RTW_ON: 231 1.1 dyoung opmode |= SA2400_OPMODE_MODE_TXRX; 232 1.1 dyoung break; 233 1.1 dyoung case RTW_SLEEP: 234 1.1 dyoung opmode |= SA2400_OPMODE_MODE_WAIT; 235 1.1 dyoung break; 236 1.1 dyoung case RTW_OFF: 237 1.1 dyoung opmode |= SA2400_OPMODE_MODE_SLEEP; 238 1.1 dyoung break; 239 1.1 dyoung } 240 1.1 dyoung 241 1.1 dyoung if (sa->sa_digphy) 242 1.1 dyoung opmode |= SA2400_OPMODE_DIGIN; 243 1.1 dyoung 244 1.1 dyoung return rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_OPMODE, 245 1.1 dyoung opmode); 246 1.1 dyoung } 247 1.1 dyoung 248 1.1 dyoung static int 249 1.1 dyoung rtw_sa2400_manrx_init(struct rtw_sa2400 *sa) 250 1.1 dyoung { 251 1.4 dyoung uint32_t manrx; 252 1.1 dyoung 253 1.1 dyoung /* XXX we are not supposed to be in RXMGC mode when we do 254 1.1 dyoung * this? 255 1.1 dyoung */ 256 1.1 dyoung manrx = SA2400_MANRX_AHSN; 257 1.1 dyoung manrx |= SA2400_MANRX_TEN; 258 1.10 dyoung manrx |= __SHIFTIN(1023, SA2400_MANRX_RXGAIN_MASK); 259 1.1 dyoung 260 1.1 dyoung return rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_MANRX, 261 1.1 dyoung manrx); 262 1.1 dyoung } 263 1.1 dyoung 264 1.1 dyoung static int 265 1.1 dyoung rtw_sa2400_vcocal_start(struct rtw_sa2400 *sa, int start) 266 1.1 dyoung { 267 1.4 dyoung uint32_t opmode; 268 1.1 dyoung 269 1.2 dyoung opmode = SA2400_OPMODE_DEFAULTS; 270 1.1 dyoung if (start) 271 1.1 dyoung opmode |= SA2400_OPMODE_MODE_VCOCALIB; 272 1.1 dyoung else 273 1.1 dyoung opmode |= SA2400_OPMODE_MODE_SLEEP; 274 1.1 dyoung 275 1.1 dyoung if (sa->sa_digphy) 276 1.1 dyoung opmode |= SA2400_OPMODE_DIGIN; 277 1.1 dyoung 278 1.1 dyoung return rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_OPMODE, 279 1.1 dyoung opmode); 280 1.1 dyoung } 281 1.1 dyoung 282 1.1 dyoung static int 283 1.1 dyoung rtw_sa2400_vco_calibration(struct rtw_sa2400 *sa) 284 1.1 dyoung { 285 1.1 dyoung int rc; 286 1.1 dyoung /* calibrate VCO */ 287 1.1 dyoung if ((rc = rtw_sa2400_vcocal_start(sa, 1)) != 0) 288 1.1 dyoung return rc; 289 1.1 dyoung DELAY(2200); /* 2.2 milliseconds */ 290 1.1 dyoung /* XXX superfluous: SA2400 automatically entered SLEEP mode. */ 291 1.1 dyoung return rtw_sa2400_vcocal_start(sa, 0); 292 1.1 dyoung } 293 1.1 dyoung 294 1.1 dyoung static int 295 1.1 dyoung rtw_sa2400_filter_calibration(struct rtw_sa2400 *sa) 296 1.1 dyoung { 297 1.4 dyoung uint32_t opmode; 298 1.1 dyoung 299 1.2 dyoung opmode = SA2400_OPMODE_DEFAULTS | SA2400_OPMODE_MODE_FCALIB; 300 1.1 dyoung if (sa->sa_digphy) 301 1.1 dyoung opmode |= SA2400_OPMODE_DIGIN; 302 1.1 dyoung 303 1.1 dyoung return rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_OPMODE, 304 1.1 dyoung opmode); 305 1.1 dyoung } 306 1.1 dyoung 307 1.1 dyoung static int 308 1.1 dyoung rtw_sa2400_dc_calibration(struct rtw_sa2400 *sa) 309 1.1 dyoung { 310 1.1 dyoung struct rtw_rf *rf = &sa->sa_rf; 311 1.1 dyoung int rc; 312 1.4 dyoung uint32_t dccal; 313 1.1 dyoung 314 1.1 dyoung (*rf->rf_continuous_tx_cb)(rf->rf_continuous_tx_arg, 1); 315 1.1 dyoung 316 1.2 dyoung dccal = SA2400_OPMODE_DEFAULTS | SA2400_OPMODE_MODE_TXRX; 317 1.1 dyoung 318 1.1 dyoung rc = rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_OPMODE, 319 1.1 dyoung dccal); 320 1.1 dyoung if (rc != 0) 321 1.1 dyoung return rc; 322 1.1 dyoung 323 1.1 dyoung DELAY(5); /* DCALIB after being in Tx mode for 5 324 1.1 dyoung * microseconds 325 1.1 dyoung */ 326 1.1 dyoung 327 1.5 perry dccal &= ~SA2400_OPMODE_MODE_MASK; 328 1.1 dyoung dccal |= SA2400_OPMODE_MODE_DCALIB; 329 1.1 dyoung 330 1.1 dyoung rc = rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_OPMODE, 331 1.1 dyoung dccal); 332 1.1 dyoung if (rc != 0) 333 1.1 dyoung return rc; 334 1.1 dyoung 335 1.1 dyoung DELAY(20); /* calibration takes at most 20 microseconds */ 336 1.1 dyoung 337 1.1 dyoung (*rf->rf_continuous_tx_cb)(rf->rf_continuous_tx_arg, 0); 338 1.1 dyoung 339 1.1 dyoung return 0; 340 1.1 dyoung } 341 1.1 dyoung 342 1.1 dyoung static int 343 1.1 dyoung rtw_sa2400_agc_init(struct rtw_sa2400 *sa) 344 1.1 dyoung { 345 1.4 dyoung uint32_t agc; 346 1.1 dyoung 347 1.10 dyoung agc = __SHIFTIN(25, SA2400_AGC_MAXGAIN_MASK); 348 1.10 dyoung agc |= __SHIFTIN(7, SA2400_AGC_BBPDELAY_MASK); 349 1.10 dyoung agc |= __SHIFTIN(15, SA2400_AGC_LNADELAY_MASK); 350 1.10 dyoung agc |= __SHIFTIN(27, SA2400_AGC_RXONDELAY_MASK); 351 1.1 dyoung 352 1.1 dyoung return rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_AGC, 353 1.1 dyoung agc); 354 1.1 dyoung } 355 1.1 dyoung 356 1.1 dyoung static void 357 1.1 dyoung rtw_sa2400_destroy(struct rtw_rf *rf) 358 1.1 dyoung { 359 1.1 dyoung struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf; 360 1.1 dyoung memset(sa, 0, sizeof(*sa)); 361 1.1 dyoung free(sa, M_DEVBUF); 362 1.1 dyoung } 363 1.1 dyoung 364 1.1 dyoung static int 365 1.2 dyoung rtw_sa2400_calibrate(struct rtw_rf *rf, u_int freq) 366 1.2 dyoung { 367 1.2 dyoung struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf; 368 1.2 dyoung int i, rc; 369 1.2 dyoung 370 1.2 dyoung /* XXX reference driver calibrates VCO twice. Is it a bug? */ 371 1.2 dyoung for (i = 0; i < 2; i++) { 372 1.2 dyoung if ((rc = rtw_sa2400_vco_calibration(sa)) != 0) 373 1.2 dyoung return rc; 374 1.2 dyoung } 375 1.2 dyoung /* VCO calibration erases synthesizer registers, so re-tune */ 376 1.2 dyoung if ((rc = rtw_sa2400_tune(rf, freq)) != 0) 377 1.2 dyoung return rc; 378 1.2 dyoung if ((rc = rtw_sa2400_filter_calibration(sa)) != 0) 379 1.2 dyoung return rc; 380 1.2 dyoung /* analog PHY needs DC calibration */ 381 1.2 dyoung if (!sa->sa_digphy) 382 1.2 dyoung return rtw_sa2400_dc_calibration(sa); 383 1.2 dyoung return 0; 384 1.2 dyoung } 385 1.2 dyoung 386 1.2 dyoung static int 387 1.4 dyoung rtw_sa2400_init(struct rtw_rf *rf, u_int freq, uint8_t opaque_txpower, 388 1.1 dyoung enum rtw_pwrstate power) 389 1.1 dyoung { 390 1.1 dyoung struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf; 391 1.1 dyoung int rc; 392 1.1 dyoung 393 1.1 dyoung if ((rc = rtw_sa2400_txpower(rf, opaque_txpower)) != 0) 394 1.1 dyoung return rc; 395 1.1 dyoung 396 1.1 dyoung /* skip configuration if it's time to sleep or to power-down. */ 397 1.1 dyoung if (power == RTW_SLEEP || power == RTW_OFF) 398 1.1 dyoung return rtw_sa2400_pwrstate(rf, power); 399 1.1 dyoung 400 1.1 dyoung /* go to sleep for configuration */ 401 1.1 dyoung if ((rc = rtw_sa2400_pwrstate(rf, RTW_SLEEP)) != 0) 402 1.1 dyoung return rc; 403 1.1 dyoung 404 1.2 dyoung if ((rc = rtw_sa2400_tune(rf, freq)) != 0) 405 1.2 dyoung return rc; 406 1.1 dyoung if ((rc = rtw_sa2400_agc_init(sa)) != 0) 407 1.1 dyoung return rc; 408 1.1 dyoung if ((rc = rtw_sa2400_manrx_init(sa)) != 0) 409 1.1 dyoung return rc; 410 1.2 dyoung if ((rc = rtw_sa2400_calibrate(rf, freq)) != 0) 411 1.2 dyoung return rc; 412 1.1 dyoung 413 1.1 dyoung /* enter Tx/Rx mode */ 414 1.1 dyoung return rtw_sa2400_pwrstate(rf, power); 415 1.1 dyoung } 416 1.1 dyoung 417 1.1 dyoung struct rtw_rf * 418 1.1 dyoung rtw_sa2400_create(struct rtw_regs *regs, rtw_rf_write_t rf_write, int digphy) 419 1.1 dyoung { 420 1.1 dyoung struct rtw_sa2400 *sa; 421 1.1 dyoung struct rtw_rfbus *bus; 422 1.1 dyoung struct rtw_rf *rf; 423 1.1 dyoung struct rtw_bbpset *bb; 424 1.1 dyoung 425 1.17 chs sa = malloc(sizeof(*sa), M_DEVBUF, M_WAITOK | M_ZERO); 426 1.1 dyoung sa->sa_digphy = digphy; 427 1.1 dyoung 428 1.1 dyoung rf = &sa->sa_rf; 429 1.1 dyoung bus = &sa->sa_bus; 430 1.1 dyoung 431 1.1 dyoung rf->rf_init = rtw_sa2400_init; 432 1.1 dyoung rf->rf_destroy = rtw_sa2400_destroy; 433 1.1 dyoung rf->rf_txpower = rtw_sa2400_txpower; 434 1.1 dyoung rf->rf_tune = rtw_sa2400_tune; 435 1.1 dyoung rf->rf_pwrstate = rtw_sa2400_pwrstate; 436 1.1 dyoung bb = &rf->rf_bbpset; 437 1.1 dyoung 438 1.1 dyoung /* XXX magic */ 439 1.1 dyoung bb->bb_antatten = RTW_BBP_ANTATTEN_PHILIPS_MAGIC; 440 1.1 dyoung bb->bb_chestlim = 0x00; 441 1.1 dyoung bb->bb_chsqlim = 0xa0; 442 1.1 dyoung bb->bb_ifagcdet = 0x64; 443 1.1 dyoung bb->bb_ifagcini = 0x90; 444 1.1 dyoung bb->bb_ifagclimit = 0x1a; 445 1.1 dyoung bb->bb_lnadet = 0xe0; 446 1.1 dyoung bb->bb_sys1 = 0x98; 447 1.1 dyoung bb->bb_sys2 = 0x47; 448 1.1 dyoung bb->bb_sys3 = 0x90; 449 1.1 dyoung bb->bb_trl = 0x88; 450 1.1 dyoung bb->bb_txagc = 0x38; 451 1.1 dyoung 452 1.1 dyoung bus->b_regs = regs; 453 1.1 dyoung bus->b_write = rf_write; 454 1.1 dyoung 455 1.1 dyoung return &sa->sa_rf; 456 1.1 dyoung } 457 1.1 dyoung 458 1.8 dyoung static int 459 1.8 dyoung rtw_grf5101_txpower(struct rtw_rf *rf, uint8_t opaque_txpower) 460 1.8 dyoung { 461 1.8 dyoung struct rtw_grf5101 *gr = (struct rtw_grf5101 *)rf; 462 1.8 dyoung 463 1.8 dyoung GCT_WRITE(gr, 0x15, 0, err); 464 1.8 dyoung GCT_WRITE(gr, 0x06, opaque_txpower, err); 465 1.8 dyoung GCT_WRITE(gr, 0x15, 0x10, err); 466 1.8 dyoung GCT_WRITE(gr, 0x15, 0x00, err); 467 1.8 dyoung return 0; 468 1.8 dyoung err: 469 1.8 dyoung return -1; 470 1.8 dyoung } 471 1.8 dyoung 472 1.8 dyoung static int 473 1.8 dyoung rtw_grf5101_pwrstate(struct rtw_rf *rf, enum rtw_pwrstate power) 474 1.8 dyoung { 475 1.8 dyoung struct rtw_grf5101 *gr = (struct rtw_grf5101 *)rf; 476 1.8 dyoung switch (power) { 477 1.8 dyoung case RTW_OFF: 478 1.8 dyoung case RTW_SLEEP: 479 1.8 dyoung GCT_WRITE(gr, 0x07, 0x0000, err); 480 1.8 dyoung GCT_WRITE(gr, 0x1f, 0x0045, err); 481 1.8 dyoung GCT_WRITE(gr, 0x1f, 0x0005, err); 482 1.8 dyoung GCT_WRITE(gr, 0x00, 0x08e4, err); 483 1.8 dyoung default: 484 1.8 dyoung break; 485 1.8 dyoung case RTW_ON: 486 1.8 dyoung GCT_WRITE(gr, 0x1f, 0x0001, err); 487 1.8 dyoung DELAY(10); 488 1.8 dyoung GCT_WRITE(gr, 0x1f, 0x0001, err); 489 1.8 dyoung DELAY(10); 490 1.8 dyoung GCT_WRITE(gr, 0x1f, 0x0041, err); 491 1.8 dyoung DELAY(10); 492 1.8 dyoung GCT_WRITE(gr, 0x1f, 0x0061, err); 493 1.8 dyoung DELAY(10); 494 1.8 dyoung GCT_WRITE(gr, 0x00, 0x0ae4, err); 495 1.8 dyoung DELAY(10); 496 1.8 dyoung GCT_WRITE(gr, 0x07, 0x1000, err); 497 1.8 dyoung DELAY(100); 498 1.8 dyoung break; 499 1.8 dyoung } 500 1.8 dyoung 501 1.8 dyoung return 0; 502 1.8 dyoung err: 503 1.8 dyoung return -1; 504 1.8 dyoung } 505 1.8 dyoung 506 1.8 dyoung static int 507 1.8 dyoung rtw_grf5101_tune(struct rtw_rf *rf, u_int freq) 508 1.8 dyoung { 509 1.8 dyoung int channel; 510 1.8 dyoung struct rtw_grf5101 *gr = (struct rtw_grf5101 *)rf; 511 1.8 dyoung 512 1.8 dyoung if (freq == 2484) 513 1.8 dyoung channel = 14; 514 1.8 dyoung else if ((channel = (freq - 2412) / 5 + 1) < 1 || channel > 13) { 515 1.8 dyoung RTW_DPRINTF(RTW_DEBUG_PHY, 516 1.8 dyoung ("%s: invalid channel %d (freq %d)\n", __func__, channel, 517 1.8 dyoung freq)); 518 1.8 dyoung return -1; 519 1.8 dyoung } 520 1.8 dyoung 521 1.8 dyoung GCT_WRITE(gr, 0x07, 0, err); 522 1.8 dyoung GCT_WRITE(gr, 0x0b, channel - 1, err); 523 1.8 dyoung GCT_WRITE(gr, 0x07, 0x1000, err); 524 1.8 dyoung return 0; 525 1.8 dyoung err: 526 1.8 dyoung return -1; 527 1.8 dyoung } 528 1.8 dyoung 529 1.8 dyoung static int 530 1.8 dyoung rtw_grf5101_init(struct rtw_rf *rf, u_int freq, uint8_t opaque_txpower, 531 1.12 christos enum rtw_pwrstate power) 532 1.8 dyoung { 533 1.8 dyoung int rc; 534 1.8 dyoung struct rtw_grf5101 *gr = (struct rtw_grf5101 *)rf; 535 1.8 dyoung 536 1.8 dyoung /* 537 1.8 dyoung * These values have been derived from the rtl8180-sa2400 538 1.8 dyoung * Linux driver. It is unknown what they all do, GCT refuse 539 1.8 dyoung * to release any documentation so these are more than 540 1.8 dyoung * likely sub optimal settings 541 1.8 dyoung */ 542 1.8 dyoung 543 1.8 dyoung GCT_WRITE(gr, 0x01, 0x1a23, err); 544 1.8 dyoung GCT_WRITE(gr, 0x02, 0x4971, err); 545 1.8 dyoung GCT_WRITE(gr, 0x03, 0x41de, err); 546 1.8 dyoung GCT_WRITE(gr, 0x04, 0x2d80, err); 547 1.8 dyoung 548 1.8 dyoung GCT_WRITE(gr, 0x05, 0x61ff, err); 549 1.8 dyoung 550 1.8 dyoung GCT_WRITE(gr, 0x06, 0x0, err); 551 1.8 dyoung 552 1.8 dyoung GCT_WRITE(gr, 0x08, 0x7533, err); 553 1.8 dyoung GCT_WRITE(gr, 0x09, 0xc401, err); 554 1.8 dyoung GCT_WRITE(gr, 0x0a, 0x0, err); 555 1.8 dyoung GCT_WRITE(gr, 0x0c, 0x1c7, err); 556 1.8 dyoung GCT_WRITE(gr, 0x0d, 0x29d3, err); 557 1.8 dyoung GCT_WRITE(gr, 0x0e, 0x2e8, err); 558 1.8 dyoung GCT_WRITE(gr, 0x10, 0x192, err); 559 1.8 dyoung GCT_WRITE(gr, 0x11, 0x248, err); 560 1.8 dyoung GCT_WRITE(gr, 0x12, 0x0, err); 561 1.8 dyoung GCT_WRITE(gr, 0x13, 0x20c4, err); 562 1.8 dyoung GCT_WRITE(gr, 0x14, 0xf4fc, err); 563 1.8 dyoung GCT_WRITE(gr, 0x15, 0x0, err); 564 1.8 dyoung GCT_WRITE(gr, 0x16, 0x1500, err); 565 1.8 dyoung 566 1.8 dyoung if ((rc = rtw_grf5101_txpower(rf, opaque_txpower)) != 0) 567 1.8 dyoung return rc; 568 1.8 dyoung 569 1.8 dyoung if ((rc = rtw_grf5101_tune(rf, freq)) != 0) 570 1.8 dyoung return rc; 571 1.8 dyoung 572 1.8 dyoung return 0; 573 1.8 dyoung err: 574 1.8 dyoung return -1; 575 1.8 dyoung } 576 1.8 dyoung 577 1.8 dyoung static void 578 1.8 dyoung rtw_grf5101_destroy(struct rtw_rf *rf) 579 1.8 dyoung { 580 1.8 dyoung struct rtw_grf5101 *gr = (struct rtw_grf5101 *)rf; 581 1.8 dyoung memset(gr, 0, sizeof(*gr)); 582 1.8 dyoung free(gr, M_DEVBUF); 583 1.8 dyoung } 584 1.8 dyoung 585 1.8 dyoung struct rtw_rf * 586 1.11 christos rtw_grf5101_create(struct rtw_regs *regs, rtw_rf_write_t rf_write, 587 1.12 christos int digphy) 588 1.8 dyoung { 589 1.8 dyoung struct rtw_grf5101 *gr; 590 1.8 dyoung struct rtw_rfbus *bus; 591 1.8 dyoung struct rtw_rf *rf; 592 1.8 dyoung struct rtw_bbpset *bb; 593 1.8 dyoung 594 1.17 chs gr = malloc(sizeof(*gr), M_DEVBUF, M_WAITOK | M_ZERO); 595 1.8 dyoung 596 1.8 dyoung rf = &gr->gr_rf; 597 1.8 dyoung bus = &gr->gr_bus; 598 1.8 dyoung 599 1.8 dyoung rf->rf_init = rtw_grf5101_init; 600 1.8 dyoung rf->rf_destroy = rtw_grf5101_destroy; 601 1.8 dyoung rf->rf_txpower = rtw_grf5101_txpower; 602 1.8 dyoung rf->rf_tune = rtw_grf5101_tune; 603 1.8 dyoung rf->rf_pwrstate = rtw_grf5101_pwrstate; 604 1.8 dyoung bb = &rf->rf_bbpset; 605 1.8 dyoung 606 1.8 dyoung /* XXX magic */ 607 1.8 dyoung bb->bb_antatten = RTW_BBP_ANTATTEN_GCT_MAGIC; 608 1.8 dyoung bb->bb_chestlim = 0x00; 609 1.8 dyoung bb->bb_chsqlim = 0xa0; 610 1.8 dyoung bb->bb_ifagcdet = 0x64; 611 1.8 dyoung bb->bb_ifagcini = 0x90; 612 1.8 dyoung bb->bb_ifagclimit = 0x1e; 613 1.8 dyoung bb->bb_lnadet = 0xc0; 614 1.8 dyoung bb->bb_sys1 = 0xa8; 615 1.8 dyoung bb->bb_sys2 = 0x47; 616 1.8 dyoung bb->bb_sys3 = 0x9b; 617 1.8 dyoung bb->bb_trl = 0x88; 618 1.8 dyoung bb->bb_txagc = 0x08; 619 1.8 dyoung 620 1.8 dyoung bus->b_regs = regs; 621 1.8 dyoung bus->b_write = rf_write; 622 1.8 dyoung 623 1.8 dyoung return &gr->gr_rf; 624 1.8 dyoung } 625 1.8 dyoung 626 1.1 dyoung /* freq is in MHz */ 627 1.1 dyoung static int 628 1.1 dyoung rtw_max2820_tune(struct rtw_rf *rf, u_int freq) 629 1.1 dyoung { 630 1.1 dyoung struct rtw_max2820 *mx = (struct rtw_max2820 *)rf; 631 1.1 dyoung struct rtw_rfbus *bus = &mx->mx_bus; 632 1.1 dyoung 633 1.1 dyoung if (freq < 2400 || freq > 2499) 634 1.1 dyoung return -1; 635 1.1 dyoung 636 1.1 dyoung return rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_CHANNEL, 637 1.10 dyoung __SHIFTIN(freq - 2400, MAX2820_CHANNEL_CF_MASK)); 638 1.1 dyoung } 639 1.1 dyoung 640 1.1 dyoung static void 641 1.1 dyoung rtw_max2820_destroy(struct rtw_rf *rf) 642 1.1 dyoung { 643 1.1 dyoung struct rtw_max2820 *mx = (struct rtw_max2820 *)rf; 644 1.1 dyoung memset(mx, 0, sizeof(*mx)); 645 1.1 dyoung free(mx, M_DEVBUF); 646 1.1 dyoung } 647 1.1 dyoung 648 1.1 dyoung static int 649 1.12 christos rtw_max2820_init(struct rtw_rf *rf, u_int freq, uint8_t opaque_txpower, 650 1.1 dyoung enum rtw_pwrstate power) 651 1.1 dyoung { 652 1.1 dyoung struct rtw_max2820 *mx = (struct rtw_max2820 *)rf; 653 1.1 dyoung struct rtw_rfbus *bus = &mx->mx_bus; 654 1.1 dyoung int rc; 655 1.1 dyoung 656 1.1 dyoung if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_TEST, 657 1.1 dyoung MAX2820_TEST_DEFAULT)) != 0) 658 1.1 dyoung return rc; 659 1.1 dyoung 660 1.1 dyoung if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_ENABLE, 661 1.1 dyoung MAX2820_ENABLE_DEFAULT)) != 0) 662 1.1 dyoung return rc; 663 1.1 dyoung 664 1.1 dyoung /* skip configuration if it's time to sleep or to power-down. */ 665 1.1 dyoung if ((rc = rtw_max2820_pwrstate(rf, power)) != 0) 666 1.1 dyoung return rc; 667 1.1 dyoung else if (power == RTW_OFF || power == RTW_SLEEP) 668 1.1 dyoung return 0; 669 1.1 dyoung 670 1.1 dyoung if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_SYNTH, 671 1.1 dyoung MAX2820_SYNTH_R_44MHZ)) != 0) 672 1.1 dyoung return rc; 673 1.1 dyoung 674 1.1 dyoung if ((rc = rtw_max2820_tune(rf, freq)) != 0) 675 1.1 dyoung return rc; 676 1.1 dyoung 677 1.1 dyoung /* XXX The MAX2820 datasheet indicates that 1C and 2C should not 678 1.1 dyoung * be changed from 7, however, the reference driver sets them 679 1.1 dyoung * to 4 and 1, respectively. 680 1.1 dyoung */ 681 1.1 dyoung if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_RECEIVE, 682 1.1 dyoung MAX2820_RECEIVE_DL_DEFAULT | 683 1.10 dyoung __SHIFTIN(4, MAX2820A_RECEIVE_1C_MASK) | 684 1.10 dyoung __SHIFTIN(1, MAX2820A_RECEIVE_2C_MASK))) != 0) 685 1.1 dyoung return rc; 686 1.1 dyoung 687 1.1 dyoung return rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_TRANSMIT, 688 1.1 dyoung MAX2820_TRANSMIT_PA_DEFAULT); 689 1.1 dyoung } 690 1.1 dyoung 691 1.1 dyoung static int 692 1.12 christos rtw_max2820_txpower(struct rtw_rf *rf, uint8_t opaque_txpower) 693 1.1 dyoung { 694 1.1 dyoung /* TBD */ 695 1.1 dyoung return 0; 696 1.1 dyoung } 697 1.1 dyoung 698 1.1 dyoung static int 699 1.1 dyoung rtw_max2820_pwrstate(struct rtw_rf *rf, enum rtw_pwrstate power) 700 1.1 dyoung { 701 1.1 dyoung uint32_t enable; 702 1.1 dyoung struct rtw_max2820 *mx; 703 1.1 dyoung struct rtw_rfbus *bus; 704 1.1 dyoung 705 1.1 dyoung mx = (struct rtw_max2820 *)rf; 706 1.1 dyoung bus = &mx->mx_bus; 707 1.1 dyoung 708 1.1 dyoung switch (power) { 709 1.1 dyoung case RTW_OFF: 710 1.1 dyoung case RTW_SLEEP: 711 1.1 dyoung default: 712 1.1 dyoung enable = 0x0; 713 1.1 dyoung break; 714 1.1 dyoung case RTW_ON: 715 1.1 dyoung enable = MAX2820_ENABLE_DEFAULT; 716 1.1 dyoung break; 717 1.1 dyoung } 718 1.1 dyoung return rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_ENABLE, enable); 719 1.1 dyoung } 720 1.1 dyoung 721 1.1 dyoung struct rtw_rf * 722 1.1 dyoung rtw_max2820_create(struct rtw_regs *regs, rtw_rf_write_t rf_write, int is_a) 723 1.1 dyoung { 724 1.1 dyoung struct rtw_max2820 *mx; 725 1.1 dyoung struct rtw_rfbus *bus; 726 1.1 dyoung struct rtw_rf *rf; 727 1.1 dyoung struct rtw_bbpset *bb; 728 1.1 dyoung 729 1.17 chs mx = malloc(sizeof(*mx), M_DEVBUF, M_WAITOK | M_ZERO); 730 1.1 dyoung mx->mx_is_a = is_a; 731 1.1 dyoung 732 1.1 dyoung rf = &mx->mx_rf; 733 1.1 dyoung bus = &mx->mx_bus; 734 1.1 dyoung 735 1.1 dyoung rf->rf_init = rtw_max2820_init; 736 1.1 dyoung rf->rf_destroy = rtw_max2820_destroy; 737 1.1 dyoung rf->rf_txpower = rtw_max2820_txpower; 738 1.1 dyoung rf->rf_tune = rtw_max2820_tune; 739 1.1 dyoung rf->rf_pwrstate = rtw_max2820_pwrstate; 740 1.1 dyoung bb = &rf->rf_bbpset; 741 1.1 dyoung 742 1.1 dyoung /* XXX magic */ 743 1.1 dyoung bb->bb_antatten = RTW_BBP_ANTATTEN_MAXIM_MAGIC; 744 1.1 dyoung bb->bb_chestlim = 0; 745 1.1 dyoung bb->bb_chsqlim = 159; 746 1.1 dyoung bb->bb_ifagcdet = 100; 747 1.1 dyoung bb->bb_ifagcini = 144; 748 1.1 dyoung bb->bb_ifagclimit = 26; 749 1.1 dyoung bb->bb_lnadet = 248; 750 1.1 dyoung bb->bb_sys1 = 136; 751 1.1 dyoung bb->bb_sys2 = 71; 752 1.1 dyoung bb->bb_sys3 = 155; 753 1.1 dyoung bb->bb_trl = 136; 754 1.1 dyoung bb->bb_txagc = 8; 755 1.1 dyoung 756 1.1 dyoung bus->b_regs = regs; 757 1.1 dyoung bus->b_write = rf_write; 758 1.1 dyoung 759 1.1 dyoung return &mx->mx_rf; 760 1.1 dyoung } 761 1.1 dyoung 762 1.1 dyoung /* freq is in MHz */ 763 1.1 dyoung int 764 1.4 dyoung rtw_phy_init(struct rtw_regs *regs, struct rtw_rf *rf, uint8_t opaque_txpower, 765 1.4 dyoung uint8_t cs_threshold, u_int freq, int antdiv, int dflantb, 766 1.1 dyoung enum rtw_pwrstate power) 767 1.1 dyoung { 768 1.1 dyoung int rc; 769 1.3 dyoung RTW_DPRINTF(RTW_DEBUG_PHY, 770 1.3 dyoung ("%s: txpower %u csthresh %u freq %u antdiv %u dflantb %u " 771 1.3 dyoung "pwrstate %s\n", __func__, opaque_txpower, cs_threshold, freq, 772 1.3 dyoung antdiv, dflantb, rtw_pwrstate_string(power))); 773 1.1 dyoung 774 1.1 dyoung /* XXX is this really necessary? */ 775 1.1 dyoung if ((rc = rtw_rf_txpower(rf, opaque_txpower)) != 0) 776 1.1 dyoung return rc; 777 1.1 dyoung if ((rc = rtw_bbp_preinit(regs, rf->rf_bbpset.bb_antatten, dflantb, 778 1.1 dyoung freq)) != 0) 779 1.1 dyoung return rc; 780 1.1 dyoung if ((rc = rtw_rf_tune(rf, freq)) != 0) 781 1.1 dyoung return rc; 782 1.1 dyoung /* initialize RF */ 783 1.1 dyoung if ((rc = rtw_rf_init(rf, freq, opaque_txpower, power)) != 0) 784 1.1 dyoung return rc; 785 1.1 dyoung #if 0 /* what is this redundant tx power setting here for? */ 786 1.1 dyoung if ((rc = rtw_rf_txpower(rf, opaque_txpower)) != 0) 787 1.1 dyoung return rc; 788 1.1 dyoung #endif 789 1.1 dyoung return rtw_bbp_init(regs, &rf->rf_bbpset, antdiv, dflantb, 790 1.1 dyoung cs_threshold, freq); 791 1.1 dyoung } 792