Loading drivers/net/wireless/ath9k/main.c +10 −2 Original line number Diff line number Diff line Loading @@ -1067,8 +1067,16 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; tx_status->flags &= ~ATH_TX_BAR; } if (tx_status->flags) if (tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY)) { if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) { /* Frame was not ACKed, but an ACK was expected */ tx_info->status.excessive_retries = 1; } } else { /* Frame was ACKed */ tx_info->flags |= IEEE80211_TX_STAT_ACK; } tx_info->status.retry_count = tx_status->retries; Loading drivers/net/wireless/ath9k/xmit.c +2 −2 Original line number Diff line number Diff line Loading @@ -357,9 +357,9 @@ static int ath_tx_prepare(struct ath_softc *sc, txctl->flags = ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */ if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) tx_info->flags |= ATH9K_TXDESC_NOACK; txctl->flags |= ATH9K_TXDESC_NOACK; if (tx_info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) tx_info->flags |= ATH9K_TXDESC_RTSENA; txctl->flags |= ATH9K_TXDESC_RTSENA; /* * Setup for rate calculations. Loading drivers/net/wireless/iwlwifi/iwl-agn-rs.c +2 −1 Original line number Diff line number Diff line Loading @@ -1153,7 +1153,8 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv, !sta->ht_info.ht_supported) return -1; if (priv->current_ht_config.tx_mimo_ps_mode == IWL_MIMO_PS_STATIC) if (((sta->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS) >> 2) == IWL_MIMO_PS_STATIC) return -1; /* Need both Tx chains/antennas to support MIMO */ Loading drivers/net/wireless/iwlwifi/iwl-agn.c +15 −12 Original line number Diff line number Diff line Loading @@ -181,14 +181,14 @@ static int iwl4965_check_rxon_cmd(struct iwl_rxon_cmd *rxon) } /** * iwl4965_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed * iwl_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed * @priv: staging_rxon is compared to active_rxon * * If the RXON structure is changing enough to require a new tune, * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required. */ static int iwl4965_full_rxon_required(struct iwl_priv *priv) static int iwl_full_rxon_required(struct iwl_priv *priv) { /* These items are only settable from the full RXON command */ Loading @@ -207,7 +207,6 @@ static int iwl4965_full_rxon_required(struct iwl_priv *priv) priv->active_rxon.ofdm_ht_single_stream_basic_rates) || (priv->staging_rxon.ofdm_ht_dual_stream_basic_rates != priv->active_rxon.ofdm_ht_dual_stream_basic_rates) || (priv->staging_rxon.rx_chain != priv->active_rxon.rx_chain) || (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id)) return 1; Loading Loading @@ -263,7 +262,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) /* If we don't need to send a full RXON, we can use * iwl4965_rxon_assoc_cmd which is used to reconfigure filter * and other flags for the current radio configuration. */ if (!iwl4965_full_rxon_required(priv)) { if (!iwl_full_rxon_required(priv)) { ret = iwl_send_rxon_assoc(priv); if (ret) { IWL_ERROR("Error setting RXON_ASSOC (%d)\n", ret); Loading Loading @@ -587,8 +586,6 @@ static void iwl4965_ht_conf(struct iwl_priv *priv, iwl_conf->supported_chan_width = 0; } iwl_conf->tx_mimo_ps_mode = (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2); memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16); iwl_conf->control_channel = ht_bss_conf->primary_channel; Loading Loading @@ -2190,6 +2187,9 @@ static void __iwl4965_down(struct iwl_priv *priv) udelay(5); /* FIXME: apm_ops.suspend(priv) */ if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status)) priv->cfg->ops->lib->apm_ops.stop(priv); else priv->cfg->ops->lib->apm_ops.reset(priv); priv->cfg->ops->lib->free_shared_mem(priv); Loading Loading @@ -3588,7 +3588,7 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk priv->assoc_id = 0; timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; priv->timestamp = le64_to_cpu(timestamp) + (priv->beacon_int * 1000); priv->timestamp = le64_to_cpu(timestamp); IWL_DEBUG_MAC80211("leave\n"); spin_unlock_irqrestore(&priv->lock, flags); Loading Loading @@ -4372,14 +4372,17 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) iwl_dbgfs_unregister(priv); sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group); /* ieee80211_unregister_hw call wil cause iwl4965_mac_stop to * to be called and iwl4965_down since we are removing the device * we need to set STATUS_EXIT_PENDING bit. */ set_bit(STATUS_EXIT_PENDING, &priv->status); if (priv->mac80211_registered) { ieee80211_unregister_hw(priv->hw); priv->mac80211_registered = 0; } set_bit(STATUS_EXIT_PENDING, &priv->status); } else { iwl4965_down(priv); } /* make sure we flush any pending irq or * tasklet for the driver Loading drivers/net/wireless/iwlwifi/iwl-core.c +46 −31 Original line number Diff line number Diff line Loading @@ -592,12 +592,11 @@ static void iwlcore_free_geos(struct iwl_priv *priv) clear_bit(STATUS_GEO_CONFIGURED, &priv->status); } static u8 is_single_rx_stream(struct iwl_priv *priv) static bool is_single_rx_stream(struct iwl_priv *priv) { return !priv->current_ht_config.is_ht || ((priv->current_ht_config.supp_mcs_set[1] == 0) && (priv->current_ht_config.supp_mcs_set[2] == 0)) || priv->ps_mode == IWL_MIMO_PS_STATIC; (priv->current_ht_config.supp_mcs_set[2] == 0)); } static u8 iwl_is_channel_extension(struct iwl_priv *priv, Loading Loading @@ -704,33 +703,39 @@ EXPORT_SYMBOL(iwl_set_rxon_ht); * MIMO (dual stream) requires at least 2, but works better with 3. * This does not determine *which* chains to use, just how many. */ static int iwlcore_get_rx_chain_counter(struct iwl_priv *priv, u8 *idle_state, u8 *rx_state) static int iwl_get_active_rx_chain_count(struct iwl_priv *priv) { u8 is_single = is_single_rx_stream(priv); u8 is_cam = test_bit(STATUS_POWER_PMI, &priv->status) ? 0 : 1; bool is_single = is_single_rx_stream(priv); bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); /* # of Rx chains to use when expecting MIMO. */ if (is_single || (!is_cam && (priv->ps_mode == IWL_MIMO_PS_STATIC))) *rx_state = 2; return 2; else *rx_state = 3; return 3; } static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt) { int idle_cnt; bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); /* # Rx chains when idling and maybe trying to save power */ switch (priv->ps_mode) { case IWL_MIMO_PS_STATIC: case IWL_MIMO_PS_DYNAMIC: *idle_state = (is_cam) ? 2 : 1; idle_cnt = (is_cam) ? 2 : 1; break; case IWL_MIMO_PS_NONE: *idle_state = (is_cam) ? *rx_state : 1; idle_cnt = (is_cam) ? active_cnt : 1; break; case IWL_MIMO_PS_INVALID: default: *idle_state = 1; IWL_ERROR("invalide mimo ps mode %d\n", priv->ps_mode); WARN_ON(1); idle_cnt = -1; break; } return 0; return idle_cnt; } /** Loading @@ -741,34 +746,44 @@ static int iwlcore_get_rx_chain_counter(struct iwl_priv *priv, */ void iwl_set_rxon_chain(struct iwl_priv *priv) { u8 is_single = is_single_rx_stream(priv); u8 idle_state, rx_state; priv->staging_rxon.rx_chain = 0; rx_state = idle_state = 3; bool is_single = is_single_rx_stream(priv); bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); u8 idle_rx_cnt, active_rx_cnt; u16 rx_chain; /* Tell uCode which antennas are actually connected. * Before first association, we assume all antennas are connected. * Just after first association, iwl_chain_noise_calibration() * checks which antennas actually *are* connected. */ priv->staging_rxon.rx_chain |= cpu_to_le16(priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS); rx_chain = priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS; /* How many receivers should we use? */ iwlcore_get_rx_chain_counter(priv, &idle_state, &rx_state); priv->staging_rxon.rx_chain |= cpu_to_le16(rx_state << RXON_RX_CHAIN_MIMO_CNT_POS); priv->staging_rxon.rx_chain |= cpu_to_le16(idle_state << RXON_RX_CHAIN_CNT_POS); if (!is_single && (rx_state >= 2) && !test_bit(STATUS_POWER_PMI, &priv->status)) active_rx_cnt = iwl_get_active_rx_chain_count(priv); idle_rx_cnt = iwl_get_idle_rx_chain_count(priv, active_rx_cnt); /* correct rx chain count accoridng hw settings */ if (priv->hw_params.rx_chains_num < active_rx_cnt) active_rx_cnt = priv->hw_params.rx_chains_num; if (priv->hw_params.rx_chains_num < idle_rx_cnt) idle_rx_cnt = priv->hw_params.rx_chains_num; rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS; rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS; priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain); if (!is_single && (active_rx_cnt >= 2) && is_cam) priv->staging_rxon.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK; else priv->staging_rxon.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK; IWL_DEBUG_ASSOC("rx chain %X\n", priv->staging_rxon.rx_chain); IWL_DEBUG_ASSOC("rx_chain=0x%Xi active=%d idle=%d\n", priv->staging_rxon.rx_chain, active_rx_cnt, idle_rx_cnt); WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 || active_rx_cnt < idle_rx_cnt); } EXPORT_SYMBOL(iwl_set_rxon_chain); Loading Loading
drivers/net/wireless/ath9k/main.c +10 −2 Original line number Diff line number Diff line Loading @@ -1067,8 +1067,16 @@ void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; tx_status->flags &= ~ATH_TX_BAR; } if (tx_status->flags) if (tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY)) { if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) { /* Frame was not ACKed, but an ACK was expected */ tx_info->status.excessive_retries = 1; } } else { /* Frame was ACKed */ tx_info->flags |= IEEE80211_TX_STAT_ACK; } tx_info->status.retry_count = tx_status->retries; Loading
drivers/net/wireless/ath9k/xmit.c +2 −2 Original line number Diff line number Diff line Loading @@ -357,9 +357,9 @@ static int ath_tx_prepare(struct ath_softc *sc, txctl->flags = ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */ if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) tx_info->flags |= ATH9K_TXDESC_NOACK; txctl->flags |= ATH9K_TXDESC_NOACK; if (tx_info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) tx_info->flags |= ATH9K_TXDESC_RTSENA; txctl->flags |= ATH9K_TXDESC_RTSENA; /* * Setup for rate calculations. Loading
drivers/net/wireless/iwlwifi/iwl-agn-rs.c +2 −1 Original line number Diff line number Diff line Loading @@ -1153,7 +1153,8 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv, !sta->ht_info.ht_supported) return -1; if (priv->current_ht_config.tx_mimo_ps_mode == IWL_MIMO_PS_STATIC) if (((sta->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS) >> 2) == IWL_MIMO_PS_STATIC) return -1; /* Need both Tx chains/antennas to support MIMO */ Loading
drivers/net/wireless/iwlwifi/iwl-agn.c +15 −12 Original line number Diff line number Diff line Loading @@ -181,14 +181,14 @@ static int iwl4965_check_rxon_cmd(struct iwl_rxon_cmd *rxon) } /** * iwl4965_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed * iwl_full_rxon_required - check if full RXON (vs RXON_ASSOC) cmd is needed * @priv: staging_rxon is compared to active_rxon * * If the RXON structure is changing enough to require a new tune, * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required. */ static int iwl4965_full_rxon_required(struct iwl_priv *priv) static int iwl_full_rxon_required(struct iwl_priv *priv) { /* These items are only settable from the full RXON command */ Loading @@ -207,7 +207,6 @@ static int iwl4965_full_rxon_required(struct iwl_priv *priv) priv->active_rxon.ofdm_ht_single_stream_basic_rates) || (priv->staging_rxon.ofdm_ht_dual_stream_basic_rates != priv->active_rxon.ofdm_ht_dual_stream_basic_rates) || (priv->staging_rxon.rx_chain != priv->active_rxon.rx_chain) || (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id)) return 1; Loading Loading @@ -263,7 +262,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) /* If we don't need to send a full RXON, we can use * iwl4965_rxon_assoc_cmd which is used to reconfigure filter * and other flags for the current radio configuration. */ if (!iwl4965_full_rxon_required(priv)) { if (!iwl_full_rxon_required(priv)) { ret = iwl_send_rxon_assoc(priv); if (ret) { IWL_ERROR("Error setting RXON_ASSOC (%d)\n", ret); Loading Loading @@ -587,8 +586,6 @@ static void iwl4965_ht_conf(struct iwl_priv *priv, iwl_conf->supported_chan_width = 0; } iwl_conf->tx_mimo_ps_mode = (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2); memcpy(iwl_conf->supp_mcs_set, ht_conf->supp_mcs_set, 16); iwl_conf->control_channel = ht_bss_conf->primary_channel; Loading Loading @@ -2190,6 +2187,9 @@ static void __iwl4965_down(struct iwl_priv *priv) udelay(5); /* FIXME: apm_ops.suspend(priv) */ if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status)) priv->cfg->ops->lib->apm_ops.stop(priv); else priv->cfg->ops->lib->apm_ops.reset(priv); priv->cfg->ops->lib->free_shared_mem(priv); Loading Loading @@ -3588,7 +3588,7 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk priv->assoc_id = 0; timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; priv->timestamp = le64_to_cpu(timestamp) + (priv->beacon_int * 1000); priv->timestamp = le64_to_cpu(timestamp); IWL_DEBUG_MAC80211("leave\n"); spin_unlock_irqrestore(&priv->lock, flags); Loading Loading @@ -4372,14 +4372,17 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) iwl_dbgfs_unregister(priv); sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group); /* ieee80211_unregister_hw call wil cause iwl4965_mac_stop to * to be called and iwl4965_down since we are removing the device * we need to set STATUS_EXIT_PENDING bit. */ set_bit(STATUS_EXIT_PENDING, &priv->status); if (priv->mac80211_registered) { ieee80211_unregister_hw(priv->hw); priv->mac80211_registered = 0; } set_bit(STATUS_EXIT_PENDING, &priv->status); } else { iwl4965_down(priv); } /* make sure we flush any pending irq or * tasklet for the driver Loading
drivers/net/wireless/iwlwifi/iwl-core.c +46 −31 Original line number Diff line number Diff line Loading @@ -592,12 +592,11 @@ static void iwlcore_free_geos(struct iwl_priv *priv) clear_bit(STATUS_GEO_CONFIGURED, &priv->status); } static u8 is_single_rx_stream(struct iwl_priv *priv) static bool is_single_rx_stream(struct iwl_priv *priv) { return !priv->current_ht_config.is_ht || ((priv->current_ht_config.supp_mcs_set[1] == 0) && (priv->current_ht_config.supp_mcs_set[2] == 0)) || priv->ps_mode == IWL_MIMO_PS_STATIC; (priv->current_ht_config.supp_mcs_set[2] == 0)); } static u8 iwl_is_channel_extension(struct iwl_priv *priv, Loading Loading @@ -704,33 +703,39 @@ EXPORT_SYMBOL(iwl_set_rxon_ht); * MIMO (dual stream) requires at least 2, but works better with 3. * This does not determine *which* chains to use, just how many. */ static int iwlcore_get_rx_chain_counter(struct iwl_priv *priv, u8 *idle_state, u8 *rx_state) static int iwl_get_active_rx_chain_count(struct iwl_priv *priv) { u8 is_single = is_single_rx_stream(priv); u8 is_cam = test_bit(STATUS_POWER_PMI, &priv->status) ? 0 : 1; bool is_single = is_single_rx_stream(priv); bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); /* # of Rx chains to use when expecting MIMO. */ if (is_single || (!is_cam && (priv->ps_mode == IWL_MIMO_PS_STATIC))) *rx_state = 2; return 2; else *rx_state = 3; return 3; } static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt) { int idle_cnt; bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); /* # Rx chains when idling and maybe trying to save power */ switch (priv->ps_mode) { case IWL_MIMO_PS_STATIC: case IWL_MIMO_PS_DYNAMIC: *idle_state = (is_cam) ? 2 : 1; idle_cnt = (is_cam) ? 2 : 1; break; case IWL_MIMO_PS_NONE: *idle_state = (is_cam) ? *rx_state : 1; idle_cnt = (is_cam) ? active_cnt : 1; break; case IWL_MIMO_PS_INVALID: default: *idle_state = 1; IWL_ERROR("invalide mimo ps mode %d\n", priv->ps_mode); WARN_ON(1); idle_cnt = -1; break; } return 0; return idle_cnt; } /** Loading @@ -741,34 +746,44 @@ static int iwlcore_get_rx_chain_counter(struct iwl_priv *priv, */ void iwl_set_rxon_chain(struct iwl_priv *priv) { u8 is_single = is_single_rx_stream(priv); u8 idle_state, rx_state; priv->staging_rxon.rx_chain = 0; rx_state = idle_state = 3; bool is_single = is_single_rx_stream(priv); bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); u8 idle_rx_cnt, active_rx_cnt; u16 rx_chain; /* Tell uCode which antennas are actually connected. * Before first association, we assume all antennas are connected. * Just after first association, iwl_chain_noise_calibration() * checks which antennas actually *are* connected. */ priv->staging_rxon.rx_chain |= cpu_to_le16(priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS); rx_chain = priv->hw_params.valid_rx_ant << RXON_RX_CHAIN_VALID_POS; /* How many receivers should we use? */ iwlcore_get_rx_chain_counter(priv, &idle_state, &rx_state); priv->staging_rxon.rx_chain |= cpu_to_le16(rx_state << RXON_RX_CHAIN_MIMO_CNT_POS); priv->staging_rxon.rx_chain |= cpu_to_le16(idle_state << RXON_RX_CHAIN_CNT_POS); if (!is_single && (rx_state >= 2) && !test_bit(STATUS_POWER_PMI, &priv->status)) active_rx_cnt = iwl_get_active_rx_chain_count(priv); idle_rx_cnt = iwl_get_idle_rx_chain_count(priv, active_rx_cnt); /* correct rx chain count accoridng hw settings */ if (priv->hw_params.rx_chains_num < active_rx_cnt) active_rx_cnt = priv->hw_params.rx_chains_num; if (priv->hw_params.rx_chains_num < idle_rx_cnt) idle_rx_cnt = priv->hw_params.rx_chains_num; rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS; rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS; priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain); if (!is_single && (active_rx_cnt >= 2) && is_cam) priv->staging_rxon.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK; else priv->staging_rxon.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK; IWL_DEBUG_ASSOC("rx chain %X\n", priv->staging_rxon.rx_chain); IWL_DEBUG_ASSOC("rx_chain=0x%Xi active=%d idle=%d\n", priv->staging_rxon.rx_chain, active_rx_cnt, idle_rx_cnt); WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 || active_rx_cnt < idle_rx_cnt); } EXPORT_SYMBOL(iwl_set_rxon_chain); Loading