1 /* 2 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 /* 6 * Copyright (c) 2004, 2005 David Young. All rights reserved. 7 * 8 * Programmed for NetBSD by David Young. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. The name of David Young may not be used to endorse or promote 19 * products derived from this software without specific prior 20 * written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY David Young ``AS IS'' AND ANY 23 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 24 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David 26 * Young BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 28 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 30 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 33 * OF SUCH DAMAGE. 34 */ 35 /* 36 * Control the Philips SA2400 RF front-end and the baseband processor 37 * built into the Realtek RTL8180. 38 */ 39 #include <sys/types.h> 40 #include <sys/sysmacros.h> 41 #include "rtwreg.h" 42 #include "rtwvar.h" 43 #include "max2820reg.h" 44 #include "sa2400reg.h" 45 #include "rtwphyio.h" 46 #include "rtwphy.h" 47 48 static int rtw_max2820_pwrstate(struct rtw_rf *, enum rtw_pwrstate); 49 static int rtw_sa2400_pwrstate(struct rtw_rf *, enum rtw_pwrstate); 50 51 static int 52 rtw_rf_init(struct rtw_rf *rf, uint_t freq, uint8_t opaque_txpower, 53 enum rtw_pwrstate power) 54 { 55 return (*rf->rf_init)(rf, freq, opaque_txpower, power); 56 } 57 58 static int 59 rtw_rf_tune(struct rtw_rf *rf, uint_t freq) 60 { 61 return (*rf->rf_tune)(rf, freq); 62 } 63 64 static int 65 rtw_rf_txpower(struct rtw_rf *rf, uint8_t opaque_txpower) 66 { 67 return (*rf->rf_txpower)(rf, opaque_txpower); 68 } 69 70 static int 71 rtw_rfbus_write(struct rtw_rfbus *bus, enum rtw_rfchipid rfchipid, uint_t addr, 72 uint32_t val) 73 { 74 return (*bus->b_write)(bus->b_regs, rfchipid, addr, val); 75 } 76 77 static int 78 rtw_bbp_preinit(struct rtw_regs *regs, uint_t antatten0, int dflantb, 79 uint_t freq) 80 { 81 uint_t antatten = antatten0; 82 if (dflantb) 83 antatten |= RTW_BBP_ANTATTEN_DFLANTB; 84 if (freq == 2484) /* channel 14 */ 85 antatten |= RTW_BBP_ANTATTEN_CHAN14; 86 return (rtw_bbp_write(regs, RTW_BBP_ANTATTEN, antatten)); 87 } 88 89 static int 90 rtw_bbp_init(struct rtw_regs *regs, struct rtw_bbpset *bb, int antdiv, 91 int dflantb, uint8_t cs_threshold, uint_t freq) 92 { 93 int rc; 94 uint32_t sys2, sys3; 95 96 sys2 = bb->bb_sys2; 97 if (antdiv) 98 sys2 |= RTW_BBP_SYS2_ANTDIV; 99 sys3 = bb->bb_sys3 | 100 LSHIFT(cs_threshold, RTW_BBP_SYS3_CSTHRESH_MASK); 101 102 #define RTW_BBP_WRITE_OR_RETURN(reg, val) \ 103 if ((rc = rtw_bbp_write(regs, reg, val)) != 0) \ 104 return (rc); 105 106 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS1, bb->bb_sys1); 107 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_TXAGC, bb->bb_txagc); 108 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_LNADET, bb->bb_lnadet); 109 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCINI, bb->bb_ifagcini); 110 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCLIMIT, bb->bb_ifagclimit); 111 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCDET, bb->bb_ifagcdet); 112 113 if ((rc = rtw_bbp_preinit(regs, bb->bb_antatten, dflantb, freq)) != 0) 114 return (rc); 115 116 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_TRL, bb->bb_trl); 117 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS2, sys2); 118 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS3, sys3); 119 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_CHESTLIM, bb->bb_chestlim); 120 RTW_BBP_WRITE_OR_RETURN(RTW_BBP_CHSQLIM, bb->bb_chsqlim); 121 return (0); 122 } 123 124 static int 125 rtw_sa2400_txpower(struct rtw_rf *rf, uint8_t opaque_txpower) 126 { 127 struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf; 128 struct rtw_rfbus *bus = &sa->sa_bus; 129 130 return (rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_TX, 131 opaque_txpower)); 132 } 133 134 #ifdef _RTW_FUTURE_DEBUG_ 135 /* 136 * make sure we're using the same settings as the reference driver 137 */ 138 static void 139 verify_syna(uint_t freq, uint32_t val) 140 { 141 uint32_t expected_val = ~val; 142 143 switch (freq) { 144 case 2412: 145 expected_val = 0x0000096c; /* ch 1 */ 146 break; 147 case 2417: 148 expected_val = 0x00080970; /* ch 2 */ 149 break; 150 case 2422: 151 expected_val = 0x00100974; /* ch 3 */ 152 break; 153 case 2427: 154 expected_val = 0x00180978; /* ch 4 */ 155 break; 156 case 2432: 157 expected_val = 0x00000980; /* ch 5 */ 158 break; 159 case 2437: 160 expected_val = 0x00080984; /* ch 6 */ 161 break; 162 case 2442: 163 expected_val = 0x00100988; /* ch 7 */ 164 break; 165 case 2447: 166 expected_val = 0x0018098c; /* ch 8 */ 167 break; 168 case 2452: 169 expected_val = 0x00000994; /* ch 9 */ 170 break; 171 case 2457: 172 expected_val = 0x00080998; /* ch 10 */ 173 break; 174 case 2462: 175 expected_val = 0x0010099c; /* ch 11 */ 176 break; 177 case 2467: 178 expected_val = 0x001809a0; /* ch 12 */ 179 break; 180 case 2472: 181 expected_val = 0x000009a8; /* ch 13 */ 182 break; 183 case 2484: 184 expected_val = 0x000009b4; /* ch 14 */ 185 break; 186 } 187 } 188 #endif /* _RTW_FUTURE_DEBUG_ */ 189 190 /* freq is in MHz */ 191 static int 192 rtw_sa2400_tune(struct rtw_rf *rf, uint_t freq) 193 { 194 struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf; 195 struct rtw_rfbus *bus = &sa->sa_bus; 196 int rc; 197 uint32_t syna, synb, sync; 198 199 /* 200 * XO = 44MHz, R = 11, hence N is in units of XO / R = 4MHz. 201 * 202 * The channel spacing (5MHz) is not divisible by 4MHz, so 203 * we set the fractional part of N to compensate. 204 */ 205 int n = freq / 4, nf = (freq % 4) * 2; 206 207 syna = LSHIFT(nf, SA2400_SYNA_NF_MASK) | LSHIFT(n, SA2400_SYNA_N_MASK); 208 /* verify_syna(freq, syna); */ 209 210 /* 211 * Divide the 44MHz crystal down to 4MHz. Set the fractional 212 * compensation charge pump value to agree with the fractional 213 * modulus. 214 */ 215 synb = LSHIFT(11, SA2400_SYNB_R_MASK) | SA2400_SYNB_L_NORMAL | 216 SA2400_SYNB_ON | SA2400_SYNB_ONE | 217 LSHIFT(80, SA2400_SYNB_FC_MASK); /* agrees w/ SA2400_SYNA_FM = 0 */ 218 219 sync = SA2400_SYNC_CP_NORMAL; 220 221 if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_SYNA, 222 syna)) != 0) 223 return (rc); 224 if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_SYNB, 225 synb)) != 0) 226 return (rc); 227 if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_SYNC, 228 sync)) != 0) 229 return (rc); 230 return (rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_SYND, 0x0)); 231 } 232 233 static int 234 rtw_sa2400_pwrstate(struct rtw_rf *rf, enum rtw_pwrstate power) 235 { 236 struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf; 237 struct rtw_rfbus *bus = &sa->sa_bus; 238 uint32_t opmode; 239 opmode = SA2400_OPMODE_DEFAULTS; 240 switch (power) { 241 case RTW_ON: 242 opmode |= SA2400_OPMODE_MODE_TXRX; 243 break; 244 case RTW_SLEEP: 245 opmode |= SA2400_OPMODE_MODE_WAIT; 246 break; 247 case RTW_OFF: 248 opmode |= SA2400_OPMODE_MODE_SLEEP; 249 break; 250 } 251 252 if (sa->sa_digphy) 253 opmode |= SA2400_OPMODE_DIGIN; 254 255 return (rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_OPMODE, 256 opmode)); 257 } 258 259 static int 260 rtw_sa2400_manrx_init(struct rtw_sa2400 *sa) 261 { 262 uint32_t manrx; 263 264 /* 265 * we are not supposed to be in RXMGC mode when we do 266 * this? 267 */ 268 manrx = SA2400_MANRX_AHSN; 269 manrx |= SA2400_MANRX_TEN; 270 manrx |= LSHIFT(1023, SA2400_MANRX_RXGAIN_MASK); 271 272 return (rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_MANRX, 273 manrx)); 274 } 275 276 static int 277 rtw_sa2400_vcocal_start(struct rtw_sa2400 *sa, int start) 278 { 279 uint32_t opmode; 280 281 opmode = SA2400_OPMODE_DEFAULTS; 282 if (start) 283 opmode |= SA2400_OPMODE_MODE_VCOCALIB; 284 else 285 opmode |= SA2400_OPMODE_MODE_SLEEP; 286 287 if (sa->sa_digphy) 288 opmode |= SA2400_OPMODE_DIGIN; 289 290 return (rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, 291 SA2400_OPMODE, opmode)); 292 } 293 294 static int 295 rtw_sa2400_vco_calibration(struct rtw_sa2400 *sa) 296 { 297 int rc; 298 /* 299 * calibrate VCO 300 */ 301 if ((rc = rtw_sa2400_vcocal_start(sa, 1)) != 0) 302 return (rc); 303 DELAY(2200); /* 2.2 milliseconds */ 304 /* 305 * XXX superfluous: SA2400 automatically entered SLEEP mode. 306 */ 307 return (rtw_sa2400_vcocal_start(sa, 0)); 308 } 309 310 static int 311 rtw_sa2400_filter_calibration(struct rtw_sa2400 *sa) 312 { 313 uint32_t opmode; 314 315 opmode = SA2400_OPMODE_DEFAULTS | SA2400_OPMODE_MODE_FCALIB; 316 if (sa->sa_digphy) 317 opmode |= SA2400_OPMODE_DIGIN; 318 319 return (rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, 320 SA2400_OPMODE, opmode)); 321 } 322 323 static int 324 rtw_sa2400_dc_calibration(struct rtw_sa2400 *sa) 325 { 326 struct rtw_rf *rf = &sa->sa_rf; 327 int rc; 328 uint32_t dccal; 329 330 (*rf->rf_continuous_tx_cb)(rf->rf_continuous_tx_arg, 1); 331 332 dccal = SA2400_OPMODE_DEFAULTS | SA2400_OPMODE_MODE_TXRX; 333 334 rc = rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_OPMODE, 335 dccal); 336 if (rc != 0) 337 return (rc); 338 339 DELAY(5); /* DCALIB after being in Tx mode for 5 microseconds */ 340 341 dccal &= ~SA2400_OPMODE_MODE_MASK; 342 dccal |= SA2400_OPMODE_MODE_DCALIB; 343 344 rc = rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_OPMODE, 345 dccal); 346 if (rc != 0) 347 return (rc); 348 DELAY(20); /* calibration takes at most 20 microseconds */ 349 350 (*rf->rf_continuous_tx_cb)(rf->rf_continuous_tx_arg, 0); 351 352 return (0); 353 } 354 355 static int 356 rtw_sa2400_agc_init(struct rtw_sa2400 *sa) 357 { 358 uint32_t agc; 359 360 agc = LSHIFT(25, SA2400_AGC_MAXGAIN_MASK); 361 agc |= LSHIFT(7, SA2400_AGC_BBPDELAY_MASK); 362 agc |= LSHIFT(15, SA2400_AGC_LNADELAY_MASK); 363 agc |= LSHIFT(27, SA2400_AGC_RXONDELAY_MASK); 364 365 return (rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_AGC, 366 agc)); 367 } 368 369 static void 370 rtw_sa2400_destroy(struct rtw_rf *rf) 371 { 372 struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf; 373 kmem_free(sa, sizeof (*sa)); 374 } 375 376 static int 377 rtw_sa2400_calibrate(struct rtw_rf *rf, uint_t freq) 378 { 379 struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf; 380 int i, rc; 381 382 /* 383 * XXX reference driver calibrates VCO twice. Is it a bug? 384 */ 385 for (i = 0; i < 2; i++) { 386 if ((rc = rtw_sa2400_vco_calibration(sa)) != 0) 387 return (rc); 388 } 389 /* 390 * VCO calibration erases synthesizer registers, so re-tune 391 */ 392 if ((rc = rtw_sa2400_tune(rf, freq)) != 0) 393 return (rc); 394 if ((rc = rtw_sa2400_filter_calibration(sa)) != 0) 395 return (rc); 396 /* 397 * analog PHY needs DC calibration 398 */ 399 if (!sa->sa_digphy) 400 return (rtw_sa2400_dc_calibration(sa)); 401 return (0); 402 } 403 404 static int 405 rtw_sa2400_init(struct rtw_rf *rf, uint_t freq, uint8_t opaque_txpower, 406 enum rtw_pwrstate power) 407 { 408 struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf; 409 int rc; 410 411 if ((rc = rtw_sa2400_txpower(rf, opaque_txpower)) != 0) 412 return (rc); 413 414 /* 415 * skip configuration if it's time to sleep or to power-down. 416 */ 417 if (power == RTW_SLEEP || power == RTW_OFF) 418 return (rtw_sa2400_pwrstate(rf, power)); 419 420 /* 421 * go to sleep for configuration 422 */ 423 if ((rc = rtw_sa2400_pwrstate(rf, RTW_SLEEP)) != 0) 424 return (rc); 425 426 if ((rc = rtw_sa2400_tune(rf, freq)) != 0) 427 return (rc); 428 if ((rc = rtw_sa2400_agc_init(sa)) != 0) 429 return (rc); 430 if ((rc = rtw_sa2400_manrx_init(sa)) != 0) 431 return (rc); 432 if ((rc = rtw_sa2400_calibrate(rf, freq)) != 0) 433 return (rc); 434 435 /* 436 * enter Tx/Rx mode 437 */ 438 return (rtw_sa2400_pwrstate(rf, power)); 439 } 440 441 struct rtw_rf * 442 rtw_sa2400_create(struct rtw_regs *regs, rtw_rf_write_t rf_write, int digphy) 443 { 444 struct rtw_sa2400 *sa; 445 struct rtw_rfbus *bus; 446 struct rtw_rf *rf; 447 struct rtw_bbpset *bb; 448 449 sa = (struct rtw_sa2400 *)kmem_zalloc(sizeof (*sa), KM_SLEEP); 450 if (sa == NULL) 451 return (NULL); 452 453 sa->sa_digphy = digphy; 454 455 rf = &sa->sa_rf; 456 bus = &sa->sa_bus; 457 458 rf->rf_init = rtw_sa2400_init; 459 rf->rf_destroy = rtw_sa2400_destroy; 460 rf->rf_txpower = rtw_sa2400_txpower; 461 rf->rf_tune = rtw_sa2400_tune; 462 rf->rf_pwrstate = rtw_sa2400_pwrstate; 463 bb = &rf->rf_bbpset; 464 465 /* 466 * XXX magic 467 */ 468 bb->bb_antatten = RTW_BBP_ANTATTEN_PHILIPS_MAGIC; 469 bb->bb_chestlim = 0x00; 470 bb->bb_chsqlim = 0xa0; 471 bb->bb_ifagcdet = 0x64; 472 bb->bb_ifagcini = 0x90; 473 bb->bb_ifagclimit = 0x1a; 474 bb->bb_lnadet = 0xe0; 475 bb->bb_sys1 = 0x98; 476 bb->bb_sys2 = 0x47; 477 bb->bb_sys3 = 0x90; 478 bb->bb_trl = 0x88; 479 bb->bb_txagc = 0x38; 480 481 bus->b_regs = regs; 482 bus->b_write = rf_write; 483 484 return (&sa->sa_rf); 485 } 486 487 /* 488 * freq is in MHz 489 */ 490 static int 491 rtw_max2820_tune(struct rtw_rf *rf, uint_t freq) 492 { 493 struct rtw_max2820 *mx = (struct rtw_max2820 *)rf; 494 struct rtw_rfbus *bus = &mx->mx_bus; 495 496 if (freq < 2400 || freq > 2499) 497 return (-1); 498 499 return (rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_CHANNEL, 500 LSHIFT(freq - 2400, MAX2820_CHANNEL_CF_MASK))); 501 } 502 503 static void 504 rtw_max2820_destroy(struct rtw_rf *rf) 505 { 506 struct rtw_max2820 *mx = (struct rtw_max2820 *)rf; 507 kmem_free(mx, sizeof (*mx)); 508 } 509 510 /*ARGSUSED*/ 511 static int 512 rtw_max2820_init(struct rtw_rf *rf, uint_t freq, uint8_t opaque_txpower, 513 enum rtw_pwrstate power) 514 { 515 struct rtw_max2820 *mx = (struct rtw_max2820 *)rf; 516 struct rtw_rfbus *bus = &mx->mx_bus; 517 int rc; 518 519 if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_TEST, 520 MAX2820_TEST_DEFAULT)) != 0) 521 return (rc); 522 523 if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_ENABLE, 524 MAX2820_ENABLE_DEFAULT)) != 0) 525 return (rc); 526 527 /* 528 * skip configuration if it's time to sleep or to power-down. 529 */ 530 if ((rc = rtw_max2820_pwrstate(rf, power)) != 0) 531 return (rc); 532 else if (power == RTW_OFF || power == RTW_SLEEP) 533 return (0); 534 535 if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_SYNTH, 536 MAX2820_SYNTH_R_44MHZ)) != 0) 537 return (rc); 538 539 if ((rc = rtw_max2820_tune(rf, freq)) != 0) 540 return (rc); 541 542 /* 543 * XXX The MAX2820 datasheet indicates that 1C and 2C should not 544 * be changed from 7, however, the reference driver sets them 545 * to 4 and 1, respectively. 546 */ 547 if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_RECEIVE, 548 MAX2820_RECEIVE_DL_DEFAULT | 549 LSHIFT(4, MAX2820A_RECEIVE_1C_MASK) | 550 LSHIFT(1, MAX2820A_RECEIVE_2C_MASK))) != 0) 551 return (rc); 552 553 return (rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_TRANSMIT, 554 MAX2820_TRANSMIT_PA_DEFAULT)); 555 } 556 557 /*ARGSUSED*/ 558 static int 559 rtw_max2820_txpower(struct rtw_rf *rf, uint8_t opaque_txpower) 560 { 561 /* TBD */ 562 return (0); 563 } 564 565 static int 566 rtw_max2820_pwrstate(struct rtw_rf *rf, enum rtw_pwrstate power) 567 { 568 uint32_t enable; 569 struct rtw_max2820 *mx; 570 struct rtw_rfbus *bus; 571 572 mx = (struct rtw_max2820 *)rf; 573 bus = &mx->mx_bus; 574 575 switch (power) { 576 case RTW_OFF: 577 case RTW_SLEEP: 578 default: 579 enable = 0x0; 580 break; 581 case RTW_ON: 582 enable = MAX2820_ENABLE_DEFAULT; 583 break; 584 } 585 return (rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, 586 MAX2820_ENABLE, enable)); 587 } 588 589 struct rtw_rf * 590 rtw_max2820_create(struct rtw_regs *regs, rtw_rf_write_t rf_write, int is_a) 591 { 592 struct rtw_max2820 *mx; 593 struct rtw_rfbus *bus; 594 struct rtw_rf *rf; 595 struct rtw_bbpset *bb; 596 597 mx = (struct rtw_max2820 *)kmem_zalloc(sizeof (*mx), KM_SLEEP); 598 if (mx == NULL) 599 return (NULL); 600 601 mx->mx_is_a = is_a; 602 603 rf = &mx->mx_rf; 604 bus = &mx->mx_bus; 605 606 rf->rf_init = rtw_max2820_init; 607 rf->rf_destroy = rtw_max2820_destroy; 608 rf->rf_txpower = rtw_max2820_txpower; 609 rf->rf_tune = rtw_max2820_tune; 610 rf->rf_pwrstate = rtw_max2820_pwrstate; 611 bb = &rf->rf_bbpset; 612 613 /* 614 * XXX magic 615 */ 616 bb->bb_antatten = RTW_BBP_ANTATTEN_MAXIM_MAGIC; 617 bb->bb_chestlim = 0; 618 bb->bb_chsqlim = 159; 619 bb->bb_ifagcdet = 100; 620 bb->bb_ifagcini = 144; 621 bb->bb_ifagclimit = 26; 622 bb->bb_lnadet = 248; 623 bb->bb_sys1 = 136; 624 bb->bb_sys2 = 71; 625 bb->bb_sys3 = 155; 626 bb->bb_trl = 136; 627 bb->bb_txagc = 8; 628 629 bus->b_regs = regs; 630 bus->b_write = rf_write; 631 632 return (&mx->mx_rf); 633 } 634 635 /* 636 * freq is in MHz 637 */ 638 int 639 rtw_phy_init(struct rtw_regs *regs, struct rtw_rf *rf, uint8_t opaque_txpower, 640 uint8_t cs_threshold, uint_t freq, int antdiv, int dflantb, 641 enum rtw_pwrstate power) 642 { 643 int rc; 644 645 /* 646 * XXX is this really necessary? 647 */ 648 if ((rc = rtw_rf_txpower(rf, opaque_txpower)) != 0) 649 return (rc); 650 if ((rc = rtw_bbp_preinit(regs, rf->rf_bbpset.bb_antatten, dflantb, 651 freq)) != 0) 652 return (rc); 653 if ((rc = rtw_rf_tune(rf, freq)) != 0) 654 return (rc); 655 /* 656 * initialize RF 657 */ 658 if ((rc = rtw_rf_init(rf, freq, opaque_txpower, power)) != 0) 659 return (rc); 660 #ifdef _RTW_FUTURE_DEBUG_ 661 /* what is this redundant tx power setting here for? */ 662 if ((rc = rtw_rf_txpower(rf, opaque_txpower)) != 0) 663 return (rc); 664 #endif /* _RTW_FUTURE_DEBUG */ 665 return (rtw_bbp_init(regs, &rf->rf_bbpset, antdiv, dflantb, 666 cs_threshold, freq)); 667 } 668