aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2010-01-15 10:10:48 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-01-15 17:05:42 -0500
commitfb43b8e23519f853f142202bb341c21382f39070 (patch)
tree76e64cf67f6140848dbf72b6de5c3fcda91b0b7d /drivers
parente9762492f5c7176660ed030e9dd816b3208def12 (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.c226
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 */
1438static 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, &params[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