diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-trans.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-trans.c | 125 |
1 files changed, 72 insertions, 53 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index cc3fc237d32..739087f3025 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c @@ -60,6 +60,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ +#include <linux/interrupt.h> + #include "iwl-dev.h" #include "iwl-trans.h" #include "iwl-core.h" @@ -218,7 +220,7 @@ static int iwl_rx_init(struct iwl_priv *priv) return 0; } -static void iwl_trans_rx_free(struct iwl_priv *priv) +static void iwl_trans_pcie_rx_free(struct iwl_priv *priv) { struct iwl_rx_queue *rxq = &priv->rxq; unsigned long flags; @@ -453,7 +455,7 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id) * * Destroy all TX DMA queues and structures */ -static void iwl_trans_tx_free(struct iwl_priv *priv) +static void iwl_trans_pcie_tx_free(struct iwl_priv *priv) { int txq_id; @@ -528,7 +530,7 @@ static int iwl_trans_tx_alloc(struct iwl_priv *priv) return 0; error: - trans_tx_free(&priv->trans); + iwl_trans_tx_free(trans(priv)); return ret; } @@ -572,7 +574,7 @@ static int iwl_tx_init(struct iwl_priv *priv) error: /*Upon error, free only if we allocated something */ if (alloc) - trans_tx_free(&priv->trans); + iwl_trans_tx_free(trans(priv)); return ret; } @@ -649,7 +651,7 @@ static int iwl_set_hw_ready(struct iwl_priv *priv) } /* Note: returns standard 0/-ERROR code */ -static int iwl_trans_prepare_card_hw(struct iwl_priv *priv) +static int iwl_trans_pcie_prepare_card_hw(struct iwl_priv *priv) { int ret; @@ -677,14 +679,14 @@ static int iwl_trans_prepare_card_hw(struct iwl_priv *priv) return ret; } -static int iwl_trans_start_device(struct iwl_priv *priv) +static int iwl_trans_pcie_start_device(struct iwl_priv *priv) { int ret; priv->ucode_owner = IWL_OWNERSHIP_DRIVER; if ((priv->cfg->sku & EEPROM_SKU_CAP_AMT_ENABLE) && - iwl_trans_prepare_card_hw(priv)) { + iwl_trans_pcie_prepare_card_hw(priv)) { IWL_WARN(priv, "Exit HW not ready\n"); return -EIO; } @@ -768,7 +770,7 @@ static const struct queue_to_fifo_ac iwlagn_ipan_queue_to_tx_fifo[] = { { IWLAGN_CMD_FIFO_NUM, IWL_AC_UNSET, }, { IWL_TX_FIFO_AUX, IWL_AC_UNSET, }, }; -static void iwl_trans_tx_start(struct iwl_priv *priv) +static void iwl_trans_pcie_tx_start(struct iwl_priv *priv) { const struct queue_to_fifo_ac *queue_to_fifo; struct iwl_rxon_context *ctx; @@ -916,7 +918,7 @@ static int iwl_trans_tx_stop(struct iwl_priv *priv) return 0; } -static void iwl_trans_stop_device(struct iwl_priv *priv) +static void iwl_trans_pcie_stop_device(struct iwl_priv *priv) { unsigned long flags; @@ -927,7 +929,7 @@ static void iwl_trans_stop_device(struct iwl_priv *priv) spin_lock_irqsave(&priv->shrd->lock, flags); iwl_disable_interrupts(priv); spin_unlock_irqrestore(&priv->shrd->lock, flags); - trans_sync_irq(&priv->trans); + iwl_trans_sync_irq(trans(priv)); /* device going down, Stop using ICT table */ iwl_disable_ict(priv); @@ -956,7 +958,7 @@ static void iwl_trans_stop_device(struct iwl_priv *priv) iwl_apm_stop(priv); } -static struct iwl_tx_cmd *iwl_trans_get_tx_cmd(struct iwl_priv *priv, +static struct iwl_tx_cmd *iwl_trans_pcie_get_tx_cmd(struct iwl_priv *priv, int txq_id) { struct iwl_tx_queue *txq = &priv->txq[txq_id]; @@ -980,7 +982,7 @@ static struct iwl_tx_cmd *iwl_trans_get_tx_cmd(struct iwl_priv *priv, return &dev_cmd->cmd.tx; } -static int iwl_trans_tx(struct iwl_priv *priv, struct sk_buff *skb, +static int iwl_trans_pcie_tx(struct iwl_priv *priv, struct sk_buff *skb, struct iwl_tx_cmd *tx_cmd, int txq_id, __le16 fc, bool ampdu, struct iwl_rxon_context *ctx) { @@ -1109,71 +1111,88 @@ static int iwl_trans_tx(struct iwl_priv *priv, struct sk_buff *skb, return 0; } -static void iwl_trans_kick_nic(struct iwl_priv *priv) +static void iwl_trans_pcie_kick_nic(struct iwl_priv *priv) { /* Remove all resets to allow NIC to operate */ iwl_write32(priv, CSR_RESET, 0); } -static void iwl_trans_sync_irq(struct iwl_priv *priv) +static int iwl_trans_pcie_request_irq(struct iwl_trans *trans) +{ + struct iwl_priv *priv = priv(trans); + int err; + + tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) + iwl_irq_tasklet, (unsigned long)priv); + + iwl_alloc_isr_ict(priv); + + err = request_irq(bus(trans)->irq, iwl_isr_ict, IRQF_SHARED, + DRV_NAME, priv); + if (err) { + IWL_ERR(priv, "Error allocating IRQ %d\n", priv->bus->irq); + iwl_free_isr_ict(priv); + return err; + } + + INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); + return 0; +} + +static void iwl_trans_pcie_sync_irq(struct iwl_priv *priv) { /* wait to make sure we flush pending tasklet*/ synchronize_irq(priv->bus->irq); tasklet_kill(&priv->irq_tasklet); } -static void iwl_trans_free(struct iwl_priv *priv) +static void iwl_trans_pcie_free(struct iwl_priv *priv) { free_irq(priv->bus->irq, priv); iwl_free_isr_ict(priv); + kfree(trans(priv)); + trans(priv) = NULL; } -static const struct iwl_trans_ops trans_ops = { - .start_device = iwl_trans_start_device, - .prepare_card_hw = iwl_trans_prepare_card_hw, - .stop_device = iwl_trans_stop_device, - - .tx_start = iwl_trans_tx_start, +const struct iwl_trans_ops trans_ops_pcie; - .rx_free = iwl_trans_rx_free, - .tx_free = iwl_trans_tx_free, +static struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd) +{ + struct iwl_trans *iwl_trans = kzalloc(sizeof(struct iwl_trans) + + sizeof(struct iwl_trans_pcie), + GFP_KERNEL); + if (iwl_trans) { + iwl_trans->ops = &trans_ops_pcie; + iwl_trans->shrd = shrd; + } - .send_cmd = iwl_send_cmd, - .send_cmd_pdu = iwl_send_cmd_pdu, + return iwl_trans; +} - .get_tx_cmd = iwl_trans_get_tx_cmd, - .tx = iwl_trans_tx, +const struct iwl_trans_ops trans_ops_pcie = { + .alloc = iwl_trans_pcie_alloc, + .request_irq = iwl_trans_pcie_request_irq, + .start_device = iwl_trans_pcie_start_device, + .prepare_card_hw = iwl_trans_pcie_prepare_card_hw, + .stop_device = iwl_trans_pcie_stop_device, - .txq_agg_disable = iwl_trans_txq_agg_disable, - .txq_agg_setup = iwl_trans_txq_agg_setup, + .tx_start = iwl_trans_pcie_tx_start, - .kick_nic = iwl_trans_kick_nic, + .rx_free = iwl_trans_pcie_rx_free, + .tx_free = iwl_trans_pcie_tx_free, - .sync_irq = iwl_trans_sync_irq, - .free = iwl_trans_free, -}; + .send_cmd = iwl_trans_pcie_send_cmd, + .send_cmd_pdu = iwl_trans_pcie_send_cmd_pdu, -int iwl_trans_register(struct iwl_trans *trans, struct iwl_priv *priv) -{ - int err; + .get_tx_cmd = iwl_trans_pcie_get_tx_cmd, + .tx = iwl_trans_pcie_tx, - priv->trans.ops = &trans_ops; - priv->trans.priv = priv; + .txq_agg_disable = iwl_trans_pcie_txq_agg_disable, + .txq_agg_setup = iwl_trans_pcie_txq_agg_setup, - tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) - iwl_irq_tasklet, (unsigned long)priv); + .kick_nic = iwl_trans_pcie_kick_nic, - iwl_alloc_isr_ict(priv); - - err = request_irq(priv->bus->irq, iwl_isr_ict, IRQF_SHARED, - DRV_NAME, priv); - if (err) { - IWL_ERR(priv, "Error allocating IRQ %d\n", priv->bus->irq); - iwl_free_isr_ict(priv); - return err; - } - - INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish); + .sync_irq = iwl_trans_pcie_sync_irq, + .free = iwl_trans_pcie_free, +}; - return 0; -} |