diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2008-05-29 04:35:12 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-06-03 15:00:24 -0400 |
commit | 17b889290a184b52ee394c31dd5a52b8c1b3456d (patch) | |
tree | 2e8889673a9f26b1a1afb2291ede6032eeadd1bb /drivers/net/wireless/iwlwifi/iwl4965-base.c | |
parent | a5e8b5056ea8762e67c9fa980c8db48009ed2a67 (diff) |
iwlwifi: move tx reclaim flow into iwl-tx
This patch
1. moves TX reclaim flow into iwl-tx
2. separates command queue and tx queue reclaim flow
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl4965-base.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl4965-base.c | 93 |
1 files changed, 1 insertions, 92 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 10d773413aa5..4322cd604f41 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -1535,51 +1535,6 @@ static int iwl4965_get_measurement(struct iwl_priv *priv, | |||
1535 | } | 1535 | } |
1536 | #endif | 1536 | #endif |
1537 | 1537 | ||
1538 | static void iwl4965_txstatus_to_ieee(struct iwl_priv *priv, | ||
1539 | struct iwl_tx_info *tx_sta) | ||
1540 | { | ||
1541 | ieee80211_tx_status_irqsafe(priv->hw, tx_sta->skb[0]); | ||
1542 | tx_sta->skb[0] = NULL; | ||
1543 | } | ||
1544 | |||
1545 | /** | ||
1546 | * iwl4965_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd | ||
1547 | * | ||
1548 | * When FW advances 'R' index, all entries between old and new 'R' index | ||
1549 | * need to be reclaimed. As result, some free space forms. If there is | ||
1550 | * enough free space (> low mark), wake the stack that feeds us. | ||
1551 | */ | ||
1552 | int iwl4965_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) | ||
1553 | { | ||
1554 | struct iwl_tx_queue *txq = &priv->txq[txq_id]; | ||
1555 | struct iwl_queue *q = &txq->q; | ||
1556 | int nfreed = 0; | ||
1557 | |||
1558 | if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) { | ||
1559 | IWL_ERROR("Read index for DMA queue txq id (%d), index %d, " | ||
1560 | "is out of range [0-%d] %d %d.\n", txq_id, | ||
1561 | index, q->n_bd, q->write_ptr, q->read_ptr); | ||
1562 | return 0; | ||
1563 | } | ||
1564 | |||
1565 | for (index = iwl_queue_inc_wrap(index, q->n_bd); | ||
1566 | q->read_ptr != index; | ||
1567 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { | ||
1568 | if (txq_id != IWL_CMD_QUEUE_NUM) { | ||
1569 | iwl4965_txstatus_to_ieee(priv, | ||
1570 | &(txq->txb[txq->q.read_ptr])); | ||
1571 | iwl_hw_txq_free_tfd(priv, txq); | ||
1572 | } else if (nfreed > 1) { | ||
1573 | IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index, | ||
1574 | q->write_ptr, q->read_ptr); | ||
1575 | queue_work(priv->workqueue, &priv->restart); | ||
1576 | } | ||
1577 | nfreed++; | ||
1578 | } | ||
1579 | |||
1580 | return nfreed; | ||
1581 | } | ||
1582 | |||
1583 | /****************************************************************************** | 1538 | /****************************************************************************** |
1584 | * | 1539 | * |
1585 | * Generic RX handler implementations | 1540 | * Generic RX handler implementations |
@@ -1961,52 +1916,6 @@ static void iwl4965_setup_rx_handlers(struct iwl_priv *priv) | |||
1961 | priv->cfg->ops->lib->rx_handler_setup(priv); | 1916 | priv->cfg->ops->lib->rx_handler_setup(priv); |
1962 | } | 1917 | } |
1963 | 1918 | ||
1964 | /** | ||
1965 | * iwl4965_tx_cmd_complete - Pull unused buffers off the queue and reclaim them | ||
1966 | * @rxb: Rx buffer to reclaim | ||
1967 | * | ||
1968 | * If an Rx buffer has an async callback associated with it the callback | ||
1969 | * will be executed. The attached skb (if present) will only be freed | ||
1970 | * if the callback returns 1 | ||
1971 | */ | ||
1972 | static void iwl4965_tx_cmd_complete(struct iwl_priv *priv, | ||
1973 | struct iwl_rx_mem_buffer *rxb) | ||
1974 | { | ||
1975 | struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; | ||
1976 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); | ||
1977 | int txq_id = SEQ_TO_QUEUE(sequence); | ||
1978 | int index = SEQ_TO_INDEX(sequence); | ||
1979 | int huge = sequence & SEQ_HUGE_FRAME; | ||
1980 | int cmd_index; | ||
1981 | struct iwl_cmd *cmd; | ||
1982 | |||
1983 | /* If a Tx command is being handled and it isn't in the actual | ||
1984 | * command queue then there a command routing bug has been introduced | ||
1985 | * in the queue management code. */ | ||
1986 | if (txq_id != IWL_CMD_QUEUE_NUM) | ||
1987 | IWL_ERROR("Error wrong command queue %d command id 0x%X\n", | ||
1988 | txq_id, pkt->hdr.cmd); | ||
1989 | BUG_ON(txq_id != IWL_CMD_QUEUE_NUM); | ||
1990 | |||
1991 | cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge); | ||
1992 | cmd = &priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index]; | ||
1993 | |||
1994 | /* Input error checking is done when commands are added to queue. */ | ||
1995 | if (cmd->meta.flags & CMD_WANT_SKB) { | ||
1996 | cmd->meta.source->u.skb = rxb->skb; | ||
1997 | rxb->skb = NULL; | ||
1998 | } else if (cmd->meta.u.callback && | ||
1999 | !cmd->meta.u.callback(priv, cmd, rxb->skb)) | ||
2000 | rxb->skb = NULL; | ||
2001 | |||
2002 | iwl4965_tx_queue_reclaim(priv, txq_id, index); | ||
2003 | |||
2004 | if (!(cmd->meta.flags & CMD_ASYNC)) { | ||
2005 | clear_bit(STATUS_HCMD_ACTIVE, &priv->status); | ||
2006 | wake_up_interruptible(&priv->wait_command_queue); | ||
2007 | } | ||
2008 | } | ||
2009 | |||
2010 | /* | 1919 | /* |
2011 | * this should be called while priv->lock is locked | 1920 | * this should be called while priv->lock is locked |
2012 | */ | 1921 | */ |
@@ -2095,7 +2004,7 @@ void iwl_rx_handle(struct iwl_priv *priv) | |||
2095 | * fire off the (possibly) blocking iwl_send_cmd() | 2004 | * fire off the (possibly) blocking iwl_send_cmd() |
2096 | * as we reclaim the driver command queue */ | 2005 | * as we reclaim the driver command queue */ |
2097 | if (rxb && rxb->skb) | 2006 | if (rxb && rxb->skb) |
2098 | iwl4965_tx_cmd_complete(priv, rxb); | 2007 | iwl_tx_cmd_complete(priv, rxb); |
2099 | else | 2008 | else |
2100 | IWL_WARNING("Claim null rxb?\n"); | 2009 | IWL_WARNING("Claim null rxb?\n"); |
2101 | } | 2010 | } |