Skip to content

Commit

Permalink
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…git/iwlwifi/iwlwifi-next
  • Loading branch information
John W. Linville committed Jan 22, 2013
2 parents 660b9ca + 1c3fea8 commit aa3c90b
Show file tree
Hide file tree
Showing 8 changed files with 212 additions and 68 deletions.
8 changes: 3 additions & 5 deletions drivers/net/wireless/iwlwifi/dvm/mac80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,8 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,

#ifdef CONFIG_PM_SLEEP
if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
priv->trans->ops->wowlan_suspend &&
priv->trans->ops->d3_suspend &&
priv->trans->ops->d3_resume &&
device_can_wakeup(priv->trans->dev)) {
hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
WIPHY_WOWLAN_DISCONNECT |
Expand Down Expand Up @@ -426,7 +427,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
if (ret)
goto error;

iwl_trans_wowlan_suspend(priv->trans);
iwl_trans_d3_suspend(priv->trans);

goto out;

Expand Down Expand Up @@ -520,9 +521,6 @@ static void iwlagn_mac_tx(struct ieee80211_hw *hw,
{
struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);

IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);

if (iwlagn_tx_skb(priv, control->sta, skb))
ieee80211_free_txskb(hw, skb);
}
Expand Down
28 changes: 16 additions & 12 deletions drivers/net/wireless/iwlwifi/dvm/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,13 +231,11 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv,
memcpy(tx_cmd->key, keyconf->key, keyconf->keylen);
if (info->flags & IEEE80211_TX_CTL_AMPDU)
tx_cmd->tx_flags |= TX_CMD_FLG_AGG_CCMP_MSK;
IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n");
break;

case WLAN_CIPHER_SUITE_TKIP:
tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key);
IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n");
break;

case WLAN_CIPHER_SUITE_WEP104:
Expand Down Expand Up @@ -355,8 +353,6 @@ int iwlagn_tx_skb(struct iwl_priv *priv,
}
}

IWL_DEBUG_TX(priv, "station Id %d\n", sta_id);

if (sta)
sta_priv = (void *)sta->drv_priv;

Expand Down Expand Up @@ -472,6 +468,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv,
WARN_ON_ONCE(is_agg &&
priv->queue_to_mac80211[txq_id] != info->hw_queue);

IWL_DEBUG_TX(priv, "TX to [%d|%d] Q:%d - seq: 0x%x\n", sta_id, tid,
txq_id, seq_number);

if (iwl_trans_tx(priv->trans, skb, dev_cmd, txq_id))
goto drop_unlock_sta;

Expand Down Expand Up @@ -953,12 +952,6 @@ static void iwl_rx_reply_tx_agg(struct iwl_priv *priv,
if (status & (AGG_TX_STATE_FEW_BYTES_MSK |
AGG_TX_STATE_ABORT_MSK))
continue;

IWL_DEBUG_TX_REPLY(priv, "status %s (0x%08x), "
"try-count (0x%08x)\n",
iwl_get_agg_tx_fail_reason(fstatus),
fstatus & AGG_TX_STATUS_MSK,
fstatus & AGG_TX_TRY_MSK);
}
}

Expand Down Expand Up @@ -1212,16 +1205,27 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
freed++;
}

WARN_ON(!is_agg && freed != 1);
if (!is_agg && freed != 1)
IWL_ERR(priv, "Q: %d, freed %d\n", txq_id, freed);

/*
* An offchannel frame can be send only on the AUX queue, where
* there is no aggregation (and reordering) so it only is single
* skb is expected to be processed.
*/
WARN_ON(is_offchannel_skb && freed != 1);
if (is_offchannel_skb && freed != 1)
IWL_ERR(priv, "OFFCHANNEL SKB freed %d\n", freed);
}

IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x)\n", txq_id,
iwl_get_tx_fail_reason(status), status);

IWL_DEBUG_TX_REPLY(priv,
"\t\t\t\tinitial_rate 0x%x retries %d, idx=%d ssn=%d seq_ctl=0x%x\n",
le32_to_cpu(tx_resp->rate_n_flags),
tx_resp->failure_frame, SEQ_TO_INDEX(sequence), ssn,
le16_to_cpu(tx_resp->seq_ctl));

iwl_check_abort_status(priv, tx_resp->frame_count, status);
spin_unlock(&priv->sta_lock);

Expand Down
4 changes: 4 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-fh.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl)
#define FH_RSCSR_CHNL0_RBDCB_WPTR_REG (FH_MEM_RSCSR_CHNL0 + 0x008)
#define FH_RSCSR_CHNL0_WPTR (FH_RSCSR_CHNL0_RBDCB_WPTR_REG)

#define FW_RSCSR_CHNL0_RXDCB_RDPTR_REG (FH_MEM_RSCSR_CHNL0 + 0x00c)
#define FH_RSCSR_CHNL0_RDPTR FW_RSCSR_CHNL0_RXDCB_RDPTR_REG

/**
* Rx Config/Status Registers (RCSR)
Expand Down Expand Up @@ -257,6 +259,8 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl)
#define FH_MEM_RCSR_CHNL0 (FH_MEM_RCSR_LOWER_BOUND)

#define FH_MEM_RCSR_CHNL0_CONFIG_REG (FH_MEM_RCSR_CHNL0)
#define FH_MEM_RCSR_CHNL0_RBDCB_WPTR (FH_MEM_RCSR_CHNL0 + 0x8)
#define FH_MEM_RCSR_CHNL0_FLUSH_RB_REQ (FH_MEM_RCSR_CHNL0 + 0x10)

#define FH_RCSR_CHNL0_RX_CONFIG_RB_TIMEOUT_MSK (0x00000FF0) /* bits 4-11 */
#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_MSK (0x00001000) /* bits 12 */
Expand Down
32 changes: 27 additions & 5 deletions drivers/net/wireless/iwlwifi/iwl-trans.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,16 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r)
#define IWL_MAX_TID_COUNT 8
#define IWL_FRAME_LIMIT 64

