aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-3945.c
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2008-03-06 20:36:55 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-03-07 16:03:02 -0500
commit91c066f27b6dacb6589fb5190af373fb9f993397 (patch)
tree0e89811d45705907265c01c49c715b6446529e9e /drivers/net/wireless/iwlwifi/iwl-3945.c
parent28447f3cfdf72f6ea97b50cc1eefe35602107dff (diff)
iwlwifi: 3945 split tx_complete to command and packet function
This patch 1. removes cmd completion from iwl3945_tx_queue_reclaim and creates iwl3945_cmd_queue_reclaim. 1. removes 11n relevant elements from this function 2. removes call to ieee80211_tx_status_irqsafe and uses ieee80211_tx_status only Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-3945.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c117
1 files changed, 115 insertions, 2 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 49b781104327..dc3d695bf096 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -227,14 +227,126 @@ __le32 iwl3945_get_antenna_flags(const struct iwl3945_priv *priv)
227 return 0; /* "diversity" is default if error */ 227 return 0; /* "diversity" is default if error */
228} 228}
229 229
230#ifdef CONFIG_IWL3945_DEBUG
231#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
232
233static const char *iwl3945_get_tx_fail_reason(u32 status)
234{
235 switch (status & TX_STATUS_MSK) {
236 case TX_STATUS_SUCCESS:
237 return "SUCCESS";
238 TX_STATUS_ENTRY(SHORT_LIMIT);
239 TX_STATUS_ENTRY(LONG_LIMIT);
240 TX_STATUS_ENTRY(FIFO_UNDERRUN);
241 TX_STATUS_ENTRY(MGMNT_ABORT);
242 TX_STATUS_ENTRY(NEXT_FRAG);
243 TX_STATUS_ENTRY(LIFE_EXPIRE);
244 TX_STATUS_ENTRY(DEST_PS);
245 TX_STATUS_ENTRY(ABORTED);
246 TX_STATUS_ENTRY(BT_RETRY);
247 TX_STATUS_ENTRY(STA_INVALID);
248 TX_STATUS_ENTRY(FRAG_DROPPED);
249 TX_STATUS_ENTRY(TID_DISABLE);
250 TX_STATUS_ENTRY(FRAME_FLUSHED);
251 TX_STATUS_ENTRY(INSUFFICIENT_CF_POLL);
252 TX_STATUS_ENTRY(TX_LOCKED);
253 TX_STATUS_ENTRY(NO_BEACON_ON_RADAR);
254 }
255
256 return "UNKNOWN";
257}
258#else
259static inline const char *iwl3945_get_tx_fail_reason(u32 status)
260{
261 return "";
262}
263#endif
264
265
266/**
267 * iwl3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd
268 *
269 * When FW advances 'R' index, all entries between old and new 'R' index
270 * need to be reclaimed. As result, some free space forms. If there is
271 * enough free space (> low mark), wake the stack that feeds us.
272 */
273static void iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv,
274 int txq_id, int index)
275{
276 struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
277 struct iwl3945_queue *q = &txq->q;
278 struct iwl3945_tx_info *tx_info;
279
280 BUG_ON(txq_id == IWL_CMD_QUEUE_NUM);
281
282 for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index;
283 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
284
285 tx_info = &txq->txb[txq->q.read_ptr];
286 ieee80211_tx_status(priv->hw, tx_info->skb[0],
287 &tx_info->status);
288 tx_info->skb[0] = NULL;
289 iwl3945_hw_txq_free_tfd(priv, txq);
290 }
291
292 if (iwl3945_queue_space(q) > q->low_mark && (txq_id >= 0) &&
293 (txq_id != IWL_CMD_QUEUE_NUM) &&
294 priv->mac80211_registered)
295 ieee80211_wake_queue(priv->hw, txq_id);
296}
297
298/**
299 * iwl3945_rx_reply_tx - Handle Tx response
300 */
301static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
302 struct iwl3945_rx_mem_buffer *rxb)
303{
304 struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
305 u16 sequence = le16_to_cpu(pkt->hdr.sequence);
306 int txq_id = SEQ_TO_QUEUE(sequence);
307 int index = SEQ_TO_INDEX(sequence);
308 struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
309 struct ieee80211_tx_status *tx_status;
310 struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
311 u32 status = le32_to_cpu(tx_resp->status);
312 int rate_idx;
313
314 if ((index >= txq->q.n_bd) || (iwl3945_x2_queue_used(&txq->q, index) == 0)) {
315 IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
316 "is out of range [0-%d] %d %d\n", txq_id,
317 index, txq->q.n_bd, txq->q.write_ptr,
318 txq->q.read_ptr);
319 return;
320 }
321
322 tx_status = &(txq->txb[txq->q.read_ptr].status);
323
324 tx_status->retry_count = tx_resp->failure_frame;
325 /* tx_status->rts_retry_count = tx_resp->failure_rts; */
326 tx_status->flags = ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ?
327 IEEE80211_TX_STATUS_ACK : 0;
328
329 IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n",
330 txq_id, iwl3945_get_tx_fail_reason(status), status,
331 tx_resp->rate, tx_resp->failure_frame);
332
333 rate_idx = iwl3945_hwrate_to_plcp_idx(tx_resp->rate);
334 tx_status->control.tx_rate = &priv->ieee_rates[rate_idx];
335 IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
336 iwl3945_tx_queue_reclaim(priv, txq_id, index);
337
338 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
339 IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
340}
341
342
343
230/***************************************************************************** 344/*****************************************************************************
231 * 345 *
232 * Intel PRO/Wireless 3945ABG/BG Network Connection 346 * Intel PRO/Wireless 3945ABG/BG Network Connection
233 * 347 *
234 * RX handler implementations 348 * RX handler implementations
235 * 349 *
236 * Used by iwl-base.c
237 *
238 *****************************************************************************/ 350 *****************************************************************************/
239 351
240void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, struct iwl3945_rx_mem_buffer *rxb) 352void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, struct iwl3945_rx_mem_buffer *rxb)
@@ -2510,6 +2622,7 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
2510 2622
2511void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv) 2623void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv)
2512{ 2624{
2625 priv->rx_handlers[REPLY_TX] = iwl3945_rx_reply_tx;
2513 priv->rx_handlers[REPLY_3945_RX] = iwl3945_rx_reply_rx; 2626 priv->rx_handlers[REPLY_3945_RX] = iwl3945_rx_reply_rx;
2514} 2627}
2515 2628