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>
This commit is contained in:
committed by
John W. Linville
parent
28447f3cfd
commit
91c066f27b
@@ -227,14 +227,126 @@ __le32 iwl3945_get_antenna_flags(const struct iwl3945_priv *priv)
|
|||||||
return 0; /* "diversity" is default if error */
|
return 0; /* "diversity" is default if error */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_IWL3945_DEBUG
|
||||||
|
#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
|
||||||
|
|
||||||
|
static const char *iwl3945_get_tx_fail_reason(u32 status)
|
||||||
|
{
|
||||||
|
switch (status & TX_STATUS_MSK) {
|
||||||
|
case TX_STATUS_SUCCESS:
|
||||||
|
return "SUCCESS";
|
||||||
|
TX_STATUS_ENTRY(SHORT_LIMIT);
|
||||||
|
TX_STATUS_ENTRY(LONG_LIMIT);
|
||||||
|
TX_STATUS_ENTRY(FIFO_UNDERRUN);
|
||||||
|
TX_STATUS_ENTRY(MGMNT_ABORT);
|
||||||
|
TX_STATUS_ENTRY(NEXT_FRAG);
|
||||||
|
TX_STATUS_ENTRY(LIFE_EXPIRE);
|
||||||
|
TX_STATUS_ENTRY(DEST_PS);
|
||||||
|
TX_STATUS_ENTRY(ABORTED);
|
||||||
|
TX_STATUS_ENTRY(BT_RETRY);
|
||||||
|
TX_STATUS_ENTRY(STA_INVALID);
|
||||||
|
TX_STATUS_ENTRY(FRAG_DROPPED);
|
||||||
|
TX_STATUS_ENTRY(TID_DISABLE);
|
||||||
|
TX_STATUS_ENTRY(FRAME_FLUSHED);
|
||||||
|
TX_STATUS_ENTRY(INSUFFICIENT_CF_POLL);
|
||||||
|
TX_STATUS_ENTRY(TX_LOCKED);
|
||||||
|
TX_STATUS_ENTRY(NO_BEACON_ON_RADAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline const char *iwl3945_get_tx_fail_reason(u32 status)
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* iwl3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd
|
||||||
|
*
|
||||||
|
* When FW advances 'R' index, all entries between old and new 'R' index
|
||||||
|
* need to be reclaimed. As result, some free space forms. If there is
|
||||||
|
* enough free space (> low mark), wake the stack that feeds us.
|
||||||
|
*/
|
||||||
|
static void iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv,
|
||||||
|
int txq_id, int index)
|
||||||
|
{
|
||||||
|
struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
|
||||||
|
struct iwl3945_queue *q = &txq->q;
|
||||||
|
struct iwl3945_tx_info *tx_info;
|
||||||
|
|
||||||
|
BUG_ON(txq_id == IWL_CMD_QUEUE_NUM);
|
||||||
|
|
||||||
|
for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index;
|
||||||
|
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
|
||||||
|
|
||||||
|
tx_info = &txq->txb[txq->q.read_ptr];
|
||||||
|
ieee80211_tx_status(priv->hw, tx_info->skb[0],
|
||||||
|
&tx_info->status);
|
||||||
|
tx_info->skb[0] = NULL;
|
||||||
|
iwl3945_hw_txq_free_tfd(priv, txq);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iwl3945_queue_space(q) > q->low_mark && (txq_id >= 0) &&
|
||||||
|
(txq_id != IWL_CMD_QUEUE_NUM) &&
|
||||||
|
priv->mac80211_registered)
|
||||||
|
ieee80211_wake_queue(priv->hw, txq_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* iwl3945_rx_reply_tx - Handle Tx response
|
||||||
|
*/
|
||||||
|
static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
|
||||||
|
struct iwl3945_rx_mem_buffer *rxb)
|
||||||
|
{
|
||||||
|
struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
|
||||||
|
u16 sequence = le16_to_cpu(pkt->hdr.sequence);
|
||||||
|
int txq_id = SEQ_TO_QUEUE(sequence);
|
||||||
|
int index = SEQ_TO_INDEX(sequence);
|
||||||
|
struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
|
||||||
|
struct ieee80211_tx_status *tx_status;
|
||||||
|
struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
|
||||||
|
u32 status = le32_to_cpu(tx_resp->status);
|
||||||
|
int rate_idx;
|
||||||
|
|
||||||
|
if ((index >= txq->q.n_bd) || (iwl3945_x2_queue_used(&txq->q, index) == 0)) {
|
||||||
|
IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
|
||||||
|
"is out of range [0-%d] %d %d\n", txq_id,
|
||||||
|
index, txq->q.n_bd, txq->q.write_ptr,
|
||||||
|
txq->q.read_ptr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tx_status = &(txq->txb[txq->q.read_ptr].status);
|
||||||
|
|
||||||
|
tx_status->retry_count = tx_resp->failure_frame;
|
||||||
|
/* tx_status->rts_retry_count = tx_resp->failure_rts; */
|
||||||
|
tx_status->flags = ((status & TX_STATUS_MSK) == TX_STATUS_SUCCESS) ?
|
||||||
|
IEEE80211_TX_STATUS_ACK : 0;
|
||||||
|
|
||||||
|
IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n",
|
||||||
|
txq_id, iwl3945_get_tx_fail_reason(status), status,
|
||||||
|
tx_resp->rate, tx_resp->failure_frame);
|
||||||
|
|
||||||
|
rate_idx = iwl3945_hwrate_to_plcp_idx(tx_resp->rate);
|
||||||
|
tx_status->control.tx_rate = &priv->ieee_rates[rate_idx];
|
||||||
|
IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
|
||||||
|
iwl3945_tx_queue_reclaim(priv, txq_id, index);
|
||||||
|
|
||||||
|
if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
|
||||||
|
IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
*
|
*
|
||||||
* Intel PRO/Wireless 3945ABG/BG Network Connection
|
* Intel PRO/Wireless 3945ABG/BG Network Connection
|
||||||
*
|
*
|
||||||
* RX handler implementations
|
* RX handler implementations
|
||||||
*
|
*
|
||||||
* Used by iwl-base.c
|
|
||||||
*
|
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, struct iwl3945_rx_mem_buffer *rxb)
|
void 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,
|
|||||||
|
|
||||||
void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv)
|
void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv)
|
||||||
{
|
{
|
||||||
|
priv->rx_handlers[REPLY_TX] = iwl3945_rx_reply_tx;
|
||||||
priv->rx_handlers[REPLY_3945_RX] = iwl3945_rx_reply_rx;
|
priv->rx_handlers[REPLY_3945_RX] = iwl3945_rx_reply_rx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2063,34 +2063,6 @@ int iwl3945_is_network_packet(struct iwl3945_priv *priv, struct ieee80211_hdr *h
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x
|
|
||||||
|
|
||||||
static const char *iwl3945_get_tx_fail_reason(u32 status)
|
|
||||||
{
|
|
||||||
switch (status & TX_STATUS_MSK) {
|
|
||||||
case TX_STATUS_SUCCESS:
|
|
||||||
return "SUCCESS";
|
|
||||||
TX_STATUS_ENTRY(SHORT_LIMIT);
|
|
||||||
TX_STATUS_ENTRY(LONG_LIMIT);
|
|
||||||
TX_STATUS_ENTRY(FIFO_UNDERRUN);
|
|
||||||
TX_STATUS_ENTRY(MGMNT_ABORT);
|
|
||||||
TX_STATUS_ENTRY(NEXT_FRAG);
|
|
||||||
TX_STATUS_ENTRY(LIFE_EXPIRE);
|
|
||||||
TX_STATUS_ENTRY(DEST_PS);
|
|
||||||
TX_STATUS_ENTRY(ABORTED);
|
|
||||||
TX_STATUS_ENTRY(BT_RETRY);
|
|
||||||
TX_STATUS_ENTRY(STA_INVALID);
|
|
||||||
TX_STATUS_ENTRY(FRAG_DROPPED);
|
|
||||||
TX_STATUS_ENTRY(TID_DISABLE);
|
|
||||||
TX_STATUS_ENTRY(FRAME_FLUSHED);
|
|
||||||
TX_STATUS_ENTRY(INSUFFICIENT_CF_POLL);
|
|
||||||
TX_STATUS_ENTRY(TX_LOCKED);
|
|
||||||
TX_STATUS_ENTRY(NO_BEACON_ON_RADAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
return "UNKNOWN";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* iwl3945_scan_cancel - Cancel any currently executing HW scan
|
* iwl3945_scan_cancel - Cancel any currently executing HW scan
|
||||||
*
|
*
|
||||||
@@ -3138,125 +3110,6 @@ static int iwl3945_get_measurement(struct iwl3945_priv *priv,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void iwl3945_txstatus_to_ieee(struct iwl3945_priv *priv,
|
|
||||||
struct iwl3945_tx_info *tx_sta)
|
|
||||||
{
|
|
||||||
|
|
||||||
tx_sta->status.ack_signal = 0;
|
|
||||||
tx_sta->status.excessive_retries = 0;
|
|
||||||
tx_sta->status.queue_length = 0;
|
|
||||||
tx_sta->status.queue_number = 0;
|
|
||||||
|
|
||||||
if (in_interrupt())
|
|
||||||
ieee80211_tx_status_irqsafe(priv->hw,
|
|
||||||
tx_sta->skb[0], &(tx_sta->status));
|
|
||||||
else
|
|
||||||
ieee80211_tx_status(priv->hw,
|
|
||||||
tx_sta->skb[0], &(tx_sta->status));
|
|
||||||
|
|
||||||
tx_sta->skb[0] = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* iwl3945_tx_queue_reclaim - Reclaim Tx queue entries already Tx'd
|
|
||||||
*
|
|
||||||
* When FW advances 'R' index, all entries between old and new 'R' index
|
|
||||||
* need to be reclaimed. As result, some free space forms. If there is
|
|
||||||
* enough free space (> low mark), wake the stack that feeds us.
|
|
||||||
*/
|
|
||||||
static int iwl3945_tx_queue_reclaim(struct iwl3945_priv *priv, int txq_id, int index)
|
|
||||||
{
|
|
||||||
struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
|
|
||||||
struct iwl3945_queue *q = &txq->q;
|
|
||||||
int nfreed = 0;
|
|
||||||
|
|
||||||
if ((index >= q->n_bd) || (iwl3945_x2_queue_used(q, index) == 0)) {
|
|
||||||
IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
|
|
||||||
"is out of range [0-%d] %d %d.\n", txq_id,
|
|
||||||
index, q->n_bd, q->write_ptr, q->read_ptr);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (index = iwl_queue_inc_wrap(index, q->n_bd);
|
|
||||||
q->read_ptr != index;
|
|
||||||
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
|
|
||||||
if (txq_id != IWL_CMD_QUEUE_NUM) {
|
|
||||||
iwl3945_txstatus_to_ieee(priv,
|
|
||||||
&(txq->txb[txq->q.read_ptr]));
|
|
||||||
iwl3945_hw_txq_free_tfd(priv, txq);
|
|
||||||
} else if (nfreed > 1) {
|
|
||||||
IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index,
|
|
||||||
q->write_ptr, q->read_ptr);
|
|
||||||
queue_work(priv->workqueue, &priv->restart);
|
|
||||||
}
|
|
||||||
nfreed++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (iwl3945_queue_space(q) > q->low_mark && (txq_id >= 0) &&
|
|
||||||
(txq_id != IWL_CMD_QUEUE_NUM) &&
|
|
||||||
priv->mac80211_registered)
|
|
||||||
ieee80211_wake_queue(priv->hw, txq_id);
|
|
||||||
|
|
||||||
|
|
||||||
return nfreed;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int iwl3945_is_tx_success(u32 status)
|
|
||||||
{
|
|
||||||
return (status & 0xFF) == 0x1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
*
|
|
||||||
* Generic RX handler implementations
|
|
||||||
*
|
|
||||||
******************************************************************************/
|
|
||||||
/**
|
|
||||||
* iwl3945_rx_reply_tx - Handle Tx response
|
|
||||||
*/
|
|
||||||
static void iwl3945_rx_reply_tx(struct iwl3945_priv *priv,
|
|
||||||
struct iwl3945_rx_mem_buffer *rxb)
|
|
||||||
{
|
|
||||||
struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
|
|
||||||
u16 sequence = le16_to_cpu(pkt->hdr.sequence);
|
|
||||||
int txq_id = SEQ_TO_QUEUE(sequence);
|
|
||||||
int index = SEQ_TO_INDEX(sequence);
|
|
||||||
struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
|
|
||||||
struct ieee80211_tx_status *tx_status;
|
|
||||||
struct iwl3945_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
|
|
||||||
u32 status = le32_to_cpu(tx_resp->status);
|
|
||||||
|
|
||||||
if ((index >= txq->q.n_bd) || (iwl3945_x2_queue_used(&txq->q, index) == 0)) {
|
|
||||||
IWL_ERROR("Read index for DMA queue txq_id (%d) index %d "
|
|
||||||
"is out of range [0-%d] %d %d\n", txq_id,
|
|
||||||
index, txq->q.n_bd, txq->q.write_ptr,
|
|
||||||
txq->q.read_ptr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
tx_status = &(txq->txb[txq->q.read_ptr].status);
|
|
||||||
|
|
||||||
tx_status->retry_count = tx_resp->failure_frame;
|
|
||||||
tx_status->queue_number = status;
|
|
||||||
tx_status->queue_length = tx_resp->bt_kill_count;
|
|
||||||
tx_status->queue_length |= tx_resp->failure_rts;
|
|
||||||
|
|
||||||
tx_status->flags =
|
|
||||||
iwl3945_is_tx_success(status) ? IEEE80211_TX_STATUS_ACK : 0;
|
|
||||||
|
|
||||||
IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) plcp rate %d retries %d\n",
|
|
||||||
txq_id, iwl3945_get_tx_fail_reason(status), status,
|
|
||||||
tx_resp->rate, tx_resp->failure_frame);
|
|
||||||
|
|
||||||
IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index);
|
|
||||||
if (index != -1)
|
|
||||||
iwl3945_tx_queue_reclaim(priv, txq_id, index);
|
|
||||||
|
|
||||||
if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
|
|
||||||
IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void iwl3945_rx_reply_alive(struct iwl3945_priv *priv,
|
static void iwl3945_rx_reply_alive(struct iwl3945_priv *priv,
|
||||||
struct iwl3945_rx_mem_buffer *rxb)
|
struct iwl3945_rx_mem_buffer *rxb)
|
||||||
{
|
{
|
||||||
@@ -3603,12 +3456,43 @@ static void iwl3945_setup_rx_handlers(struct iwl3945_priv *priv)
|
|||||||
priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] =
|
priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] =
|
||||||
iwl3945_rx_scan_complete_notif;
|
iwl3945_rx_scan_complete_notif;
|
||||||
priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif;
|
priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl3945_rx_card_state_notif;
|
||||||
priv->rx_handlers[REPLY_TX] = iwl3945_rx_reply_tx;
|
|
||||||
|
|
||||||
/* Set up hardware specific Rx handlers */
|
/* Set up hardware specific Rx handlers */
|
||||||
iwl3945_hw_rx_handler_setup(priv);
|
iwl3945_hw_rx_handler_setup(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* iwl3945_cmd_queue_reclaim - Reclaim CMD queue entries
|
||||||
|
* When FW advances 'R' index, all entries between old and new 'R' index
|
||||||
|
* need to be reclaimed.
|
||||||
|
*/
|
||||||
|
static void iwl3945_cmd_queue_reclaim(struct iwl3945_priv *priv,
|
||||||
|
int txq_id, int index)
|
||||||
|
{
|
||||||
|
struct iwl3945_tx_queue *txq = &priv->txq[txq_id];
|
||||||
|
struct iwl3945_queue *q = &txq->q;
|
||||||
|
int nfreed = 0;
|
||||||
|
|
||||||
|
if ((index >= q->n_bd) || (iwl3945_x2_queue_used(q, index) == 0)) {
|
||||||
|
IWL_ERROR("Read index for DMA queue txq id (%d), index %d, "
|
||||||
|
"is out of range [0-%d] %d %d.\n", txq_id,
|
||||||
|
index, q->n_bd, q->write_ptr, q->read_ptr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (index = iwl_queue_inc_wrap(index, q->n_bd); q->read_ptr != index;
|
||||||
|
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
|
||||||
|
if (nfreed > 1) {
|
||||||
|
IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index,
|
||||||
|
q->write_ptr, q->read_ptr);
|
||||||
|
queue_work(priv->workqueue, &priv->restart);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nfreed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* iwl3945_tx_cmd_complete - Pull unused buffers off the queue and reclaim them
|
* iwl3945_tx_cmd_complete - Pull unused buffers off the queue and reclaim them
|
||||||
* @rxb: Rx buffer to reclaim
|
* @rxb: Rx buffer to reclaim
|
||||||
@@ -3628,12 +3512,6 @@ static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv,
|
|||||||
int cmd_index;
|
int cmd_index;
|
||||||
struct iwl3945_cmd *cmd;
|
struct iwl3945_cmd *cmd;
|
||||||
|
|
||||||
/* If a Tx command is being handled and it isn't in the actual
|
|
||||||
* command queue then there a command routing bug has been introduced
|
|
||||||
* in the queue management code. */
|
|
||||||
if (txq_id != IWL_CMD_QUEUE_NUM)
|
|
||||||
IWL_ERROR("Error wrong command queue %d command id 0x%X\n",
|
|
||||||
txq_id, pkt->hdr.cmd);
|
|
||||||
BUG_ON(txq_id != IWL_CMD_QUEUE_NUM);
|
BUG_ON(txq_id != IWL_CMD_QUEUE_NUM);
|
||||||
|
|
||||||
cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
|
cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
|
||||||
@@ -3647,7 +3525,7 @@ static void iwl3945_tx_cmd_complete(struct iwl3945_priv *priv,
|
|||||||
!cmd->meta.u.callback(priv, cmd, rxb->skb))
|
!cmd->meta.u.callback(priv, cmd, rxb->skb))
|
||||||
rxb->skb = NULL;
|
rxb->skb = NULL;
|
||||||
|
|
||||||
iwl3945_tx_queue_reclaim(priv, txq_id, index);
|
iwl3945_cmd_queue_reclaim(priv, txq_id, index);
|
||||||
|
|
||||||
if (!(cmd->meta.flags & CMD_ASYNC)) {
|
if (!(cmd->meta.flags & CMD_ASYNC)) {
|
||||||
clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
|
clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
|
||||||
|
Reference in New Issue
Block a user