aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-5000.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-5000.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c81
1 files changed, 34 insertions, 47 deletions
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}