iwlwifi: don't pass iwl_rx_mem_buffer to upper layers
[deliverable/linux.git] / drivers / net / wireless / iwlwifi / iwl-trans-pcie-rx.c
index 78abff0045341bb00c5e5aa46018fd2462494fb9..68e89be60bef2e055b40fdf0710367072ec15d8c 100644 (file)
@@ -34,6 +34,8 @@
 #include "iwl-core.h"
 #include "iwl-io.h"
 #include "iwl-trans-pcie-int.h"
+#include "iwl-wifi.h"
+#include "iwl-op-mode.h"
 
 #ifdef CONFIG_IWLWIFI_IDI
 #include "iwl-amfh.h"
@@ -227,7 +229,7 @@ static void iwlagn_rx_queue_restock(struct iwl_trans *trans)
        /* If the pre-allocated buffer pool is dropping low, schedule to
         * refill it */
        if (rxq->free_count <= RX_LOW_WATERMARK)
-               queue_work(trans->shrd->workqueue, &trans_pcie->rx_replenish);
+               schedule_work(&trans_pcie->rx_replenish);
 
 
        /* If we've added more space for the firmware to place data, tell it.
@@ -331,13 +333,14 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority)
 
 void iwlagn_rx_replenish(struct iwl_trans *trans)
 {
+       struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        unsigned long flags;
 
        iwlagn_rx_allocate(trans, GFP_KERNEL);
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
        iwlagn_rx_queue_restock(trans);
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 }
 
 static void iwlagn_rx_replenish_now(struct iwl_trans *trans)
@@ -351,14 +354,8 @@ void iwl_bg_rx_replenish(struct work_struct *data)
 {
        struct iwl_trans_pcie *trans_pcie =
            container_of(data, struct iwl_trans_pcie, rx_replenish);
-       struct iwl_trans *trans = trans_pcie->trans;
-
-       if (test_bit(STATUS_EXIT_PENDING, &trans->shrd->status))
-               return;
 
-       mutex_lock(&trans->shrd->mutex);
-       iwlagn_rx_replenish(trans);
-       mutex_unlock(&trans->shrd->mutex);
+       iwlagn_rx_replenish(trans_pcie->trans);
 }
 
 /**
@@ -370,8 +367,6 @@ void iwl_bg_rx_replenish(struct work_struct *data)
  */
 static void iwl_rx_handle(struct iwl_trans *trans)
 {
-       struct iwl_rx_mem_buffer *rxb;
-       struct iwl_rx_packet *pkt;
        struct iwl_trans_pcie *trans_pcie =
                IWL_TRANS_GET_PCIE_TRANS(trans);
        struct iwl_rx_queue *rxq = &trans_pcie->rxq;
@@ -405,6 +400,9 @@ static void iwl_rx_handle(struct iwl_trans *trans)
        while (i != r) {
                int len, err;
                u16 sequence;
+               struct iwl_rx_mem_buffer *rxb;
+               struct iwl_rx_cmd_buffer rxcb;
+               struct iwl_rx_packet *pkt;
 
                rxb = rxq->queue[i];
 
@@ -421,7 +419,9 @@ static void iwl_rx_handle(struct iwl_trans *trans)
                dma_unmap_page(trans->dev, rxb->page_dma,
                               PAGE_SIZE << hw_params(trans).rx_page_order,
                               DMA_FROM_DEVICE);
-               pkt = rxb_addr(rxb);
+
+               rxcb._page = rxb->page;
+               pkt = rxb_addr(&rxcb);
 
                IWL_DEBUG_RX(trans, "r = %d, i = %d, %s, 0x%02x\n", r,
                        i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
@@ -464,10 +464,10 @@ static void iwl_rx_handle(struct iwl_trans *trans)
                     "reclaim is false, SEQ_RX_FRAME unset: %s\n",
                     get_cmd_string(pkt->hdr.cmd));
 
-               err = iwl_rx_dispatch(priv(trans), rxb, cmd);
+               err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd);
 
                /*
-                * XXX: After here, we should always check rxb->page
+                * XXX: After here, we should always check rxcb._page
                 * against NULL before touching it or its virtual
                 * memory (pkt). Because some rx_handler might have
                 * already taken or freed the pages.
@@ -478,12 +478,16 @@ static void iwl_rx_handle(struct iwl_trans *trans)
                         * and fire off the (possibly) blocking
                         * iwl_trans_send_cmd()
                         * as we reclaim the driver command queue */
-                       if (rxb->page)
-                               iwl_tx_cmd_complete(trans, rxb, err);
+                       if (rxcb._page)
+                               iwl_tx_cmd_complete(trans, &rxcb, err);
                        else
                                IWL_WARN(trans, "Claim null rxb?\n");
                }
 
