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