aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-core.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c531
1 files changed, 0 insertions, 531 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index c93368083e1a..776713c6a7ff 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -100,35 +100,6 @@ out:
100} 100}
101EXPORT_SYMBOL(iwl_alloc_all); 101EXPORT_SYMBOL(iwl_alloc_all);
102 102
103/*
104 * QoS support
105*/
106static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
107{
108 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
109 return;
110
111 if (!ctx->is_active)
112 return;
113
114 ctx->qos_data.def_qos_parm.qos_flags = 0;
115
116 if (ctx->qos_data.qos_active)
117 ctx->qos_data.def_qos_parm.qos_flags |=
118 QOS_PARAM_FLG_UPDATE_EDCA_MSK;
119
120 if (ctx->ht.enabled)
121 ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
122
123 IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
124 ctx->qos_data.qos_active,
125 ctx->qos_data.def_qos_parm.qos_flags);
126
127 iwl_send_cmd_pdu_async(priv, ctx->qos_cmd,
128 sizeof(struct iwl_qosparam_cmd),
129 &ctx->qos_data.def_qos_parm, NULL);
130}
131
132#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ 103#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
133#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ 104#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */
134static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, 105static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
@@ -1456,310 +1427,6 @@ int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw)
1456} 1427}
1457EXPORT_SYMBOL_GPL(iwl_mac_tx_last_beacon); 1428EXPORT_SYMBOL_GPL(iwl_mac_tx_last_beacon);
1458 1429
1459static void iwl_ht_conf(struct iwl_priv *priv,
1460 struct ieee80211_vif *vif)
1461{
1462 struct iwl_ht_config *ht_conf = &priv->current_ht_config;
1463 struct ieee80211_sta *sta;
1464 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
1465 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
1466
1467 IWL_DEBUG_MAC80211(priv, "enter:\n");
1468
1469 if (!ctx->ht.enabled)
1470 return;
1471
1472 ctx->ht.protection =
1473 bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
1474 ctx->ht.non_gf_sta_present =
1475 !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
1476
1477 ht_conf->single_chain_sufficient = false;
1478
1479 switch (vif->type) {
1480 case NL80211_IFTYPE_STATION:
1481 rcu_read_lock();
1482 sta = ieee80211_find_sta(vif, bss_conf->bssid);
1483 if (sta) {
1484 struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
1485 int maxstreams;
1486
1487 maxstreams = (ht_cap->mcs.tx_params &
1488 IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK)
1489 >> IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
1490 maxstreams += 1;
1491
1492 if ((ht_cap->mcs.rx_mask[1] == 0) &&
1493 (ht_cap->mcs.rx_mask[2] == 0))
1494 ht_conf->single_chain_sufficient = true;
1495 if (maxstreams <= 1)
1496 ht_conf->single_chain_sufficient = true;
1497 } else {
1498 /*
1499 * If at all, this can only happen through a race
1500 * when the AP disconnects us while we're still
1501 * setting up the connection, in that case mac80211
1502 * will soon tell us about that.
1503 */
1504 ht_conf->single_chain_sufficient = true;
1505 }
1506 rcu_read_unlock();
1507 break;
1508 case NL80211_IFTYPE_ADHOC:
1509 ht_conf->single_chain_sufficient = true;
1510 break;
1511 default:
1512 break;
1513 }
1514
1515 IWL_DEBUG_MAC80211(priv, "leave\n");
1516}
1517
1518static inline void iwl_set_no_assoc(struct iwl_priv *priv,
1519 struct ieee80211_vif *vif)
1520{
1521 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
1522
1523 iwl_led_disassociate(priv);
1524 /*
1525 * inform the ucode that there is no longer an
1526 * association and that no more packets should be
1527 * sent
1528 */
1529 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1530 ctx->staging.assoc_id = 0;
1531 iwlcore_commit_rxon(priv, ctx);
1532}
1533
1534static void iwlcore_beacon_update(struct ieee80211_hw *hw,
1535 struct ieee80211_vif *vif)
1536{
1537 struct iwl_priv *priv = hw->priv;
1538 unsigned long flags;
1539 __le64 timestamp;
1540 struct sk_buff *skb = ieee80211_beacon_get(hw, vif);
1541
1542 if (!skb)
1543 return;
1544
1545 IWL_DEBUG_ASSOC(priv, "enter\n");
1546
1547 lockdep_assert_held(&priv->mutex);
1548
1549 if (!priv->beacon_ctx) {
1550 IWL_ERR(priv, "update beacon but no beacon context!\n");
1551 dev_kfree_skb(skb);
1552 return;
1553 }
1554
1555 spin_lock_irqsave(&priv->lock, flags);
1556
1557 if (priv->beacon_skb)
1558 dev_kfree_skb(priv->beacon_skb);
1559
1560 priv->beacon_skb = skb;
1561
1562 timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
1563 priv->timestamp = le64_to_cpu(timestamp);
1564
1565 IWL_DEBUG_ASSOC(priv, "leave\n");
1566
1567 spin_unlock_irqrestore(&priv->lock, flags);
1568
1569 if (!iwl_is_ready_rf(priv)) {
1570 IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
1571 return;
1572 }
1573
1574 priv->cfg->ops->lib->post_associate(priv, priv->beacon_ctx->vif);
1575}
1576
1577void iwl_bss_info_changed(struct ieee80211_hw *hw,
1578 struct ieee80211_vif *vif,
1579 struct ieee80211_bss_conf *bss_conf,
1580 u32 changes)
1581{
1582 struct iwl_priv *priv = hw->priv;
1583 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
1584 int ret;
1585
1586 IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
1587
1588 if (!iwl_is_alive(priv))
1589 return;
1590
1591 mutex_lock(&priv->mutex);
1592
1593 if (changes & (BSS_CHANGED_BSSID | BSS_CHANGED_ASSOC |
1594 BSS_CHANGED_BEACON_ENABLED)) {
1595 /*
1596 * If there is currently a HW scan going on in the
1597 * background then we need to cancel it else the RXON
1598 * below in post_associate or set_no_assoc can fail.
1599 */
1600 if (iwl_scan_cancel_timeout(priv, 200)) {
1601 IWL_WARN(priv, "Can not cancel scan\n");
1602 goto out;
1603 }
1604 }
1605
1606 if (changes & BSS_CHANGED_QOS) {
1607 unsigned long flags;
1608
1609 spin_lock_irqsave(&priv->lock, flags);
1610 ctx->qos_data.qos_active = bss_conf->qos;
1611 iwl_update_qos(priv, ctx);
1612 spin_unlock_irqrestore(&priv->lock, flags);
1613 }
1614
1615 if (changes & BSS_CHANGED_BEACON_ENABLED) {
1616 /*
1617 * the add_interface code must make sure we only ever
1618 * have a single interface that could be beaconing at
1619 * any time.
1620 */
1621 if (vif->bss_conf.enable_beacon)
1622 priv->beacon_ctx = ctx;
1623 else
1624 priv->beacon_ctx = NULL;
1625 }
1626
1627 if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) {
1628 dev_kfree_skb(priv->beacon_skb);
1629 priv->beacon_skb = ieee80211_beacon_get(hw, vif);
1630 }
1631
1632 if (changes & BSS_CHANGED_BEACON_INT && vif->type == NL80211_IFTYPE_AP)
1633 iwl_send_rxon_timing(priv, ctx);
1634
1635 if (changes & BSS_CHANGED_BSSID) {
1636 IWL_DEBUG_MAC80211(priv, "BSSID %pM\n", bss_conf->bssid);
1637
1638 /* mac80211 only sets assoc when in STATION mode */
1639 if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) {
1640 memcpy(ctx->staging.bssid_addr,
1641 bss_conf->bssid, ETH_ALEN);
1642
1643 /* currently needed in a few places */
1644 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
1645 } else {
1646 ctx->staging.filter_flags &=
1647 ~RXON_FILTER_ASSOC_MSK;
1648 }
1649
1650 }
1651
1652 /*
1653 * This needs to be after setting the BSSID in case
1654 * mac80211 decides to do both changes at once because
1655 * it will invoke post_associate.
1656 */
1657 if (vif->type == NL80211_IFTYPE_ADHOC && changes & BSS_CHANGED_BEACON)
1658 iwlcore_beacon_update(hw, vif);
1659
1660 if (changes & BSS_CHANGED_ERP_PREAMBLE) {
1661 IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
1662 bss_conf->use_short_preamble);
1663 if (bss_conf->use_short_preamble)
1664 ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
1665 else
1666 ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
1667 }
1668
1669 if (changes & BSS_CHANGED_ERP_CTS_PROT) {
1670 IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot);
1671 if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
1672 ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
1673 else
1674 ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
1675 if (bss_conf->use_cts_prot)
1676 ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
1677 else
1678 ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
1679 }
1680
1681 if (changes & BSS_CHANGED_BASIC_RATES) {
1682 /* XXX use this information
1683 *
1684 * To do that, remove code from iwl_set_rate() and put something
1685 * like this here:
1686 *
1687 if (A-band)
1688 ctx->staging.ofdm_basic_rates =
1689 bss_conf->basic_rates;
1690 else
1691 ctx->staging.ofdm_basic_rates =
1692 bss_conf->basic_rates >> 4;
1693 ctx->staging.cck_basic_rates =
1694 bss_conf->basic_rates & 0xF;
1695 */
1696 }
1697
1698 if (changes & BSS_CHANGED_HT) {
1699 iwl_ht_conf(priv, vif);
1700
1701 if (priv->cfg->ops->hcmd->set_rxon_chain)
1702 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
1703 }
1704
1705 if (changes & BSS_CHANGED_ASSOC) {
1706 IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
1707 if (bss_conf->assoc) {
1708 priv->timestamp = bss_conf->timestamp;
1709
1710 iwl_led_associate(priv);
1711
1712 if (!iwl_is_rfkill(priv))
1713 priv->cfg->ops->lib->post_associate(priv, vif);
1714 } else
1715 iwl_set_no_assoc(priv, vif);
1716 }
1717
1718 if (changes && iwl_is_associated_ctx(ctx) && bss_conf->aid) {
1719 IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n",
1720 changes);
1721 ret = iwl_send_rxon_assoc(priv, ctx);
1722 if (!ret) {
1723 /* Sync active_rxon with latest change. */
1724 memcpy((void *)&ctx->active,
1725 &ctx->staging,
1726 sizeof(struct iwl_rxon_cmd));
1727 }
1728 }
1729
1730 if (changes & BSS_CHANGED_BEACON_ENABLED) {
1731 if (vif->bss_conf.enable_beacon) {
1732 memcpy(ctx->staging.bssid_addr,
1733 bss_conf->bssid, ETH_ALEN);
1734 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
1735 iwl_led_associate(priv);
1736 iwlcore_config_ap(priv, vif);
1737 } else
1738 iwl_set_no_assoc(priv, vif);
1739 }
1740
1741 if (changes & BSS_CHANGED_IBSS) {
1742 ret = priv->cfg->ops->lib->manage_ibss_station(priv, vif,
1743 bss_conf->ibss_joined);
1744 if (ret)
1745 IWL_ERR(priv, "failed to %s IBSS station %pM\n",
1746 bss_conf->ibss_joined ? "add" : "remove",
1747 bss_conf->bssid);
1748 }
1749
1750 if (changes & BSS_CHANGED_IDLE &&
1751 priv->cfg->ops->hcmd->set_pan_params) {
1752 if (priv->cfg->ops->hcmd->set_pan_params(priv))
1753 IWL_ERR(priv, "failed to update PAN params\n");
1754 }
1755
1756out:
1757 mutex_unlock(&priv->mutex);
1758
1759 IWL_DEBUG_MAC80211(priv, "leave\n");
1760}
1761EXPORT_SYMBOL(iwl_bss_info_changed);
1762
1763static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif) 1430static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif)
1764{ 1431{
1765 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); 1432 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
@@ -1899,204 +1566,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
1899} 1566}
1900EXPORT_SYMBOL(iwl_mac_remove_interface); 1567EXPORT_SYMBOL(iwl_mac_remove_interface);
1901 1568
1902/**
1903 * iwl_mac_config - mac80211 config callback
1904 */
1905int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
1906{
1907 struct iwl_priv *priv = hw->priv;
1908 const struct iwl_channel_info *ch_info;
1909 struct ieee80211_conf *conf = &hw->conf;
1910 struct ieee80211_channel *channel = conf->channel;
1911 struct iwl_ht_config *ht_conf = &priv->current_ht_config;
1912 struct iwl_rxon_context *ctx;
1913 unsigned long flags = 0;
1914 int ret = 0;
1915 u16 ch;
1916 int scan_active = 0;
1917
1918 mutex_lock(&priv->mutex);
1919
1920 IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
1921 channel->hw_value, changed);
1922
1923 if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
1924 test_bit(STATUS_SCANNING, &priv->status))) {
1925 scan_active = 1;
1926 IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
1927 }
1928
1929 if (changed & (IEEE80211_CONF_CHANGE_SMPS |
1930 IEEE80211_CONF_CHANGE_CHANNEL)) {
1931 /* mac80211 uses static for non-HT which is what we want */
1932 priv->current_ht_config.smps = conf->smps_mode;
1933
1934 /*
1935 * Recalculate chain counts.
1936 *
1937 * If monitor mode is enabled then mac80211 will
1938 * set up the SM PS mode to OFF if an HT channel is
1939 * configured.
1940 */
1941 if (priv->cfg->ops->hcmd->set_rxon_chain)
1942 for_each_context(priv, ctx)
1943 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
1944 }
1945
1946 /* during scanning mac80211 will delay channel setting until
1947 * scan finish with changed = 0
1948 */
1949 if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
1950 if (scan_active)
1951 goto set_ch_out;
1952
1953 ch = channel->hw_value;
1954 ch_info = iwl_get_channel_info(priv, channel->band, ch);
1955 if (!is_channel_valid(ch_info)) {
1956 IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
1957 ret = -EINVAL;
1958 goto set_ch_out;
1959 }
1960
1961 spin_lock_irqsave(&priv->lock, flags);
1962
1963 for_each_context(priv, ctx) {
1964 /* Configure HT40 channels */
1965 ctx->ht.enabled = conf_is_ht(conf);
1966 if (ctx->ht.enabled) {
1967 if (conf_is_ht40_minus(conf)) {
1968 ctx->ht.extension_chan_offset =
1969 IEEE80211_HT_PARAM_CHA_SEC_BELOW;
1970 ctx->ht.is_40mhz = true;
1971 } else if (conf_is_ht40_plus(conf)) {
1972 ctx->ht.extension_chan_offset =
1973 IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
1974 ctx->ht.is_40mhz = true;
1975 } else {
1976 ctx->ht.extension_chan_offset =
1977 IEEE80211_HT_PARAM_CHA_SEC_NONE;
1978 ctx->ht.is_40mhz = false;
1979 }
1980 } else
1981 ctx->ht.is_40mhz = false;
1982
1983 /*
1984 * Default to no protection. Protection mode will
1985 * later be set from BSS config in iwl_ht_conf
1986 */
1987 ctx->ht.protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
1988
1989 /* if we are switching from ht to 2.4 clear flags
1990 * from any ht related info since 2.4 does not
1991 * support ht */
1992 if ((le16_to_cpu(ctx->staging.channel) != ch))
1993 ctx->staging.flags = 0;
1994
1995 iwl_set_rxon_channel(priv, channel, ctx);
1996 iwl_set_rxon_ht(priv, ht_conf);
1997
1998 iwl_set_flags_for_band(priv, ctx, channel->band,
1999 ctx->vif);
2000 }
2001
2002 spin_unlock_irqrestore(&priv->lock, flags);
2003
2004 if (priv->cfg->ops->lib->update_bcast_stations)
2005 ret = priv->cfg->ops->lib->update_bcast_stations(priv);
2006
2007 set_ch_out:
2008 /* The list of supported rates and rate mask can be different
2009 * for each band; since the band may have changed, reset
2010 * the rate mask to what mac80211 lists */
2011 iwl_set_rate(priv);
2012 }
2013
2014 if (changed & (IEEE80211_CONF_CHANGE_PS |
2015 IEEE80211_CONF_CHANGE_IDLE)) {
2016 ret = iwl_power_update_mode(priv, false);
2017 if (ret)
2018 IWL_DEBUG_MAC80211(priv, "Error setting sleep level\n");
2019 }
2020
2021 if (changed & IEEE80211_CONF_CHANGE_POWER) {
2022 IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
2023 priv->tx_power_user_lmt, conf->power_level);
2024
2025 ret = iwl_set_tx_power(priv, conf->power_level, false);
2026 if (ret)
2027 IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
2028 }
2029
2030 if (!iwl_is_ready(priv)) {
2031 IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
2032 goto out;
2033 }
2034
2035 if (scan_active)
2036 goto out;
2037
2038 for_each_context(priv, ctx) {
2039 if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)))
2040 iwlcore_commit_rxon(priv, ctx);
2041 else
2042 IWL_DEBUG_INFO(priv,
2043 "Not re-sending same RXON configuration.\n");
2044 }
2045
2046out:
2047 IWL_DEBUG_MAC80211(priv, "leave\n");
2048 mutex_unlock(&priv->mutex);
2049 return ret;
2050}
2051EXPORT_SYMBOL(iwl_mac_config);
2052
2053void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
2054{
2055 struct iwl_priv *priv = hw->priv;
2056 unsigned long flags;
2057 /* IBSS can only be the IWL_RXON_CTX_BSS context */
2058 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
2059
2060 mutex_lock(&priv->mutex);
2061 IWL_DEBUG_MAC80211(priv, "enter\n");
2062
2063 spin_lock_irqsave(&priv->lock, flags);
2064 memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_config));
2065 spin_unlock_irqrestore(&priv->lock, flags);
2066
2067 spin_lock_irqsave(&priv->lock, flags);
2068
2069 /* new association get rid of ibss beacon skb */
2070 if (priv->beacon_skb)
2071 dev_kfree_skb(priv->beacon_skb);
2072
2073 priv->beacon_skb = NULL;
2074
2075 priv->timestamp = 0;
2076
2077 spin_unlock_irqrestore(&priv->lock, flags);
2078
2079 iwl_scan_cancel_timeout(priv, 100);
2080 if (!iwl_is_ready_rf(priv)) {
2081 IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
2082 mutex_unlock(&priv->mutex);
2083 return;
2084 }
2085
2086 /* we are restarting association process
2087 * clear RXON_FILTER_ASSOC_MSK bit
2088 */
2089 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2090 iwlcore_commit_rxon(priv, ctx);
2091
2092 iwl_set_rate(priv);
2093
2094 mutex_unlock(&priv->mutex);
2095
2096 IWL_DEBUG_MAC80211(priv, "leave\n");
2097}
2098EXPORT_SYMBOL(iwl_mac_reset_tsf);
2099
2100int iwl_alloc_txq_mem(struct iwl_priv *priv) 1569int iwl_alloc_txq_mem(struct iwl_priv *priv)
2101{ 1570{
2102 if (!priv->txq) 1571 if (!priv->txq)