+               /* page was stolen from us */
+               if (rxcb._page == NULL)
+                       rxb->page = NULL;
+
                /* Reuse the page if possible. For notification packets and
                 * SKBs that fail to Rx correctly, add them back into the
                 * rx_free list for reuse later. */
@@ -594,17 +598,17 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans)
 {
        u32 base;
        struct iwl_error_event_table table;
-       struct iwl_priv *priv = priv(trans);
+       struct iwl_nic *nic = nic(trans);
        struct iwl_trans_pcie *trans_pcie =
                IWL_TRANS_GET_PCIE_TRANS(trans);
 
        base = trans->shrd->device_pointers.error_event_table;
        if (trans->shrd->ucode_type == IWL_UCODE_INIT) {
                if (!base)
-                       base = priv->init_errlog_ptr;
+                       base = nic->init_errlog_ptr;
        } else {
                if (!base)
-                       base = priv->inst_errlog_ptr;
+                       base = nic->inst_errlog_ptr;
        }
 
        if (!iwlagn_hw_valid_rtc_data_addr(base)) {
@@ -616,7 +620,7 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans)
                return;
        }
 
-       iwl_read_targ_mem_words(trans(priv), base, &table, sizeof(table));
+       iwl_read_targ_mem_words(trans, base, &table, sizeof(table));
 
        if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
                IWL_ERR(trans, "Start IWL Error Log Dump:\n");
@@ -626,7 +630,7 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans)
 
        trans_pcie->isr_stats.err_code = table.error_id;
 
