aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2010-01-15 09:29:05 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-01-15 17:05:40 -0500
commit34a56f2cae865224829d3fa7b8d7ddeee139191f (patch)
tree6298c8f4fa62d1217bef0c5416a0036de33690e7
parent2faa6b832fb44b1910fe668a4ae127a69e998936 (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.c99
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 */
468static 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 */
468static void b43_nphy_tx_iq_workaround(struct b43_wldev *dev) 567static void b43_nphy_tx_iq_workaround(struct b43_wldev *dev)
469{ 568{