diff options
author | Rafał Miłecki <zajec5@gmail.com> | 2010-01-15 10:10:48 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-01-15 17:05:42 -0500 |
commit | fb43b8e23519f853f142202bb341c21382f39070 (patch) | |
tree | 76e64cf67f6140848dbf72b6de5c3fcda91b0b7d /drivers | |
parent | e9762492f5c7176660ed030e9dd816b3208def12 (diff) |
b43: N-PHY: add huge calculating TX IQ LO
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/b43/phy_n.c | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 8a3bc2c58a8..4111a462600 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c | |||
@@ -1434,6 +1434,232 @@ static void b43_nphy_restore_cal(struct b43_wldev *dev) | |||
1434 | b43_nphy_rx_iq_coeffs(dev, true, rxcal_coeffs); | 1434 | b43_nphy_rx_iq_coeffs(dev, true, rxcal_coeffs); |
1435 | } | 1435 | } |
1436 | 1436 | ||
1437 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalTxIqlo */ | ||
1438 | static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev, | ||
1439 | struct nphy_txgains target, | ||
1440 | bool full, bool mphase) | ||
1441 | { | ||
1442 | struct b43_phy_n *nphy = dev->phy.n; | ||
1443 | int i; | ||
1444 | int error = 0; | ||
1445 | int freq; | ||
1446 | bool avoid = false; | ||
1447 | u8 length; | ||
1448 | u16 tmp, core, type, count, max, numb, last, cmd; | ||
1449 | const u16 *table; | ||
1450 | bool phy6or5x; | ||
1451 | |||
1452 | u16 buffer[11]; | ||
1453 | u16 diq_start = 0; | ||
1454 | u16 save[2]; | ||
1455 | u16 gain[2]; | ||
1456 | struct nphy_iqcal_params params[2]; | ||
1457 | bool updated[2] = { }; | ||
1458 | |||
1459 | b43_nphy_stay_in_carrier_search(dev, true); | ||
1460 | |||
1461 | if (dev->phy.rev >= 4) { | ||
1462 | avoid = nphy->hang_avoid; | ||
1463 | nphy->hang_avoid = 0; | ||
1464 | } | ||
1465 | |||
1466 | /* TODO: Read an N PHY Table with ID 7, length 2, offset 0x110, | ||
1467 | width 16, and data pointer save */ | ||
1468 | |||
1469 | for (i = 0; i < 2; i++) { | ||
1470 | b43_nphy_iq_cal_gain_params(dev, i, target, ¶ms[i]); | ||
1471 | gain[i] = params[i].cal_gain; | ||
1472 | } | ||
1473 | /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110, | ||
1474 | width 16, and data pointer gain */ | ||
1475 | |||
1476 | b43_nphy_tx_cal_radio_setup(dev); | ||
1477 | /* TODO: Call N PHY TX Cal PHY Setup */ | ||
1478 | |||
1479 | phy6or5x = dev->phy.rev >= 6 || | ||
1480 | (dev->phy.rev == 5 && nphy->ipa2g_on && | ||
1481 | b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ); | ||
1482 | if (phy6or5x) { | ||
1483 | /* TODO */ | ||
1484 | } | ||
1485 | |||
1486 | b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9); | ||
1487 | |||
1488 | if (1 /* FIXME: the band width is 20 MHz */) | ||
1489 | freq = 2500; | ||
1490 | else | ||
1491 | freq = 5000; | ||
1492 | |||
1493 | if (nphy->mphase_cal_phase_id > 2) | ||
1494 | ;/* TODO: Call N PHY Run Samples with (band width * 8), | ||
1495 | 0xFFFF, 0, 1, 0 as arguments */ | ||
1496 | else | ||
1497 | ;/* TODO: Call N PHY TX Tone with freq, 250, 1, 0 as arguments | ||
1498 | and save result as error */ | ||
1499 | |||
1500 | if (error == 0) { | ||
1501 | if (nphy->mphase_cal_phase_id > 2) { | ||
1502 | table = nphy->mphase_txcal_bestcoeffs; | ||
1503 | length = 11; | ||
1504 | if (dev->phy.rev < 3) | ||
1505 | length -= 2; | ||
1506 | } else { | ||
1507 | if (!full && nphy->txiqlocal_coeffsvalid) { | ||
1508 | table = nphy->txiqlocal_bestc; | ||
1509 | length = 11; | ||
1510 | if (dev->phy.rev < 3) | ||
1511 | length -= 2; | ||
1512 | } else { | ||
1513 | full = true; | ||
1514 | if (dev->phy.rev >= 3) { | ||
1515 | table = tbl_tx_iqlo_cal_startcoefs_nphyrev3; | ||
1516 | length = B43_NTAB_TX_IQLO_CAL_STARTCOEFS_REV3; | ||
1517 | } else { | ||
1518 | table = tbl_tx_iqlo_cal_startcoefs; | ||
1519 | length = B43_NTAB_TX_IQLO_CAL_STARTCOEFS; | ||
1520 | } | ||
1521 | } | ||
1522 | } | ||
1523 | |||
1524 | /* TODO: Write an N PHY Table with ID 15, length from above, | ||
1525 | offset 64, width 16, and the data pointer from above */ | ||
1526 | |||
1527 | if (full) { | ||
1528 | if (dev->phy.rev >= 3) | ||
1529 | max = B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL_REV3; | ||
1530 | else | ||
1531 | max = B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL; | ||
1532 | } else { | ||
1533 | if (dev->phy.rev >= 3) | ||
1534 | max = B43_NTAB_TX_IQLO_CAL_CMDS_RECAL_REV3; | ||
1535 | else | ||
1536 | max = B43_NTAB_TX_IQLO_CAL_CMDS_RECAL; | ||
1537 | } | ||
1538 | |||
1539 | if (mphase) { | ||
1540 | count = nphy->mphase_txcal_cmdidx; | ||
1541 | numb = min(max, | ||
1542 | (u16)(count + nphy->mphase_txcal_numcmds)); | ||
1543 | } else { | ||
1544 | count = 0; | ||
1545 | numb = max; | ||
1546 | } | ||
1547 | |||
1548 | for (; count < numb; count++) { | ||
1549 | if (full) { | ||
1550 | if (dev->phy.rev >= 3) | ||
1551 | cmd = tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[count]; | ||
1552 | else | ||
1553 | cmd = tbl_tx_iqlo_cal_cmds_fullcal[count]; | ||
1554 | } else { | ||
1555 | if (dev->phy.rev >= 3) | ||
1556 | cmd = tbl_tx_iqlo_cal_cmds_recal_nphyrev3[count]; | ||
1557 | else | ||
1558 | cmd = tbl_tx_iqlo_cal_cmds_recal[count]; | ||
1559 | } | ||
1560 | |||
1561 | core = (cmd & 0x3000) >> 12; | ||
1562 | type = (cmd & 0x0F00) >> 8; | ||
1563 | |||
1564 | if (phy6or5x && updated[core] == 0) { | ||
1565 | b43_nphy_update_tx_cal_ladder(dev, core); | ||
1566 | updated[core] = 1; | ||
1567 | } | ||
1568 | |||
1569 | tmp = (params[core].ncorr[type] << 8) | 0x66; | ||
1570 | b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDNNUM, tmp); | ||
1571 | |||
1572 | if (type == 1 || type == 3 || type == 4) { | ||
1573 | /* TODO: Read an N PHY Table with ID 15, | ||
1574 | length 1, offset 69 + core, | ||
1575 | width 16, and data pointer buffer */ | ||
1576 | diq_start = buffer[0]; | ||
1577 | buffer[0] = 0; | ||
1578 | /* TODO: Write an N PHY Table with ID 15, | ||
1579 | length 1, offset 69 + core, width 16, | ||
1580 | and data of 0 */ | ||
1581 | } | ||
1582 | |||
1583 | b43_phy_write(dev, B43_NPHY_IQLOCAL_CMD, cmd); | ||
1584 | for (i = 0; i < 2000; i++) { | ||
1585 | tmp = b43_phy_read(dev, B43_NPHY_IQLOCAL_CMD); | ||
1586 | if (tmp & 0xC000) | ||
1587 | break; | ||
1588 | udelay(10); | ||
1589 | } | ||
1590 | |||
1591 | /* TODO: Read an N PHY Table with ID 15, | ||
1592 | length table_length, offset 96, width 16, | ||
1593 | and data pointer buffer */ | ||
1594 | /* TODO: Write an N PHY Table with ID 15, | ||
1595 | length table_length, offset 64, width 16, | ||
1596 | and data pointer buffer */ | ||
1597 | |||
1598 | if (type == 1 || type == 3 || type == 4) | ||
1599 | buffer[0] = diq_start; | ||
1600 | } | ||
1601 | |||
1602 | if (mphase) | ||
1603 | nphy->mphase_txcal_cmdidx = (numb >= max) ? 0 : numb; | ||
1604 | |||
1605 | last = (dev->phy.rev < 3) ? 6 : 7; | ||
1606 | |||
1607 | if (!mphase || nphy->mphase_cal_phase_id == last) { | ||
1608 | /* TODO: Write an N PHY Table with ID 15, length 4, | ||
1609 | offset 96, width 16, and data pointer buffer */ | ||
1610 | /* TODO: Read an N PHY Table with ID 15, length 4, | ||
1611 | offset 80, width 16, and data pointer buffer */ | ||
1612 | if (dev->phy.rev < 3) { | ||
1613 | buffer[0] = 0; | ||
1614 | buffer[1] = 0; | ||
1615 | buffer[2] = 0; | ||
1616 | buffer[3] = 0; | ||
1617 | } | ||
1618 | /* TODO: Write an N PHY Table with ID 15, length 4, | ||
1619 | offset 88, width 16, and data pointer buffer */ | ||
1620 | /* TODO: Read an N PHY Table with ID 15, length 2, | ||
1621 | offset 101, width 16, and data pointer buffer*/ | ||
1622 | /* TODO: Write an N PHY Table with ID 15, length 2, | ||
1623 | offset 85, width 16, and data pointer buffer */ | ||
1624 | /* TODO: Write an N PHY Table with ID 15, length 2, | ||
1625 | offset 93, width 16, and data pointer buffer */ | ||
1626 | length = 11; | ||
1627 | if (dev->phy.rev < 3) | ||
1628 | length -= 2; | ||
1629 | /* TODO: Read an N PHY Table with ID 15, length length, | ||
1630 | offset 96, width 16, and data pointer | ||
1631 | nphy->txiqlocal_bestc */ | ||
1632 | nphy->txiqlocal_coeffsvalid = true; | ||
1633 | /* TODO: Set nphy->txiqlocal_chanspec to | ||
1634 | the current channel */ | ||
1635 | } else { | ||
1636 | length = 11; | ||
1637 | if (dev->phy.rev < 3) | ||
1638 | length -= 2; | ||
1639 | /* TODO: Read an N PHY Table with ID 5, length length, | ||
1640 | offset 96, width 16, and data pointer | ||
1641 | nphy->mphase_txcal_bestcoeffs */ | ||
1642 | } | ||
1643 | |||
1644 | /* TODO: Call N PHY Stop Playback */ | ||
1645 | b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0); | ||
1646 | } | ||
1647 | |||
1648 | /* TODO: Call N PHY TX Cal PHY Cleanup */ | ||
1649 | /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110, | ||
1650 | width 16, and data from save */ | ||
1651 | |||
1652 | if (dev->phy.rev < 2 && (!mphase || nphy->mphase_cal_phase_id == last)) | ||
1653 | b43_nphy_tx_iq_workaround(dev); | ||
1654 | |||
1655 | if (dev->phy.rev >= 4) | ||
1656 | nphy->hang_avoid = avoid; | ||
1657 | |||
1658 | b43_nphy_stay_in_carrier_search(dev, false); | ||
1659 | |||
1660 | return error; | ||
1661 | } | ||
1662 | |||
1437 | /* | 1663 | /* |
1438 | * Init N-PHY | 1664 | * Init N-PHY |
1439 | * http://bcm-v4.sipsolutions.net/802.11/PHY/Init/N | 1665 | * http://bcm-v4.sipsolutions.net/802.11/PHY/Init/N |