diff options
author | Rafał Miłecki <zajec5@gmail.com> | 2010-01-15 09:29:05 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-01-15 17:05:40 -0500 |
commit | 34a56f2cae865224829d3fa7b8d7ddeee139191f (patch) | |
tree | 6298c8f4fa62d1217bef0c5416a0036de33690e7 | |
parent | 2faa6b832fb44b1910fe668a4ae127a69e998936 (diff) |
b43: N-PHY: implement calculating RX IQ comp
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/b43/phy_n.c | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 776d0082ef1c..d08feffdce68 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c | |||
@@ -464,6 +464,105 @@ static void b43_nphy_rx_iq_coeffs(struct b43_wldev *dev, bool write, | |||
464 | } | 464 | } |
465 | } | 465 | } |
466 | 466 | ||
467 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalcRxIqComp */ | ||
468 | static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask) | ||
469 | { | ||
470 | int i; | ||
471 | s32 iq; | ||
472 | u32 ii; | ||
473 | u32 qq; | ||
474 | int iq_nbits, qq_nbits; | ||
475 | int arsh, brsh; | ||
476 | u16 tmp, a, b; | ||
477 | |||
478 | struct nphy_iq_est est; | ||
479 | struct b43_phy_n_iq_comp old; | ||
480 | struct b43_phy_n_iq_comp new = { }; | ||
481 | bool error = false; | ||
482 | |||
483 | if (mask == 0) | ||
484 | return; | ||
485 | |||
486 | b43_nphy_rx_iq_coeffs(dev, false, &old); | ||
487 | b43_nphy_rx_iq_coeffs(dev, true, &new); | ||
488 | b43_nphy_rx_iq_est(dev, &est, 0x4000, 32, false); | ||
489 | new = old; | ||
490 | |||
491 | for (i = 0; i < 2; i++) { | ||
492 | if (i == 0 && (mask & 1)) { | ||
493 | iq = est.iq0_prod; | ||
494 | ii = est.i0_pwr; | ||
495 | qq = est.q0_pwr; | ||
496 | } else if (i == 1 && (mask & 2)) { | ||
497 | iq = est.iq1_prod; | ||
498 | ii = est.i1_pwr; | ||
499 | qq = est.q1_pwr; | ||
500 | } else { | ||
501 | B43_WARN_ON(1); | ||
502 | continue; | ||
503 | } | ||
504 | |||
505 | if (ii + qq < 2) { | ||
506 | error = true; | ||
507 | break; | ||
508 | } | ||
509 | |||
510 | iq_nbits = fls(abs(iq)); | ||
511 | qq_nbits = fls(qq); | ||
512 | |||
513 | arsh = iq_nbits - 20; | ||
514 | if (arsh >= 0) { | ||
515 | a = -((iq << (30 - iq_nbits)) + (ii >> (1 + arsh))); | ||
516 | tmp = ii >> arsh; | ||
517 | } else { | ||
518 | a = -((iq << (30 - iq_nbits)) + (ii << (-1 - arsh))); | ||
519 | tmp = ii << -arsh; | ||
520 | } | ||
521 | if (tmp == 0) { | ||
522 | error = true; | ||
523 | break; | ||
524 | } | ||
525 | a /= tmp; | ||
526 | |||
527 | brsh = qq_nbits - 11; | ||
528 | if (brsh >= 0) { | ||
529 | b = (qq << (31 - qq_nbits)); | ||
530 | tmp = ii >> brsh; | ||
531 | } else { | ||
532 | b = (qq << (31 - qq_nbits)); | ||
533 | tmp = ii << -brsh; | ||
534 | } | ||
535 | if (tmp == 0) { | ||
536 | error = true; | ||
537 | break; | ||
538 | } | ||
539 | b = int_sqrt(b / tmp - a * a) - (1 << 10); | ||
540 | |||
541 | if (i == 0 && (mask & 0x1)) { | ||
542 | if (dev->phy.rev >= 3) { | ||
543 | new.a0 = a & 0x3FF; | ||
544 | new.b0 = b & 0x3FF; | ||
545 | } else { | ||
546 | new.a0 = b & 0x3FF; | ||
547 | new.b0 = a & 0x3FF; | ||
548 | } | ||
549 | } else if (i == 1 && (mask & 0x2)) { | ||
550 | if (dev->phy.rev >= 3) { | ||
551 | new.a1 = a & 0x3FF; | ||
552 | new.b1 = b & 0x3FF; | ||
553 | } else { | ||
554 | new.a1 = b & 0x3FF; | ||
555 | new.b1 = a & 0x3FF; | ||
556 | } | ||
557 | } | ||
558 | } | ||
559 | |||
560 | if (error) | ||
561 | new = old; | ||
562 | |||
563 | b43_nphy_rx_iq_coeffs(dev, true, &new); | ||
564 | } | ||
565 | |||
467 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxIqWar */ | 566 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxIqWar */ |
468 | static void b43_nphy_tx_iq_workaround(struct b43_wldev *dev) | 567 | static void b43_nphy_tx_iq_workaround(struct b43_wldev *dev) |
469 | { | 568 | { |