/**
* enum iwl_wowlan_status - WoWLAN image/device status
* @IWL_D3_STATUS_ALIVE: firmware is still running after resume
* @IWL_D3_STATUS_RESET: device was reset while suspended
*/
enum iwl_d3_status {
IWL_D3_STATUS_ALIVE,
IWL_D3_STATUS_RESET,
};

/**
* struct iwl_trans_config - transport configuration
*
Expand Down Expand Up @@ -363,9 +373,12 @@ struct iwl_trans;
* May sleep
* @stop_device:stops the whole device (embedded CPU put to reset)
* May sleep
* @wowlan_suspend: put the device into the correct mode for WoWLAN during
* @d3_suspend: put the device into the correct mode for WoWLAN during
* suspend. This is optional, if not implemented WoWLAN will not be
* supported. This callback may sleep.
* @d3_resume: resume the device after WoWLAN, enabling the opmode to
* talk to the WoWLAN image to get its status. This is optional, if not
* implemented WoWLAN will not be supported. This callback may sleep.
* @send_cmd:send a host command. Must return -ERFKILL if RFkill is asserted.
* If RFkill is asserted in the middle of a SYNC host command, it must
* return -ERFKILL straight away.
Expand All @@ -391,7 +404,8 @@ struct iwl_trans;
* @read_prph: read a DWORD from a periphery register
* @write_prph: write a DWORD to a periphery register
* @read_mem: read device's SRAM in DWORD
* @write_mem: write device's SRAM in DWORD
* @write_mem: write device's SRAM in DWORD. If %buf is %NULL, then the memory
* will be zeroed.
* @configure: configure parameters required by the transport layer from
* the op_mode. May be called several times before start_fw, can't be
* called after that.
Expand All @@ -408,7 +422,8 @@ struct iwl_trans_ops {
void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr);
void (*stop_device)(struct iwl_trans *trans);

void (*wowlan_suspend)(struct iwl_trans *trans);
void (*d3_suspend)(struct iwl_trans *trans);
int (*d3_resume)(struct iwl_trans *trans, enum iwl_d3_status *status);

int (*send_cmd)(struct iwl_trans *trans, struct iwl_host_cmd *cmd);

Expand Down Expand Up @@ -561,10 +576,17 @@ static inline void iwl_trans_stop_device(struct iwl_trans *trans)
trans->state = IWL_TRANS_NO_FW;
}

static inline void iwl_trans_wowlan_suspend(struct iwl_trans *trans)
static inline void iwl_trans_d3_suspend(struct iwl_trans *trans)
{
might_sleep();
trans->ops->d3_suspend(trans);
}

static inline int iwl_trans_d3_resume(struct iwl_trans *trans,
enum iwl_d3_status *status)
{
might_sleep();
trans->ops->wowlan_suspend(trans);
return trans->ops->d3_resume(trans, status);
}

static inline int iwl_trans_send_cmd(struct iwl_trans *trans,
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/wireless/iwlwifi/pcie/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,8 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans,
struct iwl_rx_cmd_buffer *rxb, int handler_status);
void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
struct sk_buff_head *skbs);
void iwl_trans_pcie_tx_reset(struct iwl_trans *trans);

/*****************************************************
* Error handling
******************************************************/
Expand Down
12 changes: 8 additions & 4 deletions drivers/net/wireless/iwlwifi/pcie/rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ static int iwl_pcie_rx_alloc(struct iwl_trans *trans)
err_rb_stts:
dma_free_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE,
rxq->bd, rxq->bd_dma);
memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma));
rxq->bd_dma = 0;
rxq->bd = NULL;
err_bd:
return -ENOMEM;
Expand All @@ -455,6 +455,10 @@ static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq)

/* Stop Rx DMA */
iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
/* reset and flush pointers */
iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_RBDCB_WPTR, 0);
iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_FLUSH_RB_REQ, 0);
iwl_write_direct32(trans, FH_RSCSR_CHNL0_RDPTR, 0);

/* Reset driver's Rx queue write index */
iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
Expand Down Expand Up @@ -491,7 +495,6 @@ int iwl_pcie_rx_init(struct iwl_trans *trans)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct iwl_rxq *rxq = &trans_pcie->rxq;

int i, err;
unsigned long flags;

Expand All @@ -518,6 +521,7 @@ int iwl_pcie_rx_init(struct iwl_trans *trans)
rxq->read = rxq->write = 0;
rxq->write_actual = 0;
rxq->free_count = 0;
memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts));
spin_unlock_irqrestore(&rxq->lock, flags);

iwl_pcie_rx_replenish(trans);
Expand Down Expand Up @@ -553,7 +557,7 @@ void iwl_pcie_rx_free(struct iwl_trans *trans)

dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE,
rxq->bd, rxq->bd_dma);
memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma));
rxq->bd_dma = 0;
rxq->bd = NULL;

if (rxq->rb_stts)
Expand All @@ -562,7 +566,7 @@ void iwl_pcie_rx_free(struct iwl_trans *trans)
rxq->rb_stts, rxq->rb_stts_dma);
else
IWL_DEBUG_INFO(trans, "Free rxq->rb_stts which is NULL\n");
memset(&rxq->rb_stts_dma, 0, sizeof(rxq->rb_stts_dma));
rxq->rb_stts_dma = 0;
rxq->rb_stts = NULL;
}

Expand Down
Loading

0 comments on commit aa3c90b

Please sign in to comment.