aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwl8k.c
diff options
context:
space:
mode:
authorLennert Buytenhek <buytenh@wantstofly.org>2010-01-04 15:58:40 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-01-05 17:13:35 -0500
commit341c97918ab7e84a155ea8b18759425304d213b6 (patch)
tree084dd6619fff8a38ca70f7c243ec0c65575bc752 /drivers/net/wireless/mwl8k.c
parenta2292d83b5dcb7f378956a124854d2b17fa53aa3 (diff)
mwl8k: pass GET_HW_SPEC capability bitmask up the stack
This enables HT association and AMPDU in the receive direction for STA firmware images on hardware that supports it. Signed-off-by: Lennert Buytenhek <buytenh@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/mwl8k.c')
-rw-r--r--drivers/net/wireless/mwl8k.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 57ced0db910a..23a5a3442623 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -1578,6 +1578,68 @@ struct mwl8k_cmd_get_hw_spec_sta {
1578 __le32 total_rxd; 1578 __le32 total_rxd;
1579} __attribute__((packed)); 1579} __attribute__((packed));
1580 1580
1581#define MWL8K_CAP_MAX_AMSDU 0x20000000
1582#define MWL8K_CAP_GREENFIELD 0x08000000
1583#define MWL8K_CAP_AMPDU 0x04000000
1584#define MWL8K_CAP_RX_STBC 0x01000000
1585#define MWL8K_CAP_TX_STBC 0x00800000
1586#define MWL8K_CAP_SHORTGI_40MHZ 0x00400000
1587#define MWL8K_CAP_SHORTGI_20MHZ 0x00200000
1588#define MWL8K_CAP_RX_ANTENNA_MASK 0x000e0000
1589#define MWL8K_CAP_TX_ANTENNA_MASK 0x0001c000
1590#define MWL8K_CAP_DELAY_BA 0x00003000
1591#define MWL8K_CAP_MIMO 0x00000200
1592#define MWL8K_CAP_40MHZ 0x00000100
1593
1594static void mwl8k_set_ht_caps(struct ieee80211_hw *hw, u32 cap)
1595{
1596 struct mwl8k_priv *priv = hw->priv;
1597 int rx_streams;
1598 int tx_streams;
1599
1600 priv->band.ht_cap.ht_supported = 1;
1601
1602 if (cap & MWL8K_CAP_MAX_AMSDU)
1603 priv->band.ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
1604 if (cap & MWL8K_CAP_GREENFIELD)
1605 priv->band.ht_cap.cap |= IEEE80211_HT_CAP_GRN_FLD;
1606 if (cap & MWL8K_CAP_AMPDU) {
1607 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
1608 priv->band.ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
1609 priv->band.ht_cap.ampdu_density =
1610 IEEE80211_HT_MPDU_DENSITY_NONE;
1611 }
1612 if (cap & MWL8K_CAP_RX_STBC)
1613 priv->band.ht_cap.cap |= IEEE80211_HT_CAP_RX_STBC;
1614 if (cap & MWL8K_CAP_TX_STBC)
1615 priv->band.ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
1616 if (cap & MWL8K_CAP_SHORTGI_40MHZ)
1617 priv->band.ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
1618 if (cap & MWL8K_CAP_SHORTGI_20MHZ)
1619 priv->band.ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
1620 if (cap & MWL8K_CAP_DELAY_BA)
1621 priv->band.ht_cap.cap |= IEEE80211_HT_CAP_DELAY_BA;
1622 if (cap & MWL8K_CAP_40MHZ)
1623 priv->band.ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
1624
1625 rx_streams = hweight32(cap & MWL8K_CAP_RX_ANTENNA_MASK);
1626 tx_streams = hweight32(cap & MWL8K_CAP_TX_ANTENNA_MASK);
1627
1628 priv->band.ht_cap.mcs.rx_mask[0] = 0xff;
1629 if (rx_streams >= 2)
1630 priv->band.ht_cap.mcs.rx_mask[1] = 0xff;
1631 if (rx_streams >= 3)
1632 priv->band.ht_cap.mcs.rx_mask[2] = 0xff;
1633 priv->band.ht_cap.mcs.rx_mask[4] = 0x01;
1634 priv->band.ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
1635
1636 if (rx_streams != tx_streams) {
1637 priv->band.ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
1638 priv->band.ht_cap.mcs.tx_params |= (tx_streams - 1) <<
1639 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
1640 }
1641}
1642
1581static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw) 1643static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw)
1582{ 1644{
1583 struct mwl8k_priv *priv = hw->priv; 1645 struct mwl8k_priv *priv = hw->priv;
@@ -1608,6 +1670,8 @@ static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw)
1608 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs); 1670 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
1609 priv->fw_rev = le32_to_cpu(cmd->fw_rev); 1671 priv->fw_rev = le32_to_cpu(cmd->fw_rev);
1610 priv->hw_rev = cmd->hw_rev; 1672 priv->hw_rev = cmd->hw_rev;
1673 if (cmd->caps & cpu_to_le32(MWL8K_CAP_MIMO))
1674 mwl8k_set_ht_caps(hw, le32_to_cpu(cmd->caps));
1611 } 1675 }
1612 1676
1613 kfree(cmd); 1677 kfree(cmd);