diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-5000.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-5000.c | 81 |
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 | } |