-       trace_iwlwifi_dev_ucode_error(priv, table.error_id, table.tsf_low,
+       trace_iwlwifi_dev_ucode_error(priv(nic), table.error_id, table.tsf_low,
                                      table.data1, table.data2, table.line,
                                      table.blink1, table.blink2, table.ilink1,
                                      table.ilink2, table.bcon_time, table.gp1,
@@ -674,9 +678,8 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans)
  */
 static void iwl_irq_handle_error(struct iwl_trans *trans)
 {
-       struct iwl_priv *priv = priv(trans);
        /* W/A for WiFi/WiMAX coex and WiMAX own the RF */
-       if (cfg(priv)->internal_wimax_coex &&
+       if (cfg(trans)->internal_wimax_coex &&
            (!(iwl_read_prph(trans, APMG_CLK_CTRL_REG) &
                        APMS_CLK_VAL_MRB_FUNC_MODE) ||
             (iwl_read_prph(trans, APMG_PS_CTRL_REG) &
@@ -687,24 +690,20 @@ static void iwl_irq_handle_error(struct iwl_trans *trans)
                 */
                clear_bit(STATUS_READY, &trans->shrd->status);
                clear_bit(STATUS_HCMD_ACTIVE, &trans->shrd->status);
-               wake_up(&priv->shrd->wait_command_queue);
+               wake_up(&trans->shrd->wait_command_queue);
                IWL_ERR(trans, "RF is used by WiMAX\n");
                return;
        }
 
        IWL_ERR(trans, "Loaded firmware version: %s\n",
-               priv->hw->wiphy->fw_version);
+               nic(trans)->fw.fw_version);
 
        iwl_dump_nic_error_log(trans);
        iwl_dump_csr(trans);
        iwl_dump_fh(trans, NULL, false);
        iwl_dump_nic_event_log(trans, false, NULL, false);
-#ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_get_debug_level(trans->shrd) & IWL_DL_FW_ERRORS)
-               iwl_print_rx_config_cmd(priv(trans), IWL_RXON_CTX_BSS);
-#endif
 
-       iwlagn_fw_error(priv, false);
+       iwl_op_mode_nic_error(trans->op_mode);
 }
 
 #define EVENT_START_OFFSET  (4 * sizeof(u32))
@@ -723,7 +722,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
        u32 ptr;        /* SRAM byte address of log data */
        u32 ev, time, data; /* event log data */
        unsigned long reg_flags;
-       struct iwl_priv *priv = priv(trans);
+       struct iwl_nic *nic = nic(trans);
 
        if (num_events == 0)
                return pos;
@@ -731,10 +730,10 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
        base = trans->shrd->device_pointers.log_event_table;
        if (trans->shrd->ucode_type == IWL_UCODE_INIT) {
                if (!base)
-                       base = priv->init_evtlog_ptr;
+                       base = nic->init_evtlog_ptr;
        } else {
                if (!base)
-                       base = priv->inst_evtlog_ptr;
+                       base = nic->inst_evtlog_ptr;
        }
 
        if (mode == 0)
@@ -764,7 +763,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
                                                "EVT_LOG:0x%08x:%04u\n",
                                                time, ev);
                        } else {
-                               trace_iwlwifi_dev_ucode_event(priv, 0,
+                               trace_iwlwifi_dev_ucode_event(priv(trans), 0,
                                        time, ev);
                                IWL_ERR(trans, "EVT_LOG:0x%08x:%04u\n",
                                        time, ev);
@@ -778,7 +777,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx,
                        } else {
                                IWL_ERR(trans, "EVT_LOGT:%010u:0x%08x:%04u\n",
                                        time, data, ev);
-                               trace_iwlwifi_dev_ucode_event(priv, time,
+                               trace_iwlwifi_dev_ucode_event(priv(trans), time,
                                        data, ev);
                        }
                }
@@ -840,17 +839,17 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log,
        u32 logsize;
        int pos = 0;
        size_t bufsz = 0;
-       struct iwl_priv *priv = priv(trans);
+       struct iwl_nic *nic = nic(trans);
 
        base = trans->shrd->device_pointers.log_event_table;
        if (trans->shrd->ucode_type == IWL_UCODE_INIT) {
-               logsize = priv->init_evtlog_size;
+               logsize = nic->init_evtlog_size;
                if (!base)
-                       base = priv->init_evtlog_ptr;
+                       base = nic->init_evtlog_ptr;
        } else {
-               logsize = priv->inst_evtlog_size;
+               logsize = nic->inst_evtlog_size;
                if (!base)
-                       base = priv->inst_evtlog_ptr;
+                       base = nic->inst_evtlog_ptr;
        }
 
        if (!iwlagn_hw_valid_rtc_data_addr(base)) {
@@ -889,7 +888,7 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log,
        }
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-       if (!(iwl_get_debug_level(trans->shrd) & IWL_DL_FW_ERRORS) && !full_log)
+       if (!(iwl_have_debug_level(IWL_DL_FW_ERRORS)) && !full_log)
                size = (size > DEFAULT_DUMP_EVENT_LOG_ENTRIES)
                        ? DEFAULT_DUMP_EVENT_LOG_ENTRIES : size;
 #else
@@ -909,7 +908,7 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log,
                if (!*buf)
                        return -ENOMEM;
        }
-       if ((iwl_get_debug_level(trans->shrd) & IWL_DL_FW_ERRORS) || full_log) {
+       if (iwl_have_debug_level(IWL_DL_FW_ERRORS) || full_log) {
                /*
                 * if uCode has wrapped back to top of log,
                 * start at the oldest entry,
@@ -949,7 +948,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
        struct isr_statistics *isr_stats = &trans_pcie->isr_stats;
 
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
 
        /* Ack/clear/reset pending uCode interrupts.
         * Note:  Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
@@ -968,7 +967,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
        inta = trans_pcie->inta;
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_get_debug_level(trans->shrd) & IWL_DL_ISR) {
+       if (iwl_have_debug_level(IWL_DL_ISR)) {
                /* just for debug */
                inta_mask = iwl_read32(trans, CSR_INT_MASK);
                IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n ",
@@ -976,11 +975,11 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
        }
 #endif
 
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
-
        /* saved interrupt in inta variable now we can reset trans_pcie->inta */
        trans_pcie->inta = 0;
 
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
+
        /* Now service all interrupt bits discovered above. */
        if (inta & CSR_INT_BIT_HW_ERR) {
                IWL_ERR(trans, "Hardware error detected.  Restarting.\n");
@@ -997,7 +996,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
        }
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_get_debug_level(trans->shrd) & (IWL_DL_ISR)) {
+       if (iwl_have_debug_level(IWL_DL_ISR)) {
                /* NIC fires this, but we don't use it, redundant with WAKEUP */
                if (inta & CSR_INT_BIT_SCD) {
                        IWL_DEBUG_ISR(trans, "Scheduler finished to transmit "
@@ -1039,7 +1038,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
                        else
                                clear_bit(STATUS_RF_KILL_HW,
                                          &trans->shrd->status);
-                       iwl_set_hw_rfkill_state(priv(trans), hw_rf_kill);
+                       iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rf_kill);
                }
 
                handled |= CSR_INT_BIT_RF_KILL;
@@ -1232,7 +1231,7 @@ void iwl_reset_ict(struct iwl_trans *trans)
        if (!trans_pcie->ict_tbl)
                return;
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
        iwl_disable_interrupts(trans);
 
        memset(trans_pcie->ict_tbl, 0, ICT_SIZE);
@@ -1249,7 +1248,7 @@ void iwl_reset_ict(struct iwl_trans *trans)
        trans_pcie->ict_index = 0;
        iwl_write32(trans, CSR_INT, trans_pcie->inta_mask);
        iwl_enable_interrupts(trans);
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 }
 
 /* Device is going down disable ict interrupt usage */
@@ -1260,9 +1259,9 @@ void iwl_disable_ict(struct iwl_trans *trans)
 
        unsigned long flags;
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
        trans_pcie->use_ict = false;
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
 }
 
 static irqreturn_t iwl_isr(int irq, void *data)
@@ -1281,7 +1280,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
 
        trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
 
        /* Disable (but don't clear!) interrupts here to avoid
         *    back-to-back ISRs and sporadic interrupts from our NIC.
@@ -1309,7 +1308,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
        }
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-       if (iwl_get_debug_level(trans->shrd) & (IWL_DL_ISR)) {
+       if (iwl_have_debug_level(IWL_DL_ISR)) {
                inta_fh = iwl_read32(trans, CSR_FH_INT_STATUS);
                IWL_DEBUG_ISR(trans, "ISR inta 0x%08x, enabled 0x%08x, "
                              "fh 0x%08x\n", inta, inta_mask, inta_fh);
@@ -1325,7 +1324,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
                iwl_enable_interrupts(trans);
 
  unplugged:
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
        return IRQ_HANDLED;
 
  none:
@@ -1335,7 +1334,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
                !trans_pcie->inta)
                iwl_enable_interrupts(trans);
 
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
        return IRQ_NONE;
 }
 
@@ -1369,7 +1368,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
 
        trace_iwlwifi_dev_irq(priv(trans));
 
-       spin_lock_irqsave(&trans->shrd->lock, flags);
+       spin_lock_irqsave(&trans_pcie->irq_lock, flags);
 
        /* Disable (but don't clear!) interrupts here to avoid
         * back-to-back ISRs and sporadic interrupts from our NIC.
@@ -1440,7 +1439,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
                iwl_enable_interrupts(trans);
        }
 
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
        return IRQ_HANDLED;
 
  none:
@@ -1451,6 +1450,6 @@ irqreturn_t iwl_isr_ict(int irq, void *data)
            !trans_pcie->inta)
                iwl_enable_interrupts(trans);
 
-       spin_unlock_irqrestore(&trans->shrd->lock, flags);
+       spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
        return IRQ_NONE;
 }
This page took 0.030181 seconds and 5 git commands to generate.