aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-3945.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-3945.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c65
1 files changed, 59 insertions, 6 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 8a00245be51e..7afafb629706 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -261,6 +261,35 @@ static inline const char *iwl3945_get_tx_fail_reason(u32 status)
261} 261}
262#endif 262#endif
263 263
264/*
265 * get ieee prev rate from rate scale table.
266 * for A and B mode we need to overright prev
267 * value
268 */
269int iwl3945_rs_next_rate(struct iwl3945_priv *priv, int rate)
270{
271 int next_rate = iwl3945_get_prev_ieee_rate(rate);
272
273 switch (priv->band) {
274 case IEEE80211_BAND_5GHZ:
275 if (rate == IWL_RATE_12M_INDEX)
276 next_rate = IWL_RATE_9M_INDEX;
277 else if (rate == IWL_RATE_6M_INDEX)
278 next_rate = IWL_RATE_6M_INDEX;
279 break;
280/* XXX cannot be invoked in current mac80211 so not a regression
281 case MODE_IEEE80211B:
282 if (rate == IWL_RATE_11M_INDEX_TABLE)
283 next_rate = IWL_RATE_5M_INDEX_TABLE;
284 break;
285 */
286 default:
287 break;
288 }
289
290 return next_rate;
291}
292
264 293
265/** 294/**
266 * iwl3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd 295 * iwl3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd
@@ -308,6 +337,7 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
308 struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; 337 struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
309 u32 status = le32_to_cpu(tx_resp->status); 338 u32 status = le32_to_cpu(tx_resp->status);
310 int rate_idx; 339 int rate_idx;
340 int fail, i;
311 341
312 if ((index >= txq->q.n_bd) || (iwl3945_x2_queue_used(&txq->q, index) == 0)) { 342 if ((index >= txq->q.n_bd) || (iwl3945_x2_queue_used(&txq->q, index) == 0)) {
313 IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " 343 IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
@@ -318,9 +348,36 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
318 } 348 }
319 349
320 info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]); 350 info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]);
321 memset(&info->status, 0, sizeof(info->status)); 351 ieee80211_tx_info_clear_status(info);
352
353 /* Fill the MRR chain with some info about on-chip retransmissions */
354 rate_idx = iwl3945_hwrate_to_plcp_idx(tx_resp->rate);
355 if (info->band == IEEE80211_BAND_5GHZ)
356 rate_idx -= IWL_FIRST_OFDM_RATE;
357
358 fail = tx_resp->failure_frame;
359 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
360 int next = iwl3945_rs_next_rate(priv, rate_idx);
361
362 info->status.rates[i].idx = rate_idx;
363
364 /*
365 * Put remaining into the last count as best approximation
366 * of saying exactly what the hardware would have done...
367 */
368 if ((rate_idx == next) || (i == IEEE80211_TX_MAX_RATES - 1)) {
369 info->status.rates[i].count = fail;
370 break;
371 }
372
373 info->status.rates[i].count = priv->retry_rate;
374 fail -= priv->retry_rate;
375 rate_idx = next;
376 if (fail <= 0)
377 break;
378 }
379 info->status.rates[i].count++; /* add final attempt */
322 380
323 info->status.retry_count = tx_resp->failure_frame;
324 /* tx_status->rts_retry_count = tx_resp->failure_rts; */ 381 /* tx_status->rts_retry_count = tx_resp->failure_rts; */
325 info->flags |= ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ? 382 info->flags |= ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ?
326 IEEE80211_TX_STAT_ACK : 0; 383 IEEE80211_TX_STAT_ACK : 0;
@@ -329,10 +386,6 @@ static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
329 txq_id, iwl3945_get_tx_fail_reason(status), status, 386 txq_id, iwl3945_get_tx_fail_reason(status), status,
330 tx_resp->rate, tx_resp->failure_frame); 387 tx_resp->rate, tx_resp->failure_frame);
331 388
332 rate_idx = iwl3945_hwrate_to_plcp_idx(tx_resp->rate);
333 if (info->band == IEEE80211_BAND_5GHZ)
334 rate_idx -= IWL_FIRST_OFDM_RATE;
335 info->tx_rate_idx = rate_idx;
336 IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); 389 IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
337 iwl3945_tx_queue_reclaim(priv, txq_id, index); 390 iwl3945_tx_queue_reclaim(priv, txq_id, index);
338 391