diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965-rs.c | 50 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 34 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl4965-base.c | 9 |
4 files changed, 64 insertions, 32 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index cf7b569a2229..306fbdc6e62f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c | |||
@@ -823,6 +823,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
823 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 823 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
824 | struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate; | 824 | struct iwl4965_priv *priv = (struct iwl4965_priv *)priv_rate; |
825 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 825 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
826 | struct ieee80211_hw *hw = local_to_hw(local); | ||
826 | struct iwl4965_rate_scale_data *window = NULL; | 827 | struct iwl4965_rate_scale_data *window = NULL; |
827 | struct iwl4965_rate_scale_data *search_win = NULL; | 828 | struct iwl4965_rate_scale_data *search_win = NULL; |
828 | struct iwl4965_rate tx_mcs; | 829 | struct iwl4965_rate tx_mcs; |
@@ -884,17 +885,6 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
884 | search_win = (struct iwl4965_rate_scale_data *) | 885 | search_win = (struct iwl4965_rate_scale_data *) |
885 | &(search_tbl->win[0]); | 886 | &(search_tbl->win[0]); |
886 | 887 | ||
887 | tx_mcs.rate_n_flags = tx_resp->control.tx_rate->hw_value; | ||
888 | |||
889 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, | ||
890 | &tbl_type, &rs_index); | ||
891 | if ((rs_index < 0) || (rs_index >= IWL_RATE_COUNT)) { | ||
892 | IWL_DEBUG_RATE("bad rate index at: %d rate 0x%X\n", | ||
893 | rs_index, tx_mcs.rate_n_flags); | ||
894 | rcu_read_unlock(); | ||
895 | return; | ||
896 | } | ||
897 | |||
898 | /* | 888 | /* |
899 | * Ignore this Tx frame response if its initial rate doesn't match | 889 | * Ignore this Tx frame response if its initial rate doesn't match |
900 | * that of latest Link Quality command. There may be stragglers | 890 | * that of latest Link Quality command. There may be stragglers |
@@ -903,12 +893,28 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
903 | * to check "search" mode, or a prior "search" mode after we've moved | 893 | * to check "search" mode, or a prior "search" mode after we've moved |
904 | * to a new "search" mode (which might become the new "active" mode). | 894 | * to a new "search" mode (which might become the new "active" mode). |
905 | */ | 895 | */ |
906 | if (retries && | 896 | tx_mcs.rate_n_flags = le32_to_cpu(table->rs_table[0].rate_n_flags); |
907 | (tx_mcs.rate_n_flags != | 897 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, &tbl_type, &rs_index); |
908 | le32_to_cpu(table->rs_table[0].rate_n_flags))) { | 898 | if (priv->band == IEEE80211_BAND_5GHZ) |
909 | IWL_DEBUG_RATE("initial rate does not match 0x%x 0x%x\n", | 899 | rs_index -= IWL_FIRST_OFDM_RATE; |
910 | tx_mcs.rate_n_flags, | 900 | |
911 | le32_to_cpu(table->rs_table[0].rate_n_flags)); | 901 | if ((tx_resp->control.tx_rate == NULL) || |
902 | (tbl_type.is_SGI ^ | ||
903 | !!(tx_resp->control.flags & IEEE80211_TXCTL_SHORT_GI)) || | ||
904 | (tbl_type.is_fat ^ | ||
905 | !!(tx_resp->control.flags & IEEE80211_TXCTL_40_MHZ_WIDTH)) || | ||
906 | (tbl_type.is_dup ^ | ||
907 | !!(tx_resp->control.flags & IEEE80211_TXCTL_DUP_DATA)) || | ||
908 | (tbl_type.antenna_type ^ | ||
909 | tx_resp->control.antenna_sel_tx) || | ||
910 | (!!(tx_mcs.rate_n_flags & RATE_MCS_HT_MSK) ^ | ||
911 | !!(tx_resp->control.flags & IEEE80211_TXCTL_OFDM_HT)) || | ||
912 | (!!(tx_mcs.rate_n_flags & RATE_MCS_GF_MSK) ^ | ||
913 | !!(tx_resp->control.flags & IEEE80211_TXCTL_GREEN_FIELD)) || | ||
914 | (hw->wiphy->bands[priv->band]->bitrates[rs_index].bitrate != | ||
915 | tx_resp->control.tx_rate->bitrate)) { | ||
916 | IWL_DEBUG_RATE("initial rate does not match 0x%x\n", | ||
917 | tx_mcs.rate_n_flags); | ||
912 | rcu_read_unlock(); | 918 | rcu_read_unlock(); |
913 | return; | 919 | return; |
914 | } | 920 | } |
@@ -959,14 +965,8 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, | |||
959 | * if Tx was successful first try, use original rate, | 965 | * if Tx was successful first try, use original rate, |
960 | * else look up the rate that was, finally, successful. | 966 | * else look up the rate that was, finally, successful. |
961 | */ | 967 | */ |
962 | if (!tx_resp->retry_count) | 968 | tx_mcs.rate_n_flags = le32_to_cpu(table->rs_table[index].rate_n_flags); |
963 | tx_mcs.rate_n_flags = tx_resp->control.tx_rate->hw_value; | 969 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, &tbl_type, &rs_index); |
964 | else | ||
965 | tx_mcs.rate_n_flags = | ||
966 | le32_to_cpu(table->rs_table[index].rate_n_flags); | ||
967 | |||
968 | rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, | ||
969 | &tbl_type, &rs_index); | ||
970 | 970 | ||
971 | /* Update frame history window with "success" if Tx got ACKed ... */ | 971 | /* Update frame history window with "success" if Tx got ACKed ... */ |
972 | if (tx_resp->flags & IEEE80211_TX_STATUS_ACK) | 972 | if (tx_resp->flags & IEEE80211_TX_STATUS_ACK) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index bb8f00272af3..05ad5a9a1a55 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -150,6 +150,35 @@ int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags) | |||
150 | return -1; | 150 | return -1; |
151 | } | 151 | } |
152 | 152 | ||
153 | /** | ||
154 | * translate ucode response to mac80211 tx status control values | ||
155 | */ | ||
156 | void iwl4965_hwrate_to_tx_control(struct iwl4965_priv *priv, u32 rate_n_flags, | ||
157 | struct ieee80211_tx_control *control) | ||
158 | { | ||
159 | int rate_index; | ||
160 | |||
161 | control->antenna_sel_tx = | ||
162 | ((rate_n_flags & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_A_POS); | ||
163 | if (rate_n_flags & RATE_MCS_HT_MSK) | ||
164 | control->flags |= IEEE80211_TXCTL_OFDM_HT; | ||
165 | if (rate_n_flags & RATE_MCS_GF_MSK) | ||
166 | control->flags |= IEEE80211_TXCTL_GREEN_FIELD; | ||
167 | if (rate_n_flags & RATE_MCS_FAT_MSK) | ||
168 | control->flags |= IEEE80211_TXCTL_40_MHZ_WIDTH; | ||
169 | if (rate_n_flags & RATE_MCS_DUP_MSK) | ||
170 | control->flags |= IEEE80211_TXCTL_DUP_DATA; | ||
171 | if (rate_n_flags & RATE_MCS_SGI_MSK) | ||
172 | control->flags |= IEEE80211_TXCTL_SHORT_GI; | ||
173 | /* since iwl4965_hwrate_to_plcp_idx is band indifferent, we always use | ||
174 | * IEEE80211_BAND_2GHZ band as it contains all the rates */ | ||
175 | rate_index = iwl4965_hwrate_to_plcp_idx(rate_n_flags); | ||
176 | if (rate_index == -1) | ||
177 | control->tx_rate = NULL; | ||
178 | else | ||
179 | control->tx_rate = | ||
180 | &priv->bands[IEEE80211_BAND_2GHZ].bitrates[rate_index]; | ||
181 | } | ||
153 | 182 | ||
154 | /* | 183 | /* |
155 | * Determine how many receiver/antenna chains to use. | 184 | * Determine how many receiver/antenna chains to use. |
@@ -4084,9 +4113,8 @@ static int iwl4965_tx_status_reply_compressed_ba(struct iwl4965_priv *priv, | |||
4084 | tx_status->flags |= IEEE80211_TX_STATUS_AMPDU; | 4113 | tx_status->flags |= IEEE80211_TX_STATUS_AMPDU; |
4085 | tx_status->ampdu_ack_map = successes; | 4114 | tx_status->ampdu_ack_map = successes; |
4086 | tx_status->ampdu_ack_len = agg->frame_count; | 4115 | tx_status->ampdu_ack_len = agg->frame_count; |
4087 | /* FIXME Wrong rate | 4116 | iwl4965_hwrate_to_tx_control(priv, agg->rate_n_flags, |
4088 | tx_status->control.tx_rate = agg->rate_n_flags; | 4117 | &tx_status->control); |
4089 | */ | ||
4090 | 4118 | ||
4091 | IWL_DEBUG_TX_REPLY("Bitmap %llx\n", bitmap); | 4119 | IWL_DEBUG_TX_REPLY("Bitmap %llx\n", bitmap); |
4092 | 4120 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h index de79816c0068..5c605129dfbd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965.h | |||
@@ -757,6 +757,9 @@ extern int iwl4965_set_fat_chan_info(struct iwl4965_priv *priv, | |||
757 | const struct iwl4965_eeprom_channel *eeprom_ch, | 757 | const struct iwl4965_eeprom_channel *eeprom_ch, |
758 | u8 fat_extension_channel); | 758 | u8 fat_extension_channel); |
759 | extern void iwl4965_rf_kill_ct_config(struct iwl4965_priv *priv); | 759 | extern void iwl4965_rf_kill_ct_config(struct iwl4965_priv *priv); |
760 | extern void iwl4965_hwrate_to_tx_control(struct iwl4965_priv *priv, | ||
761 | u32 rate_n_flags, | ||
762 | struct ieee80211_tx_control *control); | ||
760 | 763 | ||
761 | #ifdef CONFIG_IWL4965_HT | 764 | #ifdef CONFIG_IWL4965_HT |
762 | void iwl4965_init_ht_hw_capab(struct ieee80211_ht_info *ht_info, | 765 | void iwl4965_init_ht_hw_capab(struct ieee80211_ht_info *ht_info, |
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index b0f6044fd6eb..f273395d4a3e 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -3410,9 +3410,9 @@ static int iwl4965_tx_status_reply_tx(struct iwl4965_priv *priv, | |||
3410 | tx_status->control.flags &= ~IEEE80211_TXCTL_AMPDU; | 3410 | tx_status->control.flags &= ~IEEE80211_TXCTL_AMPDU; |
3411 | tx_status->flags = iwl4965_is_tx_success(status)? | 3411 | tx_status->flags = iwl4965_is_tx_success(status)? |
3412 | IEEE80211_TX_STATUS_ACK : 0; | 3412 | IEEE80211_TX_STATUS_ACK : 0; |
3413 | /* FIXME Wrong Rate | 3413 | iwl4965_hwrate_to_tx_control(priv, |
3414 | tx_status->control.tx_rate = | 3414 | le32_to_cpu(tx_resp->rate_n_flags), |
3415 | iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags); */ | 3415 | &tx_status->control); |
3416 | /* FIXME: code repetition end */ | 3416 | /* FIXME: code repetition end */ |
3417 | 3417 | ||
3418 | IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n", | 3418 | IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n", |
@@ -3569,9 +3569,10 @@ static void iwl4965_rx_reply_tx(struct iwl4965_priv *priv, | |||
3569 | tx_status->queue_number = status; | 3569 | tx_status->queue_number = status; |
3570 | tx_status->queue_length = tx_resp->bt_kill_count; | 3570 | tx_status->queue_length = tx_resp->bt_kill_count; |
3571 | tx_status->queue_length |= tx_resp->failure_rts; | 3571 | tx_status->queue_length |= tx_resp->failure_rts; |
3572 | |||
3573 | tx_status->flags = | 3572 | tx_status->flags = |
3574 | iwl4965_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0; | 3573 | iwl4965_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0; |
3574 | iwl4965_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), | ||
3575 | &tx_status->control); | ||
3575 | 3576 | ||
3576 | IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x " | 3577 | IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x " |
3577 | "retries %d\n", txq_id, iwl4965_get_tx_fail_reason(status), | 3578 | "retries %d\n", txq_id, iwl4965_get_tx_fail_reason(status), |