Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 56e9c0a6 authored by David S. Miller's avatar David S. Miller
Browse files
parents 6c00055a 9aab3e3e
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -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;

+2 −2
Original line number Diff line number Diff line
@@ -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.
+2 −1
Original line number Diff line number Diff line
@@ -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 */
+15 −12
Original line number Diff line number Diff line
@@ -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 */
@@ -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;

@@ -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);
@@ -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;
@@ -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);

@@ -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);
@@ -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
+46 −31
Original line number Diff line number Diff line
@@ -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,
@@ -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;
}

/**
@@ -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