diff options
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 63 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-5000.c | 81 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-commands.h | 50 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-debug.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 9 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-tx.c | 39 |
6 files changed, 125 insertions, 119 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 222c2baa95ca..881bf0472564 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -822,7 +822,6 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) | |||
822 | } | 822 | } |
823 | 823 | ||
824 | priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; | 824 | priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; |
825 | priv->hw_params.first_ampdu_q = IWL49_FIRST_AMPDU_QUEUE; | ||
826 | priv->hw_params.max_stations = IWL4965_STATION_COUNT; | 825 | priv->hw_params.max_stations = IWL4965_STATION_COUNT; |
827 | priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID; | 826 | priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID; |
828 | priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE; | 827 | priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE; |
@@ -2059,7 +2058,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, | |||
2059 | agg->rate_n_flags = rate_n_flags; | 2058 | agg->rate_n_flags = rate_n_flags; |
2060 | agg->bitmap = 0; | 2059 | agg->bitmap = 0; |
2061 | 2060 | ||
2062 | /* # frames attempted by Tx command */ | 2061 | /* num frames attempted by Tx command */ |
2063 | if (agg->frame_count == 1) { | 2062 | if (agg->frame_count == 1) { |
2064 | /* Only one frame was attempted; no block-ack will arrive */ | 2063 | /* Only one frame was attempted; no block-ack will arrive */ |
2065 | status = le16_to_cpu(frame_status[0].status); | 2064 | status = le16_to_cpu(frame_status[0].status); |
@@ -2158,12 +2157,13 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
2158 | int txq_id = SEQ_TO_QUEUE(sequence); | 2157 | int txq_id = SEQ_TO_QUEUE(sequence); |
2159 | int index = SEQ_TO_INDEX(sequence); | 2158 | int index = SEQ_TO_INDEX(sequence); |
2160 | struct iwl_tx_queue *txq = &priv->txq[txq_id]; | 2159 | struct iwl_tx_queue *txq = &priv->txq[txq_id]; |
2160 | struct ieee80211_hdr *hdr; | ||
2161 | struct ieee80211_tx_info *info; | 2161 | struct ieee80211_tx_info *info; |
2162 | struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; | 2162 | struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; |
2163 | u32 status = le32_to_cpu(tx_resp->u.status); | 2163 | u32 status = le32_to_cpu(tx_resp->u.status); |
2164 | int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION; | 2164 | int tid = MAX_TID_COUNT; |
2165 | __le16 fc; | 2165 | int sta_id; |
2166 | struct ieee80211_hdr *hdr; | 2166 | int freed; |
2167 | u8 *qc = NULL; | 2167 | u8 *qc = NULL; |
2168 | 2168 | ||
2169 | if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { | 2169 | if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { |
@@ -2178,8 +2178,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
2178 | memset(&info->status, 0, sizeof(info->status)); | 2178 | memset(&info->status, 0, sizeof(info->status)); |
2179 | 2179 | ||
2180 | hdr = iwl_tx_queue_get_hdr(priv, txq_id, index); | 2180 | hdr = iwl_tx_queue_get_hdr(priv, txq_id, index); |
2181 | fc = hdr->frame_control; | 2181 | if (ieee80211_is_data_qos(hdr->frame_control)) { |
2182 | if (ieee80211_is_data_qos(fc)) { | ||
2183 | qc = ieee80211_get_qos_ctl(hdr); | 2182 | qc = ieee80211_get_qos_ctl(hdr); |
2184 | tid = qc[0] & 0xf; | 2183 | tid = qc[0] & 0xf; |
2185 | } | 2184 | } |
@@ -2194,8 +2193,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
2194 | const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp); | 2193 | const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp); |
2195 | struct iwl_ht_agg *agg = NULL; | 2194 | struct iwl_ht_agg *agg = NULL; |
2196 | 2195 | ||
2197 | if (!qc) | 2196 | WARN_ON(!qc); |
2198 | return; | ||
2199 | 2197 | ||
2200 | agg = &priv->stations[sta_id].tid[tid].agg; | 2198 | agg = &priv->stations[sta_id].tid[tid].agg; |
2201 | 2199 | ||
@@ -2206,54 +2204,49 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
2206 | info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; | 2204 | info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; |
2207 | 2205 | ||
2208 | if (txq->q.read_ptr != (scd_ssn & 0xff)) { | 2206 | if (txq->q.read_ptr != (scd_ssn & 0xff)) { |
2209 | int freed, ampdu_q; | ||
2210 | index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); | 2207 | index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); |
2211 | IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn " | 2208 | IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn " |
2212 | "%d index %d\n", scd_ssn , index); | 2209 | "%d index %d\n", scd_ssn , index); |
2213 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); | 2210 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); |
2214 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | 2211 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; |
2215 | 2212 | ||
2216 | if (iwl_queue_space(&txq->q) > txq->q.low_mark && | 2213 | if (priv->mac80211_registered && |
2217 | txq_id >= 0 && priv->mac80211_registered && | 2214 | (iwl_queue_space(&txq->q) > txq->q.low_mark) && |
2218 | agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) { | 2215 | (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) { |
2219 | /* calculate mac80211 ampdu sw queue to wake */ | ||
2220 | ampdu_q = txq_id - IWL49_FIRST_AMPDU_QUEUE + | ||
2221 | priv->hw->queues; | ||
2222 | if (agg->state == IWL_AGG_OFF) | 2216 | if (agg->state == IWL_AGG_OFF) |
2223 | ieee80211_wake_queue(priv->hw, txq_id); | 2217 | ieee80211_wake_queue(priv->hw, txq_id); |
2224 | else | 2218 | else |
2225 | ieee80211_wake_queue(priv->hw, ampdu_q); | 2219 | ieee80211_wake_queue(priv->hw, |
2220 | txq->swq_id); | ||
2226 | } | 2221 | } |
2227 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); | ||
2228 | } | 2222 | } |
2229 | } else { | 2223 | } else { |
2230 | info->status.rates[0].count = tx_resp->failure_frame + 1; | 2224 | info->status.rates[0].count = tx_resp->failure_frame + 1; |
2231 | info->flags |= | 2225 | info->flags |= iwl_is_tx_success(status) ? |
2232 | iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0; | 2226 | IEEE80211_TX_STAT_ACK : 0; |
2233 | iwl_hwrate_to_tx_control(priv, | 2227 | iwl_hwrate_to_tx_control(priv, |
2234 | le32_to_cpu(tx_resp->rate_n_flags), | 2228 | le32_to_cpu(tx_resp->rate_n_flags), |
2235 | info); | 2229 | info); |
2236 | 2230 | ||
2237 | IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags " | 2231 | IWL_DEBUG_TX_REPLY("TXQ %d status %s (0x%08x) " |
2238 | "0x%x retries %d\n", txq_id, | 2232 | "rate_n_flags 0x%x retries %d\n", |
2239 | iwl_get_tx_fail_reason(status), | 2233 | txq_id, |
2240 | status, le32_to_cpu(tx_resp->rate_n_flags), | 2234 | iwl_get_tx_fail_reason(status), status, |
2241 | tx_resp->failure_frame); | 2235 | le32_to_cpu(tx_resp->rate_n_flags), |
2242 | 2236 | tx_resp->failure_frame); | |
2243 | IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); | ||
2244 | 2237 | ||
2245 | if (index != -1) { | 2238 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); |
2246 | int freed = iwl_tx_queue_reclaim(priv, txq_id, index); | 2239 | if (qc) |
2247 | if (tid != MAX_TID_COUNT) | ||
2248 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | 2240 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; |
2249 | if (iwl_queue_space(&txq->q) > txq->q.low_mark && | 2241 | |
2250 | (txq_id >= 0) && priv->mac80211_registered) | 2242 | if (priv->mac80211_registered && |
2243 | (iwl_queue_space(&txq->q) > txq->q.low_mark)) | ||
2251 | ieee80211_wake_queue(priv->hw, txq_id); | 2244 | ieee80211_wake_queue(priv->hw, txq_id); |
2252 | if (tid != MAX_TID_COUNT) | ||
2253 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); | ||
2254 | } | ||
2255 | } | 2245 | } |
2256 | 2246 | ||
2247 | if (qc) | ||
2248 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); | ||
2249 | |||
2257 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) | 2250 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) |
2258 | IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n"); | 2251 | IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n"); |
2259 | } | 2252 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index ad566ef233b8..a8c8c858e209 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -683,7 +683,7 @@ static void iwl5000_tx_queue_set_status(struct iwl_priv *priv, | |||
683 | int tx_fifo_id, int scd_retry) | 683 | int tx_fifo_id, int scd_retry) |
684 | { | 684 | { |
685 | int txq_id = txq->q.id; | 685 | int txq_id = txq->q.id; |
686 | int active = test_bit(txq_id, &priv->txq_ctx_active_msk)?1:0; | 686 | int active = test_bit(txq_id, &priv->txq_ctx_active_msk) ? 1 : 0; |
687 | 687 | ||
688 | iwl_write_prph(priv, IWL50_SCD_QUEUE_STATUS_BITS(txq_id), | 688 | iwl_write_prph(priv, IWL50_SCD_QUEUE_STATUS_BITS(txq_id), |
689 | (active << IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE) | | 689 | (active << IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE) | |
@@ -801,7 +801,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) | |||
801 | } | 801 | } |
802 | 802 | ||
803 | priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; | 803 | priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; |
804 | priv->hw_params.first_ampdu_q = IWL50_FIRST_AMPDU_QUEUE; | ||
805 | priv->hw_params.max_stations = IWL5000_STATION_COUNT; | 804 | priv->hw_params.max_stations = IWL5000_STATION_COUNT; |
806 | priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; | 805 | priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID; |
807 | priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE; | 806 | priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE; |
@@ -1159,7 +1158,7 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv, | |||
1159 | info->status.rates[0].count = tx_resp->failure_frame + 1; | 1158 | info->status.rates[0].count = tx_resp->failure_frame + 1; |
1160 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; | 1159 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; |
1161 | info->flags |= iwl_is_tx_success(status)? | 1160 | info->flags |= iwl_is_tx_success(status)? |
1162 | IEEE80211_TX_STAT_ACK : 0; | 1161 | IEEE80211_TX_STAT_ACK : 0; |
1163 | iwl_hwrate_to_tx_control(priv, rate_n_flags, info); | 1162 | iwl_hwrate_to_tx_control(priv, rate_n_flags, info); |
1164 | 1163 | ||
1165 | /* FIXME: code repetition end */ | 1164 | /* FIXME: code repetition end */ |
@@ -1245,9 +1244,9 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv, | |||
1245 | struct ieee80211_tx_info *info; | 1244 | struct ieee80211_tx_info *info; |
1246 | struct iwl5000_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; | 1245 | struct iwl5000_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; |
1247 | u32 status = le16_to_cpu(tx_resp->status.status); | 1246 | u32 status = le16_to_cpu(tx_resp->status.status); |
1248 | int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION; | 1247 | int tid; |
1249 | struct ieee80211_hdr *hdr; | 1248 | int sta_id; |
1250 | u8 *qc = NULL; | 1249 | int freed; |
1251 | 1250 | ||
1252 | if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { | 1251 | if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { |
1253 | IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " | 1252 | IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " |
@@ -1260,25 +1259,13 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv, | |||
1260 | info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]); | 1259 | info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]); |
1261 | memset(&info->status, 0, sizeof(info->status)); | 1260 | memset(&info->status, 0, sizeof(info->status)); |
1262 | 1261 | ||
1263 | hdr = iwl_tx_queue_get_hdr(priv, txq_id, index); | 1262 | tid = (tx_resp->ra_tid & IWL50_TX_RES_TID_MSK) >> IWL50_TX_RES_TID_POS; |
1264 | if (ieee80211_is_data_qos(hdr->frame_control)) { | 1263 | sta_id = (tx_resp->ra_tid & IWL50_TX_RES_RA_MSK) >> IWL50_TX_RES_RA_POS; |
1265 | qc = ieee80211_get_qos_ctl(hdr); | ||
1266 | tid = qc[0] & 0xf; | ||
1267 | } | ||
1268 | |||
1269 | sta_id = iwl_get_ra_sta_id(priv, hdr); | ||
1270 | if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) { | ||
1271 | IWL_ERROR("Station not known\n"); | ||
1272 | return; | ||
1273 | } | ||
1274 | 1264 | ||
1275 | if (txq->sched_retry) { | 1265 | if (txq->sched_retry) { |
1276 | const u32 scd_ssn = iwl5000_get_scd_ssn(tx_resp); | 1266 | const u32 scd_ssn = iwl5000_get_scd_ssn(tx_resp); |
1277 | struct iwl_ht_agg *agg = NULL; | 1267 | struct iwl_ht_agg *agg = NULL; |
1278 | 1268 | ||
1279 | if (!qc) | ||
1280 | return; | ||
1281 | |||
1282 | agg = &priv->stations[sta_id].tid[tid].agg; | 1269 | agg = &priv->stations[sta_id].tid[tid].agg; |
1283 | 1270 | ||
1284 | iwl5000_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index); | 1271 | iwl5000_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index); |
@@ -1288,53 +1275,53 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv, | |||
1288 | info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; | 1275 | info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; |
1289 | 1276 | ||
1290 | if (txq->q.read_ptr != (scd_ssn & 0xff)) { | 1277 | if (txq->q.read_ptr != (scd_ssn & 0xff)) { |
1291 | int freed, ampdu_q; | ||
1292 | index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); | 1278 | index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd); |
1293 | IWL_DEBUG_TX_REPLY("Retry scheduler reclaim scd_ssn " | 1279 | IWL_DEBUG_TX_REPLY("Retry scheduler reclaim " |
1294 | "%d index %d\n", scd_ssn , index); | 1280 | "scd_ssn=%d idx=%d txq=%d swq=%d\n", |
1281 | scd_ssn , index, txq_id, txq->swq_id); | ||
1282 | |||
1295 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); | 1283 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); |
1296 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | 1284 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; |
1297 | 1285 | ||
1298 | if (iwl_queue_space(&txq->q) > txq->q.low_mark && | 1286 | if (priv->mac80211_registered && |
1299 | txq_id >= 0 && priv->mac80211_registered && | 1287 | (iwl_queue_space(&txq->q) > txq->q.low_mark) && |
1300 | agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) { | 1288 | (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) { |
1301 | /* calculate mac80211 ampdu sw queue to wake */ | ||
1302 | ampdu_q = txq_id - IWL50_FIRST_AMPDU_QUEUE + | ||
1303 | priv->hw->queues; | ||
1304 | if (agg->state == IWL_AGG_OFF) | 1289 | if (agg->state == IWL_AGG_OFF) |
1305 | ieee80211_wake_queue(priv->hw, txq_id); | 1290 | ieee80211_wake_queue(priv->hw, txq_id); |
1306 | else | 1291 | else |
1307 | ieee80211_wake_queue(priv->hw, ampdu_q); | 1292 | ieee80211_wake_queue(priv->hw, |
1293 | txq->swq_id); | ||
1308 | } | 1294 | } |
1309 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); | ||
1310 | } | 1295 | } |
1311 | } else { | 1296 | } else { |
1297 | BUG_ON(txq_id != txq->swq_id); | ||
1298 | |||
1312 | info->status.rates[0].count = tx_resp->failure_frame + 1; | 1299 | info->status.rates[0].count = tx_resp->failure_frame + 1; |
1313 | info->flags = | 1300 | info->flags |= iwl_is_tx_success(status) ? |
1314 | iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0; | 1301 | IEEE80211_TX_STAT_ACK : 0; |
1315 | iwl_hwrate_to_tx_control(priv, | 1302 | iwl_hwrate_to_tx_control(priv, |
1316 | le32_to_cpu(tx_resp->rate_n_flags), | 1303 | le32_to_cpu(tx_resp->rate_n_flags), |
1317 | info); | 1304 | info); |
1318 | 1305 | ||
1319 | IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags " | 1306 | IWL_DEBUG_TX_REPLY("TXQ %d status %s (0x%08x) rate_n_flags " |
1320 | "0x%x retries %d\n", txq_id, | 1307 | "0x%x retries %d\n", |
1321 | iwl_get_tx_fail_reason(status), | 1308 | txq_id, |
1322 | status, le32_to_cpu(tx_resp->rate_n_flags), | 1309 | iwl_get_tx_fail_reason(status), status, |
1323 | tx_resp->failure_frame); | 1310 | le32_to_cpu(tx_resp->rate_n_flags), |
1311 | tx_resp->failure_frame); | ||
1324 | 1312 | ||
1325 | IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); | 1313 | freed = iwl_tx_queue_reclaim(priv, txq_id, index); |
1326 | if (index != -1) { | 1314 | if (ieee80211_is_data_qos(tx_resp->frame_ctrl)) |
1327 | int freed = iwl_tx_queue_reclaim(priv, txq_id, index); | ||
1328 | if (tid != MAX_TID_COUNT) | ||
1329 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | 1315 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; |
1330 | if (iwl_queue_space(&txq->q) > txq->q.low_mark && | 1316 | |
1331 | (txq_id >= 0) && priv->mac80211_registered) | 1317 | if (priv->mac80211_registered && |
1318 | (iwl_queue_space(&txq->q) > txq->q.low_mark)) | ||
1332 | ieee80211_wake_queue(priv->hw, txq_id); | 1319 | ieee80211_wake_queue(priv->hw, txq_id); |
1333 | if (tid != MAX_TID_COUNT) | ||
1334 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); | ||
1335 | } | ||
1336 | } | 1320 | } |
1337 | 1321 | ||
1322 | if (ieee80211_is_data_qos(tx_resp->frame_ctrl)) | ||
1323 | iwl_txq_check_empty(priv, sta_id, tid, txq_id); | ||
1324 | |||
1338 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) | 1325 | if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) |
1339 | IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n"); | 1326 | IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n"); |
1340 | } | 1327 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 67680a74afde..8f8734fc4f39 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h | |||
@@ -1413,21 +1413,21 @@ enum { | |||
1413 | }; | 1413 | }; |
1414 | 1414 | ||
1415 | enum { | 1415 | enum { |
1416 | TX_STATUS_MSK = 0x000000ff, /* bits 0:7 */ | 1416 | TX_STATUS_MSK = 0x000000ff, /* bits 0:7 */ |
1417 | TX_STATUS_DELAY_MSK = 0x00000040, | 1417 | TX_STATUS_DELAY_MSK = 0x00000040, |
1418 | TX_STATUS_ABORT_MSK = 0x00000080, | 1418 | TX_STATUS_ABORT_MSK = 0x00000080, |
1419 | TX_PACKET_MODE_MSK = 0x0000ff00, /* bits 8:15 */ | 1419 | TX_PACKET_MODE_MSK = 0x0000ff00, /* bits 8:15 */ |
1420 | TX_FIFO_NUMBER_MSK = 0x00070000, /* bits 16:18 */ | 1420 | TX_FIFO_NUMBER_MSK = 0x00070000, /* bits 16:18 */ |
1421 | TX_RESERVED = 0x00780000, /* bits 19:22 */ | 1421 | TX_RESERVED = 0x00780000, /* bits 19:22 */ |
1422 | TX_POWER_PA_DETECT_MSK = 0x7f800000, /* bits 23:30 */ | 1422 | TX_POWER_PA_DETECT_MSK = 0x7f800000, /* bits 23:30 */ |
1423 | TX_ABORT_REQUIRED_MSK = 0x80000000, /* bits 31:31 */ | 1423 | TX_ABORT_REQUIRED_MSK = 0x80000000, /* bits 31:31 */ |
1424 | }; | 1424 | }; |
1425 | 1425 | ||
1426 | static inline int iwl_is_tx_success(u32 status) | 1426 | static inline bool iwl_is_tx_success(u32 status) |
1427 | { | 1427 | { |
1428 | status &= TX_STATUS_MSK; | 1428 | status &= TX_STATUS_MSK; |
1429 | return (status == TX_STATUS_SUCCESS) | 1429 | return (status == TX_STATUS_SUCCESS) || |
1430 | || (status == TX_STATUS_DIRECT_DONE); | 1430 | (status == TX_STATUS_DIRECT_DONE); |
1431 | } | 1431 | } |
1432 | 1432 | ||
1433 | 1433 | ||
@@ -1452,10 +1452,9 @@ enum { | |||
1452 | AGG_TX_STATE_DELAY_TX_MSK = 0x400 | 1452 | AGG_TX_STATE_DELAY_TX_MSK = 0x400 |
1453 | }; | 1453 | }; |
1454 | 1454 | ||
1455 | #define AGG_TX_STATE_LAST_SENT_MSK \ | 1455 | #define AGG_TX_STATE_LAST_SENT_MSK (AGG_TX_STATE_LAST_SENT_TTL_MSK | \ |
1456 | (AGG_TX_STATE_LAST_SENT_TTL_MSK | \ | 1456 | AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK | \ |
1457 | AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK | \ | 1457 | AGG_TX_STATE_LAST_SENT_BT_KILL_MSK) |
1458 | AGG_TX_STATE_LAST_SENT_BT_KILL_MSK) | ||
1459 | 1458 | ||
1460 | /* # tx attempts for first frame in aggregation */ | 1459 | /* # tx attempts for first frame in aggregation */ |
1461 | #define AGG_TX_STATE_TRY_CNT_POS 12 | 1460 | #define AGG_TX_STATE_TRY_CNT_POS 12 |
@@ -1528,6 +1527,28 @@ struct iwl4965_tx_resp { | |||
1528 | } u; | 1527 | } u; |
1529 | } __attribute__ ((packed)); | 1528 | } __attribute__ ((packed)); |
1530 | 1529 | ||
1530 | /* | ||
1531 | * definitions for initial rate index field | ||
1532 | * bits [3:0] inital rate index | ||
1533 | * bits [6:4] rate table color, used for the initial rate | ||
1534 | * bit-7 invalid rate indication | ||
1535 | * i.e. rate was not chosen from rate table | ||
1536 | * or rate table color was changed during frame retries | ||
1537 | * refer tlc rate info | ||
1538 | */ | ||
1539 | |||
1540 | #define IWL50_TX_RES_INIT_RATE_INDEX_POS 0 | ||
1541 | #define IWL50_TX_RES_INIT_RATE_INDEX_MSK 0x0f | ||
1542 | #define IWL50_TX_RES_RATE_TABLE_COLOR_POS 4 | ||
1543 | #define IWL50_TX_RES_RATE_TABLE_COLOR_MSK 0x70 | ||
1544 | #define IWL50_TX_RES_INV_RATE_INDEX_MSK 0x80 | ||
1545 | |||
1546 | /* refer to ra_tid */ | ||
1547 | #define IWL50_TX_RES_TID_POS 0 | ||
1548 | #define IWL50_TX_RES_TID_MSK 0x0f | ||
1549 | #define IWL50_TX_RES_RA_POS 4 | ||
1550 | #define IWL50_TX_RES_RA_MSK 0xf0 | ||
1551 | |||
1531 | struct iwl5000_tx_resp { | 1552 | struct iwl5000_tx_resp { |
1532 | u8 frame_count; /* 1 no aggregation, >1 aggregation */ | 1553 | u8 frame_count; /* 1 no aggregation, >1 aggregation */ |
1533 | u8 bt_kill_count; /* # blocked by bluetooth (unused for agg) */ | 1554 | u8 bt_kill_count; /* # blocked by bluetooth (unused for agg) */ |
@@ -1542,14 +1563,17 @@ struct iwl5000_tx_resp { | |||
1542 | * For agg: RTS + CTS + aggregation tx time + block-ack time. */ | 1563 | * For agg: RTS + CTS + aggregation tx time + block-ack time. */ |
1543 | __le16 wireless_media_time; /* uSecs */ | 1564 | __le16 wireless_media_time; /* uSecs */ |
1544 | 1565 | ||
1545 | __le16 reserved; | 1566 | u8 pa_status; /* RF power amplifier measurement (not used) */ |
1546 | __le32 pa_power1; /* RF power amplifier measurement (not used) */ | 1567 | u8 pa_integ_res_a[3]; |
1547 | __le32 pa_power2; | 1568 | u8 pa_integ_res_b[3]; |
1569 | u8 pa_integ_res_C[3]; | ||
1548 | 1570 | ||
1549 | __le32 tfd_info; | 1571 | __le32 tfd_info; |
1550 | __le16 seq_ctl; | 1572 | __le16 seq_ctl; |
1551 | __le16 byte_cnt; | 1573 | __le16 byte_cnt; |
1552 | __le32 tlc_info; | 1574 | u8 tlc_info; |
1575 | u8 ra_tid; /* tid (0:3), sta_id (4:7) */ | ||
1576 | __le16 frame_ctrl; | ||
1553 | /* | 1577 | /* |
1554 | * For non-agg: frame status TX_STATUS_* | 1578 | * For non-agg: frame status TX_STATUS_* |
1555 | * For agg: status of 1st frame, AGG_TX_STATE_*; other frame status | 1579 | * For agg: status of 1st frame, AGG_TX_STATE_*; other frame status |
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index e548d67f87fd..2b48a4c01776 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h | |||
@@ -183,6 +183,8 @@ static inline void iwl_dbgfs_unregister(struct iwl_priv *priv) | |||
183 | #define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a) | 183 | #define IWL_DEBUG_STATS(f, a...) IWL_DEBUG(IWL_DL_STATS, f, ## a) |
184 | #define IWL_DEBUG_STATS_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_STATS, f, ## a) | 184 | #define IWL_DEBUG_STATS_LIMIT(f, a...) IWL_DEBUG_LIMIT(IWL_DL_STATS, f, ## a) |
185 | #define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a) | 185 | #define IWL_DEBUG_TX_REPLY(f, a...) IWL_DEBUG(IWL_DL_TX_REPLY, f, ## a) |
186 | #define IWL_DEBUG_TX_REPLY_LIMIT(f, a...) \ | ||
187 | IWL_DEBUG_LIMIT(IWL_DL_TX_REPLY, f, ## a) | ||
186 | #define IWL_DEBUG_QOS(f, a...) IWL_DEBUG(IWL_DL_QOS, f, ## a) | 188 | #define IWL_DEBUG_QOS(f, a...) IWL_DEBUG(IWL_DL_QOS, f, ## a) |
187 | #define IWL_DEBUG_RADIO(f, a...) IWL_DEBUG(IWL_DL_RADIO, f, ## a) | 189 | #define IWL_DEBUG_RADIO(f, a...) IWL_DEBUG(IWL_DL_RADIO, f, ## a) |
188 | #define IWL_DEBUG_POWER(f, a...) IWL_DEBUG(IWL_DL_POWER, f, ## a) | 190 | #define IWL_DEBUG_POWER(f, a...) IWL_DEBUG(IWL_DL_POWER, f, ## a) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 1f42e90c5f30..2f871f0c5d36 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -135,9 +135,10 @@ struct iwl_tx_queue { | |||
135 | struct iwl_tfd *tfds; | 135 | struct iwl_tfd *tfds; |
136 | struct iwl_cmd *cmd[TFD_TX_CMD_SLOTS]; | 136 | struct iwl_cmd *cmd[TFD_TX_CMD_SLOTS]; |
137 | struct iwl_tx_info *txb; | 137 | struct iwl_tx_info *txb; |
138 | int need_update; | 138 | u8 need_update; |
139 | int sched_retry; | 139 | u8 sched_retry; |
140 | int active; | 140 | u8 active; |
141 | u8 swq_id; | ||
141 | }; | 142 | }; |
142 | 143 | ||
143 | #define IWL_NUM_SCAN_RATES (2) | 144 | #define IWL_NUM_SCAN_RATES (2) |
@@ -519,7 +520,6 @@ struct iwl_sensitivity_ranges { | |||
519 | * @ct_kill_threshold: temperature threshold | 520 | * @ct_kill_threshold: temperature threshold |
520 | * @calib_init_cfg: setup initial claibrations for the hw | 521 | * @calib_init_cfg: setup initial claibrations for the hw |
521 | * @struct iwl_sensitivity_ranges: range of sensitivity values | 522 | * @struct iwl_sensitivity_ranges: range of sensitivity values |
522 | * @first_ampdu_q: first HW queue available for ampdu | ||
523 | */ | 523 | */ |
524 | struct iwl_hw_params { | 524 | struct iwl_hw_params { |
525 | u16 max_txq_num; | 525 | u16 max_txq_num; |
@@ -541,7 +541,6 @@ struct iwl_hw_params { | |||
541 | u32 ct_kill_threshold; /* value in hw-dependent units */ | 541 | u32 ct_kill_threshold; /* value in hw-dependent units */ |
542 | u32 calib_init_cfg; | 542 | u32 calib_init_cfg; |
543 | const struct iwl_sensitivity_ranges *sens; | 543 | const struct iwl_sensitivity_ranges *sens; |
544 | u8 first_ampdu_q; | ||
545 | }; | 544 | }; |
546 | 545 | ||
547 | #define HT_SHORT_GI_20MHZ (1 << 0) | 546 | #define HT_SHORT_GI_20MHZ (1 << 0) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 6cf4a7c428dd..cfa78260c594 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -895,9 +895,9 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
895 | priv->stations[sta_id].tid[tid].tfds_in_queue++; | 895 | priv->stations[sta_id].tid[tid].tfds_in_queue++; |
896 | } | 896 | } |
897 | 897 | ||
898 | /* Descriptor for chosen Tx queue */ | ||
899 | txq = &priv->txq[txq_id]; | 898 | txq = &priv->txq[txq_id]; |
900 | q = &txq->q; | 899 | q = &txq->q; |
900 | txq->swq_id = swq_id; | ||
901 | 901 | ||
902 | spin_lock_irqsave(&priv->lock, flags); | 902 | spin_lock_irqsave(&priv->lock, flags); |
903 | 903 | ||
@@ -1023,7 +1023,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
1023 | iwl_txq_update_write_ptr(priv, txq); | 1023 | iwl_txq_update_write_ptr(priv, txq); |
1024 | spin_unlock_irqrestore(&priv->lock, flags); | 1024 | spin_unlock_irqrestore(&priv->lock, flags); |
1025 | } else { | 1025 | } else { |
1026 | ieee80211_stop_queue(priv->hw, swq_id); | 1026 | ieee80211_stop_queue(priv->hw, txq->swq_id); |
1027 | } | 1027 | } |
1028 | } | 1028 | } |
1029 | 1029 | ||
@@ -1395,8 +1395,8 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id) | |||
1395 | case IWL_EMPTYING_HW_QUEUE_DELBA: | 1395 | case IWL_EMPTYING_HW_QUEUE_DELBA: |
1396 | /* We are reclaiming the last packet of the */ | 1396 | /* We are reclaiming the last packet of the */ |
1397 | /* aggregated HW queue */ | 1397 | /* aggregated HW queue */ |
1398 | if (txq_id == tid_data->agg.txq_id && | 1398 | if ((txq_id == tid_data->agg.txq_id) && |
1399 | q->read_ptr == q->write_ptr) { | 1399 | (q->read_ptr == q->write_ptr)) { |
1400 | u16 ssn = SEQ_TO_SN(tid_data->seq_number); | 1400 | u16 ssn = SEQ_TO_SN(tid_data->seq_number); |
1401 | int tx_fifo = default_tid_to_tx_fifo[tid]; | 1401 | int tx_fifo = default_tid_to_tx_fifo[tid]; |
1402 | IWL_DEBUG_HT("HW queue empty: continue DELBA flow\n"); | 1402 | IWL_DEBUG_HT("HW queue empty: continue DELBA flow\n"); |
@@ -1447,7 +1447,7 @@ static int iwl_tx_status_reply_compressed_ba(struct iwl_priv *priv, | |||
1447 | IWL_DEBUG_TX_REPLY("BA %d %d\n", agg->start_idx, ba_resp->seq_ctl); | 1447 | IWL_DEBUG_TX_REPLY("BA %d %d\n", agg->start_idx, ba_resp->seq_ctl); |
1448 | 1448 | ||
1449 | /* Calculate shift to align block-ack bits with our Tx window bits */ | 1449 | /* Calculate shift to align block-ack bits with our Tx window bits */ |
1450 | sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl>>4); | 1450 | sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl >> 4); |
1451 | if (sh < 0) /* tbw something is wrong with indices */ | 1451 | if (sh < 0) /* tbw something is wrong with indices */ |
1452 | sh += 0x100; | 1452 | sh += 0x100; |
1453 | 1453 | ||
@@ -1497,9 +1497,11 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
1497 | { | 1497 | { |
1498 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | 1498 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; |
1499 | struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; | 1499 | struct iwl_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba; |
1500 | int index; | ||
1501 | struct iwl_tx_queue *txq = NULL; | 1500 | struct iwl_tx_queue *txq = NULL; |
1502 | struct iwl_ht_agg *agg; | 1501 | struct iwl_ht_agg *agg; |
1502 | int index; | ||
1503 | int sta_id; | ||
1504 | int tid; | ||
1503 | 1505 | ||
1504 | /* "flow" corresponds to Tx queue */ | 1506 | /* "flow" corresponds to Tx queue */ |
1505 | u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); | 1507 | u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); |
@@ -1514,14 +1516,16 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
1514 | } | 1516 | } |
1515 | 1517 | ||
1516 | txq = &priv->txq[scd_flow]; | 1518 | txq = &priv->txq[scd_flow]; |
1517 | agg = &priv->stations[ba_resp->sta_id].tid[ba_resp->tid].agg; | 1519 | sta_id = ba_resp->sta_id; |
1520 | tid = ba_resp->tid; | ||
1521 | agg = &priv->stations[sta_id].tid[tid].agg; | ||
1518 | 1522 | ||
1519 | /* Find index just before block-ack window */ | 1523 | /* Find index just before block-ack window */ |
1520 | index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd); | 1524 | index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd); |
1521 | 1525 | ||
1522 | /* TODO: Need to get this copy more safely - now good for debug */ | 1526 | /* TODO: Need to get this copy more safely - now good for debug */ |
1523 | 1527 | ||
1524 | IWL_DEBUG_TX_REPLY("REPLY_COMPRESSED_BA [%d]Received from %pM, " | 1528 | IWL_DEBUG_TX_REPLY("REPLY_COMPRESSED_BA [%d] Received from %pM, " |
1525 | "sta_id = %d\n", | 1529 | "sta_id = %d\n", |
1526 | agg->wait_for_ba, | 1530 | agg->wait_for_ba, |
1527 | (u8 *) &ba_resp->sta_addr_lo32, | 1531 | (u8 *) &ba_resp->sta_addr_lo32, |
@@ -1545,18 +1549,15 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv, | |||
1545 | * transmitted ... if not, it's too late anyway). */ | 1549 | * transmitted ... if not, it's too late anyway). */ |
1546 | if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) { | 1550 | if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) { |
1547 | /* calculate mac80211 ampdu sw queue to wake */ | 1551 | /* calculate mac80211 ampdu sw queue to wake */ |
1548 | int ampdu_q = | ||
1549 | scd_flow - priv->hw_params.first_ampdu_q + priv->hw->queues; | ||
1550 | int freed = iwl_tx_queue_reclaim(priv, scd_flow, index); | 1552 | int freed = iwl_tx_queue_reclaim(priv, scd_flow, index); |
1551 | priv->stations[ba_resp->sta_id]. | 1553 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; |
1552 | tid[ba_resp->tid].tfds_in_queue -= freed; | 1554 | |
1553 | if (iwl_queue_space(&txq->q) > txq->q.low_mark && | 1555 | if ((iwl_queue_space(&txq->q) > txq->q.low_mark) && |
1554 | priv->mac80211_registered && | 1556 | priv->mac80211_registered && |
1555 | agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) | 1557 | (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA)) |
1556 | ieee80211_wake_queue(priv->hw, ampdu_q); | 1558 | ieee80211_wake_queue(priv->hw, txq->swq_id); |
1557 | 1559 | ||
1558 | iwl_txq_check_empty(priv, ba_resp->sta_id, | 1560 | iwl_txq_check_empty(priv, sta_id, tid, scd_flow); |
1559 | ba_resp->tid, scd_flow); | ||
1560 | } | 1561 | } |
1561 | } | 1562 | } |
1562 | EXPORT_SYMBOL(iwl_rx_reply_compressed_ba); | 1563 | EXPORT_SYMBOL(iwl_rx_reply_compressed_ba); |