aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/p54/p54common.c
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@web.de>2009-01-10 19:14:18 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-01-29 16:00:24 -0500
commit6917f506a03b6bd7389683e8a8e08a1ad977b33e (patch)
tree1a5ed1755ae86666eea587a2c942984f9444932c /drivers/net/wireless/p54/p54common.c
parent83cf1b6edba6bde87c8cf852b182d44b12ae7f88 (diff)
p54: longbow frontend support
This patch adds support for longbow RF chip. Signed-off-by: Christian Lamparter <chunkeey@web.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/p54/p54common.c')
-rw-r--r--drivers/net/wireless/p54/p54common.c141
1 files changed, 104 insertions, 37 deletions
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index ec0d109c0095..9fc0c9efe701 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -651,7 +651,7 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
651 } 651 }
652 652
653 priv->rxhw = synth & PDR_SYNTH_FRONTEND_MASK; 653 priv->rxhw = synth & PDR_SYNTH_FRONTEND_MASK;
654 if (priv->rxhw == 4) 654 if (priv->rxhw == PDR_SYNTH_FRONTEND_XBOW)
655 p54_init_xbow_synth(dev); 655 p54_init_xbow_synth(dev);
656 if (!(synth & PDR_SYNTH_24_GHZ_DISABLED)) 656 if (!(synth & PDR_SYNTH_24_GHZ_DISABLED))
657 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz; 657 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz;
@@ -704,7 +704,14 @@ static int p54_rssi_to_dbm(struct ieee80211_hw *dev, int rssi)
704 struct p54_common *priv = dev->priv; 704 struct p54_common *priv = dev->priv;
705 int band = dev->conf.channel->band; 705 int band = dev->conf.channel->band;
706 706
707 return ((rssi * priv->rssical_db[band].mul) / 64 + 707 if (priv->rxhw != PDR_SYNTH_FRONTEND_LONGBOW)
708 return ((rssi * priv->rssical_db[band].mul) / 64 +
709 priv->rssical_db[band].add) / 4;
710 else
711 /*
712 * TODO: find the correct formula
713 */
714 return ((rssi * priv->rssical_db[band].mul) / 64 +
708 priv->rssical_db[band].add) / 4; 715 priv->rssical_db[band].add) / 4;
709} 716}
710 717
@@ -1612,8 +1619,13 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
1612 memset(txhdr->durations, 0, sizeof(txhdr->durations)); 1619 memset(txhdr->durations, 0, sizeof(txhdr->durations));
1613 txhdr->tx_antenna = ((info->antenna_sel_tx == 0) ? 1620 txhdr->tx_antenna = ((info->antenna_sel_tx == 0) ?
1614 2 : info->antenna_sel_tx - 1) & priv->tx_diversity_mask; 1621 2 : info->antenna_sel_tx - 1) & priv->tx_diversity_mask;
1615 txhdr->output_power = priv->output_power; 1622 if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
1616 txhdr->cts_rate = cts_rate; 1623 txhdr->longbow.cts_rate = cts_rate;
1624 txhdr->longbow.output_power = cpu_to_le16(priv->output_power);
1625 } else {
1626 txhdr->normal.output_power = priv->output_power;
1627 txhdr->normal.cts_rate = cts_rate;
1628 }
1617 if (padding) 1629 if (padding)
1618 txhdr->align[0] = padding; 1630 txhdr->align[0] = padding;
1619 1631
@@ -1715,47 +1727,77 @@ static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell)
1715{ 1727{
1716 struct p54_common *priv = dev->priv; 1728 struct p54_common *priv = dev->priv;
1717 struct sk_buff *skb; 1729 struct sk_buff *skb;
1718 struct p54_scan *chan; 1730 struct p54_hdr *hdr;
1731 struct p54_scan_head *head;
1732 struct p54_iq_autocal_entry *iq_autocal;
1733 union p54_scan_body_union *body;
1734 struct p54_scan_tail_rate *rate;
1735 struct pda_rssi_cal_entry *rssi;
1719 unsigned int i; 1736 unsigned int i;
1720 void *entry; 1737 void *entry;
1721 int band = dev->conf.channel->band; 1738 int band = dev->conf.channel->band;
1722 __le16 freq = cpu_to_le16(dev->conf.channel->center_freq); 1739 __le16 freq = cpu_to_le16(dev->conf.channel->center_freq);
1723 1740
1724 skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*chan), 1741 skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*head) +
1742 2 + sizeof(*iq_autocal) + sizeof(*body) +
1743 sizeof(*rate) + 2 * sizeof(*rssi),
1725 P54_CONTROL_TYPE_SCAN, GFP_ATOMIC); 1744 P54_CONTROL_TYPE_SCAN, GFP_ATOMIC);
1726 if (!skb) 1745 if (!skb)
1727 return -ENOMEM; 1746 return -ENOMEM;
1728 1747
1729 chan = (struct p54_scan *) skb_put(skb, sizeof(*chan)); 1748 head = (struct p54_scan_head *) skb_put(skb, sizeof(*head));
1730 memset(chan->scan_params, 0, sizeof(chan->scan_params)); 1749 memset(head->scan_params, 0, sizeof(head->scan_params));
1731 chan->mode = cpu_to_le16(mode); 1750 head->mode = cpu_to_le16(mode);
1732 chan->dwell = cpu_to_le16(dwell); 1751 head->dwell = cpu_to_le16(dwell);
1752 head->freq = freq;
1733 1753
1754 if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
1755 __le16 *pa_power_points = (__le16 *) skb_put(skb, 2);
1756 *pa_power_points = cpu_to_le16(0x0c);
1757 }
1758
1759 iq_autocal = (void *) skb_put(skb, sizeof(*iq_autocal));
1734 for (i = 0; i < priv->iq_autocal_len; i++) { 1760 for (i = 0; i < priv->iq_autocal_len; i++) {
1735 if (priv->iq_autocal[i].freq != freq) 1761 if (priv->iq_autocal[i].freq != freq)
1736 continue; 1762 continue;
1737 1763
1738 memcpy(&chan->iq_autocal, &priv->iq_autocal[i], 1764 memcpy(iq_autocal, &priv->iq_autocal[i].params,
1739 sizeof(*priv->iq_autocal)); 1765 sizeof(struct p54_iq_autocal_entry));
1740 break; 1766 break;
1741 } 1767 }
1742 if (i == priv->iq_autocal_len) 1768 if (i == priv->iq_autocal_len)
1743 goto err; 1769 goto err;
1744 1770
1771 if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW)
1772 body = (void *) skb_put(skb, sizeof(body->longbow));
1773 else
1774 body = (void *) skb_put(skb, sizeof(body->normal));
1775
1745 for (i = 0; i < priv->output_limit->entries; i++) { 1776 for (i = 0; i < priv->output_limit->entries; i++) {
1746 struct pda_channel_output_limit *limits;
1747 __le16 *entry_freq = (void *) (priv->output_limit->data + 1777 __le16 *entry_freq = (void *) (priv->output_limit->data +
1748 priv->output_limit->entry_size * i); 1778 priv->output_limit->entry_size * i);
1749 1779
1750 if (*entry_freq != freq) 1780 if (*entry_freq != freq)
1751 continue; 1781 continue;
1752 1782
1753 limits = (void *) entry_freq; 1783 if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
1754 chan->val_barker = 0x38; 1784 memcpy(&body->longbow.power_limits,
1755 chan->val_bpsk = chan->dup_bpsk = limits->val_bpsk; 1785 (void *) entry_freq + sizeof(__le16),
1756 chan->val_qpsk = chan->dup_qpsk = limits->val_qpsk; 1786 priv->output_limit->entry_size);
1757 chan->val_16qam = chan->dup_16qam = limits->val_16qam; 1787 } else {
1758 chan->val_64qam = chan->dup_64qam = limits->val_64qam; 1788 struct pda_channel_output_limit *limits =
1789 (void *) entry_freq;
1790
1791 body->normal.val_barker = 0x38;
1792 body->normal.val_bpsk = body->normal.dup_bpsk =
1793 limits->val_bpsk;
1794 body->normal.val_qpsk = body->normal.dup_qpsk =
1795 limits->val_qpsk;
1796 body->normal.val_16qam = body->normal.dup_16qam =
1797 limits->val_16qam;
1798 body->normal.val_64qam = body->normal.dup_64qam =
1799 limits->val_64qam;
1800 }
1759 break; 1801 break;
1760 } 1802 }
1761 if (i == priv->output_limit->entries) 1803 if (i == priv->output_limit->entries)
@@ -1763,34 +1805,59 @@ static int p54_scan(struct ieee80211_hw *dev, u16 mode, u16 dwell)
1763 1805
1764 entry = (void *)(priv->curve_data->data + priv->curve_data->offset); 1806 entry = (void *)(priv->curve_data->data + priv->curve_data->offset);
1765 for (i = 0; i < priv->curve_data->entries; i++) { 1807 for (i = 0; i < priv->curve_data->entries; i++) {
1766 struct pda_pa_curve_data *curve_data;
1767 if (*((__le16 *)entry) != freq) { 1808 if (*((__le16 *)entry) != freq) {
1768 entry += priv->curve_data->entry_size; 1809 entry += priv->curve_data->entry_size;
1769 continue; 1810 continue;
1770 } 1811 }
1771 1812
1772 entry += sizeof(__le16); 1813 if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
1773 chan->pa_points_per_curve = 8; 1814 memcpy(&body->longbow.curve_data,
1774 memset(chan->curve_data, 0, sizeof(*chan->curve_data)); 1815 (void *) entry + sizeof(__le16),
1775 curve_data = (void *) priv->curve_data->data; 1816 priv->curve_data->entry_size);
1776 1817 } else {
1777 memcpy(chan->curve_data, entry, 1818 struct p54_scan_body *chan = &body->normal;
1778 sizeof(struct p54_pa_curve_data_sample) * 1819 struct pda_pa_curve_data *curve_data =
1779 min_t(u8, 8, curve_data->points_per_channel)); 1820 (void *) priv->curve_data->data;
1821
1822 entry += sizeof(__le16);
1823 chan->pa_points_per_curve = 8;
1824 memset(chan->curve_data, 0, sizeof(*chan->curve_data));
1825 memcpy(chan->curve_data, entry,
1826 sizeof(struct p54_pa_curve_data_sample) *
1827 min((u8)8, curve_data->points_per_channel));
1828 }
1780 break; 1829 break;
1781 } 1830 }
1782 if (i == priv->curve_data->entries) 1831 if (i == priv->curve_data->entries)
1783 goto err; 1832 goto err;
1784 1833
1785 if (priv->fw_var < 0x500) { 1834 if ((priv->fw_var >= 0x500) && (priv->fw_var < 0x509)) {
1786 chan->v1_rssi.mul = cpu_to_le16(priv->rssical_db[band].mul); 1835 rate = (void *) skb_put(skb, sizeof(*rate));
1787 chan->v1_rssi.add = cpu_to_le16(priv->rssical_db[band].add); 1836 rate->basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
1788 } else { 1837 for (i = 0; i < sizeof(rate->rts_rates); i++)
1789 chan->v2.rssi.mul = cpu_to_le16(priv->rssical_db[band].mul); 1838 rate->rts_rates[i] = i;
1790 chan->v2.rssi.add = cpu_to_le16(priv->rssical_db[band].add);
1791 chan->v2.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
1792 memset(chan->v2.rts_rates, 0, 8);
1793 } 1839 }
1840
1841 rssi = (struct pda_rssi_cal_entry *) skb_put(skb, sizeof(*rssi));
1842 rssi->mul = cpu_to_le16(priv->rssical_db[band].mul);
1843 rssi->add = cpu_to_le16(priv->rssical_db[band].add);
1844 if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
1845 /* Longbow frontend needs ever more */
1846 rssi = (void *) skb_put(skb, sizeof(*rssi));
1847 rssi->mul = cpu_to_le16(priv->rssical_db[band].longbow_unkn);
1848 rssi->add = cpu_to_le16(priv->rssical_db[band].longbow_unk2);
1849 }
1850
1851 if (priv->fw_var >= 0x509) {
1852 rate = (void *) skb_put(skb, sizeof(*rate));
1853 rate->basic_rate_mask = cpu_to_le32(priv->basic_rate_mask);
1854 for (i = 0; i < sizeof(rate->rts_rates); i++)
1855 rate->rts_rates[i] = i;
1856 }
1857
1858 hdr = (struct p54_hdr *) skb->data;
1859 hdr->len = cpu_to_le16(skb->len - sizeof(*hdr));
1860
1794 priv->tx(dev, skb); 1861 priv->tx(dev, skb);
1795 return 0; 1862 return 0;
1796 1863