Merge branch 'for-linville' of git://github.com/kvalo/ath
authorJohn W. Linville <linville@tuxdriver.com>
Thu, 28 Aug 2014 18:36:38 +0000 (14:36 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 28 Aug 2014 18:36:38 +0000 (14:36 -0400)
30 files changed:
drivers/net/wireless/ath/ath10k/Kconfig
drivers/net/wireless/ath/ath10k/Makefile
drivers/net/wireless/ath/ath10k/bmi.c
drivers/net/wireless/ath/ath10k/ce.c
drivers/net/wireless/ath/ath10k/ce.h
drivers/net/wireless/ath/ath10k/core.c
drivers/net/wireless/ath/ath10k/core.h
drivers/net/wireless/ath/ath10k/debug.c
drivers/net/wireless/ath/ath10k/debug.h
drivers/net/wireless/ath/ath10k/htc.c
drivers/net/wireless/ath/ath10k/htc.h
drivers/net/wireless/ath/ath10k/htt.c
drivers/net/wireless/ath/ath10k/htt_rx.c
drivers/net/wireless/ath/ath10k/htt_tx.c
drivers/net/wireless/ath/ath10k/hw.h
drivers/net/wireless/ath/ath10k/mac.c
drivers/net/wireless/ath/ath10k/mac.h
drivers/net/wireless/ath/ath10k/pci.c
drivers/net/wireless/ath/ath10k/pci.h
drivers/net/wireless/ath/ath10k/spectral.c [new file with mode: 0644]
drivers/net/wireless/ath/ath10k/spectral.h [new file with mode: 0644]
drivers/net/wireless/ath/ath10k/txrx.c
drivers/net/wireless/ath/ath10k/wmi.c
drivers/net/wireless/ath/ath10k/wmi.h
drivers/net/wireless/ath/ath6kl/init.c
drivers/net/wireless/ath/ath6kl/main.c
drivers/net/wireless/ath/ath6kl/sdio.c
drivers/net/wireless/ath/ath6kl/usb.c
drivers/net/wireless/ath/ath9k/spectral.h
drivers/net/wireless/ath/spectral_common.h [new file with mode: 0644]

index a6f5285235af04e7527ab7436ae31a63666a037f..1053bb5f2cdcb33dbc4381dfb3ac3f00dbb3a91c 100644 (file)
@@ -25,6 +25,7 @@ config ATH10K_DEBUG
 config ATH10K_DEBUGFS
        bool "Atheros ath10k debugfs support"
        depends on ATH10K
+       select RELAY
        ---help---
          Enabled debugfs support
 
index a4179f49ee1f3db7cd3882abd5972c5b2d884132..2cfb63ca9327f8e9c7417dfeb0893d0df8cdd33d 100644 (file)
@@ -10,6 +10,7 @@ ath10k_core-y += mac.o \
                 wmi.o \
                 bmi.o
 
+ath10k_core-$(CONFIG_ATH10K_DEBUGFS) += spectral.o
 ath10k_core-$(CONFIG_ATH10K_TRACING) += trace.o
 
 obj-$(CONFIG_ATH10K_PCI) += ath10k_pci.o
index 17d221abd58c0bb70d72a6fbf14f1e7422f8ced5..3d29b0875b3e0e0abf442d8f875fe39b7ddb9171 100644 (file)
@@ -22,7 +22,7 @@
 
 void ath10k_bmi_start(struct ath10k *ar)
 {
-       ath10k_dbg(ATH10K_DBG_BMI, "bmi start\n");
+       ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi start\n");
 
        ar->bmi.done_sent = false;
 }
@@ -33,10 +33,10 @@ int ath10k_bmi_done(struct ath10k *ar)
        u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.done);
        int ret;
 
-       ath10k_dbg(ATH10K_DBG_BMI, "bmi done\n");
+       ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi done\n");
 
        if (ar->bmi.done_sent) {
-               ath10k_dbg(ATH10K_DBG_BMI, "bmi skipped\n");
+               ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi skipped\n");
                return 0;
        }
 
@@ -45,7 +45,7 @@ int ath10k_bmi_done(struct ath10k *ar)
 
        ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, NULL, NULL);
        if (ret) {
-               ath10k_warn("unable to write to the device: %d\n", ret);
+               ath10k_warn(ar, "unable to write to the device: %d\n", ret);
                return ret;
        }
 
@@ -61,10 +61,10 @@ int ath10k_bmi_get_target_info(struct ath10k *ar,
        u32 resplen = sizeof(resp.get_target_info);
        int ret;
 
-       ath10k_dbg(ATH10K_DBG_BMI, "bmi get target info\n");
+       ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi get target info\n");
 
        if (ar->bmi.done_sent) {
-               ath10k_warn("BMI Get Target Info Command disallowed\n");
+               ath10k_warn(ar, "BMI Get Target Info Command disallowed\n");
                return -EBUSY;
        }
 
@@ -72,12 +72,12 @@ int ath10k_bmi_get_target_info(struct ath10k *ar,
 
        ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, &resp, &resplen);
        if (ret) {
-               ath10k_warn("unable to get target info from device\n");
+               ath10k_warn(ar, "unable to get target info from device\n");
                return ret;
        }
 
        if (resplen < sizeof(resp.get_target_info)) {
-               ath10k_warn("invalid get_target_info response length (%d)\n",
+               ath10k_warn(ar, "invalid get_target_info response length (%d)\n",
                            resplen);
                return -EIO;
        }
@@ -97,11 +97,11 @@ int ath10k_bmi_read_memory(struct ath10k *ar,
        u32 rxlen;
        int ret;
 
-       ath10k_dbg(ATH10K_DBG_BMI, "bmi read address 0x%x length %d\n",
+       ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi read address 0x%x length %d\n",
                   address, length);
 
        if (ar->bmi.done_sent) {
-               ath10k_warn("command disallowed\n");
+               ath10k_warn(ar, "command disallowed\n");
                return -EBUSY;
        }
 
@@ -115,7 +115,7 @@ int ath10k_bmi_read_memory(struct ath10k *ar,
                ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen,
                                                  &resp, &rxlen);
                if (ret) {
-                       ath10k_warn("unable to read from the device (%d)\n",
+                       ath10k_warn(ar, "unable to read from the device (%d)\n",
                                    ret);
                        return ret;
                }
@@ -137,11 +137,11 @@ int ath10k_bmi_write_memory(struct ath10k *ar,
        u32 txlen;
        int ret;
 
-       ath10k_dbg(ATH10K_DBG_BMI, "bmi write address 0x%x length %d\n",
+       ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi write address 0x%x length %d\n",
                   address, length);
 
        if (ar->bmi.done_sent) {
-               ath10k_warn("command disallowed\n");
+               ath10k_warn(ar, "command disallowed\n");
                return -EBUSY;
        }
 
@@ -159,7 +159,7 @@ int ath10k_bmi_write_memory(struct ath10k *ar,
                ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, hdrlen + txlen,
                                                  NULL, NULL);
                if (ret) {
-                       ath10k_warn("unable to write to the device (%d)\n",
+                       ath10k_warn(ar, "unable to write to the device (%d)\n",
                                    ret);
                        return ret;
                }
@@ -183,11 +183,11 @@ int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 param, u32 *result)
        u32 resplen = sizeof(resp.execute);
        int ret;
 
-       ath10k_dbg(ATH10K_DBG_BMI, "bmi execute address 0x%x param 0x%x\n",
+       ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi execute address 0x%x param 0x%x\n",
                   address, param);
 
        if (ar->bmi.done_sent) {
-               ath10k_warn("command disallowed\n");
+               ath10k_warn(ar, "command disallowed\n");
                return -EBUSY;
        }
 
@@ -197,19 +197,19 @@ int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 param, u32 *result)
 
        ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, &resp, &resplen);
        if (ret) {
-               ath10k_warn("unable to read from the device\n");
+               ath10k_warn(ar, "unable to read from the device\n");
                return ret;
        }
 
        if (resplen < sizeof(resp.execute)) {
-               ath10k_warn("invalid execute response length (%d)\n",
+               ath10k_warn(ar, "invalid execute response length (%d)\n",
                            resplen);
                return -EIO;
        }
 
        *result = __le32_to_cpu(resp.execute.result);
 
-       ath10k_dbg(ATH10K_DBG_BMI, "bmi execute result 0x%x\n", *result);
+       ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi execute result 0x%x\n", *result);
 
        return 0;
 }
@@ -221,11 +221,11 @@ int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length)
        u32 txlen;
        int ret;
 
-       ath10k_dbg(ATH10K_DBG_BMI, "bmi lz data buffer 0x%p length %d\n",
+       ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi lz data buffer 0x%p length %d\n",
                   buffer, length);
 
        if (ar->bmi.done_sent) {
-               ath10k_warn("command disallowed\n");
+               ath10k_warn(ar, "command disallowed\n");
                return -EBUSY;
        }
 
@@ -241,7 +241,7 @@ int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length)
                ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, hdrlen + txlen,
                                                  NULL, NULL);
                if (ret) {
-                       ath10k_warn("unable to write to the device\n");
+                       ath10k_warn(ar, "unable to write to the device\n");
                        return ret;
                }
 
@@ -258,11 +258,11 @@ int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address)
        u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.lz_start);
        int ret;
 
-       ath10k_dbg(ATH10K_DBG_BMI, "bmi lz stream start address 0x%x\n",
+       ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi lz stream start address 0x%x\n",
                   address);
 
        if (ar->bmi.done_sent) {
-               ath10k_warn("command disallowed\n");
+               ath10k_warn(ar, "command disallowed\n");
                return -EBUSY;
        }
 
@@ -271,7 +271,7 @@ int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address)
 
        ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, NULL, NULL);
        if (ret) {
-               ath10k_warn("unable to Start LZ Stream to the device\n");
+               ath10k_warn(ar, "unable to Start LZ Stream to the device\n");
                return ret;
        }
 
@@ -286,7 +286,7 @@ int ath10k_bmi_fast_download(struct ath10k *ar,
        u32 trailer_len = length - head_len;
        int ret;
 
-       ath10k_dbg(ATH10K_DBG_BMI,
+       ath10k_dbg(ar, ATH10K_DBG_BMI,
                   "bmi fast download address 0x%x buffer 0x%p length %d\n",
                   address, buffer, length);
 
index 4333107ecf37b8325c55f31569361a9b537dddc6..71eef233bd01e2f542cff7cd94520c2c05c0ff39 100644 (file)
@@ -284,13 +284,9 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state,
        int ret = 0;
 
        if (nbytes > ce_state->src_sz_max)
-               ath10k_warn("%s: send more we can (nbytes: %d, max: %d)\n",
+               ath10k_warn(ar, "%s: send more we can (nbytes: %d, max: %d)\n",
                            __func__, nbytes, ce_state->src_sz_max);
 
-       ret = ath10k_pci_wake(ar);
-       if (ret)
-               return ret;
-
        if (unlikely(CE_RING_DELTA(nentries_mask,
                                   write_index, sw_index - 1) <= 0)) {
                ret = -ENOSR;
@@ -325,7 +321,6 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state,
 
        src_ring->write_index = write_index;
 exit:
-       ath10k_pci_sleep(ar);
        return ret;
 }
 
@@ -390,49 +385,57 @@ int ath10k_ce_num_free_src_entries(struct ath10k_ce_pipe *pipe)
        return delta;
 }
 
-int ath10k_ce_recv_buf_enqueue(struct ath10k_ce_pipe *ce_state,
-                              void *per_recv_context,
-                              u32 buffer)
+
+int __ath10k_ce_rx_num_free_bufs(struct ath10k_ce_pipe *pipe)
 {
-       struct ath10k_ce_ring *dest_ring = ce_state->dest_ring;
-       u32 ctrl_addr = ce_state->ctrl_addr;
-       struct ath10k *ar = ce_state->ar;
+       struct ath10k *ar = pipe->ar;
        struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+       struct ath10k_ce_ring *dest_ring = pipe->dest_ring;
        unsigned int nentries_mask = dest_ring->nentries_mask;
-       unsigned int write_index;
-       unsigned int sw_index;
-       int ret;
+       unsigned int write_index = dest_ring->write_index;
+       unsigned int sw_index = dest_ring->sw_index;
 
-       spin_lock_bh(&ar_pci->ce_lock);
-       write_index = dest_ring->write_index;
-       sw_index = dest_ring->sw_index;
+       lockdep_assert_held(&ar_pci->ce_lock);
 
-       ret = ath10k_pci_wake(ar);
-       if (ret)
-               goto out;
+       return CE_RING_DELTA(nentries_mask, write_index, sw_index - 1);
+}
 
-       if (CE_RING_DELTA(nentries_mask, write_index, sw_index - 1) > 0) {
-               struct ce_desc *base = dest_ring->base_addr_owner_space;
-               struct ce_desc *desc = CE_DEST_RING_TO_DESC(base, write_index);
+int __ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr)
+{
+       struct ath10k *ar = pipe->ar;
+       struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+       struct ath10k_ce_ring *dest_ring = pipe->dest_ring;
+       unsigned int nentries_mask = dest_ring->nentries_mask;
+       unsigned int write_index = dest_ring->write_index;
+       unsigned int sw_index = dest_ring->sw_index;
+       struct ce_desc *base = dest_ring->base_addr_owner_space;
+       struct ce_desc *desc = CE_DEST_RING_TO_DESC(base, write_index);
+       u32 ctrl_addr = pipe->ctrl_addr;
 
-               /* Update destination descriptor */
-               desc->addr    = __cpu_to_le32(buffer);
-               desc->nbytes = 0;
+       lockdep_assert_held(&ar_pci->ce_lock);
 
-               dest_ring->per_transfer_context[write_index] =
-                                                       per_recv_context;
+       if (CE_RING_DELTA(nentries_mask, write_index, sw_index - 1) == 0)
+               return -EIO;
 
-               /* Update Destination Ring Write Index */
-               write_index = CE_RING_IDX_INCR(nentries_mask, write_index);
-               ath10k_ce_dest_ring_write_index_set(ar, ctrl_addr, write_index);
-               dest_ring->write_index = write_index;
-               ret = 0;
-       } else {
-               ret = -EIO;
-       }
-       ath10k_pci_sleep(ar);
+       desc->addr = __cpu_to_le32(paddr);
+       desc->nbytes = 0;
+
+       dest_ring->per_transfer_context[write_index] = ctx;
+       write_index = CE_RING_IDX_INCR(nentries_mask, write_index);
+       ath10k_ce_dest_ring_write_index_set(ar, ctrl_addr, write_index);
+       dest_ring->write_index = write_index;
+
+       return 0;
+}
+
+int ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr)
+{
+       struct ath10k *ar = pipe->ar;
+       struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+       int ret;
 
-out:
+       spin_lock_bh(&ar_pci->ce_lock);
+       ret = __ath10k_ce_rx_post_buf(pipe, ctx, paddr);
        spin_unlock_bh(&ar_pci->ce_lock);
 
        return ret;
@@ -588,7 +591,6 @@ static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
        unsigned int sw_index = src_ring->sw_index;
        struct ce_desc *sdesc, *sbase;
        unsigned int read_index;
-       int ret;
 
        if (src_ring->hw_index == sw_index) {
                /*
@@ -599,18 +601,12 @@ static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
                 * value of the HW index has become stale.
                 */
 
-               ret = ath10k_pci_wake(ar);
-               if (ret)
-                       return ret;
-
                read_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr);
                if (read_index == 0xffffffff)
                        return -ENODEV;
 
                read_index &= nentries_mask;
                src_ring->hw_index = read_index;
-
-               ath10k_pci_sleep(ar);
        }
 
        read_index = src_ring->hw_index;
@@ -731,11 +727,6 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id)
        struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
        struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
        u32 ctrl_addr = ce_state->ctrl_addr;
-       int ret;
-
-       ret = ath10k_pci_wake(ar);
-       if (ret)
-               return;
 
        spin_lock_bh(&ar_pci->ce_lock);
 
@@ -760,7 +751,6 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id)
        ath10k_ce_engine_int_status_clear(ar, ctrl_addr, CE_WATERMARK_MASK);
 
        spin_unlock_bh(&ar_pci->ce_lock);
-       ath10k_pci_sleep(ar);
 }
 
 /*
@@ -771,13 +761,9 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id)
 
 void ath10k_ce_per_engine_service_any(struct ath10k *ar)
 {
-       int ce_id, ret;
+       int ce_id;
        u32 intr_summary;
 
-       ret = ath10k_pci_wake(ar);
-       if (ret)
-               return;
-
        intr_summary = CE_INTERRUPT_SUMMARY(ar);
 
        for (ce_id = 0; intr_summary && (ce_id < CE_COUNT); ce_id++) {
@@ -789,8 +775,6 @@ void ath10k_ce_per_engine_service_any(struct ath10k *ar)
 
                ath10k_ce_per_engine_service(ar, ce_id);
        }
-
-       ath10k_pci_sleep(ar);
 }
 
 /*
@@ -800,16 +784,11 @@ void ath10k_ce_per_engine_service_any(struct ath10k *ar)
  *
  * Called with ce_lock held.
  */
-static void ath10k_ce_per_engine_handler_adjust(struct ath10k_ce_pipe *ce_state,
-                                               int disable_copy_compl_intr)
+static void ath10k_ce_per_engine_handler_adjust(struct ath10k_ce_pipe *ce_state)
 {
        u32 ctrl_addr = ce_state->ctrl_addr;
        struct ath10k *ar = ce_state->ar;
-       int ret;
-
-       ret = ath10k_pci_wake(ar);
-       if (ret)
-               return;
+       bool disable_copy_compl_intr = ce_state->attr_flags & CE_ATTR_DIS_INTR;
 
        if ((!disable_copy_compl_intr) &&
            (ce_state->send_cb || ce_state->recv_cb))
@@ -818,17 +797,11 @@ static void ath10k_ce_per_engine_handler_adjust(struct ath10k_ce_pipe *ce_state,
                ath10k_ce_copy_complete_intr_disable(ar, ctrl_addr);
 
        ath10k_ce_watermark_intr_disable(ar, ctrl_addr);
-
-       ath10k_pci_sleep(ar);
 }
 
 int ath10k_ce_disable_interrupts(struct ath10k *ar)
 {
-       int ce_id, ret;
-
-       ret = ath10k_pci_wake(ar);
-       if (ret)
-               return ret;
+       int ce_id;
 
        for (ce_id = 0; ce_id < CE_COUNT; ce_id++) {
                u32 ctrl_addr = ath10k_ce_base_address(ce_id);
@@ -838,34 +811,16 @@ int ath10k_ce_disable_interrupts(struct ath10k *ar)
                ath10k_ce_watermark_intr_disable(ar, ctrl_addr);
        }
 
-       ath10k_pci_sleep(ar);
-
        return 0;
 }
 
-void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state,
-                               void (*send_cb)(struct ath10k_ce_pipe *),
-                               int disable_interrupts)
+void ath10k_ce_enable_interrupts(struct ath10k *ar)
 {
-       struct ath10k *ar = ce_state->ar;
        struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+       int ce_id;
 
-       spin_lock_bh(&ar_pci->ce_lock);
-       ce_state->send_cb = send_cb;
-       ath10k_ce_per_engine_handler_adjust(ce_state, disable_interrupts);
-       spin_unlock_bh(&ar_pci->ce_lock);
-}
-
-void ath10k_ce_recv_cb_register(struct ath10k_ce_pipe *ce_state,
-                               void (*recv_cb)(struct ath10k_ce_pipe *))
-{
-       struct ath10k *ar = ce_state->ar;
-       struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
-
-       spin_lock_bh(&ar_pci->ce_lock);
-       ce_state->recv_cb = recv_cb;
-       ath10k_ce_per_engine_handler_adjust(ce_state, 0);
-       spin_unlock_bh(&ar_pci->ce_lock);
+       for (ce_id = 0; ce_id < CE_COUNT; ce_id++)
+               ath10k_ce_per_engine_handler_adjust(&ar_pci->ce_states[ce_id]);
 }
 
 static int ath10k_ce_init_src_ring(struct ath10k *ar,
@@ -898,7 +853,7 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar,
        ath10k_ce_src_ring_lowmark_set(ar, ctrl_addr, 0);
        ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, nentries);
 
-       ath10k_dbg(ATH10K_DBG_BOOT,
+       ath10k_dbg(ar, ATH10K_DBG_BOOT,
                   "boot init ce src ring id %d entries %d base_addr %p\n",
                   ce_id, nentries, src_ring->base_addr_owner_space);
 
@@ -932,7 +887,7 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar,
        ath10k_ce_dest_ring_lowmark_set(ar, ctrl_addr, 0);
        ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, nentries);
 
-       ath10k_dbg(ATH10K_DBG_BOOT,
+       ath10k_dbg(ar, ATH10K_DBG_BOOT,
                   "boot ce dest ring id %d entries %d base_addr %p\n",
                   ce_id, nentries, dest_ring->base_addr_owner_space);
 
@@ -1067,7 +1022,9 @@ ath10k_ce_alloc_dest_ring(struct ath10k *ar, unsigned int ce_id,
  * initialized by software/firmware.
  */
 int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id,
-                       const struct ce_attr *attr)
+                       const struct ce_attr *attr,
+                       void (*send_cb)(struct ath10k_ce_pipe *),
+                       void (*recv_cb)(struct ath10k_ce_pipe *))
 {
        struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
        struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
@@ -1084,39 +1041,37 @@ int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id,
        BUILD_BUG_ON(2*TARGET_10X_NUM_MSDU_DESC >
                     (CE_HTT_H2T_MSG_SRC_NENTRIES - 1));
 
-       ret = ath10k_pci_wake(ar);
-       if (ret)
-               return ret;
-
        spin_lock_bh(&ar_pci->ce_lock);
        ce_state->ar = ar;
        ce_state->id = ce_id;
        ce_state->ctrl_addr = ath10k_ce_base_address(ce_id);
        ce_state->attr_flags = attr->flags;
        ce_state->src_sz_max = attr->src_sz_max;
+       if (attr->src_nentries)
+               ce_state->send_cb = send_cb;
+       if (attr->dest_nentries)
+               ce_state->recv_cb = recv_cb;
        spin_unlock_bh(&ar_pci->ce_lock);
 
        if (attr->src_nentries) {
                ret = ath10k_ce_init_src_ring(ar, ce_id, attr);
                if (ret) {
-                       ath10k_err("Failed to initialize CE src ring for ID: %d (%d)\n",
+                       ath10k_err(ar, "Failed to initialize CE src ring for ID: %d (%d)\n",
                                   ce_id, ret);
-                       goto out;
+                       return ret;
                }
        }
 
        if (attr->dest_nentries) {
                ret = ath10k_ce_init_dest_ring(ar, ce_id, attr);
                if (ret) {
-                       ath10k_err("Failed to initialize CE dest ring for ID: %d (%d)\n",
+                       ath10k_err(ar, "Failed to initialize CE dest ring for ID: %d (%d)\n",
                                   ce_id, ret);
-                       goto out;
+                       return ret;
                }
        }
 
-out:
-       ath10k_pci_sleep(ar);
-       return ret;
+       return 0;
 }
 
 static void ath10k_ce_deinit_src_ring(struct ath10k *ar, unsigned int ce_id)
@@ -1140,16 +1095,8 @@ static void ath10k_ce_deinit_dest_ring(struct ath10k *ar, unsigned int ce_id)
 
 void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id)
 {
-       int ret;
-
-       ret = ath10k_pci_wake(ar);
-       if (ret)
-               return;
-
        ath10k_ce_deinit_src_ring(ar, ce_id);
        ath10k_ce_deinit_dest_ring(ar, ce_id);
-
-       ath10k_pci_sleep(ar);
 }
 
 int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
@@ -1163,7 +1110,7 @@ int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
                ce_state->src_ring = ath10k_ce_alloc_src_ring(ar, ce_id, attr);
                if (IS_ERR(ce_state->src_ring)) {
                        ret = PTR_ERR(ce_state->src_ring);
-                       ath10k_err("failed to allocate copy engine source ring %d: %d\n",
+                       ath10k_err(ar, "failed to allocate copy engine source ring %d: %d\n",
                                   ce_id, ret);
                        ce_state->src_ring = NULL;
                        return ret;
@@ -1175,7 +1122,7 @@ int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
                                                                attr);
                if (IS_ERR(ce_state->dest_ring)) {
                        ret = PTR_ERR(ce_state->dest_ring);
-                       ath10k_err("failed to allocate copy engine destination ring %d: %d\n",
+                       ath10k_err(ar, "failed to allocate copy engine destination ring %d: %d\n",
                                   ce_id, ret);
                        ce_state->dest_ring = NULL;
                        return ret;
index 7a5a36fc59c1ad19c51e2c69496660f75aeca073..82d1f23546b9e343db6d7ad0960083ff185281e6 100644 (file)
@@ -162,30 +162,13 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state,
 
 void __ath10k_ce_send_revert(struct ath10k_ce_pipe *pipe);
 
-void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state,
-                               void (*send_cb)(struct ath10k_ce_pipe *),
-                               int disable_interrupts);
-
 int ath10k_ce_num_free_src_entries(struct ath10k_ce_pipe *pipe);
 
 /*==================Recv=======================*/
 
-/*
- * Make a buffer available to receive. The buffer must be at least of a
- * minimal size appropriate for this copy engine (src_sz_max attribute).
- *   ce                    - which copy engine to use
- *   per_transfer_recv_context  - context passed back to caller's recv_cb
- *   buffer                     - address of buffer in CE space
- * Returns 0 on success; otherwise an error status.
- *
- * Implemenation note: Pushes a buffer to Dest ring.
- */
-int ath10k_ce_recv_buf_enqueue(struct ath10k_ce_pipe *ce_state,
-                              void *per_transfer_recv_context,
-                              u32 buffer);
-
-void ath10k_ce_recv_cb_register(struct ath10k_ce_pipe *ce_state,
-                               void (*recv_cb)(struct ath10k_ce_pipe *));
+int __ath10k_ce_rx_num_free_bufs(struct ath10k_ce_pipe *pipe);
+int __ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr);
+int ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr);
 
 /* recv flags */
 /* Data is byte-swapped */
@@ -214,7 +197,9 @@ int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state,
 /*==================CE Engine Initialization=======================*/
 
 int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id,
-                       const struct ce_attr *attr);
+                       const struct ce_attr *attr,
+                       void (*send_cb)(struct ath10k_ce_pipe *),
+                       void (*recv_cb)(struct ath10k_ce_pipe *));
 void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id);
 int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
                          const struct ce_attr *attr);
@@ -245,6 +230,7 @@ int ath10k_ce_cancel_send_next(struct ath10k_ce_pipe *ce_state,
 void ath10k_ce_per_engine_service_any(struct ath10k *ar);
 void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id);
 int ath10k_ce_disable_interrupts(struct ath10k *ar);
+void ath10k_ce_enable_interrupts(struct ath10k *ar);
 
 /* ce_attr.flags values */
 /* Use NonSnooping PCIe accesses? */
index 93adb8c5896926c787bb80e6c0869cd7f5fd4672..651a6da8adf5544de4c254b5511a8cad5cb568de 100644 (file)
@@ -53,7 +53,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
 
 static void ath10k_send_suspend_complete(struct ath10k *ar)
 {
-       ath10k_dbg(ATH10K_DBG_BOOT, "boot suspend complete\n");
+       ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot suspend complete\n");
 
        complete(&ar->target_suspend);
 }
@@ -67,14 +67,14 @@ static int ath10k_init_configure_target(struct ath10k *ar)
        ret = ath10k_bmi_write32(ar, hi_app_host_interest,
                                 HTC_PROTOCOL_VERSION);
        if (ret) {
-               ath10k_err("settings HTC version failed\n");
+               ath10k_err(ar, "settings HTC version failed\n");
                return ret;
        }
 
        /* set the firmware mode to STA/IBSS/AP */
        ret = ath10k_bmi_read32(ar, hi_option_flag, &param_host);
        if (ret) {
-               ath10k_err("setting firmware mode (1/2) failed\n");
+               ath10k_err(ar, "setting firmware mode (1/2) failed\n");
                return ret;
        }
 
@@ -93,14 +93,14 @@ static int ath10k_init_configure_target(struct ath10k *ar)
 
        ret = ath10k_bmi_write32(ar, hi_option_flag, param_host);
        if (ret) {
-               ath10k_err("setting firmware mode (2/2) failed\n");
+               ath10k_err(ar, "setting firmware mode (2/2) failed\n");
                return ret;
        }
 
        /* We do all byte-swapping on the host */
        ret = ath10k_bmi_write32(ar, hi_be, 0);
        if (ret) {
-               ath10k_err("setting host CPU BE mode failed\n");
+               ath10k_err(ar, "setting host CPU BE mode failed\n");
                return ret;
        }
 
@@ -108,7 +108,7 @@ static int ath10k_init_configure_target(struct ath10k *ar)
        ret = ath10k_bmi_write32(ar, hi_fw_swap, 0);
 
        if (ret) {
-               ath10k_err("setting FW data/desc swap flags failed\n");
+               ath10k_err(ar, "setting FW data/desc swap flags failed\n");
                return ret;
        }
 
@@ -146,11 +146,12 @@ static int ath10k_push_board_ext_data(struct ath10k *ar)
 
        ret = ath10k_bmi_read32(ar, hi_board_ext_data, &board_ext_data_addr);
        if (ret) {
-               ath10k_err("could not read board ext data addr (%d)\n", ret);
+               ath10k_err(ar, "could not read board ext data addr (%d)\n",
+                          ret);
                return ret;
        }
 
-       ath10k_dbg(ATH10K_DBG_BOOT,
+       ath10k_dbg(ar, ATH10K_DBG_BOOT,
                   "boot push board extended data addr 0x%x\n",
                   board_ext_data_addr);
 
@@ -158,7 +159,7 @@ static int ath10k_push_board_ext_data(struct ath10k *ar)
                return 0;
 
        if (ar->board_len != (board_data_size + board_ext_data_size)) {
-               ath10k_err("invalid board (ext) data sizes %zu != %d+%d\n",
+               ath10k_err(ar, "invalid board (ext) data sizes %zu != %d+%d\n",
                           ar->board_len, board_data_size, board_ext_data_size);
                return -EINVAL;
        }
@@ -167,14 +168,15 @@ static int ath10k_push_board_ext_data(struct ath10k *ar)
                                      ar->board_data + board_data_size,
                                      board_ext_data_size);
        if (ret) {
-               ath10k_err("could not write board ext data (%d)\n", ret);
+               ath10k_err(ar, "could not write board ext data (%d)\n", ret);
                return ret;
        }
 
        ret = ath10k_bmi_write32(ar, hi_board_ext_data_config,
                                 (board_ext_data_size << 16) | 1);
        if (ret) {
-               ath10k_err("could not write board ext data bit (%d)\n", ret);
+               ath10k_err(ar, "could not write board ext data bit (%d)\n",
+                          ret);
                return ret;
        }
 
@@ -189,13 +191,13 @@ static int ath10k_download_board_data(struct ath10k *ar)
 
        ret = ath10k_push_board_ext_data(ar);
        if (ret) {
-               ath10k_err("could not push board ext data (%d)\n", ret);
+               ath10k_err(ar, "could not push board ext data (%d)\n", ret);
                goto exit;
        }
 
        ret = ath10k_bmi_read32(ar, hi_board_data, &address);
        if (ret) {
-               ath10k_err("could not read board data addr (%d)\n", ret);
+               ath10k_err(ar, "could not read board data addr (%d)\n", ret);
                goto exit;
        }
 
@@ -203,13 +205,13 @@ static int ath10k_download_board_data(struct ath10k *ar)
                                      min_t(u32, board_data_size,
                                            ar->board_len));
        if (ret) {
-               ath10k_err("could not write board data (%d)\n", ret);
+               ath10k_err(ar, "could not write board data (%d)\n", ret);
                goto exit;
        }
 
        ret = ath10k_bmi_write32(ar, hi_board_data_initialized, 1);
        if (ret) {
-               ath10k_err("could not write board data bit (%d)\n", ret);
+               ath10k_err(ar, "could not write board data bit (%d)\n", ret);
                goto exit;
        }
 
@@ -225,30 +227,30 @@ static int ath10k_download_and_run_otp(struct ath10k *ar)
        /* OTP is optional */
 
        if (!ar->otp_data || !ar->otp_len) {
-               ath10k_warn("Not running otp, calibration will be incorrect (otp-data %p otp_len %zd)!\n",
+               ath10k_warn(ar, "Not running otp, calibration will be incorrect (otp-data %p otp_len %zd)!\n",
                            ar->otp_data, ar->otp_len);
                return 0;
        }
 
-       ath10k_dbg(ATH10K_DBG_BOOT, "boot upload otp to 0x%x len %zd\n",
+       ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot upload otp to 0x%x len %zd\n",
                   address, ar->otp_len);
 
        ret = ath10k_bmi_fast_download(ar, address, ar->otp_data, ar->otp_len);
        if (ret) {
-               ath10k_err("could not write otp (%d)\n", ret);
+               ath10k_err(ar, "could not write otp (%d)\n", ret);
                return ret;
        }
 
        ret = ath10k_bmi_execute(ar, address, 0, &result);
        if (ret) {
-               ath10k_err("could not execute otp (%d)\n", ret);
+               ath10k_err(ar, "could not execute otp (%d)\n", ret);
                return ret;
        }
 
-       ath10k_dbg(ATH10K_DBG_BOOT, "boot otp execute result %d\n", result);
+       ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot otp execute result %d\n", result);
 
        if (result != 0) {
-               ath10k_err("otp calibration failed: %d", result);
+               ath10k_err(ar, "otp calibration failed: %d", result);
                return -EINVAL;
        }
 
@@ -265,7 +267,7 @@ static int ath10k_download_fw(struct ath10k *ar)
        ret = ath10k_bmi_fast_download(ar, address, ar->firmware_data,
                                       ar->firmware_len);
        if (ret) {
-               ath10k_err("could not write fw (%d)\n", ret);
+               ath10k_err(ar, "could not write fw (%d)\n", ret);
                goto exit;
        }
 
@@ -302,12 +304,12 @@ static int ath10k_core_fetch_firmware_api_1(struct ath10k *ar)
        int ret = 0;
 
        if (ar->hw_params.fw.fw == NULL) {
-               ath10k_err("firmware file not defined\n");
+               ath10k_err(ar, "firmware file not defined\n");
                return -EINVAL;
        }
 
        if (ar->hw_params.fw.board == NULL) {
-               ath10k_err("board data file not defined");
+               ath10k_err(ar, "board data file not defined");
                return -EINVAL;
        }
 
@@ -316,7 +318,7 @@ static int ath10k_core_fetch_firmware_api_1(struct ath10k *ar)
                                         ar->hw_params.fw.board);
        if (IS_ERR(ar->board)) {
                ret = PTR_ERR(ar->board);
-               ath10k_err("could not fetch board data (%d)\n", ret);
+               ath10k_err(ar, "could not fetch board data (%d)\n", ret);
                goto err;
        }
 
@@ -328,7 +330,7 @@ static int ath10k_core_fetch_firmware_api_1(struct ath10k *ar)
                                            ar->hw_params.fw.fw);
        if (IS_ERR(ar->firmware)) {
                ret = PTR_ERR(ar->firmware);
-               ath10k_err("could not fetch firmware (%d)\n", ret);
+               ath10k_err(ar, "could not fetch firmware (%d)\n", ret);
                goto err;
        }
 
@@ -344,7 +346,7 @@ static int ath10k_core_fetch_firmware_api_1(struct ath10k *ar)
                                       ar->hw_params.fw.otp);
        if (IS_ERR(ar->otp)) {
                ret = PTR_ERR(ar->otp);
-               ath10k_err("could not fetch otp (%d)\n", ret);
+               ath10k_err(ar, "could not fetch otp (%d)\n", ret);
                goto err;
        }
 
@@ -369,7 +371,7 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
        /* first fetch the firmware file (firmware-*.bin) */
        ar->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, name);
        if (IS_ERR(ar->firmware)) {
-               ath10k_err("could not fetch firmware file '%s/%s': %ld\n",
+               ath10k_err(ar, "could not fetch firmware file '%s/%s': %ld\n",
                           ar->hw_params.fw.dir, name, PTR_ERR(ar->firmware));
                return PTR_ERR(ar->firmware);
        }
@@ -381,14 +383,14 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
        magic_len = strlen(ATH10K_FIRMWARE_MAGIC) + 1;
 
        if (len < magic_len) {
-               ath10k_err("firmware file '%s/%s' too small to contain magic: %zu\n",
+               ath10k_err(ar, "firmware file '%s/%s' too small to contain magic: %zu\n",
                           ar->hw_params.fw.dir, name, len);
                ret = -EINVAL;
                goto err;
        }
 
        if (memcmp(data, ATH10K_FIRMWARE_MAGIC, magic_len) != 0) {
-               ath10k_err("invalid firmware magic\n");
+               ath10k_err(ar, "invalid firmware magic\n");
                ret = -EINVAL;
                goto err;
        }
@@ -410,7 +412,7 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
                data += sizeof(*hdr);
 
                if (len < ie_len) {
-                       ath10k_err("invalid length for FW IE %d (%zu < %zu)\n",
+                       ath10k_err(ar, "invalid length for FW IE %d (%zu < %zu)\n",
                                   ie_id, len, ie_len);
                        ret = -EINVAL;
                        goto err;
@@ -424,7 +426,7 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
                        memcpy(ar->hw->wiphy->fw_version, data, ie_len);
                        ar->hw->wiphy->fw_version[ie_len] = '\0';
 
-                       ath10k_dbg(ATH10K_DBG_BOOT,
+                       ath10k_dbg(ar, ATH10K_DBG_BOOT,
                                   "found fw version %s\n",
                                    ar->hw->wiphy->fw_version);
                        break;
@@ -434,11 +436,11 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
 
                        timestamp = (__le32 *)data;
 
-                       ath10k_dbg(ATH10K_DBG_BOOT, "found fw timestamp %d\n",
+                       ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw timestamp %d\n",
                                   le32_to_cpup(timestamp));
                        break;
                case ATH10K_FW_IE_FEATURES:
-                       ath10k_dbg(ATH10K_DBG_BOOT,
+                       ath10k_dbg(ar, ATH10K_DBG_BOOT,
                                   "found firmware features ie (%zd B)\n",
                                   ie_len);
 
@@ -450,19 +452,19 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
                                        break;
 
                                if (data[index] & (1 << bit)) {
-                                       ath10k_dbg(ATH10K_DBG_BOOT,
+                                       ath10k_dbg(ar, ATH10K_DBG_BOOT,
                                                   "Enabling feature bit: %i\n",
                                                   i);
                                        __set_bit(i, ar->fw_features);
                                }
                        }
 
-                       ath10k_dbg_dump(ATH10K_DBG_BOOT, "features", "",
+                       ath10k_dbg_dump(ar, ATH10K_DBG_BOOT, "features", "",
                                        ar->fw_features,
                                        sizeof(ar->fw_features));
                        break;
                case ATH10K_FW_IE_FW_IMAGE:
-                       ath10k_dbg(ATH10K_DBG_BOOT,
+                       ath10k_dbg(ar, ATH10K_DBG_BOOT,
                                   "found fw image ie (%zd B)\n",
                                   ie_len);
 
@@ -471,7 +473,7 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
 
                        break;
                case ATH10K_FW_IE_OTP_IMAGE:
-                       ath10k_dbg(ATH10K_DBG_BOOT,
+                       ath10k_dbg(ar, ATH10K_DBG_BOOT,
                                   "found otp image ie (%zd B)\n",
                                   ie_len);
 
@@ -480,7 +482,7 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
 
                        break;
                default:
-                       ath10k_warn("Unknown FW IE: %u\n",
+                       ath10k_warn(ar, "Unknown FW IE: %u\n",
                                    le32_to_cpu(hdr->id));
                        break;
                }
@@ -493,15 +495,22 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
        }
 
        if (!ar->firmware_data || !ar->firmware_len) {
-               ath10k_warn("No ATH10K_FW_IE_FW_IMAGE found from '%s/%s', skipping\n",
+               ath10k_warn(ar, "No ATH10K_FW_IE_FW_IMAGE found from '%s/%s', skipping\n",
                            ar->hw_params.fw.dir, name);
                ret = -ENOMEDIUM;
                goto err;
        }
 
+       if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features) &&
+           !test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
+               ath10k_err(ar, "feature bits corrupted: 10.2 feature requires 10.x feature to be set as well");
+               ret = -EINVAL;
+               goto err;
+       }
+
        /* now fetch the board file */
        if (ar->hw_params.fw.board == NULL) {
-               ath10k_err("board data file not defined");
+               ath10k_err(ar, "board data file not defined");
                ret = -EINVAL;
                goto err;
        }
@@ -511,7 +520,7 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
                                         ar->hw_params.fw.board);
        if (IS_ERR(ar->board)) {
                ret = PTR_ERR(ar->board);
-               ath10k_err("could not fetch board data '%s/%s' (%d)\n",
+               ath10k_err(ar, "could not fetch board data '%s/%s' (%d)\n",
                           ar->hw_params.fw.dir, ar->hw_params.fw.board,
                           ret);
                goto err;
@@ -531,22 +540,29 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
 {
        int ret;
 
+       ar->fw_api = 3;
+       ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
+
+       ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API3_FILE);
+       if (ret == 0)
+               goto success;
+
        ar->fw_api = 2;
-       ath10k_dbg(ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
+       ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
 
        ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API2_FILE);
        if (ret == 0)
                goto success;
 
        ar->fw_api = 1;
-       ath10k_dbg(ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
+       ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
 
        ret = ath10k_core_fetch_firmware_api_1(ar);
        if (ret)
                return ret;
 
 success:
-       ath10k_dbg(ATH10K_DBG_BOOT, "using fw api %d\n", ar->fw_api);
+       ath10k_dbg(ar, ATH10K_DBG_BOOT, "using fw api %d\n", ar->fw_api);
 
        return 0;
 }
@@ -557,19 +573,19 @@ static int ath10k_init_download_firmware(struct ath10k *ar)
 
        ret = ath10k_download_board_data(ar);
        if (ret) {
-               ath10k_err("failed to download board data: %d\n", ret);
+               ath10k_err(ar, "failed to download board data: %d\n", ret);
                return ret;
        }
 
        ret = ath10k_download_and_run_otp(ar);
        if (ret) {
-               ath10k_err("failed to run otp: %d\n", ret);
+               ath10k_err(ar, "failed to run otp: %d\n", ret);
                return ret;
        }
 
        ret = ath10k_download_fw(ar);
        if (ret) {
-               ath10k_err("failed to download firmware: %d\n", ret);
+               ath10k_err(ar, "failed to download firmware: %d\n", ret);
                return ret;
        }
 
@@ -586,7 +602,7 @@ static int ath10k_init_uart(struct ath10k *ar)
         */
        ret = ath10k_bmi_write32(ar, hi_serial_enable, 0);
        if (ret) {
-               ath10k_warn("could not disable UART prints (%d)\n", ret);
+               ath10k_warn(ar, "could not disable UART prints (%d)\n", ret);
                return ret;
        }
 
@@ -595,24 +611,24 @@ static int ath10k_init_uart(struct ath10k *ar)
 
        ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, 7);
        if (ret) {
-               ath10k_warn("could not enable UART prints (%d)\n", ret);
+               ath10k_warn(ar, "could not enable UART prints (%d)\n", ret);
                return ret;
        }
 
        ret = ath10k_bmi_write32(ar, hi_serial_enable, 1);
        if (ret) {
-               ath10k_warn("could not enable UART prints (%d)\n", ret);
+               ath10k_warn(ar, "could not enable UART prints (%d)\n", ret);
                return ret;
        }
 
        /* Set the UART baud rate to 19200. */
        ret = ath10k_bmi_write32(ar, hi_desired_baud_rate, 19200);
        if (ret) {
-               ath10k_warn("could not set the baud rate (%d)\n", ret);
+               ath10k_warn(ar, "could not set the baud rate (%d)\n", ret);
                return ret;
        }
 
-       ath10k_info("UART prints enabled\n");
+       ath10k_info(ar, "UART prints enabled\n");
        return 0;
 }
 
@@ -629,14 +645,14 @@ static int ath10k_init_hw_params(struct ath10k *ar)
        }
 
        if (i == ARRAY_SIZE(ath10k_hw_params_list)) {
-               ath10k_err("Unsupported hardware version: 0x%x\n",
+               ath10k_err(ar, "Unsupported hardware version: 0x%x\n",
                           ar->target_version);
                return -EINVAL;
        }
 
        ar->hw_params = *hw_params;
 
-       ath10k_dbg(ATH10K_DBG_BOOT, "Hardware name %s version 0x%x\n",
+       ath10k_dbg(ar, ATH10K_DBG_BOOT, "Hardware name %s version 0x%x\n",
                   ar->hw_params.name, ar->target_version);
 
        return 0;
@@ -651,14 +667,14 @@ static void ath10k_core_restart(struct work_struct *work)
        switch (ar->state) {
        case ATH10K_STATE_ON:
                ar->state = ATH10K_STATE_RESTARTING;
-               del_timer_sync(&ar->scan.timeout);
-               ath10k_reset_scan((unsigned long)ar);
+               ath10k_hif_stop(ar);
+               ath10k_scan_finish(ar);
                ieee80211_restart_hw(ar->hw);
                break;
        case ATH10K_STATE_OFF:
                /* this can happen if driver is being unloaded
                 * or if the crash happens during FW probing */
-               ath10k_warn("cannot restart a device that hasn't been started\n");
+               ath10k_warn(ar, "cannot restart a device that hasn't been started\n");
                break;
        case ATH10K_STATE_RESTARTING:
                /* hw restart might be requested from multiple places */
@@ -667,7 +683,7 @@ static void ath10k_core_restart(struct work_struct *work)
                ar->state = ATH10K_STATE_WEDGED;
                /* fall through */
        case ATH10K_STATE_WEDGED:
-               ath10k_warn("device is wedged, will not restart\n");
+               ath10k_warn(ar, "device is wedged, will not restart\n");
                break;
        }
 
@@ -700,7 +716,7 @@ int ath10k_core_start(struct ath10k *ar)
 
        status = ath10k_htc_init(ar);
        if (status) {
-               ath10k_err("could not init HTC (%d)\n", status);
+               ath10k_err(ar, "could not init HTC (%d)\n", status);
                goto err;
        }
 
@@ -710,90 +726,91 @@ int ath10k_core_start(struct ath10k *ar)
 
        status = ath10k_wmi_attach(ar);
        if (status) {
-               ath10k_err("WMI attach failed: %d\n", status);
+               ath10k_err(ar, "WMI attach failed: %d\n", status);
                goto err;
        }
 
        status = ath10k_htt_init(ar);
        if (status) {
-               ath10k_err("failed to init htt: %d\n", status);
+               ath10k_err(ar, "failed to init htt: %d\n", status);
                goto err_wmi_detach;
        }
 
        status = ath10k_htt_tx_alloc(&ar->htt);
        if (status) {
-               ath10k_err("failed to alloc htt tx: %d\n", status);
+               ath10k_err(ar, "failed to alloc htt tx: %d\n", status);
                goto err_wmi_detach;
        }
 
        status = ath10k_htt_rx_alloc(&ar->htt);
        if (status) {
-               ath10k_err("failed to alloc htt rx: %d\n", status);
+               ath10k_err(ar, "failed to alloc htt rx: %d\n", status);
                goto err_htt_tx_detach;
        }
 
        status = ath10k_hif_start(ar);
        if (status) {
-               ath10k_err("could not start HIF: %d\n", status);
+               ath10k_err(ar, "could not start HIF: %d\n", status);
                goto err_htt_rx_detach;
        }
 
        status = ath10k_htc_wait_target(&ar->htc);
        if (status) {
-               ath10k_err("failed to connect to HTC: %d\n", status);
+               ath10k_err(ar, "failed to connect to HTC: %d\n", status);
                goto err_hif_stop;
        }
 
        status = ath10k_htt_connect(&ar->htt);
        if (status) {
-               ath10k_err("failed to connect htt (%d)\n", status);
+               ath10k_err(ar, "failed to connect htt (%d)\n", status);
                goto err_hif_stop;
        }
 
        status = ath10k_wmi_connect(ar);
        if (status) {
-               ath10k_err("could not connect wmi: %d\n", status);
+               ath10k_err(ar, "could not connect wmi: %d\n", status);
                goto err_hif_stop;
        }
 
        status = ath10k_htc_start(&ar->htc);
        if (status) {
-               ath10k_err("failed to start htc: %d\n", status);
+               ath10k_err(ar, "failed to start htc: %d\n", status);
                goto err_hif_stop;
        }
 
        status = ath10k_wmi_wait_for_service_ready(ar);
        if (status <= 0) {
-               ath10k_warn("wmi service ready event not received");
+               ath10k_warn(ar, "wmi service ready event not received");
                status = -ETIMEDOUT;
-               goto err_htc_stop;
+               goto err_hif_stop;
        }
 
-       ath10k_dbg(ATH10K_DBG_BOOT, "firmware %s booted\n",
+       ath10k_dbg(ar, ATH10K_DBG_BOOT, "firmware %s booted\n",
                   ar->hw->wiphy->fw_version);
 
        status = ath10k_wmi_cmd_init(ar);
        if (status) {
-               ath10k_err("could not send WMI init command (%d)\n", status);
-               goto err_htc_stop;
+               ath10k_err(ar, "could not send WMI init command (%d)\n",
+                          status);
+               goto err_hif_stop;
        }
 
        status = ath10k_wmi_wait_for_unified_ready(ar);
        if (status <= 0) {
-               ath10k_err("wmi unified ready event not received\n");
+               ath10k_err(ar, "wmi unified ready event not received\n");
                status = -ETIMEDOUT;
-               goto err_htc_stop;
+               goto err_hif_stop;
        }
 
        status = ath10k_htt_setup(&ar->htt);
        if (status) {
-               ath10k_err("failed to setup htt: %d\n", status);
-               goto err_htc_stop;
+               ath10k_err(ar, "failed to setup htt: %d\n", status);
+               goto err_hif_stop;
        }
 
        status = ath10k_debug_start(ar);
        if (status)
-               goto err_htc_stop;
+               goto err_hif_stop;
 
        if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features))
                ar->free_vdev_map = (1 << TARGET_10X_NUM_VDEVS) - 1;
@@ -802,28 +819,8 @@ int ath10k_core_start(struct ath10k *ar)
 
        INIT_LIST_HEAD(&ar->arvifs);
 
-       if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags)) {
-               ath10k_info("%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d\n",
-                           ar->hw_params.name,
-                           ar->target_version,
-                           ar->chip_id,
-                           ar->hw->wiphy->fw_version,
-                           ar->fw_api,
-                           ar->htt.target_version_major,
-                           ar->htt.target_version_minor);
-               ath10k_info("debug %d debugfs %d tracing %d dfs %d\n",
-                           config_enabled(CONFIG_ATH10K_DEBUG),
-                           config_enabled(CONFIG_ATH10K_DEBUGFS),
-                           config_enabled(CONFIG_ATH10K_TRACING),
-                           config_enabled(CONFIG_ATH10K_DFS_CERTIFIED));
-       }
-
-       __set_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags);
-
        return 0;
 
-err_htc_stop:
-       ath10k_htc_stop(&ar->htc);
 err_hif_stop:
        ath10k_hif_stop(ar);
 err_htt_rx_detach:
@@ -845,14 +842,14 @@ int ath10k_wait_for_suspend(struct ath10k *ar, u32 suspend_opt)
 
        ret = ath10k_wmi_pdev_suspend_target(ar, suspend_opt);
        if (ret) {
-               ath10k_warn("could not suspend target (%d)\n", ret);
+               ath10k_warn(ar, "could not suspend target (%d)\n", ret);
                return ret;
        }
 
        ret = wait_for_completion_timeout(&ar->target_suspend, 1 * HZ);
 
        if (ret == 0) {
-               ath10k_warn("suspend timed out - target pause event never came\n");
+               ath10k_warn(ar, "suspend timed out - target pause event never came\n");
                return -ETIMEDOUT;
        }
 
@@ -868,7 +865,6 @@ void ath10k_core_stop(struct ath10k *ar)
                ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR);
 
        ath10k_debug_stop(ar);
-       ath10k_htc_stop(&ar->htc);
        ath10k_hif_stop(ar);
        ath10k_htt_tx_free(&ar->htt);
        ath10k_htt_rx_free(&ar->htt);
@@ -887,14 +883,14 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
 
        ret = ath10k_hif_power_up(ar);
        if (ret) {
-               ath10k_err("could not start pci hif (%d)\n", ret);
+               ath10k_err(ar, "could not start pci hif (%d)\n", ret);
                return ret;
        }
 
        memset(&target_info, 0, sizeof(target_info));
        ret = ath10k_bmi_get_target_info(ar, &target_info);
        if (ret) {
-               ath10k_err("could not get target info (%d)\n", ret);
+               ath10k_err(ar, "could not get target info (%d)\n", ret);
                ath10k_hif_power_down(ar);
                return ret;
        }
@@ -904,14 +900,14 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
 
        ret = ath10k_init_hw_params(ar);
        if (ret) {
-               ath10k_err("could not get hw params (%d)\n", ret);
+               ath10k_err(ar, "could not get hw params (%d)\n", ret);
                ath10k_hif_power_down(ar);
                return ret;
        }
 
        ret = ath10k_core_fetch_firmware_files(ar);
        if (ret) {
-               ath10k_err("could not fetch firmware files (%d)\n", ret);
+               ath10k_err(ar, "could not fetch firmware files (%d)\n", ret);
                ath10k_hif_power_down(ar);
                return ret;
        }
@@ -920,13 +916,14 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
 
        ret = ath10k_core_start(ar);
        if (ret) {
-               ath10k_err("could not init core (%d)\n", ret);
+               ath10k_err(ar, "could not init core (%d)\n", ret);
                ath10k_core_free_firmware_files(ar);
                ath10k_hif_power_down(ar);
                mutex_unlock(&ar->conf_mutex);
                return ret;
        }
 
+       ath10k_print_driver_info(ar);
        ath10k_core_stop(ar);
 
        mutex_unlock(&ar->conf_mutex);
@@ -939,7 +936,7 @@ static int ath10k_core_check_chip_id(struct ath10k *ar)
 {
        u32 hw_revision = MS(ar->chip_id, SOC_CHIP_ID_REV);
 
-       ath10k_dbg(ATH10K_DBG_BOOT, "boot chip_id 0x%08x hw_revision 0x%x\n",
+       ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot chip_id 0x%08x hw_revision 0x%x\n",
                   ar->chip_id, hw_revision);
 
        /* Check that we are not using hw1.0 (some of them have same pci id
@@ -947,7 +944,7 @@ static int ath10k_core_check_chip_id(struct ath10k *ar)
         * due to missing hw1.0 workarounds. */
        switch (hw_revision) {
        case QCA988X_HW_1_0_CHIP_ID_REV:
-               ath10k_err("ERROR: qca988x hw1.0 is not supported\n");
+               ath10k_err(ar, "ERROR: qca988x hw1.0 is not supported\n");
                return -EOPNOTSUPP;
 
        case QCA988X_HW_2_0_CHIP_ID_REV:
@@ -955,7 +952,7 @@ static int ath10k_core_check_chip_id(struct ath10k *ar)
                return 0;
 
        default:
-               ath10k_warn("Warning: hardware revision unknown (0x%x), expect problems\n",
+               ath10k_warn(ar, "Warning: hardware revision unknown (0x%x), expect problems\n",
                            ar->chip_id);
                return 0;
        }
@@ -970,25 +967,33 @@ static void ath10k_core_register_work(struct work_struct *work)
 
        status = ath10k_core_probe_fw(ar);
        if (status) {
-               ath10k_err("could not probe fw (%d)\n", status);
+               ath10k_err(ar, "could not probe fw (%d)\n", status);
                goto err;
        }
 
        status = ath10k_mac_register(ar);
        if (status) {
-               ath10k_err("could not register to mac80211 (%d)\n", status);
+               ath10k_err(ar, "could not register to mac80211 (%d)\n", status);
                goto err_release_fw;
        }
 
        status = ath10k_debug_create(ar);
        if (status) {
-               ath10k_err("unable to initialize debugfs\n");
+               ath10k_err(ar, "unable to initialize debugfs\n");
                goto err_unregister_mac;
        }
 
+       status = ath10k_spectral_create(ar);
+       if (status) {
+               ath10k_err(ar, "failed to initialize spectral\n");
+               goto err_debug_destroy;
+       }
+
        set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags);
        return;
 
+err_debug_destroy:
+       ath10k_debug_destroy(ar);
 err_unregister_mac:
        ath10k_mac_unregister(ar);
 err_release_fw:
@@ -1008,7 +1013,7 @@ int ath10k_core_register(struct ath10k *ar, u32 chip_id)
 
        status = ath10k_core_check_chip_id(ar);
        if (status) {
-               ath10k_err("Unsupported chip id 0x%08x\n", ar->chip_id);
+               ath10k_err(ar, "Unsupported chip id 0x%08x\n", ar->chip_id);
                return status;
        }
 
@@ -1025,6 +1030,12 @@ void ath10k_core_unregister(struct ath10k *ar)
        if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags))
                return;
 
+       /* Stop spectral before unregistering from mac80211 to remove the
+        * relayfs debugfs file cleanly. Otherwise the parent debugfs tree
+        * would be already be free'd recursively, leading to a double free.
+        */
+       ath10k_spectral_destroy(ar);
+
        /* We must unregister from mac80211 before we stop HTC and HIF.
         * Otherwise we will fail to submit commands to FW and mac80211 will be
         * unhappy about callback failures. */
@@ -1036,12 +1047,12 @@ void ath10k_core_unregister(struct ath10k *ar)
 }
 EXPORT_SYMBOL(ath10k_core_unregister);
 
-struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev,
+struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
                                  const struct ath10k_hif_ops *hif_ops)
 {
        struct ath10k *ar;
 
-       ar = ath10k_mac_create();
+       ar = ath10k_mac_create(priv_size);
        if (!ar)
                return NULL;
 
@@ -1051,7 +1062,6 @@ struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev,
        ar->p2p = !!ath10k_p2p;
        ar->dev = dev;
 
-       ar->hif.priv = hif_priv;
        ar->hif.ops = hif_ops;
 
        init_completion(&ar->scan.started);
@@ -1062,7 +1072,7 @@ struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev,
        init_completion(&ar->install_key_done);
        init_completion(&ar->vdev_setup_done);
 
-       setup_timer(&ar->scan.timeout, ath10k_reset_scan, (unsigned long)ar);
+       INIT_DELAYED_WORK(&ar->scan.timeout, ath10k_scan_timeout_work);
 
        ar->workqueue = create_singlethread_workqueue("ath10k_wq");
        if (!ar->workqueue)
index 83a5fa91531d159b9095ef0fff37db55c38e0eeb..4ef476099225775567b4ade0a45e227e855b4d1d 100644 (file)
@@ -22,6 +22,8 @@
 #include <linux/if_ether.h>
 #include <linux/types.h>
 #include <linux/pci.h>
+#include <linux/uuid.h>
+#include <linux/time.h>
 
 #include "htt.h"
 #include "htc.h"
@@ -31,6 +33,7 @@
 #include "../ath.h"
 #include "../regd.h"
 #include "../dfs_pattern_detector.h"
+#include "spectral.h"
 
 #define MS(_v, _f) (((_v) & _f##_MASK) >> _f##_LSB)
 #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK)
@@ -237,6 +240,7 @@ struct ath10k_vif {
 
        bool is_started;
        bool is_up;
+       bool spectral_enabled;
        u32 aid;
        u8 bssid[ETH_ALEN];
 
@@ -276,11 +280,20 @@ struct ath10k_vif_iter {
        struct ath10k_vif *arvif;
 };
 
+/* used for crash-dump storage, protected by data-lock */
+struct ath10k_fw_crash_data {
+       bool crashed_since_read;
+
+       uuid_le uuid;
+       struct timespec timestamp;
+       __le32 registers[REG_DUMP_COUNT_QCA988X];
+};
+
 struct ath10k_debug {
        struct dentry *debugfs_phy;
 
        struct ath10k_target_stats target_stats;
-       u32 wmi_service_bitmap[WMI_SERVICE_BM_SIZE];
+       DECLARE_BITMAP(wmi_service_bitmap, WMI_SERVICE_BM_SIZE);
 
        struct completion event_stats_compl;
 
@@ -293,6 +306,8 @@ struct ath10k_debug {
 
        u8 htt_max_amsdu;
        u8 htt_max_ampdu;
+
+       struct ath10k_fw_crash_data *fw_crash_data;
 };
 
 enum ath10k_state {
@@ -330,6 +345,11 @@ enum ath10k_fw_features {
        /* Firmware does not support P2P */
        ATH10K_FW_FEATURE_NO_P2P = 3,
 
+       /* Firmware 10.2 feature bit. The ATH10K_FW_FEATURE_WMI_10X feature bit
+        * is required to be set as well.
+        */
+       ATH10K_FW_FEATURE_WMI_10_2 = 4,
+
        /* keep last */
        ATH10K_FW_FEATURE_COUNT,
 };
@@ -337,10 +357,32 @@ enum ath10k_fw_features {
 enum ath10k_dev_flags {
        /* Indicates that ath10k device is during CAC phase of DFS */
        ATH10K_CAC_RUNNING,
-       ATH10K_FLAG_FIRST_BOOT_DONE,
        ATH10K_FLAG_CORE_REGISTERED,
 };
 
+enum ath10k_scan_state {
+       ATH10K_SCAN_IDLE,
+       ATH10K_SCAN_STARTING,
+       ATH10K_SCAN_RUNNING,
+       ATH10K_SCAN_ABORTING,
+};
+
+static inline const char *ath10k_scan_state_str(enum ath10k_scan_state state)
+{
+       switch (state) {
+       case ATH10K_SCAN_IDLE:
+               return "idle";
+       case ATH10K_SCAN_STARTING:
+               return "starting";
+       case ATH10K_SCAN_RUNNING:
+               return "running";
+       case ATH10K_SCAN_ABORTING:
+               return "aborting";
+       }
+
+       return "unknown";
+}
+
 struct ath10k {
        struct ath_common ath_common;
        struct ieee80211_hw *hw;
@@ -368,7 +410,6 @@ struct ath10k {
        bool p2p;
 
        struct {
-               void *priv;
                const struct ath10k_hif_ops *ops;
        } hif;
 
@@ -410,10 +451,9 @@ struct ath10k {
                struct completion started;
                struct completion completed;
                struct completion on_channel;
-               struct timer_list timeout;
+               struct delayed_work timeout;
+               enum ath10k_scan_state state;
                bool is_roc;
-               bool in_progress;
-               bool aborting;
                int vdev_id;
                int roc_freq;
        } scan;
@@ -494,9 +534,21 @@ struct ath10k {
 #ifdef CONFIG_ATH10K_DEBUGFS
        struct ath10k_debug debug;
 #endif
+
+       struct {
+               /* relay(fs) channel for spectral scan */
+               struct rchan *rfs_chan_spec_scan;
+
+               /* spectral_mode and spec_config are protected by conf_mutex */
+               enum ath10k_spectral_mode mode;
+               struct ath10k_spec_scan config;
+       } spectral;
+
+       /* must be last */
+       u8 drv_priv[0] __aligned(sizeof(void *));
 };
 
-struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev,
+struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
                                  const struct ath10k_hif_ops *hif_ops);
 void ath10k_core_destroy(struct ath10k *ar);
 
index 3030158c478e86cd9ee193af14b29da614f0d168..f3f0a80f8bab3eac6996b03629941d670f378456 100644 (file)
@@ -17,6 +17,9 @@
 
 #include <linux/module.h>
 #include <linux/debugfs.h>
+#include <linux/version.h>
+#include <linux/vermagic.h>
+#include <linux/vmalloc.h>
 
 #include "core.h"
 #include "debug.h"
 /* ms */
 #define ATH10K_DEBUG_HTT_STATS_INTERVAL 1000
 
-static int ath10k_printk(const char *level, const char *fmt, ...)
-{
-       struct va_format vaf;
-       va_list args;
-       int rtn;
+#define ATH10K_FW_CRASH_DUMP_VERSION 1
 
-       va_start(args, fmt);
+/**
+ * enum ath10k_fw_crash_dump_type - types of data in the dump file
+ * @ATH10K_FW_CRASH_DUMP_REGDUMP: Register crash dump in binary format
+ */
+enum ath10k_fw_crash_dump_type {
+       ATH10K_FW_CRASH_DUMP_REGISTERS = 0,
 
-       vaf.fmt = fmt;
-       vaf.va = &args;
+       ATH10K_FW_CRASH_DUMP_MAX,
+};
 
-       rtn = printk("%sath10k: %pV", level, &vaf);
+struct ath10k_tlv_dump_data {
+       /* see ath10k_fw_crash_dump_type above */
+       __le32 type;
 
-       va_end(args);
+       /* in bytes */
+       __le32 tlv_len;
 
-       return rtn;
-}
+       /* pad to 32-bit boundaries as needed */
+       u8 tlv_data[];
+} __packed;
+
+struct ath10k_dump_file_data {
+       /* dump file information */
+
+       /* "ATH10K-FW-DUMP" */
+       char df_magic[16];
+
+       __le32 len;
+
+       /* file dump version */
+       __le32 version;
+
+       /* some info we can get from ath10k struct that might help */
+
+       u8 uuid[16];
+
+       __le32 chip_id;
+
+       /* 0 for now, in place for later hardware */
+       __le32 bus_type;
+
+       __le32 target_version;
+       __le32 fw_version_major;
+       __le32 fw_version_minor;
+       __le32 fw_version_release;
+       __le32 fw_version_build;
+       __le32 phy_capability;
+       __le32 hw_min_tx_power;
+       __le32 hw_max_tx_power;
+       __le32 ht_cap_info;
+       __le32 vht_cap_info;
+       __le32 num_rf_chains;
+
+       /* firmware version string */
+       char fw_ver[ETHTOOL_FWVERS_LEN];
+
+       /* Kernel related information */
+
+       /* time-of-day stamp */
+       __le64 tv_sec;
 
-int ath10k_info(const char *fmt, ...)
+       /* time-of-day stamp, nano-seconds */
+       __le64 tv_nsec;
+
+       /* LINUX_VERSION_CODE */
+       __le32 kernel_ver_code;
+
+       /* VERMAGIC_STRING */
+       char kernel_ver[64];
+
+       /* room for growth w/out changing binary format */
+       u8 unused[128];
+
+       /* struct ath10k_tlv_dump_data + more */
+       u8 data[0];
+} __packed;
+
+int ath10k_info(struct ath10k *ar, const char *fmt, ...)
 {
        struct va_format vaf = {
                .fmt = fmt,
@@ -52,7 +116,7 @@ int ath10k_info(const char *fmt, ...)
 
        va_start(args, fmt);
        vaf.va = &args;
-       ret = ath10k_printk(KERN_INFO, "%pV", &vaf);
+       ret = dev_info(ar->dev, "%pV", &vaf);
        trace_ath10k_log_info(&vaf);
        va_end(args);
 
@@ -60,7 +124,25 @@ int ath10k_info(const char *fmt, ...)
 }
 EXPORT_SYMBOL(ath10k_info);
 
-int ath10k_err(const char *fmt, ...)
+void ath10k_print_driver_info(struct ath10k *ar)
+{
+       ath10k_info(ar, "%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d\n",
+                   ar->hw_params.name,
+                   ar->target_version,
+                   ar->chip_id,
+                   ar->hw->wiphy->fw_version,
+                   ar->fw_api,
+                   ar->htt.target_version_major,
+                   ar->htt.target_version_minor);
+       ath10k_info(ar, "debug %d debugfs %d tracing %d dfs %d\n",
+                   config_enabled(CONFIG_ATH10K_DEBUG),
+                   config_enabled(CONFIG_ATH10K_DEBUGFS),
+                   config_enabled(CONFIG_ATH10K_TRACING),
+                   config_enabled(CONFIG_ATH10K_DFS_CERTIFIED));
+}
+EXPORT_SYMBOL(ath10k_print_driver_info);
+
+int ath10k_err(struct ath10k *ar, const char *fmt, ...)
 {
        struct va_format vaf = {
                .fmt = fmt,
@@ -70,7 +152,7 @@ int ath10k_err(const char *fmt, ...)
 
        va_start(args, fmt);
        vaf.va = &args;
-       ret = ath10k_printk(KERN_ERR, "%pV", &vaf);
+       ret = dev_err(ar->dev, "%pV", &vaf);
        trace_ath10k_log_err(&vaf);
        va_end(args);
 
@@ -78,25 +160,21 @@ int ath10k_err(const char *fmt, ...)
 }
 EXPORT_SYMBOL(ath10k_err);
 
-int ath10k_warn(const char *fmt, ...)
+int ath10k_warn(struct ath10k *ar, const char *fmt, ...)
 {
        struct va_format vaf = {
                .fmt = fmt,
        };
        va_list args;
-       int ret = 0;
 
        va_start(args, fmt);
        vaf.va = &args;
-
-       if (net_ratelimit())
-               ret = ath10k_printk(KERN_WARNING, "%pV", &vaf);
-
+       dev_warn_ratelimited(ar->dev, "%pV", &vaf);
        trace_ath10k_log_warn(&vaf);
 
        va_end(args);
 
-       return ret;
+       return 0;
 }
 EXPORT_SYMBOL(ath10k_warn);
 
@@ -115,9 +193,10 @@ static ssize_t ath10k_read_wmi_services(struct file *file,
 {
        struct ath10k *ar = file->private_data;
        char *buf;
-       unsigned int len = 0, buf_len = 1500;
-       const char *status;
+       unsigned int len = 0, buf_len = 4096;
+       const char *name;
        ssize_t ret_cnt;
+       bool enabled;
        int i;
 
        buf = kzalloc(buf_len, GFP_KERNEL);
@@ -129,15 +208,22 @@ static ssize_t ath10k_read_wmi_services(struct file *file,
        if (len > buf_len)
                len = buf_len;
 
-       for (i = 0; i < WMI_SERVICE_LAST; i++) {
-               if (WMI_SERVICE_IS_ENABLED(ar->debug.wmi_service_bitmap, i))
-                       status = "enabled";
-               else
-                       status = "disabled";
+       for (i = 0; i < WMI_MAX_SERVICE; i++) {
+               enabled = test_bit(i, ar->debug.wmi_service_bitmap);
+               name = wmi_service_name(i);
+
+               if (!name) {
+                       if (enabled)
+                               len += scnprintf(buf + len, buf_len - len,
+                                                "%-40s %s (bit %d)\n",
+                                                "unknown", "enabled", i);
+
+                       continue;
+               }
 
                len += scnprintf(buf + len, buf_len - len,
-                                "0x%02x - %20s - %s\n",
-                                i, wmi_service_name(i), status);
+                                "%-40s %s\n",
+                                name, enabled ? "enabled" : "-");
        }
 
        ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len);
@@ -309,7 +395,7 @@ static ssize_t ath10k_read_fw_stats(struct file *file, char __user *user_buf,
 
        ret = ath10k_wmi_request_stats(ar, WMI_REQUEST_PEER_STAT);
        if (ret) {
-               ath10k_warn("could not request stats (%d)\n", ret);
+               ath10k_warn(ar, "could not request stats (%d)\n", ret);
                goto exit;
        }
 
@@ -527,11 +613,14 @@ static ssize_t ath10k_write_simulate_fw_crash(struct file *file,
        }
 
        if (!strcmp(buf, "soft")) {
-               ath10k_info("simulating soft firmware crash\n");
+               ath10k_info(ar, "simulating soft firmware crash\n");
                ret = ath10k_wmi_force_fw_hang(ar, WMI_FORCE_FW_HANG_ASSERT, 0);
        } else if (!strcmp(buf, "hard")) {
-               ath10k_info("simulating hard firmware crash\n");
-               ret = ath10k_wmi_vdev_set_param(ar, TARGET_NUM_VDEVS + 1,
+               ath10k_info(ar, "simulating hard firmware crash\n");
+               /* 0x7fff is vdev id, and it is always out of range for all
+                * firmware variants in order to force a firmware crash.
+                */
+               ret = ath10k_wmi_vdev_set_param(ar, 0x7fff,
                                        ar->wmi.vdev_param->rts_threshold, 0);
        } else {
                ret = -EINVAL;
@@ -539,7 +628,7 @@ static ssize_t ath10k_write_simulate_fw_crash(struct file *file,
        }
 
        if (ret) {
-               ath10k_warn("failed to simulate firmware crash: %d\n", ret);
+               ath10k_warn(ar, "failed to simulate firmware crash: %d\n", ret);
                goto exit;
        }
 
@@ -577,6 +666,138 @@ static const struct file_operations fops_chip_id = {
        .llseek = default_llseek,
 };
 
+struct ath10k_fw_crash_data *
+ath10k_debug_get_new_fw_crash_data(struct ath10k *ar)
+{
+       struct ath10k_fw_crash_data *crash_data = ar->debug.fw_crash_data;
+
+       lockdep_assert_held(&ar->data_lock);
+
+       crash_data->crashed_since_read = true;
+       uuid_le_gen(&crash_data->uuid);
+       getnstimeofday(&crash_data->timestamp);
+
+       return crash_data;
+}
+EXPORT_SYMBOL(ath10k_debug_get_new_fw_crash_data);
+
+static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar)
+{
+       struct ath10k_fw_crash_data *crash_data = ar->debug.fw_crash_data;
+       struct ath10k_dump_file_data *dump_data;
+       struct ath10k_tlv_dump_data *dump_tlv;
+       int hdr_len = sizeof(*dump_data);
+       unsigned int len, sofar = 0;
+       unsigned char *buf;
+
+       len = hdr_len;
+       len += sizeof(*dump_tlv) + sizeof(crash_data->registers);
+
+       sofar += hdr_len;
+
+       /* This is going to get big when we start dumping FW RAM and such,
+        * so go ahead and use vmalloc.
+        */
+       buf = vzalloc(len);
+       if (!buf)
+               return NULL;
+
+       spin_lock_bh(&ar->data_lock);
+
+       if (!crash_data->crashed_since_read) {
+               spin_unlock_bh(&ar->data_lock);
+               vfree(buf);
+               return NULL;
+       }
+
+       dump_data = (struct ath10k_dump_file_data *)(buf);
+       strlcpy(dump_data->df_magic, "ATH10K-FW-DUMP",
+               sizeof(dump_data->df_magic));
+       dump_data->len = cpu_to_le32(len);
+
+       dump_data->version = cpu_to_le32(ATH10K_FW_CRASH_DUMP_VERSION);
+
+       memcpy(dump_data->uuid, &crash_data->uuid, sizeof(dump_data->uuid));
+       dump_data->chip_id = cpu_to_le32(ar->chip_id);
+       dump_data->bus_type = cpu_to_le32(0);
+       dump_data->target_version = cpu_to_le32(ar->target_version);
+       dump_data->fw_version_major = cpu_to_le32(ar->fw_version_major);
+       dump_data->fw_version_minor = cpu_to_le32(ar->fw_version_minor);
+       dump_data->fw_version_release = cpu_to_le32(ar->fw_version_release);
+       dump_data->fw_version_build = cpu_to_le32(ar->fw_version_build);
+       dump_data->phy_capability = cpu_to_le32(ar->phy_capability);
+       dump_data->hw_min_tx_power = cpu_to_le32(ar->hw_min_tx_power);
+       dump_data->hw_max_tx_power = cpu_to_le32(ar->hw_max_tx_power);
+       dump_data->ht_cap_info = cpu_to_le32(ar->ht_cap_info);
+       dump_data->vht_cap_info = cpu_to_le32(ar->vht_cap_info);
+       dump_data->num_rf_chains = cpu_to_le32(ar->num_rf_chains);
+
+       strlcpy(dump_data->fw_ver, ar->hw->wiphy->fw_version,
+               sizeof(dump_data->fw_ver));
+
+       dump_data->kernel_ver_code = cpu_to_le32(LINUX_VERSION_CODE);
+       strlcpy(dump_data->kernel_ver, VERMAGIC_STRING,
+               sizeof(dump_data->kernel_ver));
+
+       dump_data->tv_sec = cpu_to_le64(crash_data->timestamp.tv_sec);
+       dump_data->tv_nsec = cpu_to_le64(crash_data->timestamp.tv_nsec);
+
+       /* Gather crash-dump */
+       dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar);
+       dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_REGISTERS);
+       dump_tlv->tlv_len = cpu_to_le32(sizeof(crash_data->registers));
+       memcpy(dump_tlv->tlv_data, &crash_data->registers,
+              sizeof(crash_data->registers));
+       sofar += sizeof(*dump_tlv) + sizeof(crash_data->registers);
+
+       ar->debug.fw_crash_data->crashed_since_read = false;
+
+       spin_unlock_bh(&ar->data_lock);
+
+       return dump_data;
+}
+
+static int ath10k_fw_crash_dump_open(struct inode *inode, struct file *file)
+{
+       struct ath10k *ar = inode->i_private;
+       struct ath10k_dump_file_data *dump;
+
+       dump = ath10k_build_dump_file(ar);
+       if (!dump)
+               return -ENODATA;
+
+       file->private_data = dump;
+
+       return 0;
+}
+
+static ssize_t ath10k_fw_crash_dump_read(struct file *file,
+                                        char __user *user_buf,
+                                        size_t count, loff_t *ppos)
+{
+       struct ath10k_dump_file_data *dump_file = file->private_data;
+
+       return simple_read_from_buffer(user_buf, count, ppos,
+                                      dump_file,
+                                      le32_to_cpu(dump_file->len));
+}
+
+static int ath10k_fw_crash_dump_release(struct inode *inode,
+                                       struct file *file)
+{
+       vfree(file->private_data);
+
+       return 0;
+}
+
+static const struct file_operations fops_fw_crash_dump = {
+       .open = ath10k_fw_crash_dump_open,
+       .read = ath10k_fw_crash_dump_read,
+       .release = ath10k_fw_crash_dump_release,
+       .owner = THIS_MODULE,
+       .llseek = default_llseek,
+};
+
 static int ath10k_debug_htt_stats_req(struct ath10k *ar)
 {
        u64 cookie;
@@ -596,7 +817,7 @@ static int ath10k_debug_htt_stats_req(struct ath10k *ar)
        ret = ath10k_htt_h2t_stats_req(&ar->htt, ar->debug.htt_stats_mask,
                                       cookie);
        if (ret) {
-               ath10k_warn("failed to send htt stats request: %d\n", ret);
+               ath10k_warn(ar, "failed to send htt stats request: %d\n", ret);
                return ret;
        }
 
@@ -770,7 +991,7 @@ static ssize_t ath10k_write_fw_dbglog(struct file *file,
        if (ar->state == ATH10K_STATE_ON) {
                ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask);
                if (ret) {
-                       ath10k_warn("dbglog cfg failed from debugfs: %d\n",
+                       ath10k_warn(ar, "dbglog cfg failed from debugfs: %d\n",
                                    ret);
                        goto exit;
                }
@@ -801,13 +1022,14 @@ int ath10k_debug_start(struct ath10k *ar)
        ret = ath10k_debug_htt_stats_req(ar);
        if (ret)
                /* continue normally anyway, this isn't serious */
-               ath10k_warn("failed to start htt stats workqueue: %d\n", ret);
+               ath10k_warn(ar, "failed to start htt stats workqueue: %d\n",
+                           ret);
 
        if (ar->debug.fw_dbglog_mask) {
                ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask);
                if (ret)
                        /* not serious */
-                       ath10k_warn("failed to enable dbglog during start: %d",
+                       ath10k_warn(ar, "failed to enable dbglog during start: %d",
                                    ret);
        }
 
@@ -910,11 +1132,20 @@ static const struct file_operations fops_dfs_stats = {
 
 int ath10k_debug_create(struct ath10k *ar)
 {
+       int ret;
+
+       ar->debug.fw_crash_data = vzalloc(sizeof(*ar->debug.fw_crash_data));
+       if (!ar->debug.fw_crash_data) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
        ar->debug.debugfs_phy = debugfs_create_dir("ath10k",
                                                   ar->hw->wiphy->debugfsdir);
-
-       if (!ar->debug.debugfs_phy)
-               return -ENOMEM;
+       if (!ar->debug.debugfs_phy) {
+               ret = -ENOMEM;
+               goto err_free_fw_crash_data;
+       }
 
        INIT_DELAYED_WORK(&ar->debug.htt_stats_dwork,
                          ath10k_debug_htt_stats_dwork);
@@ -930,6 +1161,9 @@ int ath10k_debug_create(struct ath10k *ar)
        debugfs_create_file("simulate_fw_crash", S_IRUSR, ar->debug.debugfs_phy,
                            ar, &fops_simulate_fw_crash);
 
+       debugfs_create_file("fw_crash_dump", S_IRUSR, ar->debug.debugfs_phy,
+                           ar, &fops_fw_crash_dump);
+
        debugfs_create_file("chip_id", S_IRUSR, ar->debug.debugfs_phy,
                            ar, &fops_chip_id);
 
@@ -958,17 +1192,25 @@ int ath10k_debug_create(struct ath10k *ar)
        }
 
        return 0;
+
+err_free_fw_crash_data:
+       vfree(ar->debug.fw_crash_data);
+
+err:
+       return ret;
 }
 
 void ath10k_debug_destroy(struct ath10k *ar)
 {
+       vfree(ar->debug.fw_crash_data);
        cancel_delayed_work_sync(&ar->debug.htt_stats_dwork);
 }
 
 #endif /* CONFIG_ATH10K_DEBUGFS */
 
 #ifdef CONFIG_ATH10K_DEBUG
-void ath10k_dbg(enum ath10k_debug_mask mask, const char *fmt, ...)
+void ath10k_dbg(struct ath10k *ar, enum ath10k_debug_mask mask,
+               const char *fmt, ...)
 {
        struct va_format vaf;
        va_list args;
@@ -979,7 +1221,7 @@ void ath10k_dbg(enum ath10k_debug_mask mask, const char *fmt, ...)
        vaf.va = &args;
 
        if (ath10k_debug_mask & mask)
-               ath10k_printk(KERN_DEBUG, "%pV", &vaf);
+               dev_printk(KERN_DEBUG, ar->dev, "%pV", &vaf);
 
        trace_ath10k_log_dbg(mask, &vaf);
 
@@ -987,13 +1229,14 @@ void ath10k_dbg(enum ath10k_debug_mask mask, const char *fmt, ...)
 }
 EXPORT_SYMBOL(ath10k_dbg);
 
-void ath10k_dbg_dump(enum ath10k_debug_mask mask,
+void ath10k_dbg_dump(struct ath10k *ar,
+                    enum ath10k_debug_mask mask,
                     const char *msg, const char *prefix,
                     const void *buf, size_t len)
 {
        if (ath10k_debug_mask & mask) {
                if (msg)
-                       ath10k_dbg(mask, "%s\n", msg);
+                       ath10k_dbg(ar, mask, "%s\n", msg);
 
                print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len);
        }
index a5824990bd2a8c789e69d18bb2e3f12f26548248..56746539bea2c6da6da647fa414d2989abff894e 100644 (file)
@@ -39,9 +39,10 @@ enum ath10k_debug_mask {
 
 extern unsigned int ath10k_debug_mask;
 
-__printf(1, 2) int ath10k_info(const char *fmt, ...);
-__printf(1, 2) int ath10k_err(const char *fmt, ...);
-__printf(1, 2) int ath10k_warn(const char *fmt, ...);
+__printf(2, 3) int ath10k_info(struct ath10k *ar, const char *fmt, ...);
+__printf(2, 3) int ath10k_err(struct ath10k *ar, const char *fmt, ...);
+__printf(2, 3) int ath10k_warn(struct ath10k *ar, const char *fmt, ...);
+void ath10k_print_driver_info(struct ath10k *ar);
 
 #ifdef CONFIG_ATH10K_DEBUGFS
 int ath10k_debug_start(struct ath10k *ar);
@@ -53,6 +54,10 @@ void ath10k_debug_read_service_map(struct ath10k *ar,
                                   size_t map_size);
 void ath10k_debug_read_target_stats(struct ath10k *ar,
                                    struct wmi_stats_event *ev);
+struct ath10k_fw_crash_data *
+ath10k_debug_get_new_fw_crash_data(struct ath10k *ar);
+
+void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer, int len);
 
 #define ATH10K_DFS_STAT_INC(ar, c) (ar->debug.dfs_stats.c++)
 
@@ -86,25 +91,40 @@ static inline void ath10k_debug_read_target_stats(struct ath10k *ar,
 {
 }
 
+static inline void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer,
+                                          int len)
+{
+}
+
+static inline struct ath10k_fw_crash_data *
+ath10k_debug_get_new_fw_crash_data(struct ath10k *ar)
+{
+       return NULL;
+}
+
 #define ATH10K_DFS_STAT_INC(ar, c) do { } while (0)
 
 #endif /* CONFIG_ATH10K_DEBUGFS */
 
 #ifdef CONFIG_ATH10K_DEBUG
-__printf(2, 3) void ath10k_dbg(enum ath10k_debug_mask mask,
+__printf(3, 4) void ath10k_dbg(struct ath10k *ar,
+                              enum ath10k_debug_mask mask,
                               const char *fmt, ...);
-void ath10k_dbg_dump(enum ath10k_debug_mask mask,
+void ath10k_dbg_dump(struct ath10k *ar,
+                    enum ath10k_debug_mask mask,
                     const char *msg, const char *prefix,
                     const void *buf, size_t len);
 #else /* CONFIG_ATH10K_DEBUG */
 
-static inline int ath10k_dbg(enum ath10k_debug_mask dbg_mask,
+static inline int ath10k_dbg(struct ath10k *ar,
+                            enum ath10k_debug_mask dbg_mask,
                             const char *fmt, ...)
 {
        return 0;
 }
 
-static inline void ath10k_dbg_dump(enum ath10k_debug_mask mask,
+static inline void ath10k_dbg_dump(struct ath10k *ar,
+                                  enum ath10k_debug_mask mask,
                                   const char *msg, const char *prefix,
                                   const void *buf, size_t len)
 {
index 5fdc40d3b378303a77edb1b39fc46cb5c3660d0a..fd9a251f06596a646a07167477b2f85beb4269eb 100644 (file)
@@ -46,7 +46,7 @@ static struct sk_buff *ath10k_htc_build_tx_ctrl_skb(void *ar)
 
        skb = dev_alloc_skb(ATH10K_HTC_CONTROL_BUFFER_SIZE);
        if (!skb) {
-               ath10k_warn("Unable to allocate ctrl skb\n");
+               ath10k_warn(ar, "Unable to allocate ctrl skb\n");
                return NULL;
        }
 
@@ -56,7 +56,7 @@ static struct sk_buff *ath10k_htc_build_tx_ctrl_skb(void *ar)
        skb_cb = ATH10K_SKB_CB(skb);
        memset(skb_cb, 0, sizeof(*skb_cb));
 
-       ath10k_dbg(ATH10K_DBG_HTC, "%s: skb %p\n", __func__, skb);
+       ath10k_dbg(ar, ATH10K_DBG_HTC, "%s: skb %p\n", __func__, skb);
        return skb;
 }
 
@@ -72,13 +72,15 @@ static inline void ath10k_htc_restore_tx_skb(struct ath10k_htc *htc,
 static void ath10k_htc_notify_tx_completion(struct ath10k_htc_ep *ep,
                                            struct sk_buff *skb)
 {
-       ath10k_dbg(ATH10K_DBG_HTC, "%s: ep %d skb %p\n", __func__,
+       struct ath10k *ar = ep->htc->ar;
+
+       ath10k_dbg(ar, ATH10K_DBG_HTC, "%s: ep %d skb %p\n", __func__,
                   ep->eid, skb);
 
        ath10k_htc_restore_tx_skb(ep->htc, skb);
 
        if (!ep->ep_ops.ep_tx_complete) {
-               ath10k_warn("no tx handler for eid %d\n", ep->eid);
+               ath10k_warn(ar, "no tx handler for eid %d\n", ep->eid);
                dev_kfree_skb_any(skb);
                return;
        }
@@ -89,12 +91,14 @@ static void ath10k_htc_notify_tx_completion(struct ath10k_htc_ep *ep,
 /* assumes tx_lock is held */
 static bool ath10k_htc_ep_need_credit_update(struct ath10k_htc_ep *ep)
 {
+       struct ath10k *ar = ep->htc->ar;
+
        if (!ep->tx_credit_flow_enabled)
                return false;
        if (ep->tx_credits >= ep->tx_credits_per_max_message)
                return false;
 
-       ath10k_dbg(ATH10K_DBG_HTC, "HTC: endpoint %d needs credit update\n",
+       ath10k_dbg(ar, ATH10K_DBG_HTC, "HTC: endpoint %d needs credit update\n",
                   ep->eid);
        return true;
 }
@@ -123,6 +127,7 @@ int ath10k_htc_send(struct ath10k_htc *htc,
                    enum ath10k_htc_ep_id eid,
                    struct sk_buff *skb)
 {
+       struct ath10k *ar = htc->ar;
        struct ath10k_htc_ep *ep = &htc->endpoint[eid];
        struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
        struct ath10k_hif_sg_item sg_item;
@@ -134,18 +139,10 @@ int ath10k_htc_send(struct ath10k_htc *htc,
                return -ECOMM;
 
        if (eid >= ATH10K_HTC_EP_COUNT) {
-               ath10k_warn("Invalid endpoint id: %d\n", eid);
+               ath10k_warn(ar, "Invalid endpoint id: %d\n", eid);
                return -ENOENT;
        }
 
-       /* FIXME: This looks ugly, can we fix it? */
-       spin_lock_bh(&htc->tx_lock);
-       if (htc->stopped) {
-               spin_unlock_bh(&htc->tx_lock);
-               return -ESHUTDOWN;
-       }
-       spin_unlock_bh(&htc->tx_lock);
-
        skb_push(skb, sizeof(struct ath10k_htc_hdr));
 
        if (ep->tx_credit_flow_enabled) {
@@ -157,7 +154,7 @@ int ath10k_htc_send(struct ath10k_htc *htc,
                        goto err_pull;
                }
                ep->tx_credits -= credits;
-               ath10k_dbg(ATH10K_DBG_HTC,
+               ath10k_dbg(ar, ATH10K_DBG_HTC,
                           "htc ep %d consumed %d credits (total %d)\n",
                           eid, credits, ep->tx_credits);
                spin_unlock_bh(&htc->tx_lock);
@@ -188,7 +185,7 @@ err_credits:
        if (ep->tx_credit_flow_enabled) {
                spin_lock_bh(&htc->tx_lock);
                ep->tx_credits += credits;
-               ath10k_dbg(ATH10K_DBG_HTC,
+               ath10k_dbg(ar, ATH10K_DBG_HTC,
                           "htc ep %d reverted %d credits back (total %d)\n",
                           eid, credits, ep->tx_credits);
                spin_unlock_bh(&htc->tx_lock);
@@ -227,11 +224,12 @@ ath10k_htc_process_credit_report(struct ath10k_htc *htc,
                                 int len,
                                 enum ath10k_htc_ep_id eid)
 {
+       struct ath10k *ar = htc->ar;
        struct ath10k_htc_ep *ep;
        int i, n_reports;
 
        if (len % sizeof(*report))
-               ath10k_warn("Uneven credit report len %d", len);
+               ath10k_warn(ar, "Uneven credit report len %d", len);
 
        n_reports = len / sizeof(*report);
 
@@ -243,7 +241,7 @@ ath10k_htc_process_credit_report(struct ath10k_htc *htc,
                ep = &htc->endpoint[report->eid];
                ep->tx_credits += report->credits;
 
-               ath10k_dbg(ATH10K_DBG_HTC, "htc ep %d got %d credits (total %d)\n",
+               ath10k_dbg(ar, ATH10K_DBG_HTC, "htc ep %d got %d credits (total %d)\n",
                           report->eid, report->credits, ep->tx_credits);
 
                if (ep->ep_ops.ep_tx_credits) {
@@ -260,6 +258,7 @@ static int ath10k_htc_process_trailer(struct ath10k_htc *htc,
                                      int length,
                                      enum ath10k_htc_ep_id src_eid)
 {
+       struct ath10k *ar = htc->ar;
        int status = 0;
        struct ath10k_htc_record *record;
        u8 *orig_buffer;
@@ -279,7 +278,7 @@ static int ath10k_htc_process_trailer(struct ath10k_htc *htc,
 
                if (record->hdr.len > length) {
                        /* no room left in buffer for record */
-                       ath10k_warn("Invalid record length: %d\n",
+                       ath10k_warn(ar, "Invalid record length: %d\n",
                                    record->hdr.len);
                        status = -EINVAL;
                        break;
@@ -289,7 +288,7 @@ static int ath10k_htc_process_trailer(struct ath10k_htc *htc,
                case ATH10K_HTC_RECORD_CREDITS:
                        len = sizeof(struct ath10k_htc_credit_report);
                        if (record->hdr.len < len) {
-                               ath10k_warn("Credit report too long\n");
+                               ath10k_warn(ar, "Credit report too long\n");
                                status = -EINVAL;
                                break;
                        }
@@ -299,7 +298,7 @@ static int ath10k_htc_process_trailer(struct ath10k_htc *htc,
                                                         src_eid);
                        break;
                default:
-                       ath10k_warn("Unhandled record: id:%d length:%d\n",
+                       ath10k_warn(ar, "Unhandled record: id:%d length:%d\n",
                                    record->hdr.id, record->hdr.len);
                        break;
                }
@@ -313,7 +312,7 @@ static int ath10k_htc_process_trailer(struct ath10k_htc *htc,
        }
 
        if (status)
-               ath10k_dbg_dump(ATH10K_DBG_HTC, "htc rx bad trailer", "",
+               ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc rx bad trailer", "",
                                orig_buffer, orig_length);
 
        return status;
@@ -339,8 +338,8 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
        eid = hdr->eid;
 
        if (eid >= ATH10K_HTC_EP_COUNT) {
-               ath10k_warn("HTC Rx: invalid eid %d\n", eid);
-               ath10k_dbg_dump(ATH10K_DBG_HTC, "htc bad header", "",
+               ath10k_warn(ar, "HTC Rx: invalid eid %d\n", eid);
+               ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc bad header", "",
                                hdr, sizeof(*hdr));
                status = -EINVAL;
                goto out;
@@ -360,19 +359,19 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
        payload_len = __le16_to_cpu(hdr->len);
 
        if (payload_len + sizeof(*hdr) > ATH10K_HTC_MAX_LEN) {
-               ath10k_warn("HTC rx frame too long, len: %zu\n",
+               ath10k_warn(ar, "HTC rx frame too long, len: %zu\n",
                            payload_len + sizeof(*hdr));
-               ath10k_dbg_dump(ATH10K_DBG_HTC, "htc bad rx pkt len", "",
+               ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc bad rx pkt len", "",
                                hdr, sizeof(*hdr));
                status = -EINVAL;
                goto out;
        }
 
        if (skb->len < payload_len) {
-               ath10k_dbg(ATH10K_DBG_HTC,
+               ath10k_dbg(ar, ATH10K_DBG_HTC,
                           "HTC Rx: insufficient length, got %d, expected %d\n",
                           skb->len, payload_len);
-               ath10k_dbg_dump(ATH10K_DBG_HTC, "htc bad rx pkt len",
+               ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc bad rx pkt len",
                                "", hdr, sizeof(*hdr));
                status = -EINVAL;
                goto out;
@@ -388,7 +387,7 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
 
                if ((trailer_len < min_len) ||
                    (trailer_len > payload_len)) {
-                       ath10k_warn("Invalid trailer length: %d\n",
+                       ath10k_warn(ar, "Invalid trailer length: %d\n",
                                    trailer_len);
                        status = -EPROTO;
                        goto out;
@@ -421,7 +420,7 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
                                 * this is a fatal error, target should not be
                                 * sending unsolicited messages on the ep 0
                                 */
-                               ath10k_warn("HTC rx ctrl still processing\n");
+                               ath10k_warn(ar, "HTC rx ctrl still processing\n");
                                status = -EINVAL;
                                complete(&htc->ctl_resp);
                                goto out;
@@ -442,7 +441,7 @@ static int ath10k_htc_rx_completion_handler(struct ath10k *ar,
                goto out;
        }
 
-       ath10k_dbg(ATH10K_DBG_HTC, "htc rx completion ep %d skb %p\n",
+       ath10k_dbg(ar, ATH10K_DBG_HTC, "htc rx completion ep %d skb %p\n",
                   eid, skb);
        ep->ep_ops.ep_rx_complete(ar, skb);
 
@@ -459,7 +458,7 @@ static void ath10k_htc_control_rx_complete(struct ath10k *ar,
 {
        /* This is unexpected. FW is not supposed to send regular rx on this
         * endpoint. */
-       ath10k_warn("unexpected htc rx\n");
+       ath10k_warn(ar, "unexpected htc rx\n");
        kfree_skb(skb);
 }
 
@@ -546,6 +545,7 @@ static u8 ath10k_htc_get_credit_allocation(struct ath10k_htc *htc,
 
 int ath10k_htc_wait_target(struct ath10k_htc *htc)
 {
+       struct ath10k *ar = htc->ar;
        int i, status = 0;
        struct ath10k_htc_svc_conn_req conn_req;
        struct ath10k_htc_svc_conn_resp conn_resp;
@@ -563,7 +563,7 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
                 * iomap writes unmasking PCI CE irqs aren't propagated
                 * properly in KVM PCI-passthrough sometimes.
                 */
-               ath10k_warn("failed to receive control response completion, polling..\n");
+               ath10k_warn(ar, "failed to receive control response completion, polling..\n");
 
                for (i = 0; i < CE_COUNT; i++)
                        ath10k_hif_send_complete_check(htc->ar, i, 1);
@@ -576,12 +576,12 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
        }
 
        if (status < 0) {
-               ath10k_err("ctl_resp never came in (%d)\n", status);
+               ath10k_err(ar, "ctl_resp never came in (%d)\n", status);
                return status;
        }
 
        if (htc->control_resp_len < sizeof(msg->hdr) + sizeof(msg->ready)) {
-               ath10k_err("Invalid HTC ready msg len:%d\n",
+               ath10k_err(ar, "Invalid HTC ready msg len:%d\n",
                           htc->control_resp_len);
                return -ECOMM;
        }
@@ -592,21 +592,21 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
        credit_size  = __le16_to_cpu(msg->ready.credit_size);
 
        if (message_id != ATH10K_HTC_MSG_READY_ID) {
-               ath10k_err("Invalid HTC ready msg: 0x%x\n", message_id);
+               ath10k_err(ar, "Invalid HTC ready msg: 0x%x\n", message_id);
                return -ECOMM;
        }
 
        htc->total_transmit_credits = credit_count;
        htc->target_credit_size = credit_size;
 
-       ath10k_dbg(ATH10K_DBG_HTC,
+       ath10k_dbg(ar, ATH10K_DBG_HTC,
                   "Target ready! transmit resources: %d size:%d\n",
                   htc->total_transmit_credits,
                   htc->target_credit_size);
 
        if ((htc->total_transmit_credits == 0) ||
            (htc->target_credit_size == 0)) {
-               ath10k_err("Invalid credit size received\n");
+               ath10k_err(ar, "Invalid credit size received\n");
                return -ECOMM;
        }
 
@@ -623,7 +623,8 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
        /* connect fake service */
        status = ath10k_htc_connect_service(htc, &conn_req, &conn_resp);
        if (status) {
-               ath10k_err("could not connect to htc service (%d)\n", status);
+               ath10k_err(ar, "could not connect to htc service (%d)\n",
+                          status);
                return status;
        }
 
@@ -634,6 +635,7 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc,
                               struct ath10k_htc_svc_conn_req *conn_req,
                               struct ath10k_htc_svc_conn_resp *conn_resp)
 {
+       struct ath10k *ar = htc->ar;
        struct ath10k_htc_msg *msg;
        struct ath10k_htc_conn_svc *req_msg;
        struct ath10k_htc_conn_svc_response resp_msg_dummy;
@@ -659,13 +661,13 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc,
        tx_alloc = ath10k_htc_get_credit_allocation(htc,
                                                    conn_req->service_id);
        if (!tx_alloc)
-               ath10k_dbg(ATH10K_DBG_BOOT,
+               ath10k_dbg(ar, ATH10K_DBG_BOOT,
                           "boot htc service %s does not allocate target credits\n",
                           htc_service_name(conn_req->service_id));
 
        skb = ath10k_htc_build_tx_ctrl_skb(htc->ar);
        if (!skb) {
-               ath10k_err("Failed to allocate HTC packet\n");
+               ath10k_err(ar, "Failed to allocate HTC packet\n");
                return -ENOMEM;
        }
 
@@ -703,7 +705,7 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc,
        if (status <= 0) {
                if (status == 0)
                        status = -ETIMEDOUT;
-               ath10k_err("Service connect timeout: %d\n", status);
+               ath10k_err(ar, "Service connect timeout: %d\n", status);
                return status;
        }
 
@@ -716,11 +718,11 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc,
        if ((message_id != ATH10K_HTC_MSG_CONNECT_SERVICE_RESP_ID) ||
            (htc->control_resp_len < sizeof(msg->hdr) +
             sizeof(msg->connect_service_response))) {
-               ath10k_err("Invalid resp message ID 0x%x", message_id);
+               ath10k_err(ar, "Invalid resp message ID 0x%x", message_id);
                return -EPROTO;
        }
 
-       ath10k_dbg(ATH10K_DBG_HTC,
+       ath10k_dbg(ar, ATH10K_DBG_HTC,
                   "HTC Service %s connect response: status: 0x%x, assigned ep: 0x%x\n",
                   htc_service_name(service_id),
                   resp_msg->status, resp_msg->eid);
@@ -729,7 +731,7 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc,
 
        /* check response status */
        if (resp_msg->status != ATH10K_HTC_CONN_SVC_STATUS_SUCCESS) {
-               ath10k_err("HTC Service %s connect request failed: 0x%x)\n",
+               ath10k_err(ar, "HTC Service %s connect request failed: 0x%x)\n",
                           htc_service_name(service_id),
                           resp_msg->status);
                return -EPROTO;
@@ -780,18 +782,18 @@ setup:
        if (status)
                return status;
 
-       ath10k_dbg(ATH10K_DBG_BOOT,
+       ath10k_dbg(ar, ATH10K_DBG_BOOT,
                   "boot htc service '%s' ul pipe %d dl pipe %d eid %d ready\n",
                   htc_service_name(ep->service_id), ep->ul_pipe_id,
                   ep->dl_pipe_id, ep->eid);
 
-       ath10k_dbg(ATH10K_DBG_BOOT,
+       ath10k_dbg(ar, ATH10K_DBG_BOOT,
                   "boot htc ep %d ul polled %d dl polled %d\n",
                   ep->eid, ep->ul_is_polled, ep->dl_is_polled);
 
        if (disable_credit_flow_ctrl && ep->tx_credit_flow_enabled) {
                ep->tx_credit_flow_enabled = false;
-               ath10k_dbg(ATH10K_DBG_BOOT,
+               ath10k_dbg(ar, ATH10K_DBG_BOOT,
                           "boot htc service '%s' eid %d TX flow control disabled\n",
                           htc_service_name(ep->service_id), assigned_eid);
        }
@@ -799,13 +801,13 @@ setup:
        return status;
 }
 
-struct sk_buff *ath10k_htc_alloc_skb(int size)
+struct sk_buff *ath10k_htc_alloc_skb(struct ath10k *ar, int size)
 {
        struct sk_buff *skb;
 
        skb = dev_alloc_skb(size + sizeof(struct ath10k_htc_hdr));
        if (!skb) {
-               ath10k_warn("could not allocate HTC tx skb\n");
+               ath10k_warn(ar, "could not allocate HTC tx skb\n");
                return NULL;
        }
 
@@ -813,13 +815,14 @@ struct sk_buff *ath10k_htc_alloc_skb(int size)
 
        /* FW/HTC requires 4-byte aligned streams */
        if (!IS_ALIGNED((unsigned long)skb->data, 4))
-               ath10k_warn("Unaligned HTC tx skb\n");
+               ath10k_warn(ar, "Unaligned HTC tx skb\n");
 
        return skb;
 }
 
 int ath10k_htc_start(struct ath10k_htc *htc)
 {
+       struct ath10k *ar = htc->ar;
        struct sk_buff *skb;
        int status = 0;
        struct ath10k_htc_msg *msg;
@@ -835,7 +838,7 @@ int ath10k_htc_start(struct ath10k_htc *htc)
        msg->hdr.message_id =
                __cpu_to_le16(ATH10K_HTC_MSG_SETUP_COMPLETE_EX_ID);
 
-       ath10k_dbg(ATH10K_DBG_HTC, "HTC is using TX credit flow control\n");
+       ath10k_dbg(ar, ATH10K_DBG_HTC, "HTC is using TX credit flow control\n");
 
        status = ath10k_htc_send(htc, ATH10K_HTC_EP_0, skb);
        if (status) {
@@ -846,13 +849,6 @@ int ath10k_htc_start(struct ath10k_htc *htc)
        return 0;
 }
 
-void ath10k_htc_stop(struct ath10k_htc *htc)
-{
-       spin_lock_bh(&htc->tx_lock);
-       htc->stopped = true;
-       spin_unlock_bh(&htc->tx_lock);
-}
-
 /* registered target arrival callback from the HIF layer */
 int ath10k_htc_init(struct ath10k *ar)
 {
@@ -862,7 +858,6 @@ int ath10k_htc_init(struct ath10k *ar)
 
        spin_lock_init(&htc->tx_lock);
 
-       htc->stopped = false;
        ath10k_htc_reset_endpoint_states(htc);
 
        /* setup HIF layer callbacks */
index 4716d331e6b6504d712c858345545a410cbcbab1..bf532f6711892e9b1dee4a1f971fe8d251832561 100644 (file)
@@ -332,7 +332,7 @@ struct ath10k_htc {
        struct ath10k *ar;
        struct ath10k_htc_ep endpoint[ATH10K_HTC_EP_COUNT];
 
-       /* protects endpoint and stopped fields */
+       /* protects endpoints */
        spinlock_t tx_lock;
 
        struct ath10k_htc_ops htc_ops;
@@ -345,8 +345,6 @@ struct ath10k_htc {
        int total_transmit_credits;
        struct ath10k_htc_svc_tx_credits service_tx_alloc[ATH10K_HTC_EP_COUNT];
        int target_credit_size;
-
-       bool stopped;
 };
 
 int ath10k_htc_init(struct ath10k *ar);
@@ -357,7 +355,6 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc,
                               struct ath10k_htc_svc_conn_resp *conn_resp);
 int ath10k_htc_send(struct ath10k_htc *htc, enum ath10k_htc_ep_id eid,
                    struct sk_buff *packet);
-void ath10k_htc_stop(struct ath10k_htc *htc);
-struct sk_buff *ath10k_htc_alloc_skb(int size);
+struct sk_buff *ath10k_htc_alloc_skb(struct ath10k *ar, int size);
 
 #endif
index 19c12cc8d66317ebbb8123b4a54b6654c5705c26..87daae11f1160ba8d181dd7fa56924f2f3cb3306 100644 (file)
@@ -74,12 +74,14 @@ int ath10k_htt_init(struct ath10k *ar)
 
 static int ath10k_htt_verify_version(struct ath10k_htt *htt)
 {
-       ath10k_dbg(ATH10K_DBG_BOOT, "htt target version %d.%d\n",
+       struct ath10k *ar = htt->ar;
+
+       ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt target version %d.%d\n",
                   htt->target_version_major, htt->target_version_minor);
 
        if (htt->target_version_major != 2 &&
            htt->target_version_major != 3) {
-               ath10k_err("unsupported htt major version %d. supported versions are 2 and 3\n",
+               ath10k_err(ar, "unsupported htt major version %d. supported versions are 2 and 3\n",
                           htt->target_version_major);
                return -ENOTSUPP;
        }
@@ -89,6 +91,7 @@ static int ath10k_htt_verify_version(struct ath10k_htt *htt)
 
 int ath10k_htt_setup(struct ath10k_htt *htt)
 {
+       struct ath10k *ar = htt->ar;
        int status;
 
        init_completion(&htt->target_version_received);
@@ -100,7 +103,7 @@ int ath10k_htt_setup(struct ath10k_htt *htt)
        status = wait_for_completion_timeout(&htt->target_version_received,
                                                HTT_TARGET_VERSION_TIMEOUT_HZ);
        if (status <= 0) {
-               ath10k_warn("htt version request timed out\n");
+               ath10k_warn(ar, "htt version request timed out\n");
                return -ETIMEDOUT;
        }
 
index 80cdac15588a2352608881acb5fc59fe8808f0ec..30927b1d71098519f04b80d5cbcff4d607a85a40 100644 (file)
@@ -271,13 +271,14 @@ void ath10k_htt_rx_free(struct ath10k_htt *htt)
 
 static inline struct sk_buff *ath10k_htt_rx_netbuf_pop(struct ath10k_htt *htt)
 {
+       struct ath10k *ar = htt->ar;
        int idx;
        struct sk_buff *msdu;
 
        lockdep_assert_held(&htt->rx_ring.lock);
 
        if (htt->rx_ring.fill_cnt == 0) {
-               ath10k_warn("tried to pop sk_buff from an empty rx ring\n");
+               ath10k_warn(ar, "tried to pop sk_buff from an empty rx ring\n");
                return NULL;
        }
 
@@ -311,6 +312,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
                                   struct sk_buff **tail_msdu,
                                   u32 *attention)
 {
+       struct ath10k *ar = htt->ar;
        int msdu_len, msdu_chaining = 0;
        struct sk_buff *msdu;
        struct htt_rx_desc *rx_desc;
@@ -318,7 +320,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
        lockdep_assert_held(&htt->rx_ring.lock);
 
        if (htt->rx_confused) {
-               ath10k_warn("htt is confused. refusing rx\n");
+               ath10k_warn(ar, "htt is confused. refusing rx\n");
                return -1;
        }
 
@@ -331,7 +333,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
                                 msdu->len + skb_tailroom(msdu),
                                 DMA_FROM_DEVICE);
 
-               ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx pop: ",
+               ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx pop: ",
                                msdu->data, msdu->len + skb_tailroom(msdu));
 
                rx_desc = (struct htt_rx_desc *)msdu->data;
@@ -354,7 +356,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
                        ath10k_htt_rx_free_msdu_chain(*head_msdu);
                        *head_msdu = NULL;
                        msdu = NULL;
-                       ath10k_err("htt rx stopped. cannot recover\n");
+                       ath10k_err(ar, "htt rx stopped. cannot recover\n");
                        htt->rx_confused = true;
                        break;
                }
@@ -429,7 +431,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
                                         next->len + skb_tailroom(next),
                                         DMA_FROM_DEVICE);
 
-                       ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL,
+                       ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL,
                                        "htt rx chained: ", next->data,
                                        next->len + skb_tailroom(next));
 
@@ -483,13 +485,14 @@ static void ath10k_htt_rx_replenish_task(unsigned long ptr)
 
 int ath10k_htt_rx_alloc(struct ath10k_htt *htt)
 {
+       struct ath10k *ar = htt->ar;
        dma_addr_t paddr;
        void *vaddr;
        struct timer_list *timer = &htt->rx_ring.refill_retry_timer;
 
        htt->rx_ring.size = ath10k_htt_rx_ring_size(htt);
        if (!is_power_of_2(htt->rx_ring.size)) {
-               ath10k_warn("htt rx ring size is not power of 2\n");
+               ath10k_warn(ar, "htt rx ring size is not power of 2\n");
                return -EINVAL;
        }
 
@@ -550,7 +553,7 @@ int ath10k_htt_rx_alloc(struct ath10k_htt *htt)
        tasklet_init(&htt->txrx_compl_task, ath10k_htt_txrx_compl_task,
                     (unsigned long)htt);
 
-       ath10k_dbg(ATH10K_DBG_BOOT, "htt rx ring size %d fill_level %d\n",
+       ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt rx ring size %d fill_level %d\n",
                   htt->rx_ring.size, htt->rx_ring.fill_level);
        return 0;
 
@@ -572,7 +575,8 @@ err_netbuf:
        return -ENOMEM;
 }
 
-static int ath10k_htt_rx_crypto_param_len(enum htt_rx_mpdu_encrypt_type type)
+static int ath10k_htt_rx_crypto_param_len(struct ath10k *ar,
+                                         enum htt_rx_mpdu_encrypt_type type)
 {
        switch (type) {
        case HTT_RX_MPDU_ENCRYPT_WEP40:
@@ -588,11 +592,12 @@ static int ath10k_htt_rx_crypto_param_len(enum htt_rx_mpdu_encrypt_type type)
                return 0;
        }
 
-       ath10k_warn("unknown encryption type %d\n", type);
+       ath10k_warn(ar, "unknown encryption type %d\n", type);
        return 0;
 }
 
-static int ath10k_htt_rx_crypto_tail_len(enum htt_rx_mpdu_encrypt_type type)
+static int ath10k_htt_rx_crypto_tail_len(struct ath10k *ar,
+                                        enum htt_rx_mpdu_encrypt_type type)
 {
        switch (type) {
        case HTT_RX_MPDU_ENCRYPT_NONE:
@@ -608,7 +613,7 @@ static int ath10k_htt_rx_crypto_tail_len(enum htt_rx_mpdu_encrypt_type type)
                return 8;
        }
 
-       ath10k_warn("unknown encryption type %d\n", type);
+       ath10k_warn(ar, "unknown encryption type %d\n", type);
        return 0;
 }
 
@@ -819,19 +824,55 @@ static bool ath10k_htt_rx_h_channel(struct ath10k *ar,
        return true;
 }
 
+static const char * const tid_to_ac[] = {
+       "BE",
+       "BK",
+       "BK",
+       "BE",
+       "VI",
+       "VI",
+       "VO",
+       "VO",
+};
+
+static char *ath10k_get_tid(struct ieee80211_hdr *hdr, char *out, size_t size)
+{
+       u8 *qc;
+       int tid;
+
+       if (!ieee80211_is_data_qos(hdr->frame_control))
+               return "";
+
+       qc = ieee80211_get_qos_ctl(hdr);
+       tid = *qc & IEEE80211_QOS_CTL_TID_MASK;
+       if (tid < 8)
+               snprintf(out, size, "tid %d (%s)", tid, tid_to_ac[tid]);
+       else
+               snprintf(out, size, "tid %d", tid);
+
+       return out;
+}
+
 static void ath10k_process_rx(struct ath10k *ar,
                              struct ieee80211_rx_status *rx_status,
                              struct sk_buff *skb)
 {
        struct ieee80211_rx_status *status;
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       char tid[32];
 
        status = IEEE80211_SKB_RXCB(skb);
        *status = *rx_status;
 
-       ath10k_dbg(ATH10K_DBG_DATA,
-                  "rx skb %p len %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %imic-err %i\n",
+       ath10k_dbg(ar, ATH10K_DBG_DATA,
+                  "rx skb %p len %u peer %pM %s %s sn %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n",
                   skb,
                   skb->len,
+                  ieee80211_get_SA(hdr),
+                  ath10k_get_tid(hdr, tid, sizeof(tid)),
+                  is_multicast_ether_addr(ieee80211_get_DA(hdr)) ?
+                                                       "mcast" : "ucast",
+                  (__le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4,
                   status->flag == 0 ? "legacy" : "",
                   status->flag & RX_FLAG_HT ? "ht" : "",
                   status->flag & RX_FLAG_VHT ? "vht" : "",
@@ -843,8 +884,9 @@ static void ath10k_process_rx(struct ath10k *ar,
                   status->freq,
                   status->band, status->flag,
                   !!(status->flag & RX_FLAG_FAILED_FCS_CRC),
-                  !!(status->flag & RX_FLAG_MMIC_ERROR));
-       ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "rx skb: ",
+                  !!(status->flag & RX_FLAG_MMIC_ERROR),
+                  !!(status->flag & RX_FLAG_AMSDU_MORE));
+       ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "rx skb: ",
                        skb->data, skb->len);
 
        ieee80211_rx(ar->hw, skb);
@@ -860,13 +902,14 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
                                struct ieee80211_rx_status *rx_status,
                                struct sk_buff *skb_in)
 {
+       struct ath10k *ar = htt->ar;
        struct htt_rx_desc *rxd;
        struct sk_buff *skb = skb_in;
        struct sk_buff *first;
        enum rx_msdu_decap_format fmt;
        enum htt_rx_mpdu_encrypt_type enctype;
        struct ieee80211_hdr *hdr;
-       u8 hdr_buf[64], addr[ETH_ALEN], *qos;
+       u8 hdr_buf[64], da[ETH_ALEN], sa[ETH_ALEN], *qos;
        unsigned int hdr_len;
 
        rxd = (void *)skb->data - sizeof(*rxd);
@@ -893,8 +936,8 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
                /* First frame in an A-MSDU chain has more decapped data. */
                if (skb == first) {
                        len = round_up(ieee80211_hdrlen(hdr->frame_control), 4);
-                       len += round_up(ath10k_htt_rx_crypto_param_len(enctype),
-                                       4);
+                       len += round_up(ath10k_htt_rx_crypto_param_len(ar,
+                                               enctype), 4);
                        decap_hdr += len;
                }
 
@@ -904,10 +947,11 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
                        skb_trim(skb, skb->len - FCS_LEN);
                        break;
                case RX_MSDU_DECAP_NATIVE_WIFI:
-                       /* pull decapped header and copy DA */
+                       /* pull decapped header and copy SA & DA */
                        hdr = (struct ieee80211_hdr *)skb->data;
                        hdr_len = ath10k_htt_rx_nwifi_hdrlen(hdr);
-                       memcpy(addr, ieee80211_get_DA(hdr), ETH_ALEN);
+                       memcpy(da, ieee80211_get_DA(hdr), ETH_ALEN);
+                       memcpy(sa, ieee80211_get_SA(hdr), ETH_ALEN);
                        skb_pull(skb, hdr_len);
 
                        /* push original 802.11 header */
@@ -921,8 +965,11 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
                        qos = ieee80211_get_qos_ctl(hdr);
                        qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
 
-                       /* original 802.11 header has a different DA */
-                       memcpy(ieee80211_get_DA(hdr), addr, ETH_ALEN);
+                       /* original 802.11 header has a different DA and in
+                        * case of 4addr it may also have different SA
+                        */
+                       memcpy(ieee80211_get_DA(hdr), da, ETH_ALEN);
+                       memcpy(ieee80211_get_SA(hdr), sa, ETH_ALEN);
                        break;
                case RX_MSDU_DECAP_ETHERNET2_DIX:
                        /* strip ethernet header and insert decapped 802.11
@@ -965,6 +1012,7 @@ static void ath10k_htt_rx_msdu(struct ath10k_htt *htt,
                               struct ieee80211_rx_status *rx_status,
                               struct sk_buff *skb)
 {
+       struct ath10k *ar = htt->ar;
        struct htt_rx_desc *rxd;
        struct ieee80211_hdr *hdr;
        enum rx_msdu_decap_format fmt;
@@ -974,7 +1022,7 @@ static void ath10k_htt_rx_msdu(struct ath10k_htt *htt,
 
        /* This shouldn't happen. If it does than it may be a FW bug. */
        if (skb->next) {
-               ath10k_warn("htt rx received chained non A-MSDU frame\n");
+               ath10k_warn(ar, "htt rx received chained non A-MSDU frame\n");
                ath10k_htt_rx_free_msdu_chain(skb->next);
                skb->next = NULL;
        }
@@ -1011,7 +1059,8 @@ static void ath10k_htt_rx_msdu(struct ath10k_htt *htt,
 
                rfc1042 = hdr;
                rfc1042 += roundup(hdr_len, 4);
-               rfc1042 += roundup(ath10k_htt_rx_crypto_param_len(enctype), 4);
+               rfc1042 += roundup(ath10k_htt_rx_crypto_param_len(ar,
+                                       enctype), 4);
 
                skb_pull(skb, sizeof(struct ethhdr));
                memcpy(skb_push(skb, sizeof(struct rfc1042_hdr)),
@@ -1120,27 +1169,29 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt,
                                        bool channel_set,
                                        u32 attention)
 {
+       struct ath10k *ar = htt->ar;
+
        if (head->len == 0) {
-               ath10k_dbg(ATH10K_DBG_HTT,
+               ath10k_dbg(ar, ATH10K_DBG_HTT,
                           "htt rx dropping due to zero-len\n");
                return false;
        }
 
        if (attention & RX_ATTENTION_FLAGS_DECRYPT_ERR) {
-               ath10k_dbg(ATH10K_DBG_HTT,
+               ath10k_dbg(ar, ATH10K_DBG_HTT,
                           "htt rx dropping due to decrypt-err\n");
                return false;
        }
 
        if (!channel_set) {
-               ath10k_warn("no channel configured; ignoring frame!\n");
+               ath10k_warn(ar, "no channel configured; ignoring frame!\n");
                return false;
        }
 
        /* Skip mgmt frames while we handle this in WMI */
        if (status == HTT_RX_IND_MPDU_STATUS_MGMT_CTRL ||
            attention & RX_ATTENTION_FLAGS_MGMT_TYPE) {
-               ath10k_dbg(ATH10K_DBG_HTT, "htt rx mgmt ctrl\n");
+               ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx mgmt ctrl\n");
                return false;
        }
 
@@ -1148,14 +1199,14 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt,
            status != HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR &&
            status != HTT_RX_IND_MPDU_STATUS_ERR_INV_PEER &&
            !htt->ar->monitor_started) {
-               ath10k_dbg(ATH10K_DBG_HTT,
+               ath10k_dbg(ar, ATH10K_DBG_HTT,
                           "htt rx ignoring frame w/ status %d\n",
                           status);
                return false;
        }
 
        if (test_bit(ATH10K_CAC_RUNNING, &htt->ar->dev_flags)) {
-               ath10k_dbg(ATH10K_DBG_HTT,
+               ath10k_dbg(ar, ATH10K_DBG_HTT,
                           "htt rx CAC running\n");
                return false;
        }
@@ -1166,6 +1217,7 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt,
 static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
                                  struct htt_rx_indication *rx)
 {
+       struct ath10k *ar = htt->ar;
        struct ieee80211_rx_status *rx_status = &htt->rx_status;
        struct htt_rx_indication_mpdu_range *mpdu_ranges;
        struct htt_rx_desc *rxd;
@@ -1211,7 +1263,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
                                      rx_status);
        }
 
-       ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx ind: ",
+       ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx ind: ",
                        rx, sizeof(*rx) +
                        (sizeof(struct htt_rx_indication_mpdu_range) *
                                num_mpdu_ranges));
@@ -1233,7 +1285,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
                                                      &attention);
 
                        if (ret < 0) {
-                               ath10k_warn("failed to pop amsdu from htt rx ring %d\n",
+                               ath10k_warn(ar, "failed to pop amsdu from htt rx ring %d\n",
                                            ret);
                                ath10k_htt_rx_free_msdu_chain(msdu_head);
                                continue;
@@ -1282,6 +1334,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
 static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
                                struct htt_rx_fragment_indication *frag)
 {
+       struct ath10k *ar = htt->ar;
        struct sk_buff *msdu_head, *msdu_tail;
        enum htt_rx_mpdu_encrypt_type enctype;
        struct htt_rx_desc *rxd;
@@ -1308,10 +1361,10 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
                                      &attention);
        spin_unlock_bh(&htt->rx_ring.lock);
 
-       ath10k_dbg(ATH10K_DBG_HTT_DUMP, "htt rx frag ahead\n");
+       ath10k_dbg(ar, ATH10K_DBG_HTT_DUMP, "htt rx frag ahead\n");
 
        if (ret) {
-               ath10k_warn("failed to pop amsdu from httr rx ring for fragmented rx %d\n",
+               ath10k_warn(ar, "failed to pop amsdu from httr rx ring for fragmented rx %d\n",
                            ret);
                ath10k_htt_rx_free_msdu_chain(msdu_head);
                return;
@@ -1328,7 +1381,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
                        RX_MSDU_START_INFO1_DECAP_FORMAT);
 
        if (fmt != RX_MSDU_DECAP_RAW) {
-               ath10k_warn("we dont support non-raw fragmented rx yet\n");
+               ath10k_warn(ar, "we dont support non-raw fragmented rx yet\n");
                dev_kfree_skb_any(msdu_head);
                goto end;
        }
@@ -1340,17 +1393,17 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
        msdu_head->ip_summed = ath10k_htt_rx_get_csum_state(msdu_head);
 
        if (tkip_mic_err)
-               ath10k_warn("tkip mic error\n");
+               ath10k_warn(ar, "tkip mic error\n");
 
        if (decrypt_err) {
-               ath10k_warn("decryption err in fragmented rx\n");
+               ath10k_warn(ar, "decryption err in fragmented rx\n");
                dev_kfree_skb_any(msdu_head);
                goto end;
        }
 
        if (enctype != HTT_RX_MPDU_ENCRYPT_NONE) {
                hdrlen = ieee80211_hdrlen(hdr->frame_control);
-               paramlen = ath10k_htt_rx_crypto_param_len(enctype);
+               paramlen = ath10k_htt_rx_crypto_param_len(ar, enctype);
 
                /* It is more efficient to move the header than the payload */
                memmove((void *)msdu_head->data + paramlen,
@@ -1364,7 +1417,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
        trim  = 4;
 
        /* remove crypto trailer */
-       trim += ath10k_htt_rx_crypto_tail_len(enctype);
+       trim += ath10k_htt_rx_crypto_tail_len(ar, enctype);
 
        /* last fragment of TKIP frags has MIC */
        if (!ieee80211_has_morefrags(hdr->frame_control) &&
@@ -1372,20 +1425,20 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
                trim += 8;
 
        if (trim > msdu_head->len) {
-               ath10k_warn("htt rx fragment: trailer longer than the frame itself? drop\n");
+               ath10k_warn(ar, "htt rx fragment: trailer longer than the frame itself? drop\n");
                dev_kfree_skb_any(msdu_head);
                goto end;
        }
 
        skb_trim(msdu_head, msdu_head->len - trim);
 
-       ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx frag mpdu: ",
+       ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx frag mpdu: ",
                        msdu_head->data, msdu_head->len);
        ath10k_process_rx(htt->ar, rx_status, msdu_head);
 
 end:
        if (fw_desc_len > 0) {
-               ath10k_dbg(ATH10K_DBG_HTT,
+               ath10k_dbg(ar, ATH10K_DBG_HTT,
                           "expecting more fragmented rx in one indication %d\n",
                           fw_desc_len);
        }
@@ -1415,12 +1468,12 @@ static void ath10k_htt_rx_frm_tx_compl(struct ath10k *ar,
                tx_done.discard = true;
                break;
        default:
-               ath10k_warn("unhandled tx completion status %d\n", status);
+               ath10k_warn(ar, "unhandled tx completion status %d\n", status);
                tx_done.discard = true;
                break;
        }
 
-       ath10k_dbg(ATH10K_DBG_HTT, "htt tx completion num_msdus %d\n",
+       ath10k_dbg(ar, ATH10K_DBG_HTT, "htt tx completion num_msdus %d\n",
                   resp->data_tx_completion.num_msdus);
 
        for (i = 0; i < resp->data_tx_completion.num_msdus; i++) {
@@ -1441,14 +1494,14 @@ static void ath10k_htt_rx_addba(struct ath10k *ar, struct htt_resp *resp)
        tid = MS(info0, HTT_RX_BA_INFO0_TID);
        peer_id = MS(info0, HTT_RX_BA_INFO0_PEER_ID);
 
-       ath10k_dbg(ATH10K_DBG_HTT,
+       ath10k_dbg(ar, ATH10K_DBG_HTT,
                   "htt rx addba tid %hu peer_id %hu size %hhu\n",
                   tid, peer_id, ev->window_size);
 
        spin_lock_bh(&ar->data_lock);
        peer = ath10k_peer_find_by_id(ar, peer_id);
        if (!peer) {
-               ath10k_warn("received addba event for invalid peer_id: %hu\n",
+               ath10k_warn(ar, "received addba event for invalid peer_id: %hu\n",
                            peer_id);
                spin_unlock_bh(&ar->data_lock);
                return;
@@ -1456,13 +1509,13 @@ static void ath10k_htt_rx_addba(struct ath10k *ar, struct htt_resp *resp)
 
        arvif = ath10k_get_arvif(ar, peer->vdev_id);
        if (!arvif) {
-               ath10k_warn("received addba event for invalid vdev_id: %u\n",
+               ath10k_warn(ar, "received addba event for invalid vdev_id: %u\n",
                            peer->vdev_id);
                spin_unlock_bh(&ar->data_lock);
                return;
        }
 
-       ath10k_dbg(ATH10K_DBG_HTT,
+       ath10k_dbg(ar, ATH10K_DBG_HTT,
                   "htt rx start rx ba session sta %pM tid %hu size %hhu\n",
                   peer->addr, tid, ev->window_size);
 
@@ -1481,14 +1534,14 @@ static void ath10k_htt_rx_delba(struct ath10k *ar, struct htt_resp *resp)
        tid = MS(info0, HTT_RX_BA_INFO0_TID);
        peer_id = MS(info0, HTT_RX_BA_INFO0_PEER_ID);
 
-       ath10k_dbg(ATH10K_DBG_HTT,
+       ath10k_dbg(ar, ATH10K_DBG_HTT,
                   "htt rx delba tid %hu peer_id %hu\n",
                   tid, peer_id);
 
        spin_lock_bh(&ar->data_lock);
        peer = ath10k_peer_find_by_id(ar, peer_id);
        if (!peer) {
-               ath10k_warn("received addba event for invalid peer_id: %hu\n",
+               ath10k_warn(ar, "received addba event for invalid peer_id: %hu\n",
                            peer_id);
                spin_unlock_bh(&ar->data_lock);
                return;
@@ -1496,13 +1549,13 @@ static void ath10k_htt_rx_delba(struct ath10k *ar, struct htt_resp *resp)
 
        arvif = ath10k_get_arvif(ar, peer->vdev_id);
        if (!arvif) {
-               ath10k_warn("received addba event for invalid vdev_id: %u\n",
+               ath10k_warn(ar, "received addba event for invalid vdev_id: %u\n",
                            peer->vdev_id);
                spin_unlock_bh(&ar->data_lock);
                return;
        }
 
-       ath10k_dbg(ATH10K_DBG_HTT,
+       ath10k_dbg(ar, ATH10K_DBG_HTT,
                   "htt rx stop rx ba session sta %pM tid %hu\n",
                   peer->addr, tid);
 
@@ -1517,9 +1570,9 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
 
        /* confirm alignment */
        if (!IS_ALIGNED((unsigned long)skb->data, 4))
-               ath10k_warn("unaligned htt message, expect trouble\n");
+               ath10k_warn(ar, "unaligned htt message, expect trouble\n");
 
-       ath10k_dbg(ATH10K_DBG_HTT, "htt rx, msg_type: 0x%0X\n",
+       ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx, msg_type: 0x%0X\n",
                   resp->hdr.msg_type);
        switch (resp->hdr.msg_type) {
        case HTT_T2H_MSG_TYPE_VERSION_CONF: {
@@ -1583,7 +1636,7 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
                struct ath10k *ar = htt->ar;
                struct htt_security_indication *ev = &resp->security_indication;
 
-               ath10k_dbg(ATH10K_DBG_HTT,
+               ath10k_dbg(ar, ATH10K_DBG_HTT,
                           "sec ind peer_id %d unicast %d type %d\n",
                          __le16_to_cpu(ev->peer_id),
                          !!(ev->flags & HTT_SECURITY_IS_UNICAST),
@@ -1592,7 +1645,7 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
                break;
        }
        case HTT_T2H_MSG_TYPE_RX_FRAG_IND: {
-               ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt event: ",
+               ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt event: ",
                                skb->data, skb->len);
                ath10k_htt_rx_frag_handler(htt, &resp->rx_frag_ind);
                break;
@@ -1609,7 +1662,7 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
                 * sends all tx frames as already inspected so this shouldn't
                 * happen unless fw has a bug.
                 */
-               ath10k_warn("received an unexpected htt tx inspect event\n");
+               ath10k_warn(ar, "received an unexpected htt tx inspect event\n");
                break;
        case HTT_T2H_MSG_TYPE_RX_ADDBA:
                ath10k_htt_rx_addba(ar, resp);
@@ -1624,9 +1677,9 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
                break;
        }
        default:
-               ath10k_dbg(ATH10K_DBG_HTT, "htt event (%d) not handled\n",
+               ath10k_dbg(ar, ATH10K_DBG_HTT, "htt event (%d) not handled\n",
                           resp->hdr.msg_type);
-               ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt event: ",
+               ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt event: ",
                                skb->data, skb->len);
                break;
        };
index 8b27bfcc1de39b3d3b86dc7881b532064e0a76f7..eaa73aa99c20e08816cad0905ef5dcd3e5b22e34 100644 (file)
@@ -58,6 +58,7 @@ exit:
 
 int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt)
 {
+       struct ath10k *ar = htt->ar;
        int msdu_id;
 
        lockdep_assert_held(&htt->tx_lock);
@@ -67,24 +68,29 @@ int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt)
        if (msdu_id == htt->max_num_pending_tx)
                return -ENOBUFS;
 
-       ath10k_dbg(ATH10K_DBG_HTT, "htt tx alloc msdu_id %d\n", msdu_id);
+       ath10k_dbg(ar, ATH10K_DBG_HTT, "htt tx alloc msdu_id %d\n", msdu_id);
        __set_bit(msdu_id, htt->used_msdu_ids);
        return msdu_id;
 }
 
 void ath10k_htt_tx_free_msdu_id(struct ath10k_htt *htt, u16 msdu_id)
 {
+       struct ath10k *ar = htt->ar;
+
        lockdep_assert_held(&htt->tx_lock);
 
        if (!test_bit(msdu_id, htt->used_msdu_ids))
-               ath10k_warn("trying to free unallocated msdu_id %d\n", msdu_id);
+               ath10k_warn(ar, "trying to free unallocated msdu_id %d\n",
+                           msdu_id);
 
-       ath10k_dbg(ATH10K_DBG_HTT, "htt tx free msdu_id %hu\n", msdu_id);
+       ath10k_dbg(ar, ATH10K_DBG_HTT, "htt tx free msdu_id %hu\n", msdu_id);
        __clear_bit(msdu_id, htt->used_msdu_ids);
 }
 
 int ath10k_htt_tx_alloc(struct ath10k_htt *htt)
 {
+       struct ath10k *ar = htt->ar;
+
        spin_lock_init(&htt->tx_lock);
        init_waitqueue_head(&htt->empty_tx_wq);
 
@@ -93,7 +99,7 @@ int ath10k_htt_tx_alloc(struct ath10k_htt *htt)
        else
                htt->max_num_pending_tx = TARGET_NUM_MSDU_DESC;
 
-       ath10k_dbg(ATH10K_DBG_BOOT, "htt tx max num pending tx %d\n",
+       ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt tx max num pending tx %d\n",
                   htt->max_num_pending_tx);
 
        htt->pending_tx = kzalloc(sizeof(*htt->pending_tx) *
@@ -122,6 +128,7 @@ int ath10k_htt_tx_alloc(struct ath10k_htt *htt)
 
 static void ath10k_htt_tx_free_pending(struct ath10k_htt *htt)
 {
+       struct ath10k *ar = htt->ar;
        struct htt_tx_done tx_done = {0};
        int msdu_id;
 
@@ -130,7 +137,7 @@ static void ath10k_htt_tx_free_pending(struct ath10k_htt *htt)
                if (!test_bit(msdu_id, htt->used_msdu_ids))
                        continue;
 
-               ath10k_dbg(ATH10K_DBG_HTT, "force cleanup msdu_id %hu\n",
+               ath10k_dbg(ar, ATH10K_DBG_HTT, "force cleanup msdu_id %hu\n",
                           msdu_id);
 
                tx_done.discard = 1;
@@ -157,6 +164,7 @@ void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb)
 
 int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt)
 {
+       struct ath10k *ar = htt->ar;
        struct sk_buff *skb;
        struct htt_cmd *cmd;
        int len = 0;
@@ -165,7 +173,7 @@ int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt)
        len += sizeof(cmd->hdr);
        len += sizeof(cmd->ver_req);
 
-       skb = ath10k_htc_alloc_skb(len);
+       skb = ath10k_htc_alloc_skb(ar, len);
        if (!skb)
                return -ENOMEM;
 
@@ -184,6 +192,7 @@ int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt)
 
 int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie)
 {
+       struct ath10k *ar = htt->ar;
        struct htt_stats_req *req;
        struct sk_buff *skb;
        struct htt_cmd *cmd;
@@ -192,7 +201,7 @@ int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie)
        len += sizeof(cmd->hdr);
        len += sizeof(cmd->stats_req);
 
-       skb = ath10k_htc_alloc_skb(len);
+       skb = ath10k_htc_alloc_skb(ar, len);
        if (!skb)
                return -ENOMEM;
 
@@ -214,7 +223,8 @@ int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie)
 
        ret = ath10k_htc_send(&htt->ar->htc, htt->eid, skb);
        if (ret) {
-               ath10k_warn("failed to send htt type stats request: %d", ret);
+               ath10k_warn(ar, "failed to send htt type stats request: %d",
+                           ret);
                dev_kfree_skb_any(skb);
                return ret;
        }
@@ -224,6 +234,7 @@ int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie)
 
 int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt)
 {
+       struct ath10k *ar = htt->ar;
        struct sk_buff *skb;
        struct htt_cmd *cmd;
        struct htt_rx_ring_setup_ring *ring;
@@ -242,7 +253,7 @@ int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt)
 
        len = sizeof(cmd->hdr) + sizeof(cmd->rx_setup.hdr)
            + (sizeof(*ring) * num_rx_ring);
-       skb = ath10k_htc_alloc_skb(len);
+       skb = ath10k_htc_alloc_skb(ar, len);
        if (!skb)
                return -ENOMEM;
 
@@ -311,6 +322,7 @@ int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
                                u8 max_subfrms_ampdu,
                                u8 max_subfrms_amsdu)
 {
+       struct ath10k *ar = htt->ar;
        struct htt_aggr_conf *aggr_conf;
        struct sk_buff *skb;
        struct htt_cmd *cmd;
@@ -328,7 +340,7 @@ int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
        len = sizeof(cmd->hdr);
        len += sizeof(cmd->aggr_conf);
 
-       skb = ath10k_htc_alloc_skb(len);
+       skb = ath10k_htc_alloc_skb(ar, len);
        if (!skb)
                return -ENOMEM;
 
@@ -340,7 +352,7 @@ int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
        aggr_conf->max_num_ampdu_subframes = max_subfrms_ampdu;
        aggr_conf->max_num_amsdu_subframes = max_subfrms_amsdu;
 
-       ath10k_dbg(ATH10K_DBG_HTT, "htt h2t aggr cfg msg amsdu %d ampdu %d",
+       ath10k_dbg(ar, ATH10K_DBG_HTT, "htt h2t aggr cfg msg amsdu %d ampdu %d",
                   aggr_conf->max_num_amsdu_subframes,
                   aggr_conf->max_num_ampdu_subframes);
 
@@ -355,7 +367,8 @@ int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
 
 int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
 {
-       struct device *dev = htt->ar->dev;
+       struct ath10k *ar = htt->ar;
+       struct device *dev = ar->dev;
        struct sk_buff *txdesc = NULL;
        struct htt_cmd *cmd;
        struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
@@ -382,7 +395,7 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
        htt->pending_tx[msdu_id] = msdu;
        spin_unlock_bh(&htt->tx_lock);
 
-       txdesc = ath10k_htc_alloc_skb(len);
+       txdesc = ath10k_htc_alloc_skb(ar, len);
        if (!txdesc) {
                res = -ENOMEM;
                goto err_free_msdu_id;
@@ -429,7 +442,8 @@ err:
 
 int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
 {
-       struct device *dev = htt->ar->dev;
+       struct ath10k *ar = htt->ar;
+       struct device *dev = ar->dev;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
        struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
        struct ath10k_hif_sg_item sg_items[2];
@@ -545,11 +559,11 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
        skb_cb->htt.txbuf->cmd_tx.frags_paddr = __cpu_to_le32(frags_paddr);
        skb_cb->htt.txbuf->cmd_tx.peerid = __cpu_to_le32(HTT_INVALID_PEERID);
 
-       ath10k_dbg(ATH10K_DBG_HTT,
+       ath10k_dbg(ar, ATH10K_DBG_HTT,
                   "htt tx flags0 %hhu flags1 %hu len %d id %hu frags_paddr %08x, msdu_paddr %08x vdev %hhu tid %hhu\n",
                   flags0, flags1, msdu->len, msdu_id, frags_paddr,
                   (u32)skb_cb->paddr, vdev_id, tid);
-       ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt tx msdu: ",
+       ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt tx msdu: ",
                        msdu->data, msdu->len);
 
        sg_items[0].transfer_id = 0;
index 007e855f4ba99f9067725a11b85fdeadb3412483..13568b01de9feced302385eb4594f77e9e5ac4e9 100644 (file)
 #define QCA988X_HW_2_0_CHIP_ID_REV     0x2
 #define QCA988X_HW_2_0_FW_DIR          "ath10k/QCA988X/hw2.0"
 #define QCA988X_HW_2_0_FW_FILE         "firmware.bin"
-#define QCA988X_HW_2_0_FW_2_FILE       "firmware-2.bin"
+#define QCA988X_HW_2_0_FW_3_FILE       "firmware-3.bin"
 #define QCA988X_HW_2_0_OTP_FILE                "otp.bin"
 #define QCA988X_HW_2_0_BOARD_DATA_FILE "board.bin"
 #define QCA988X_HW_2_0_PATCH_LOAD_ADDR 0x1234
 
 #define ATH10K_FW_API2_FILE            "firmware-2.bin"
+#define ATH10K_FW_API3_FILE            "firmware-3.bin"
 
 /* includes also the null byte */
 #define ATH10K_FIRMWARE_MAGIC               "QCA-ATH10K"
 
+#define REG_DUMP_COUNT_QCA988X 60
+
 struct ath10k_fw_ie {
        __le32 id;
        __le32 len;
index 9d61bb157189bed0798170f8f5be5b76ead4387b..b858c8288196228c426e9f930586f63b774e7e78 100644 (file)
@@ -36,6 +36,7 @@ static int ath10k_send_key(struct ath10k_vif *arvif,
                           enum set_key_cmd cmd,
                           const u8 *macaddr)
 {
+       struct ath10k *ar = arvif->ar;
        struct wmi_vdev_install_key_arg arg = {
                .vdev_id = arvif->vdev_id,
                .key_idx = key->keyidx,
@@ -73,7 +74,7 @@ static int ath10k_send_key(struct ath10k_vif *arvif,
                        arg.key_flags = WMI_KEY_PAIRWISE;
                break;
        default:
-               ath10k_warn("cipher %d is not supported\n", key->cipher);
+               ath10k_warn(ar, "cipher %d is not supported\n", key->cipher);
                return -EOPNOTSUPP;
        }
 
@@ -168,7 +169,7 @@ static int ath10k_clear_peer_keys(struct ath10k_vif *arvif,
                        first_errno = ret;
 
                if (ret)
-                       ath10k_warn("failed to remove peer wep key %d: %d\n",
+                       ath10k_warn(ar, "failed to remove peer wep key %d: %d\n",
                                    i, ret);
 
                peer->keys[i] = NULL;
@@ -216,7 +217,7 @@ static int ath10k_clear_vdev_key(struct ath10k_vif *arvif,
                        first_errno = ret;
 
                if (ret)
-                       ath10k_warn("failed to remove key for %pM: %d\n",
+                       ath10k_warn(ar, "failed to remove key for %pM: %d\n",
                                    addr, ret);
        }
 
@@ -327,14 +328,14 @@ static int ath10k_peer_create(struct ath10k *ar, u32 vdev_id, const u8 *addr)
 
        ret = ath10k_wmi_peer_create(ar, vdev_id, addr);
        if (ret) {
-               ath10k_warn("failed to create wmi peer %pM on vdev %i: %i\n",
+               ath10k_warn(ar, "failed to create wmi peer %pM on vdev %i: %i\n",
                            addr, vdev_id, ret);
                return ret;
        }
 
        ret = ath10k_wait_for_peer_created(ar, vdev_id, addr);
        if (ret) {
-               ath10k_warn("failed to wait for created wmi peer %pM on vdev %i: %i\n",
+               ath10k_warn(ar, "failed to wait for created wmi peer %pM on vdev %i: %i\n",
                            addr, vdev_id, ret);
                return ret;
        }
@@ -355,7 +356,7 @@ static int ath10k_mac_set_kickout(struct ath10k_vif *arvif)
        ret = ath10k_wmi_pdev_set_param(ar, param,
                                        ATH10K_KICKOUT_THRESHOLD);
        if (ret) {
-               ath10k_warn("failed to set kickout threshold on vdev %i: %d\n",
+               ath10k_warn(ar, "failed to set kickout threshold on vdev %i: %d\n",
                            arvif->vdev_id, ret);
                return ret;
        }
@@ -364,7 +365,7 @@ static int ath10k_mac_set_kickout(struct ath10k_vif *arvif)
        ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
                                        ATH10K_KEEPALIVE_MIN_IDLE);
        if (ret) {
-               ath10k_warn("failed to set keepalive minimum idle time on vdev %i: %d\n",
+               ath10k_warn(ar, "failed to set keepalive minimum idle time on vdev %i: %d\n",
                            arvif->vdev_id, ret);
                return ret;
        }
@@ -373,7 +374,7 @@ static int ath10k_mac_set_kickout(struct ath10k_vif *arvif)
        ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
                                        ATH10K_KEEPALIVE_MAX_IDLE);
        if (ret) {
-               ath10k_warn("failed to set keepalive maximum idle time on vdev %i: %d\n",
+               ath10k_warn(ar, "failed to set keepalive maximum idle time on vdev %i: %d\n",
                            arvif->vdev_id, ret);
                return ret;
        }
@@ -382,7 +383,7 @@ static int ath10k_mac_set_kickout(struct ath10k_vif *arvif)
        ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param,
                                        ATH10K_KEEPALIVE_MAX_UNRESPONSIVE);
        if (ret) {
-               ath10k_warn("failed to set keepalive maximum unresponsive time on vdev %i: %d\n",
+               ath10k_warn(ar, "failed to set keepalive maximum unresponsive time on vdev %i: %d\n",
                            arvif->vdev_id, ret);
                return ret;
        }
@@ -449,7 +450,7 @@ static void ath10k_peer_cleanup(struct ath10k *ar, u32 vdev_id)
                if (peer->vdev_id != vdev_id)
                        continue;
 
-               ath10k_warn("removing stale peer %pM from vdev_id %d\n",
+               ath10k_warn(ar, "removing stale peer %pM from vdev_id %d\n",
                            peer->addr, vdev_id);
 
                list_del(&peer->list);
@@ -496,7 +497,7 @@ static bool ath10k_monitor_is_enabled(struct ath10k *ar)
 {
        lockdep_assert_held(&ar->conf_mutex);
 
-       ath10k_dbg(ATH10K_DBG_MAC,
+       ath10k_dbg(ar, ATH10K_DBG_MAC,
                   "mac monitor refs: promisc %d monitor %d cac %d\n",
                   ar->promisc, ar->monitor,
                   test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags));
@@ -531,35 +532,35 @@ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
 
        ret = ath10k_wmi_vdev_start(ar, &arg);
        if (ret) {
-               ath10k_warn("failed to request monitor vdev %i start: %d\n",
+               ath10k_warn(ar, "failed to request monitor vdev %i start: %d\n",
                            vdev_id, ret);
                return ret;
        }
 
        ret = ath10k_vdev_setup_sync(ar);
        if (ret) {
-               ath10k_warn("failed to synchronize setup for monitor vdev %i: %d\n",
+               ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i: %d\n",
                            vdev_id, ret);
                return ret;
        }
 
        ret = ath10k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr);
        if (ret) {
-               ath10k_warn("failed to put up monitor vdev %i: %d\n",
+               ath10k_warn(ar, "failed to put up monitor vdev %i: %d\n",
                            vdev_id, ret);
                goto vdev_stop;
        }
 
        ar->monitor_vdev_id = vdev_id;
 
-       ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %i started\n",
+       ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i started\n",
                   ar->monitor_vdev_id);
        return 0;
 
 vdev_stop:
        ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
        if (ret)
-               ath10k_warn("failed to stop monitor vdev %i after start failure: %d\n",
+               ath10k_warn(ar, "failed to stop monitor vdev %i after start failure: %d\n",
                            ar->monitor_vdev_id, ret);
 
        return ret;
@@ -573,20 +574,20 @@ static int ath10k_monitor_vdev_stop(struct ath10k *ar)
 
        ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id);
        if (ret)
-               ath10k_warn("failed to put down monitor vdev %i: %d\n",
+               ath10k_warn(ar, "failed to put down monitor vdev %i: %d\n",
                            ar->monitor_vdev_id, ret);
 
        ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
        if (ret)
-               ath10k_warn("failed to to request monitor vdev %i stop: %d\n",
+               ath10k_warn(ar, "failed to to request monitor vdev %i stop: %d\n",
                            ar->monitor_vdev_id, ret);
 
        ret = ath10k_vdev_setup_sync(ar);
        if (ret)
-               ath10k_warn("failed to synchronise monitor vdev %i: %d\n",
+               ath10k_warn(ar, "failed to synchronise monitor vdev %i: %d\n",
                            ar->monitor_vdev_id, ret);
 
-       ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n",
+       ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n",
                   ar->monitor_vdev_id);
        return ret;
 }
@@ -597,35 +598,29 @@ static int ath10k_monitor_vdev_create(struct ath10k *ar)
 
        lockdep_assert_held(&ar->conf_mutex);
 
-       bit = ffs(ar->free_vdev_map);
-       if (bit == 0) {
-               ath10k_warn("failed to find free vdev id for monitor vdev\n");
+       if (ar->free_vdev_map == 0) {
+               ath10k_warn(ar, "failed to find free vdev id for monitor vdev\n");
                return -ENOMEM;
        }
 
+       bit = ffs(ar->free_vdev_map);
+
        ar->monitor_vdev_id = bit - 1;
-       ar->free_vdev_map &= ~(1 << ar->monitor_vdev_id);
 
        ret = ath10k_wmi_vdev_create(ar, ar->monitor_vdev_id,
                                     WMI_VDEV_TYPE_MONITOR,
                                     0, ar->mac_addr);
        if (ret) {
-               ath10k_warn("failed to request monitor vdev %i creation: %d\n",
+               ath10k_warn(ar, "failed to request monitor vdev %i creation: %d\n",
                            ar->monitor_vdev_id, ret);
-               goto vdev_fail;
+               return ret;
        }
 
-       ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %d created\n",
+       ar->free_vdev_map &= ~(1 << ar->monitor_vdev_id);
+       ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d created\n",
                   ar->monitor_vdev_id);
 
        return 0;
-
-vdev_fail:
-       /*
-        * Restore the ID to the global map.
-        */
-       ar->free_vdev_map |= 1 << (ar->monitor_vdev_id);
-       return ret;
 }
 
 static int ath10k_monitor_vdev_delete(struct ath10k *ar)
@@ -636,14 +631,14 @@ static int ath10k_monitor_vdev_delete(struct ath10k *ar)
 
        ret = ath10k_wmi_vdev_delete(ar, ar->monitor_vdev_id);
        if (ret) {
-               ath10k_warn("failed to request wmi monitor vdev %i removal: %d\n",
+               ath10k_warn(ar, "failed to request wmi monitor vdev %i removal: %d\n",
                            ar->monitor_vdev_id, ret);
                return ret;
        }
 
-       ar->free_vdev_map |= 1 << (ar->monitor_vdev_id);
+       ar->free_vdev_map |= 1 << ar->monitor_vdev_id;
 
-       ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n",
+       ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n",
                   ar->monitor_vdev_id);
        return ret;
 }
@@ -655,30 +650,30 @@ static int ath10k_monitor_start(struct ath10k *ar)
        lockdep_assert_held(&ar->conf_mutex);
 
        if (!ath10k_monitor_is_enabled(ar)) {
-               ath10k_warn("trying to start monitor with no references\n");
+               ath10k_warn(ar, "trying to start monitor with no references\n");
                return 0;
        }
 
        if (ar->monitor_started) {
-               ath10k_dbg(ATH10K_DBG_MAC, "mac monitor already started\n");
+               ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor already started\n");
                return 0;
        }
 
        ret = ath10k_monitor_vdev_create(ar);
        if (ret) {
-               ath10k_warn("failed to create monitor vdev: %d\n", ret);
+               ath10k_warn(ar, "failed to create monitor vdev: %d\n", ret);
                return ret;
        }
 
        ret = ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id);
        if (ret) {
-               ath10k_warn("failed to start monitor vdev: %d\n", ret);
+               ath10k_warn(ar, "failed to start monitor vdev: %d\n", ret);
                ath10k_monitor_vdev_delete(ar);
                return ret;
        }
 
        ar->monitor_started = true;
-       ath10k_dbg(ATH10K_DBG_MAC, "mac monitor started\n");
+       ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor started\n");
 
        return 0;
 }
@@ -690,27 +685,27 @@ static void ath10k_monitor_stop(struct ath10k *ar)
        lockdep_assert_held(&ar->conf_mutex);
 
        if (ath10k_monitor_is_enabled(ar)) {
-               ath10k_dbg(ATH10K_DBG_MAC,
+               ath10k_dbg(ar, ATH10K_DBG_MAC,
                           "mac monitor will be stopped later\n");
                return;
        }
 
        if (!ar->monitor_started) {
-               ath10k_dbg(ATH10K_DBG_MAC,
+               ath10k_dbg(ar, ATH10K_DBG_MAC,
                           "mac monitor probably failed to start earlier\n");
                return;
        }
 
        ret = ath10k_monitor_vdev_stop(ar);
        if (ret)
-               ath10k_warn("failed to stop monitor vdev: %d\n", ret);
+               ath10k_warn(ar, "failed to stop monitor vdev: %d\n", ret);
 
        ret = ath10k_monitor_vdev_delete(ar);
        if (ret)
-               ath10k_warn("failed to delete monitor vdev: %d\n", ret);
+               ath10k_warn(ar, "failed to delete monitor vdev: %d\n", ret);
 
        ar->monitor_started = false;
-       ath10k_dbg(ATH10K_DBG_MAC, "mac monitor stopped\n");
+       ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopped\n");
 }
 
 static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif)
@@ -743,12 +738,12 @@ static int ath10k_start_cac(struct ath10k *ar)
 
        ret = ath10k_monitor_start(ar);
        if (ret) {
-               ath10k_warn("failed to start monitor (cac): %d\n", ret);
+               ath10k_warn(ar, "failed to start monitor (cac): %d\n", ret);
                clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
                return ret;
        }
 
-       ath10k_dbg(ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n",
+       ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n",
                   ar->monitor_vdev_id);
 
        return 0;
@@ -765,7 +760,7 @@ static int ath10k_stop_cac(struct ath10k *ar)
        clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
        ath10k_monitor_stop(ar);
 
-       ath10k_dbg(ATH10K_DBG_MAC, "mac cac finished\n");
+       ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac finished\n");
 
        return 0;
 }
@@ -791,12 +786,12 @@ static void ath10k_recalc_radar_detection(struct ath10k *ar)
                 * radiation is not allowed, make this channel DFS_UNAVAILABLE
                 * by indicating that radar was detected.
                 */
-               ath10k_warn("failed to start CAC: %d\n", ret);
+               ath10k_warn(ar, "failed to start CAC: %d\n", ret);
                ieee80211_radar_detected(ar->hw);
        }
 }
 
-static int ath10k_vdev_start(struct ath10k_vif *arvif)
+static int ath10k_vdev_start_restart(struct ath10k_vif *arvif, bool restart)
 {
        struct ath10k *ar = arvif->ar;
        struct cfg80211_chan_def *chandef = &ar->chandef;
@@ -833,21 +828,25 @@ static int ath10k_vdev_start(struct ath10k_vif *arvif)
                arg.ssid_len = arvif->vif->bss_conf.ssid_len;
        }
 
-       ath10k_dbg(ATH10K_DBG_MAC,
+       ath10k_dbg(ar, ATH10K_DBG_MAC,
                   "mac vdev %d start center_freq %d phymode %s\n",
                   arg.vdev_id, arg.channel.freq,
                   ath10k_wmi_phymode_str(arg.channel.mode));
 
-       ret = ath10k_wmi_vdev_start(ar, &arg);
+       if (restart)
+               ret = ath10k_wmi_vdev_restart(ar, &arg);
+       else
+               ret = ath10k_wmi_vdev_start(ar, &arg);
+
        if (ret) {
-               ath10k_warn("failed to start WMI vdev %i: %d\n",
+               ath10k_warn(ar, "failed to start WMI vdev %i: %d\n",
                            arg.vdev_id, ret);
                return ret;
        }
 
        ret = ath10k_vdev_setup_sync(ar);
        if (ret) {
-               ath10k_warn("failed to synchronise setup for vdev %i: %d\n",
+               ath10k_warn(ar, "failed to synchronise setup for vdev %i: %d\n",
                            arg.vdev_id, ret);
                return ret;
        }
@@ -858,6 +857,16 @@ static int ath10k_vdev_start(struct ath10k_vif *arvif)
        return ret;
 }
 
+static int ath10k_vdev_start(struct ath10k_vif *arvif)
+{
+       return ath10k_vdev_start_restart(arvif, false);
+}
+
+static int ath10k_vdev_restart(struct ath10k_vif *arvif)
+{
+       return ath10k_vdev_start_restart(arvif, true);
+}
+
 static int ath10k_vdev_stop(struct ath10k_vif *arvif)
 {
        struct ath10k *ar = arvif->ar;
@@ -869,14 +878,14 @@ static int ath10k_vdev_stop(struct ath10k_vif *arvif)
 
        ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id);
        if (ret) {
-               ath10k_warn("failed to stop WMI vdev %i: %d\n",
+               ath10k_warn(ar, "failed to stop WMI vdev %i: %d\n",
                            arvif->vdev_id, ret);
                return ret;
        }
 
        ret = ath10k_vdev_setup_sync(ar);
        if (ret) {
-               ath10k_warn("failed to syncronise setup for vdev %i: %d\n",
+               ath10k_warn(ar, "failed to syncronise setup for vdev %i: %d\n",
                            arvif->vdev_id, ret);
                return ret;
        }
@@ -894,6 +903,7 @@ static int ath10k_vdev_stop(struct ath10k_vif *arvif)
 static void ath10k_control_beaconing(struct ath10k_vif *arvif,
                                struct ieee80211_bss_conf *info)
 {
+       struct ath10k *ar = arvif->ar;
        int ret = 0;
 
        lockdep_assert_held(&arvif->ar->conf_mutex);
@@ -931,7 +941,7 @@ static void ath10k_control_beaconing(struct ath10k_vif *arvif,
        ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
                                 arvif->bssid);
        if (ret) {
-               ath10k_warn("failed to bring up vdev %d: %i\n",
+               ath10k_warn(ar, "failed to bring up vdev %d: %i\n",
                            arvif->vdev_id, ret);
                ath10k_vdev_stop(arvif);
                return;
@@ -940,13 +950,14 @@ static void ath10k_control_beaconing(struct ath10k_vif *arvif,
        arvif->is_started = true;
        arvif->is_up = true;
 
-       ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id);
+       ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id);
 }
 
 static void ath10k_control_ibss(struct ath10k_vif *arvif,
                                struct ieee80211_bss_conf *info,
                                const u8 self_peer[ETH_ALEN])
 {
+       struct ath10k *ar = arvif->ar;
        u32 vdev_param;
        int ret = 0;
 
@@ -955,7 +966,7 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif,
        if (!info->ibss_joined) {
                ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, self_peer);
                if (ret)
-                       ath10k_warn("failed to delete IBSS self peer %pM for vdev %d: %d\n",
+                       ath10k_warn(ar, "failed to delete IBSS self peer %pM for vdev %d: %d\n",
                                    self_peer, arvif->vdev_id, ret);
 
                if (is_zero_ether_addr(arvif->bssid))
@@ -964,7 +975,7 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif,
                ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id,
                                         arvif->bssid);
                if (ret) {
-                       ath10k_warn("failed to delete IBSS BSSID peer %pM for vdev %d: %d\n",
+                       ath10k_warn(ar, "failed to delete IBSS BSSID peer %pM for vdev %d: %d\n",
                                    arvif->bssid, arvif->vdev_id, ret);
                        return;
                }
@@ -976,7 +987,7 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif,
 
        ret = ath10k_peer_create(arvif->ar, arvif->vdev_id, self_peer);
        if (ret) {
-               ath10k_warn("failed to create IBSS self peer %pM for vdev %d: %d\n",
+               ath10k_warn(ar, "failed to create IBSS self peer %pM for vdev %d: %d\n",
                            self_peer, arvif->vdev_id, ret);
                return;
        }
@@ -985,7 +996,7 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif,
        ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, vdev_param,
                                        ATH10K_DEFAULT_ATIM);
        if (ret)
-               ath10k_warn("failed to set IBSS ATIM for vdev %d: %d\n",
+               ath10k_warn(ar, "failed to set IBSS ATIM for vdev %d: %d\n",
                            arvif->vdev_id, ret);
 }
 
@@ -1012,7 +1023,7 @@ static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
                ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param,
                                                  conf->dynamic_ps_timeout);
                if (ret) {
-                       ath10k_warn("failed to set inactivity time for vdev %d: %i\n",
+                       ath10k_warn(ar, "failed to set inactivity time for vdev %d: %i\n",
                                    arvif->vdev_id, ret);
                        return ret;
                }
@@ -1020,12 +1031,12 @@ static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
                psmode = WMI_STA_PS_MODE_DISABLED;
        }
 
-       ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d psmode %s\n",
+       ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d psmode %s\n",
                   arvif->vdev_id, psmode ? "enable" : "disable");
 
        ret = ath10k_wmi_set_psmode(ar, arvif->vdev_id, psmode);
        if (ret) {
-               ath10k_warn("failed to set PS Mode %d for vdev %d: %d\n",
+               ath10k_warn(ar, "failed to set PS Mode %d for vdev %d: %d\n",
                            psmode, arvif->vdev_id, ret);
                return ret;
        }
@@ -1109,12 +1120,12 @@ static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
 
        /* FIXME: base on RSN IE/WPA IE is a correct idea? */
        if (rsnie || wpaie) {
-               ath10k_dbg(ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__);
+               ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__);
                arg->peer_flags |= WMI_PEER_NEED_PTK_4_WAY;
        }
 
        if (wpaie) {
-               ath10k_dbg(ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__);
+               ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__);
                arg->peer_flags |= WMI_PEER_NEED_GTK_2_WAY;
        }
 }
@@ -1223,7 +1234,7 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
                arg->peer_num_spatial_streams = sta->rx_nss;
        }
 
-       ath10k_dbg(ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n",
+       ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n",
                   arg->addr,
                   arg->peer_ht_rates.num_rates,
                   arg->peer_num_spatial_streams);
@@ -1240,7 +1251,7 @@ static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
        lockdep_assert_held(&ar->conf_mutex);
 
        if (sta->wme && sta->uapsd_queues) {
-               ath10k_dbg(ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n",
+               ath10k_dbg(ar, ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n",
                           sta->uapsd_queues, sta->max_sp);
 
                if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
@@ -1265,7 +1276,7 @@ static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
                                                 WMI_AP_PS_PEER_PARAM_UAPSD,
                                                 uapsd);
                if (ret) {
-                       ath10k_warn("failed to set ap ps peer param uapsd for vdev %i: %d\n",
+                       ath10k_warn(ar, "failed to set ap ps peer param uapsd for vdev %i: %d\n",
                                    arvif->vdev_id, ret);
                        return ret;
                }
@@ -1275,7 +1286,7 @@ static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
                                                 WMI_AP_PS_PEER_PARAM_MAX_SP,
                                                 max_sp);
                if (ret) {
-                       ath10k_warn("failed to set ap ps peer param max sp for vdev %i: %d\n",
+                       ath10k_warn(ar, "failed to set ap ps peer param max sp for vdev %i: %d\n",
                                    arvif->vdev_id, ret);
                        return ret;
                }
@@ -1287,7 +1298,7 @@ static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
                ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr,
                                        WMI_AP_PS_PEER_PARAM_AGEOUT_TIME, 10);
                if (ret) {
-                       ath10k_warn("failed to set ap ps peer param ageout time for vdev %i: %d\n",
+                       ath10k_warn(ar, "failed to set ap ps peer param ageout time for vdev %i: %d\n",
                                    arvif->vdev_id, ret);
                        return ret;
                }
@@ -1334,7 +1345,7 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
        arg->peer_vht_rates.tx_mcs_set =
                __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map);
 
-       ath10k_dbg(ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
+       ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
                   sta->addr, arg->peer_max_mpdu, arg->peer_flags);
 }
 
@@ -1407,7 +1418,7 @@ static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
                break;
        }
 
-       ath10k_dbg(ATH10K_DBG_MAC, "mac peer %pM phymode %s\n",
+       ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM phymode %s\n",
                   sta->addr, ath10k_wmi_phymode_str(phymode));
 
        arg->peer_phymode = phymode;
@@ -1480,7 +1491,7 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
 
        ap_sta = ieee80211_find_sta(vif, bss_conf->bssid);
        if (!ap_sta) {
-               ath10k_warn("failed to find station entry for bss %pM vdev %i\n",
+               ath10k_warn(ar, "failed to find station entry for bss %pM vdev %i\n",
                            bss_conf->bssid, arvif->vdev_id);
                rcu_read_unlock();
                return;
@@ -1493,7 +1504,7 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
        ret = ath10k_peer_assoc_prepare(ar, arvif, ap_sta,
                                        bss_conf, &peer_arg);
        if (ret) {
-               ath10k_warn("failed to prepare peer assoc for %pM vdev %i: %d\n",
+               ath10k_warn(ar, "failed to prepare peer assoc for %pM vdev %i: %d\n",
                            bss_conf->bssid, arvif->vdev_id, ret);
                rcu_read_unlock();
                return;
@@ -1503,19 +1514,19 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
 
        ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
        if (ret) {
-               ath10k_warn("failed to run peer assoc for %pM vdev %i: %d\n",
+               ath10k_warn(ar, "failed to run peer assoc for %pM vdev %i: %d\n",
                            bss_conf->bssid, arvif->vdev_id, ret);
                return;
        }
 
        ret = ath10k_setup_peer_smps(ar, arvif, bss_conf->bssid, &ht_cap);
        if (ret) {
-               ath10k_warn("failed to setup peer SMPS for vdev %i: %d\n",
+               ath10k_warn(ar, "failed to setup peer SMPS for vdev %i: %d\n",
                            arvif->vdev_id, ret);
                return;
        }
 
-       ath10k_dbg(ATH10K_DBG_MAC,
+       ath10k_dbg(ar, ATH10K_DBG_MAC,
                   "mac vdev %d up (associated) bssid %pM aid %d\n",
                   arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
 
@@ -1524,7 +1535,7 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
 
        ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);
        if (ret) {
-               ath10k_warn("failed to set vdev %d up: %d\n",
+               ath10k_warn(ar, "failed to set vdev %d up: %d\n",
                            arvif->vdev_id, ret);
                return;
        }
@@ -1550,7 +1561,7 @@ static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
         * No idea why this happens, even though VDEV-DOWN is supposed
         * to be analogous to link down, so just stop the VDEV.
         */
-       ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d stop (disassociated\n",
+       ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d stop (disassociated\n",
                   arvif->vdev_id);
 
        /* FIXME: check return value */
@@ -1563,7 +1574,7 @@ static void ath10k_bss_disassoc(struct ieee80211_hw *hw,
         * interfaces as it expects there is no rx when no interface is
         * running.
         */
-       ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d down\n", arvif->vdev_id);
+       ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d down\n", arvif->vdev_id);
 
        /* FIXME: why don't we print error if wmi call fails? */
        ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
@@ -1584,7 +1595,7 @@ static int ath10k_station_assoc(struct ath10k *ar, struct ath10k_vif *arvif,
 
        ret = ath10k_peer_assoc_prepare(ar, arvif, sta, NULL, &peer_arg);
        if (ret) {
-               ath10k_warn("failed to prepare WMI peer assoc for %pM vdev %i: %i\n",
+               ath10k_warn(ar, "failed to prepare WMI peer assoc for %pM vdev %i: %i\n",
                            sta->addr, arvif->vdev_id, ret);
                return ret;
        }
@@ -1592,14 +1603,14 @@ static int ath10k_station_assoc(struct ath10k *ar, struct ath10k_vif *arvif,
        peer_arg.peer_reassoc = reassoc;
        ret = ath10k_wmi_peer_assoc(ar, &peer_arg);
        if (ret) {
-               ath10k_warn("failed to run peer assoc for STA %pM vdev %i: %d\n",
+               ath10k_warn(ar, "failed to run peer assoc for STA %pM vdev %i: %d\n",
                            sta->addr, arvif->vdev_id, ret);
                return ret;
        }
 
        ret = ath10k_setup_peer_smps(ar, arvif, sta->addr, &sta->ht_cap);
        if (ret) {
-               ath10k_warn("failed to setup peer SMPS for vdev %d: %d\n",
+               ath10k_warn(ar, "failed to setup peer SMPS for vdev %d: %d\n",
                            arvif->vdev_id, ret);
                return ret;
        }
@@ -1608,7 +1619,7 @@ static int ath10k_station_assoc(struct ath10k *ar, struct ath10k_vif *arvif,
                arvif->num_legacy_stations++;
                ret  = ath10k_recalc_rtscts_prot(arvif);
                if (ret) {
-                       ath10k_warn("failed to recalculate rts/cts prot for vdev %d: %d\n",
+                       ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
                                    arvif->vdev_id, ret);
                        return ret;
                }
@@ -1616,14 +1627,14 @@ static int ath10k_station_assoc(struct ath10k *ar, struct ath10k_vif *arvif,
 
        ret = ath10k_install_peer_wep_keys(arvif, sta->addr);
        if (ret) {
-               ath10k_warn("failed to install peer wep keys for vdev %i: %d\n",
+               ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n",
                            arvif->vdev_id, ret);
                return ret;
        }
 
        ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta);
        if (ret) {
-               ath10k_warn("failed to set qos params for STA %pM for vdev %i: %d\n",
+               ath10k_warn(ar, "failed to set qos params for STA %pM for vdev %i: %d\n",
                            sta->addr, arvif->vdev_id, ret);
                return ret;
        }
@@ -1642,7 +1653,7 @@ static int ath10k_station_disassoc(struct ath10k *ar, struct ath10k_vif *arvif,
                arvif->num_legacy_stations--;
                ret = ath10k_recalc_rtscts_prot(arvif);
                if (ret) {
-                       ath10k_warn("failed to recalculate rts/cts prot for vdev %d: %d\n",
+                       ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
                                    arvif->vdev_id, ret);
                        return ret;
                }
@@ -1650,7 +1661,7 @@ static int ath10k_station_disassoc(struct ath10k *ar, struct ath10k_vif *arvif,
 
        ret = ath10k_clear_peer_keys(arvif, sta->addr);
        if (ret) {
-               ath10k_warn("failed to clear all peer wep keys for vdev %i: %d\n",
+               ath10k_warn(ar, "failed to clear all peer wep keys for vdev %i: %d\n",
                            arvif->vdev_id, ret);
                return ret;
        }
@@ -1742,7 +1753,7 @@ static int ath10k_update_channel_list(struct ath10k *ar)
                        if (WARN_ON_ONCE(ch->mode == MODE_UNKNOWN))
                                continue;
 
-                       ath10k_dbg(ATH10K_DBG_WMI,
+                       ath10k_dbg(ar, ATH10K_DBG_WMI,
                                   "mac channel [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n",
                                    ch - arg.channels, arg.n_channels,
                                   ch->freq, ch->max_power, ch->max_reg_power,
@@ -1785,7 +1796,7 @@ static void ath10k_regd_update(struct ath10k *ar)
 
        ret = ath10k_update_channel_list(ar);
        if (ret)
-               ath10k_warn("failed to update channel list: %d\n", ret);
+               ath10k_warn(ar, "failed to update channel list: %d\n", ret);
 
        regpair = ar->ath_common.regulatory.regpair;
 
@@ -1806,7 +1817,7 @@ static void ath10k_regd_update(struct ath10k *ar)
                                            regpair->reg_5ghz_ctl,
                                            wmi_dfs_reg);
        if (ret)
-               ath10k_warn("failed to set pdev regdomain: %d\n", ret);
+               ath10k_warn(ar, "failed to set pdev regdomain: %d\n", ret);
 }
 
 static void ath10k_reg_notifier(struct wiphy *wiphy,
@@ -1819,12 +1830,12 @@ static void ath10k_reg_notifier(struct wiphy *wiphy,
        ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory);
 
        if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
-               ath10k_dbg(ATH10K_DBG_REGULATORY, "dfs region 0x%x\n",
+               ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs region 0x%x\n",
                           request->dfs_region);
                result = ar->dfs_detector->set_dfs_domain(ar->dfs_detector,
                                                          request->dfs_region);
                if (!result)
-                       ath10k_warn("DFS region 0x%X not supported, will trigger radar for every pulse\n",
+                       ath10k_warn(ar, "DFS region 0x%X not supported, will trigger radar for every pulse\n",
                                    request->dfs_region);
        }
 
@@ -1861,7 +1872,7 @@ static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar,
        if (ar->monitor_started)
                return ar->monitor_vdev_id;
 
-       ath10k_warn("failed to resolve vdev id\n");
+       ath10k_warn(ar, "failed to resolve vdev id\n");
        return 0;
 }
 
@@ -1897,6 +1908,7 @@ static void ath10k_tx_wep_key_work(struct work_struct *work)
 {
        struct ath10k_vif *arvif = container_of(work, struct ath10k_vif,
                                                wep_key_work);
+       struct ath10k *ar = arvif->ar;
        int ret, keyidx = arvif->def_wep_key_newidx;
 
        mutex_lock(&arvif->ar->conf_mutex);
@@ -1907,7 +1919,7 @@ static void ath10k_tx_wep_key_work(struct work_struct *work)
        if (arvif->def_wep_key_idx == keyidx)
                goto unlock;
 
-       ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n",
+       ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n",
                   arvif->vdev_id, keyidx);
 
        ret = ath10k_wmi_vdev_set_param(arvif->ar,
@@ -1915,7 +1927,7 @@ static void ath10k_tx_wep_key_work(struct work_struct *work)
                                        arvif->ar->wmi.vdev_param->def_keyid,
                                        keyidx);
        if (ret) {
-               ath10k_warn("failed to update wep key index for vdev %d: %d\n",
+               ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n",
                            arvif->vdev_id,
                            ret);
                goto unlock;
@@ -1995,7 +2007,7 @@ static void ath10k_tx_htt(struct ath10k *ar, struct sk_buff *skb)
                             ar->fw_features)) {
                        if (skb_queue_len(&ar->wmi_mgmt_tx_queue) >=
                            ATH10K_MAX_NUM_MGMT_PENDING) {
-                               ath10k_warn("reached WMI management tranmist queue limit\n");
+                               ath10k_warn(ar, "reached WMI management transmit queue limit\n");
                                ret = -EBUSY;
                                goto exit;
                        }
@@ -2019,7 +2031,8 @@ static void ath10k_tx_htt(struct ath10k *ar, struct sk_buff *skb)
 
 exit:
        if (ret) {
-               ath10k_warn("failed to transmit packet, dropping: %d\n", ret);
+               ath10k_warn(ar, "failed to transmit packet, dropping: %d\n",
+                           ret);
                ieee80211_free_txskb(ar->hw, skb);
        }
 }
@@ -2061,7 +2074,7 @@ void ath10k_offchan_tx_work(struct work_struct *work)
 
                mutex_lock(&ar->conf_mutex);
 
-               ath10k_dbg(ATH10K_DBG_MAC, "mac offchannel skb %p\n",
+               ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %p\n",
                           skb);
 
                hdr = (struct ieee80211_hdr *)skb->data;
@@ -2074,13 +2087,13 @@ void ath10k_offchan_tx_work(struct work_struct *work)
 
                if (peer)
                        /* FIXME: should this use ath10k_warn()? */
-                       ath10k_dbg(ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n",
+                       ath10k_dbg(ar, ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n",
                                   peer_addr, vdev_id);
 
                if (!peer) {
                        ret = ath10k_peer_create(ar, vdev_id, peer_addr);
                        if (ret)
-                               ath10k_warn("failed to create peer %pM on vdev %d: %d\n",
+                               ath10k_warn(ar, "failed to create peer %pM on vdev %d: %d\n",
                                            peer_addr, vdev_id, ret);
                }
 
@@ -2094,13 +2107,13 @@ void ath10k_offchan_tx_work(struct work_struct *work)
                ret = wait_for_completion_timeout(&ar->offchan_tx_completed,
                                                  3 * HZ);
                if (ret <= 0)
-                       ath10k_warn("timed out waiting for offchannel skb %p\n",
+                       ath10k_warn(ar, "timed out waiting for offchannel skb %p\n",
                                    skb);
 
                if (!peer) {
                        ret = ath10k_peer_delete(ar, vdev_id, peer_addr);
                        if (ret)
-                               ath10k_warn("failed to delete peer %pM on vdev %d: %d\n",
+                               ath10k_warn(ar, "failed to delete peer %pM on vdev %d: %d\n",
                                            peer_addr, vdev_id, ret);
                }
 
@@ -2134,7 +2147,7 @@ void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
 
                ret = ath10k_wmi_mgmt_tx(ar, skb);
                if (ret) {
-                       ath10k_warn("failed to transmit management frame via WMI: %d\n",
+                       ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n",
                                    ret);
                        ieee80211_free_txskb(ar->hw, skb);
                }
@@ -2145,34 +2158,40 @@ void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work)
 /* Scanning */
 /************/
 
-/*
- * This gets called if we dont get a heart-beat during scan.
- * This may indicate the FW has hung and we need to abort the
- * scan manually to prevent cancel_hw_scan() from deadlocking
- */
-void ath10k_reset_scan(unsigned long ptr)
+void __ath10k_scan_finish(struct ath10k *ar)
 {
-       struct ath10k *ar = (struct ath10k *)ptr;
+       lockdep_assert_held(&ar->data_lock);
 
-       spin_lock_bh(&ar->data_lock);
-       if (!ar->scan.in_progress) {
-               spin_unlock_bh(&ar->data_lock);
-               return;
+       switch (ar->scan.state) {
+       case ATH10K_SCAN_IDLE:
+               break;
+       case ATH10K_SCAN_RUNNING:
+       case ATH10K_SCAN_ABORTING:
+               if (ar->scan.is_roc)
+                       ieee80211_remain_on_channel_expired(ar->hw);
+               else
+                       ieee80211_scan_completed(ar->hw,
+                                                (ar->scan.state ==
+                                                 ATH10K_SCAN_ABORTING));
+               /* fall through */
+       case ATH10K_SCAN_STARTING:
+               ar->scan.state = ATH10K_SCAN_IDLE;
+               ar->scan_channel = NULL;
+               ath10k_offchan_tx_purge(ar);
+               cancel_delayed_work(&ar->scan.timeout);
+               complete_all(&ar->scan.completed);
+               break;
        }
+}
 
-       ath10k_warn("scan timed out, firmware problem?\n");
-
-       if (ar->scan.is_roc)
-               ieee80211_remain_on_channel_expired(ar->hw);
-       else
-               ieee80211_scan_completed(ar->hw, 1 /* aborted */);
-
-       ar->scan.in_progress = false;
-       complete_all(&ar->scan.completed);
+void ath10k_scan_finish(struct ath10k *ar)
+{
+       spin_lock_bh(&ar->data_lock);
+       __ath10k_scan_finish(ar);
        spin_unlock_bh(&ar->data_lock);
 }
 
-static int ath10k_abort_scan(struct ath10k *ar)
+static int ath10k_scan_stop(struct ath10k *ar)
 {
        struct wmi_stop_scan_arg arg = {
                .req_id = 1, /* FIXME */
@@ -2183,47 +2202,79 @@ static int ath10k_abort_scan(struct ath10k *ar)
 
        lockdep_assert_held(&ar->conf_mutex);
 
-       del_timer_sync(&ar->scan.timeout);
+       ret = ath10k_wmi_stop_scan(ar, &arg);
+       if (ret) {
+               ath10k_warn(ar, "failed to stop wmi scan: %d\n", ret);
+               goto out;
+       }
 
-       spin_lock_bh(&ar->data_lock);
-       if (!ar->scan.in_progress) {
-               spin_unlock_bh(&ar->data_lock);
-               return 0;
+       ret = wait_for_completion_timeout(&ar->scan.completed, 3*HZ);
+       if (ret == 0) {
+               ath10k_warn(ar, "failed to receive scan abortion completion: timed out\n");
+               ret = -ETIMEDOUT;
+       } else if (ret > 0) {
+               ret = 0;
        }
 
-       ar->scan.aborting = true;
+out:
+       /* Scan state should be updated upon scan completion but in case
+        * firmware fails to deliver the event (for whatever reason) it is
+        * desired to clean up scan state anyway. Firmware may have just
+        * dropped the scan completion event delivery due to transport pipe
+        * being overflown with data and/or it can recover on its own before
+        * next scan request is submitted.
+        */
+       spin_lock_bh(&ar->data_lock);
+       if (ar->scan.state != ATH10K_SCAN_IDLE)
+               __ath10k_scan_finish(ar);
        spin_unlock_bh(&ar->data_lock);
 
-       ret = ath10k_wmi_stop_scan(ar, &arg);
-       if (ret) {
-               ath10k_warn("failed to stop wmi scan: %d\n", ret);
-               spin_lock_bh(&ar->data_lock);
-               ar->scan.in_progress = false;
-               ath10k_offchan_tx_purge(ar);
-               spin_unlock_bh(&ar->data_lock);
-               return -EIO;
-       }
+       return ret;
+}
 
-       ret = wait_for_completion_timeout(&ar->scan.completed, 3*HZ);
-       if (ret == 0)
-               ath10k_warn("timed out while waiting for scan to stop\n");
+static void ath10k_scan_abort(struct ath10k *ar)
+{
+       int ret;
 
-       /* scan completion may be done right after we timeout here, so let's
-        * check the in_progress and tell mac80211 scan is completed. if we
-        * don't do that and FW fails to send us scan completion indication
-        * then userspace won't be able to scan anymore */
-       ret = 0;
+       lockdep_assert_held(&ar->conf_mutex);
 
        spin_lock_bh(&ar->data_lock);
-       if (ar->scan.in_progress) {
-               ath10k_warn("failed to stop scan, it's still in progress\n");
-               ar->scan.in_progress = false;
-               ath10k_offchan_tx_purge(ar);
-               ret = -ETIMEDOUT;
+
+       switch (ar->scan.state) {
+       case ATH10K_SCAN_IDLE:
+               /* This can happen if timeout worker kicked in and called
+                * abortion while scan completion was being processed.
+                */
+               break;
+       case ATH10K_SCAN_STARTING:
+       case ATH10K_SCAN_ABORTING:
+               ath10k_warn(ar, "refusing scan abortion due to invalid scan state: %s (%d)\n",
+                           ath10k_scan_state_str(ar->scan.state),
+                           ar->scan.state);
+               break;
+       case ATH10K_SCAN_RUNNING:
+               ar->scan.state = ATH10K_SCAN_ABORTING;
+               spin_unlock_bh(&ar->data_lock);
+
+               ret = ath10k_scan_stop(ar);
+               if (ret)
+                       ath10k_warn(ar, "failed to abort scan: %d\n", ret);
+
+               spin_lock_bh(&ar->data_lock);
+               break;
        }
+
        spin_unlock_bh(&ar->data_lock);
+}
 
-       return ret;
+void ath10k_scan_timeout_work(struct work_struct *work)
+{
+       struct ath10k *ar = container_of(work, struct ath10k,
+                                        scan.timeout.work);
+
+       mutex_lock(&ar->conf_mutex);
+       ath10k_scan_abort(ar);
+       mutex_unlock(&ar->conf_mutex);
 }
 
 static int ath10k_start_scan(struct ath10k *ar,
@@ -2239,17 +2290,16 @@ static int ath10k_start_scan(struct ath10k *ar,
 
        ret = wait_for_completion_timeout(&ar->scan.started, 1*HZ);
        if (ret == 0) {
-               ath10k_abort_scan(ar);
-               return ret;
+               ret = ath10k_scan_stop(ar);
+               if (ret)
+                       ath10k_warn(ar, "failed to stop scan: %d\n", ret);
+
+               return -ETIMEDOUT;
        }
 
-       /* the scan can complete earlier, before we even
-        * start the timer. in that case the timer handler
-        * checks ar->scan.in_progress and bails out if its
-        * false. Add a 200ms margin to account event/command
-        * processing. */
-       mod_timer(&ar->scan.timeout, jiffies +
-                 msecs_to_jiffies(arg->max_scan_time+200));
+       /* Add a 200ms margin to account for event/command processing */
+       ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
+                                    msecs_to_jiffies(arg->max_scan_time+200));
        return 0;
 }
 
@@ -2269,7 +2319,7 @@ static void ath10k_tx(struct ieee80211_hw *hw,
 
        /* We should disable CCK RATE due to P2P */
        if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
-               ath10k_dbg(ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");
+               ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");
 
        ATH10K_SKB_CB(skb)->htt.is_offchan = false;
        ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
@@ -2289,7 +2339,8 @@ static void ath10k_tx(struct ieee80211_hw *hw,
                ATH10K_SKB_CB(skb)->vdev_id = ar->scan.vdev_id;
                spin_unlock_bh(&ar->data_lock);
 
-               ath10k_dbg(ATH10K_DBG_MAC, "queued offchannel skb %p\n", skb);
+               ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n",
+                          skb);
 
                skb_queue_tail(&ar->offchan_tx_queue, skb);
                ieee80211_queue_work(hw, &ar->offchan_tx_work);
@@ -2325,8 +2376,7 @@ void ath10k_halt(struct ath10k *ar)
                ath10k_monitor_stop(ar);
        }
 
-       del_timer_sync(&ar->scan.timeout);
-       ath10k_reset_scan((unsigned long)ar);
+       ath10k_scan_finish(ar);
        ath10k_peer_cleanup_all(ar);
        ath10k_core_stop(ar);
        ath10k_hif_power_down(ar);
@@ -2380,7 +2430,7 @@ static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant)
        ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask,
                                        tx_ant);
        if (ret) {
-               ath10k_warn("failed to set tx-chainmask: %d, req 0x%x\n",
+               ath10k_warn(ar, "failed to set tx-chainmask: %d, req 0x%x\n",
                            ret, tx_ant);
                return ret;
        }
@@ -2388,7 +2438,7 @@ static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant)
        ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask,
                                        rx_ant);
        if (ret) {
-               ath10k_warn("failed to set rx-chainmask: %d, req 0x%x\n",
+               ath10k_warn(ar, "failed to set rx-chainmask: %d, req 0x%x\n",
                            ret, rx_ant);
                return ret;
        }
@@ -2439,25 +2489,25 @@ static int ath10k_start(struct ieee80211_hw *hw)
 
        ret = ath10k_hif_power_up(ar);
        if (ret) {
-               ath10k_err("Could not init hif: %d\n", ret);
+               ath10k_err(ar, "Could not init hif: %d\n", ret);
                goto err_off;
        }
 
        ret = ath10k_core_start(ar);
        if (ret) {
-               ath10k_err("Could not init core: %d\n", ret);
+               ath10k_err(ar, "Could not init core: %d\n", ret);
                goto err_power_down;
        }
 
        ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->pmf_qos, 1);
        if (ret) {
-               ath10k_warn("failed to enable PMF QOS: %d\n", ret);
+               ath10k_warn(ar, "failed to enable PMF QOS: %d\n", ret);
                goto err_core_stop;
        }
 
        ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->dynamic_bw, 1);
        if (ret) {
-               ath10k_warn("failed to enable dynamic BW: %d\n", ret);
+               ath10k_warn(ar, "failed to enable dynamic BW: %d\n", ret);
                goto err_core_stop;
        }
 
@@ -2477,7 +2527,7 @@ static int ath10k_start(struct ieee80211_hw *hw)
        ret = ath10k_wmi_pdev_set_param(ar,
                                        ar->wmi.pdev_param->arp_ac_override, 0);
        if (ret) {
-               ath10k_warn("failed to set arp ac override parameter: %d\n",
+               ath10k_warn(ar, "failed to set arp ac override parameter: %d\n",
                            ret);
                goto err_core_stop;
        }
@@ -2485,6 +2535,8 @@ static int ath10k_start(struct ieee80211_hw *hw)
        ar->num_started_vdevs = 0;
        ath10k_regd_update(ar);
 
+       ath10k_spectral_start(ar);
+
        mutex_unlock(&ar->conf_mutex);
        return 0;
 
@@ -2515,6 +2567,7 @@ static void ath10k_stop(struct ieee80211_hw *hw)
        }
        mutex_unlock(&ar->conf_mutex);
 
+       cancel_delayed_work_sync(&ar->scan.timeout);
        cancel_work_sync(&ar->restart_work);
 }
 
@@ -2528,7 +2581,7 @@ static int ath10k_config_ps(struct ath10k *ar)
        list_for_each_entry(arvif, &ar->arvifs, list) {
                ret = ath10k_mac_vif_setup_ps(arvif);
                if (ret) {
-                       ath10k_warn("failed to setup powersave: %d\n", ret);
+                       ath10k_warn(ar, "failed to setup powersave: %d\n", ret);
                        break;
                }
        }
@@ -2566,7 +2619,7 @@ static void ath10k_config_chan(struct ath10k *ar)
 
        lockdep_assert_held(&ar->conf_mutex);
 
-       ath10k_dbg(ATH10K_DBG_MAC,
+       ath10k_dbg(ar, ATH10K_DBG_MAC,
                   "mac config channel to %dMHz (cf1 %dMHz cf2 %dMHz width %s)\n",
                   ar->chandef.chan->center_freq,
                   ar->chandef.center_freq1,
@@ -2582,18 +2635,21 @@ static void ath10k_config_chan(struct ath10k *ar)
                if (!arvif->is_started)
                        continue;
 
+               if (!arvif->is_up)
+                       continue;
+
                if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
                        continue;
 
-               ret = ath10k_vdev_stop(arvif);
+               ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
                if (ret) {
-                       ath10k_warn("failed to stop vdev %d: %d\n",
+                       ath10k_warn(ar, "failed to down vdev %d: %d\n",
                                    arvif->vdev_id, ret);
                        continue;
                }
        }
 
-       /* all vdevs are now stopped - now attempt to restart them */
+       /* all vdevs are downed now - attempt to restart and re-up them */
 
        list_for_each_entry(arvif, &ar->arvifs, list) {
                if (!arvif->is_started)
@@ -2602,9 +2658,9 @@ static void ath10k_config_chan(struct ath10k *ar)
                if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
                        continue;
 
-               ret = ath10k_vdev_start(arvif);
+               ret = ath10k_vdev_restart(arvif);
                if (ret) {
-                       ath10k_warn("failed to start vdev %d: %d\n",
+                       ath10k_warn(ar, "failed to restart vdev %d: %d\n",
                                    arvif->vdev_id, ret);
                        continue;
                }
@@ -2615,7 +2671,7 @@ static void ath10k_config_chan(struct ath10k *ar)
                ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
                                         arvif->bssid);
                if (ret) {
-                       ath10k_warn("failed to bring vdev up %d: %d\n",
+                       ath10k_warn(ar, "failed to bring vdev up %d: %d\n",
                                    arvif->vdev_id, ret);
                        continue;
                }
@@ -2635,7 +2691,7 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
        mutex_lock(&ar->conf_mutex);
 
        if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-               ath10k_dbg(ATH10K_DBG_MAC,
+               ath10k_dbg(ar, ATH10K_DBG_MAC,
                           "mac config channel %dMHz flags 0x%x radar %d\n",
                           conf->chandef.chan->center_freq,
                           conf->chandef.chan->flags,
@@ -2655,21 +2711,21 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
        }
 
        if (changed & IEEE80211_CONF_CHANGE_POWER) {
-               ath10k_dbg(ATH10K_DBG_MAC, "mac config power %d\n",
+               ath10k_dbg(ar, ATH10K_DBG_MAC, "mac config power %d\n",
                           hw->conf.power_level);
 
                param = ar->wmi.pdev_param->txpower_limit2g;
                ret = ath10k_wmi_pdev_set_param(ar, param,
                                                hw->conf.power_level * 2);
                if (ret)
-                       ath10k_warn("failed to set 2g txpower %d: %d\n",
+                       ath10k_warn(ar, "failed to set 2g txpower %d: %d\n",
                                    hw->conf.power_level, ret);
 
                param = ar->wmi.pdev_param->txpower_limit5g;
                ret = ath10k_wmi_pdev_set_param(ar, param,
                                                hw->conf.power_level * 2);
                if (ret)
-                       ath10k_warn("failed to set 5g txpower %d: %d\n",
+                       ath10k_warn(ar, "failed to set 5g txpower %d: %d\n",
                                    hw->conf.power_level, ret);
        }
 
@@ -2681,7 +2737,7 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
                        ar->monitor = true;
                        ret = ath10k_monitor_start(ar);
                        if (ret) {
-                               ath10k_warn("failed to start monitor (config): %d\n",
+                               ath10k_warn(ar, "failed to start monitor (config): %d\n",
                                            ret);
                                ar->monitor = false;
                        }
@@ -2724,11 +2780,12 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
        INIT_WORK(&arvif->wep_key_work, ath10k_tx_wep_key_work);
        INIT_LIST_HEAD(&arvif->list);
 
-       bit = ffs(ar->free_vdev_map);
-       if (bit == 0) {
+       if (ar->free_vdev_map == 0) {
+               ath10k_warn(ar, "Free vdev map is empty, no more interfaces allowed.\n");
                ret = -EBUSY;
                goto err;
        }
+       bit = ffs(ar->free_vdev_map);
 
        arvif->vdev_id = bit - 1;
        arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE;
@@ -2760,25 +2817,25 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
                break;
        }
 
-       ath10k_dbg(ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d\n",
+       ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d\n",
                   arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype);
 
        ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type,
                                     arvif->vdev_subtype, vif->addr);
        if (ret) {
-               ath10k_warn("failed to create WMI vdev %i: %d\n",
+               ath10k_warn(ar, "failed to create WMI vdev %i: %d\n",
                            arvif->vdev_id, ret);
                goto err;
        }
 
-       ar->free_vdev_map &= ~BIT(arvif->vdev_id);
+       ar->free_vdev_map &= ~(1 << arvif->vdev_id);
        list_add(&arvif->list, &ar->arvifs);
 
        vdev_param = ar->wmi.vdev_param->def_keyid;
        ret = ath10k_wmi_vdev_set_param(ar, 0, vdev_param,
                                        arvif->def_wep_key_idx);
        if (ret) {
-               ath10k_warn("failed to set vdev %i default key id: %d\n",
+               ath10k_warn(ar, "failed to set vdev %i default key id: %d\n",
                            arvif->vdev_id, ret);
                goto err_vdev_delete;
        }
@@ -2788,7 +2845,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
                                        ATH10K_HW_TXRX_NATIVE_WIFI);
        /* 10.X firmware does not support this VDEV parameter. Do not warn */
        if (ret && ret != -EOPNOTSUPP) {
-               ath10k_warn("failed to set vdev %i TX encapsulation: %d\n",
+               ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
                            arvif->vdev_id, ret);
                goto err_vdev_delete;
        }
@@ -2796,14 +2853,14 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
        if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
                ret = ath10k_peer_create(ar, arvif->vdev_id, vif->addr);
                if (ret) {
-                       ath10k_warn("failed to create vdev %i peer for AP: %d\n",
+                       ath10k_warn(ar, "failed to create vdev %i peer for AP: %d\n",
                                    arvif->vdev_id, ret);
                        goto err_vdev_delete;
                }
 
                ret = ath10k_mac_set_kickout(arvif);
                if (ret) {
-                       ath10k_warn("failed to set vdev %i kickout parameters: %d\n",
+                       ath10k_warn(ar, "failed to set vdev %i kickout parameters: %d\n",
                                    arvif->vdev_id, ret);
                        goto err_peer_delete;
                }
@@ -2815,7 +2872,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
                ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
                                                  param, value);
                if (ret) {
-                       ath10k_warn("failed to set vdev %i RX wake policy: %d\n",
+                       ath10k_warn(ar, "failed to set vdev %i RX wake policy: %d\n",
                                    arvif->vdev_id, ret);
                        goto err_peer_delete;
                }
@@ -2825,7 +2882,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
                ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
                                                  param, value);
                if (ret) {
-                       ath10k_warn("failed to set vdev %i TX wake thresh: %d\n",
+                       ath10k_warn(ar, "failed to set vdev %i TX wake thresh: %d\n",
                                    arvif->vdev_id, ret);
                        goto err_peer_delete;
                }
@@ -2835,7 +2892,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
                ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
                                                  param, value);
                if (ret) {
-                       ath10k_warn("failed to set vdev %i PSPOLL count: %d\n",
+                       ath10k_warn(ar, "failed to set vdev %i PSPOLL count: %d\n",
                                    arvif->vdev_id, ret);
                        goto err_peer_delete;
                }
@@ -2843,14 +2900,14 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
 
        ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold);
        if (ret) {
-               ath10k_warn("failed to set rts threshold for vdev %d: %d\n",
+               ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
                            arvif->vdev_id, ret);
                goto err_peer_delete;
        }
 
        ret = ath10k_mac_set_frag(arvif, ar->hw->wiphy->frag_threshold);
        if (ret) {
-               ath10k_warn("failed to set frag threshold for vdev %d: %d\n",
+               ath10k_warn(ar, "failed to set frag threshold for vdev %d: %d\n",
                            arvif->vdev_id, ret);
                goto err_peer_delete;
        }
@@ -2864,7 +2921,7 @@ err_peer_delete:
 
 err_vdev_delete:
        ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
-       ar->free_vdev_map &= ~BIT(arvif->vdev_id);
+       ar->free_vdev_map |= 1 << arvif->vdev_id;
        list_del(&arvif->list);
 
 err:
@@ -2892,26 +2949,32 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
                dev_kfree_skb_any(arvif->beacon);
                arvif->beacon = NULL;
        }
+
        spin_unlock_bh(&ar->data_lock);
 
-       ar->free_vdev_map |= 1 << (arvif->vdev_id);
+       ret = ath10k_spectral_vif_stop(arvif);
+       if (ret)
+               ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n",
+                           arvif->vdev_id, ret);
+
+       ar->free_vdev_map |= 1 << arvif->vdev_id;
        list_del(&arvif->list);
 
        if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
                ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, vif->addr);
                if (ret)
-                       ath10k_warn("failed to remove peer for AP vdev %i: %d\n",
+                       ath10k_warn(ar, "failed to remove peer for AP vdev %i: %d\n",
                                    arvif->vdev_id, ret);
 
                kfree(arvif->u.ap.noa_data);
        }
 
-       ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n",
+       ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n",
                   arvif->vdev_id);
 
        ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id);
        if (ret)
-               ath10k_warn("failed to delete WMI vdev %i: %d\n",
+               ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n",
                            arvif->vdev_id, ret);
 
        ath10k_peer_cleanup(ar, arvif->vdev_id);
@@ -2950,7 +3013,7 @@ static void ath10k_configure_filter(struct ieee80211_hw *hw,
                ar->promisc = true;
                ret = ath10k_monitor_start(ar);
                if (ret) {
-                       ath10k_warn("failed to start monitor (promisc): %d\n",
+                       ath10k_warn(ar, "failed to start monitor (promisc): %d\n",
                                    ret);
                        ar->promisc = false;
                }
@@ -2982,17 +3045,17 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
                vdev_param = ar->wmi.vdev_param->beacon_interval;
                ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
                                                arvif->beacon_interval);
-               ath10k_dbg(ATH10K_DBG_MAC,
+               ath10k_dbg(ar, ATH10K_DBG_MAC,
                           "mac vdev %d beacon_interval %d\n",
                           arvif->vdev_id, arvif->beacon_interval);
 
                if (ret)
-                       ath10k_warn("failed to set beacon interval for vdev %d: %i\n",
+                       ath10k_warn(ar, "failed to set beacon interval for vdev %d: %i\n",
                                    arvif->vdev_id, ret);
        }
 
        if (changed & BSS_CHANGED_BEACON) {
-               ath10k_dbg(ATH10K_DBG_MAC,
+               ath10k_dbg(ar, ATH10K_DBG_MAC,
                           "vdev %d set beacon tx mode to staggered\n",
                           arvif->vdev_id);
 
@@ -3000,14 +3063,14 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
                ret = ath10k_wmi_pdev_set_param(ar, pdev_param,
                                                WMI_BEACON_STAGGERED_MODE);
                if (ret)
-                       ath10k_warn("failed to set beacon mode for vdev %d: %i\n",
+                       ath10k_warn(ar, "failed to set beacon mode for vdev %d: %i\n",
                                    arvif->vdev_id, ret);
        }
 
        if (changed & BSS_CHANGED_BEACON_INFO) {
                arvif->dtim_period = info->dtim_period;
 
-               ath10k_dbg(ATH10K_DBG_MAC,
+               ath10k_dbg(ar, ATH10K_DBG_MAC,
                           "mac vdev %d dtim_period %d\n",
                           arvif->vdev_id, arvif->dtim_period);
 
@@ -3015,7 +3078,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
                ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
                                                arvif->dtim_period);
                if (ret)
-                       ath10k_warn("failed to set dtim period for vdev %d: %i\n",
+                       ath10k_warn(ar, "failed to set dtim period for vdev %d: %i\n",
                                    arvif->vdev_id, ret);
        }
 
@@ -3034,14 +3097,14 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
        if (changed & BSS_CHANGED_BSSID &&
            vif->type != NL80211_IFTYPE_AP) {
                if (!is_zero_ether_addr(info->bssid)) {
-                       ath10k_dbg(ATH10K_DBG_MAC,
+                       ath10k_dbg(ar, ATH10K_DBG_MAC,
                                   "mac vdev %d create peer %pM\n",
                                   arvif->vdev_id, info->bssid);
 
                        ret = ath10k_peer_create(ar, arvif->vdev_id,
                                                 info->bssid);
                        if (ret)
-                               ath10k_warn("failed to add peer %pM for vdev %d when changing bssid: %i\n",
+                               ath10k_warn(ar, "failed to add peer %pM for vdev %d when changing bssid: %i\n",
                                            info->bssid, arvif->vdev_id, ret);
 
                        if (vif->type == NL80211_IFTYPE_STATION) {
@@ -3051,13 +3114,13 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
                                 */
                                memcpy(arvif->bssid, info->bssid, ETH_ALEN);
 
-                               ath10k_dbg(ATH10K_DBG_MAC,
+                               ath10k_dbg(ar, ATH10K_DBG_MAC,
                                           "mac vdev %d start %pM\n",
                                           arvif->vdev_id, info->bssid);
 
                                ret = ath10k_vdev_start(arvif);
                                if (ret) {
-                                       ath10k_warn("failed to start vdev %i: %d\n",
+                                       ath10k_warn(ar, "failed to start vdev %i: %d\n",
                                                    arvif->vdev_id, ret);
                                        goto exit;
                                }
@@ -3081,12 +3144,12 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
 
        if (changed & BSS_CHANGED_ERP_CTS_PROT) {
                arvif->use_cts_prot = info->use_cts_prot;
-               ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d cts_prot %d\n",
+               ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d cts_prot %d\n",
                           arvif->vdev_id, info->use_cts_prot);
 
                ret = ath10k_recalc_rtscts_prot(arvif);
                if (ret)
-                       ath10k_warn("failed to recalculate rts/cts prot for vdev %d: %d\n",
+                       ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n",
                                    arvif->vdev_id, ret);
        }
 
@@ -3098,14 +3161,14 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
                else
                        slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */
 
-               ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n",
+               ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n",
                           arvif->vdev_id, slottime);
 
                vdev_param = ar->wmi.vdev_param->slot_time;
                ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
                                                slottime);
                if (ret)
-                       ath10k_warn("failed to set erp slot for vdev %d: %i\n",
+                       ath10k_warn(ar, "failed to set erp slot for vdev %d: %i\n",
                                    arvif->vdev_id, ret);
        }
 
@@ -3116,7 +3179,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
                else
                        preamble = WMI_VDEV_PREAMBLE_LONG;
 
-               ath10k_dbg(ATH10K_DBG_MAC,
+               ath10k_dbg(ar, ATH10K_DBG_MAC,
                           "mac vdev %d preamble %dn",
                           arvif->vdev_id, preamble);
 
@@ -3124,7 +3187,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
                ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
                                                preamble);
                if (ret)
-                       ath10k_warn("failed to set preamble for vdev %d: %i\n",
+                       ath10k_warn(ar, "failed to set preamble for vdev %d: %i\n",
                                    arvif->vdev_id, ret);
        }
 
@@ -3151,20 +3214,26 @@ static int ath10k_hw_scan(struct ieee80211_hw *hw,
        mutex_lock(&ar->conf_mutex);
 
        spin_lock_bh(&ar->data_lock);
-       if (ar->scan.in_progress) {
-               spin_unlock_bh(&ar->data_lock);
+       switch (ar->scan.state) {
+       case ATH10K_SCAN_IDLE:
+               reinit_completion(&ar->scan.started);
+               reinit_completion(&ar->scan.completed);
+               ar->scan.state = ATH10K_SCAN_STARTING;
+               ar->scan.is_roc = false;
+               ar->scan.vdev_id = arvif->vdev_id;
+               ret = 0;
+               break;
+       case ATH10K_SCAN_STARTING:
+       case ATH10K_SCAN_RUNNING:
+       case ATH10K_SCAN_ABORTING:
                ret = -EBUSY;
-               goto exit;
+               break;
        }
-
-       reinit_completion(&ar->scan.started);
-       reinit_completion(&ar->scan.completed);
-       ar->scan.in_progress = true;
-       ar->scan.aborting = false;
-       ar->scan.is_roc = false;
-       ar->scan.vdev_id = arvif->vdev_id;
        spin_unlock_bh(&ar->data_lock);
 
+       if (ret)
+               goto exit;
+
        memset(&arg, 0, sizeof(arg));
        ath10k_wmi_start_scan_init(ar, &arg);
        arg.vdev_id = arvif->vdev_id;
@@ -3196,9 +3265,9 @@ static int ath10k_hw_scan(struct ieee80211_hw *hw,
 
        ret = ath10k_start_scan(ar, &arg);
        if (ret) {
-               ath10k_warn("failed to start hw scan: %d\n", ret);
+               ath10k_warn(ar, "failed to start hw scan: %d\n", ret);
                spin_lock_bh(&ar->data_lock);
-               ar->scan.in_progress = false;
+               ar->scan.state = ATH10K_SCAN_IDLE;
                spin_unlock_bh(&ar->data_lock);
        }
 
@@ -3211,14 +3280,10 @@ static void ath10k_cancel_hw_scan(struct ieee80211_hw *hw,
                                  struct ieee80211_vif *vif)
 {
        struct ath10k *ar = hw->priv;
-       int ret;
 
        mutex_lock(&ar->conf_mutex);
-       ret = ath10k_abort_scan(ar);
-       if (ret) {
-               ath10k_warn("failed to abort scan: %d\n", ret);
-               ieee80211_scan_completed(hw, 1 /* aborted */);
-       }
+       cancel_delayed_work_sync(&ar->scan.timeout);
+       ath10k_scan_abort(ar);
        mutex_unlock(&ar->conf_mutex);
 }
 
@@ -3256,7 +3321,7 @@ static void ath10k_set_key_h_def_keyidx(struct ath10k *ar,
        ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
                                        key->keyidx);
        if (ret)
-               ath10k_warn("failed to set vdev %i group key as default key: %d\n",
+               ath10k_warn(ar, "failed to set vdev %i group key as default key: %d\n",
                            arvif->vdev_id, ret);
 }
 
@@ -3294,7 +3359,7 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 
        if (!peer) {
                if (cmd == SET_KEY) {
-                       ath10k_warn("failed to install key for non-existent peer %pM\n",
+                       ath10k_warn(ar, "failed to install key for non-existent peer %pM\n",
                                    peer_addr);
                        ret = -EOPNOTSUPP;
                        goto exit;
@@ -3317,7 +3382,7 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 
        ret = ath10k_install_key(arvif, key, cmd, peer_addr);
        if (ret) {
-               ath10k_warn("failed to install key for vdev %i peer %pM: %d\n",
+               ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n",
                            arvif->vdev_id, peer_addr, ret);
                goto exit;
        }
@@ -3332,7 +3397,7 @@ static int ath10k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                peer->keys[key->keyidx] = NULL;
        else if (peer == NULL)
                /* impossible unless FW goes crazy */
-               ath10k_warn("Peer %pM disappeared!\n", peer_addr);
+               ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr);
        spin_unlock_bh(&ar->data_lock);
 
 exit:
@@ -3368,45 +3433,45 @@ static void ath10k_sta_rc_update_wk(struct work_struct *wk)
        mutex_lock(&ar->conf_mutex);
 
        if (changed & IEEE80211_RC_BW_CHANGED) {
-               ath10k_dbg(ATH10K_DBG_MAC, "mac update sta %pM peer bw %d\n",
+               ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d\n",
                           sta->addr, bw);
 
                err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
                                                WMI_PEER_CHAN_WIDTH, bw);
                if (err)
-                       ath10k_warn("failed to update STA %pM peer bw %d: %d\n",
+                       ath10k_warn(ar, "failed to update STA %pM peer bw %d: %d\n",
                                    sta->addr, bw, err);
        }
 
        if (changed & IEEE80211_RC_NSS_CHANGED) {
-               ath10k_dbg(ATH10K_DBG_MAC, "mac update sta %pM nss %d\n",
+               ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM nss %d\n",
                           sta->addr, nss);
 
                err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
                                                WMI_PEER_NSS, nss);
                if (err)
-                       ath10k_warn("failed to update STA %pM nss %d: %d\n",
+                       ath10k_warn(ar, "failed to update STA %pM nss %d: %d\n",
                                    sta->addr, nss, err);
        }
 
        if (changed & IEEE80211_RC_SMPS_CHANGED) {
-               ath10k_dbg(ATH10K_DBG_MAC, "mac update sta %pM smps %d\n",
+               ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM smps %d\n",
                           sta->addr, smps);
 
                err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr,
                                                WMI_PEER_SMPS_STATE, smps);
                if (err)
-                       ath10k_warn("failed to update STA %pM smps %d: %d\n",
+                       ath10k_warn(ar, "failed to update STA %pM smps %d: %d\n",
                                    sta->addr, smps, err);
        }
 
        if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
-               ath10k_dbg(ATH10K_DBG_MAC, "mac update sta %pM supp rates\n",
+               ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates\n",
                           sta->addr);
 
                err = ath10k_station_assoc(ar, arvif, sta, true);
                if (err)
-                       ath10k_warn("failed to reassociate station: %pM\n",
+                       ath10k_warn(ar, "failed to reassociate station: %pM\n",
                                    sta->addr);
        }
 
@@ -3451,31 +3516,31 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
                        max_num_peers = TARGET_NUM_PEERS;
 
                if (ar->num_peers >= max_num_peers) {
-                       ath10k_warn("number of peers exceeded: peers number %d (max peers %d)\n",
+                       ath10k_warn(ar, "number of peers exceeded: peers number %d (max peers %d)\n",
                                    ar->num_peers, max_num_peers);
                        ret = -ENOBUFS;
                        goto exit;
                }
 
-               ath10k_dbg(ATH10K_DBG_MAC,
+               ath10k_dbg(ar, ATH10K_DBG_MAC,
                           "mac vdev %d peer create %pM (new sta) num_peers %d\n",
                           arvif->vdev_id, sta->addr, ar->num_peers);
 
                ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr);
                if (ret)
-                       ath10k_warn("failed to add peer %pM for vdev %d when adding a new sta: %i\n",
+                       ath10k_warn(ar, "failed to add peer %pM for vdev %d when adding a new sta: %i\n",
                                    sta->addr, arvif->vdev_id, ret);
        } else if ((old_state == IEEE80211_STA_NONE &&
                    new_state == IEEE80211_STA_NOTEXIST)) {
                /*
                 * Existing station deletion.
                 */
-               ath10k_dbg(ATH10K_DBG_MAC,
+               ath10k_dbg(ar, ATH10K_DBG_MAC,
                           "mac vdev %d peer delete %pM (sta gone)\n",
                           arvif->vdev_id, sta->addr);
                ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr);
                if (ret)
-                       ath10k_warn("failed to delete peer %pM for vdev %d: %i\n",
+                       ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n",
                                    sta->addr, arvif->vdev_id, ret);
 
                if (vif->type == NL80211_IFTYPE_STATION)
@@ -3487,12 +3552,12 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
                /*
                 * New association.
                 */
-               ath10k_dbg(ATH10K_DBG_MAC, "mac sta %pM associated\n",
+               ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM associated\n",
                           sta->addr);
 
                ret = ath10k_station_assoc(ar, arvif, sta, false);
                if (ret)
-                       ath10k_warn("failed to associate station %pM for vdev %i: %i\n",
+                       ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n",
                                    sta->addr, arvif->vdev_id, ret);
        } else if (old_state == IEEE80211_STA_ASSOC &&
                   new_state == IEEE80211_STA_AUTH &&
@@ -3501,12 +3566,12 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
                /*
                 * Disassociation.
                 */
-               ath10k_dbg(ATH10K_DBG_MAC, "mac sta %pM disassociated\n",
+               ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM disassociated\n",
                           sta->addr);
 
                ret = ath10k_station_disassoc(ar, arvif, sta);
                if (ret)
-                       ath10k_warn("failed to disassociate station: %pM vdev %i: %i\n",
+                       ath10k_warn(ar, "failed to disassociate station: %pM vdev %i: %i\n",
                                    sta->addr, arvif->vdev_id, ret);
        }
 exit:
@@ -3554,7 +3619,7 @@ static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
                                          WMI_STA_PS_PARAM_UAPSD,
                                          arvif->u.sta.uapsd);
        if (ret) {
-               ath10k_warn("failed to set uapsd params: %d\n", ret);
+               ath10k_warn(ar, "failed to set uapsd params: %d\n", ret);
                goto exit;
        }
 
@@ -3567,7 +3632,7 @@ static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
                                          WMI_STA_PS_PARAM_RX_WAKE_POLICY,
                                          value);
        if (ret)
-               ath10k_warn("failed to set rx wake param: %d\n", ret);
+               ath10k_warn(ar, "failed to set rx wake param: %d\n", ret);
 
 exit:
        return ret;
@@ -3617,13 +3682,13 @@ static int ath10k_conf_tx(struct ieee80211_hw *hw,
        /* FIXME: FW accepts wmm params per hw, not per vif */
        ret = ath10k_wmi_pdev_set_wmm_params(ar, &ar->wmm_params);
        if (ret) {
-               ath10k_warn("failed to set wmm params: %d\n", ret);
+               ath10k_warn(ar, "failed to set wmm params: %d\n", ret);
                goto exit;
        }
 
        ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd);
        if (ret)
-               ath10k_warn("failed to set sta uapsd: %d\n", ret);
+               ath10k_warn(ar, "failed to set sta uapsd: %d\n", ret);
 
 exit:
        mutex_unlock(&ar->conf_mutex);
@@ -3641,27 +3706,33 @@ static int ath10k_remain_on_channel(struct ieee80211_hw *hw,
        struct ath10k *ar = hw->priv;
        struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
        struct wmi_start_scan_arg arg;
-       int ret;
+       int ret = 0;
 
        mutex_lock(&ar->conf_mutex);
 
        spin_lock_bh(&ar->data_lock);
-       if (ar->scan.in_progress) {
-               spin_unlock_bh(&ar->data_lock);
+       switch (ar->scan.state) {
+       case ATH10K_SCAN_IDLE:
+               reinit_completion(&ar->scan.started);
+               reinit_completion(&ar->scan.completed);
+               reinit_completion(&ar->scan.on_channel);
+               ar->scan.state = ATH10K_SCAN_STARTING;
+               ar->scan.is_roc = true;
+               ar->scan.vdev_id = arvif->vdev_id;
+               ar->scan.roc_freq = chan->center_freq;
+               ret = 0;
+               break;
+       case ATH10K_SCAN_STARTING:
+       case ATH10K_SCAN_RUNNING:
+       case ATH10K_SCAN_ABORTING:
                ret = -EBUSY;
-               goto exit;
+               break;
        }
-
-       reinit_completion(&ar->scan.started);
-       reinit_completion(&ar->scan.completed);
-       reinit_completion(&ar->scan.on_channel);
-       ar->scan.in_progress = true;
-       ar->scan.aborting = false;
-       ar->scan.is_roc = true;
-       ar->scan.vdev_id = arvif->vdev_id;
-       ar->scan.roc_freq = chan->center_freq;
        spin_unlock_bh(&ar->data_lock);
 
+       if (ret)
+               goto exit;
+
        memset(&arg, 0, sizeof(arg));
        ath10k_wmi_start_scan_init(ar, &arg);
        arg.vdev_id = arvif->vdev_id;
@@ -3676,17 +3747,21 @@ static int ath10k_remain_on_channel(struct ieee80211_hw *hw,
 
        ret = ath10k_start_scan(ar, &arg);
        if (ret) {
-               ath10k_warn("failed to start roc scan: %d\n", ret);
+               ath10k_warn(ar, "failed to start roc scan: %d\n", ret);
                spin_lock_bh(&ar->data_lock);
-               ar->scan.in_progress = false;
+               ar->scan.state = ATH10K_SCAN_IDLE;
                spin_unlock_bh(&ar->data_lock);
                goto exit;
        }
 
        ret = wait_for_completion_timeout(&ar->scan.on_channel, 3*HZ);
        if (ret == 0) {
-               ath10k_warn("failed to switch to channel for roc scan\n");
-               ath10k_abort_scan(ar);
+               ath10k_warn(ar, "failed to switch to channel for roc scan\n");
+
+               ret = ath10k_scan_stop(ar);
+               if (ret)
+                       ath10k_warn(ar, "failed to stop scan: %d\n", ret);
+
                ret = -ETIMEDOUT;
                goto exit;
        }
@@ -3702,7 +3777,8 @@ static int ath10k_cancel_remain_on_channel(struct ieee80211_hw *hw)
        struct ath10k *ar = hw->priv;
 
        mutex_lock(&ar->conf_mutex);
-       ath10k_abort_scan(ar);
+       cancel_delayed_work_sync(&ar->scan.timeout);
+       ath10k_scan_abort(ar);
        mutex_unlock(&ar->conf_mutex);
 
        return 0;
@@ -3721,12 +3797,12 @@ static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
 
        mutex_lock(&ar->conf_mutex);
        list_for_each_entry(arvif, &ar->arvifs, list) {
-               ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n",
+               ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n",
                           arvif->vdev_id, value);
 
                ret = ath10k_mac_set_rts(arvif, value);
                if (ret) {
-                       ath10k_warn("failed to set rts threshold for vdev %d: %d\n",
+                       ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n",
                                    arvif->vdev_id, ret);
                        break;
                }
@@ -3744,12 +3820,12 @@ static int ath10k_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
 
        mutex_lock(&ar->conf_mutex);
        list_for_each_entry(arvif, &ar->arvifs, list) {
-               ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d fragmentation threshold %d\n",
+               ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d fragmentation threshold %d\n",
                           arvif->vdev_id, value);
 
                ret = ath10k_mac_set_rts(arvif, value);
                if (ret) {
-                       ath10k_warn("failed to set fragmentation threshold for vdev %d: %d\n",
+                       ath10k_warn(ar, "failed to set fragmentation threshold for vdev %d: %d\n",
                                    arvif->vdev_id, ret);
                        break;
                }
@@ -3789,7 +3865,7 @@ static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                }), ATH10K_FLUSH_TIMEOUT_HZ);
 
        if (ret <= 0 || skip)
-               ath10k_warn("failed to flush transmit queue (skip %i ar-state %i): %i\n",
+               ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %i\n",
                            skip, ar->state, ret);
 
 skip:
@@ -3824,7 +3900,7 @@ static int ath10k_suspend(struct ieee80211_hw *hw,
 
        ret = ath10k_hif_suspend(ar);
        if (ret) {
-               ath10k_warn("failed to suspend hif: %d\n", ret);
+               ath10k_warn(ar, "failed to suspend hif: %d\n", ret);
                goto resume;
        }
 
@@ -3833,7 +3909,7 @@ static int ath10k_suspend(struct ieee80211_hw *hw,
 resume:
        ret = ath10k_wmi_pdev_resume_target(ar);
        if (ret)
-               ath10k_warn("failed to resume target: %d\n", ret);
+               ath10k_warn(ar, "failed to resume target: %d\n", ret);
 
        ret = 1;
 exit:
@@ -3850,14 +3926,14 @@ static int ath10k_resume(struct ieee80211_hw *hw)
 
        ret = ath10k_hif_resume(ar);
        if (ret) {
-               ath10k_warn("failed to resume hif: %d\n", ret);
+               ath10k_warn(ar, "failed to resume hif: %d\n", ret);
                ret = 1;
                goto exit;
        }
 
        ret = ath10k_wmi_pdev_resume_target(ar);
        if (ret) {
-               ath10k_warn("failed to resume target: %d\n", ret);
+               ath10k_warn(ar, "failed to resume target: %d\n", ret);
                ret = 1;
                goto exit;
        }
@@ -3878,7 +3954,7 @@ static void ath10k_restart_complete(struct ieee80211_hw *hw)
        /* If device failed to restart it will be in a different state, e.g.
         * ATH10K_STATE_WEDGED */
        if (ar->state == ATH10K_STATE_RESTARTED) {
-               ath10k_info("device successfully recovered\n");
+               ath10k_info(ar, "device successfully recovered\n");
                ar->state = ATH10K_STATE_ON;
        }
 
@@ -4075,7 +4151,8 @@ ath10k_bitrate_mask_correct(const struct cfg80211_bitrate_mask *mask,
 }
 
 static bool
-ath10k_bitrate_mask_rate(const struct cfg80211_bitrate_mask *mask,
+ath10k_bitrate_mask_rate(struct ath10k *ar,
+                        const struct cfg80211_bitrate_mask *mask,
                         enum ieee80211_band band,
                         u8 *fixed_rate,
                         u8 *fixed_nss)
@@ -4133,7 +4210,7 @@ ath10k_bitrate_mask_rate(const struct cfg80211_bitrate_mask *mask,
        nss <<= 4;
        pream <<= 6;
 
-       ath10k_dbg(ATH10K_DBG_MAC, "mac fixed rate pream 0x%02x nss 0x%02x rate 0x%02x\n",
+       ath10k_dbg(ar, ATH10K_DBG_MAC, "mac fixed rate pream 0x%02x nss 0x%02x rate 0x%02x\n",
                   pream, nss, rate);
 
        *fixed_rate = pream | nss | rate;
@@ -4141,7 +4218,8 @@ ath10k_bitrate_mask_rate(const struct cfg80211_bitrate_mask *mask,
        return true;
 }
 
-static bool ath10k_get_fixed_rate_nss(const struct cfg80211_bitrate_mask *mask,
+static bool ath10k_get_fixed_rate_nss(struct ath10k *ar,
+                                     const struct cfg80211_bitrate_mask *mask,
                                      enum ieee80211_band band,
                                      u8 *fixed_rate,
                                      u8 *fixed_nss)
@@ -4151,7 +4229,7 @@ static bool ath10k_get_fixed_rate_nss(const struct cfg80211_bitrate_mask *mask,
                return true;
 
        /* Next Check single rate is set */
-       return ath10k_bitrate_mask_rate(mask, band, fixed_rate, fixed_nss);
+       return ath10k_bitrate_mask_rate(ar, mask, band, fixed_rate, fixed_nss);
 }
 
 static int ath10k_set_fixed_rate_param(struct ath10k_vif *arvif,
@@ -4171,16 +4249,16 @@ static int ath10k_set_fixed_rate_param(struct ath10k_vif *arvif,
                goto exit;
 
        if (fixed_rate == WMI_FIXED_RATE_NONE)
-               ath10k_dbg(ATH10K_DBG_MAC, "mac disable fixed bitrate mask\n");
+               ath10k_dbg(ar, ATH10K_DBG_MAC, "mac disable fixed bitrate mask\n");
 
        if (force_sgi)
-               ath10k_dbg(ATH10K_DBG_MAC, "mac force sgi\n");
+               ath10k_dbg(ar, ATH10K_DBG_MAC, "mac force sgi\n");
 
        vdev_param = ar->wmi.vdev_param->fixed_rate;
        ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id,
                                        vdev_param, fixed_rate);
        if (ret) {
-               ath10k_warn("failed to set fixed rate param 0x%02x: %d\n",
+               ath10k_warn(ar, "failed to set fixed rate param 0x%02x: %d\n",
                            fixed_rate, ret);
                ret = -EINVAL;
                goto exit;
@@ -4193,7 +4271,7 @@ static int ath10k_set_fixed_rate_param(struct ath10k_vif *arvif,
                                        vdev_param, fixed_nss);
 
        if (ret) {
-               ath10k_warn("failed to set fixed nss param %d: %d\n",
+               ath10k_warn(ar, "failed to set fixed nss param %d: %d\n",
                            fixed_nss, ret);
                ret = -EINVAL;
                goto exit;
@@ -4206,7 +4284,7 @@ static int ath10k_set_fixed_rate_param(struct ath10k_vif *arvif,
                                        force_sgi);
 
        if (ret) {
-               ath10k_warn("failed to set sgi param %d: %d\n",
+               ath10k_warn(ar, "failed to set sgi param %d: %d\n",
                            force_sgi, ret);
                ret = -EINVAL;
                goto exit;
@@ -4235,14 +4313,14 @@ static int ath10k_set_bitrate_mask(struct ieee80211_hw *hw,
                return -EINVAL;
 
        if (!ath10k_default_bitrate_mask(ar, band, mask)) {
-               if (!ath10k_get_fixed_rate_nss(mask, band,
+               if (!ath10k_get_fixed_rate_nss(ar, mask, band,
                                               &fixed_rate,
                                               &fixed_nss))
                        return -EINVAL;
        }
 
        if (fixed_rate == WMI_FIXED_RATE_NONE && force_sgi) {
-               ath10k_warn("failed to force SGI usage for default rate settings\n");
+               ath10k_warn(ar, "failed to force SGI usage for default rate settings\n");
                return -EINVAL;
        }
 
@@ -4261,7 +4339,7 @@ static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
 
        spin_lock_bh(&ar->data_lock);
 
-       ath10k_dbg(ATH10K_DBG_MAC,
+       ath10k_dbg(ar, ATH10K_DBG_MAC,
                   "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n",
                   sta->addr, changed, sta->bandwidth, sta->rx_nss,
                   sta->smps_mode);
@@ -4280,7 +4358,7 @@ static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
                        bw = WMI_PEER_CHWIDTH_80MHZ;
                        break;
                case IEEE80211_STA_RX_BW_160:
-                       ath10k_warn("Invalid bandwith %d in rc update for %pM\n",
+                       ath10k_warn(ar, "Invalid bandwith %d in rc update for %pM\n",
                                    sta->bandwidth, sta->addr);
                        bw = WMI_PEER_CHWIDTH_20MHZ;
                        break;
@@ -4307,7 +4385,7 @@ static void ath10k_sta_rc_update(struct ieee80211_hw *hw,
                        smps = WMI_PEER_SMPS_DYNAMIC;
                        break;
                case IEEE80211_SMPS_NUM_MODES:
-                       ath10k_warn("Invalid smps %d in sta rc update for %pM\n",
+                       ath10k_warn(ar, "Invalid smps %d in sta rc update for %pM\n",
                                    sta->smps_mode, sta->addr);
                        smps = WMI_PEER_SMPS_PS_NONE;
                        break;
@@ -4339,9 +4417,10 @@ static int ath10k_ampdu_action(struct ieee80211_hw *hw,
                               struct ieee80211_sta *sta, u16 tid, u16 *ssn,
                               u8 buf_size)
 {
+       struct ath10k *ar = hw->priv;
        struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
 
-       ath10k_dbg(ATH10K_DBG_MAC, "mac ampdu vdev_id %i sta %pM tid %hu action %d\n",
+       ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ampdu vdev_id %i sta %pM tid %hu action %d\n",
                   arvif->vdev_id, sta->addr, tid, action);
 
        switch (action) {
@@ -4489,12 +4568,12 @@ static struct ieee80211_rate ath10k_rates[] = {
 #define ath10k_g_rates (ath10k_rates + 0)
 #define ath10k_g_rates_size (ARRAY_SIZE(ath10k_rates))
 
-struct ath10k *ath10k_mac_create(void)
+struct ath10k *ath10k_mac_create(size_t priv_size)
 {
        struct ieee80211_hw *hw;
        struct ath10k *ar;
 
-       hw = ieee80211_alloc_hw(sizeof(struct ath10k), &ath10k_ops);
+       hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, &ath10k_ops);
        if (!hw)
                return NULL;
 
@@ -4669,7 +4748,7 @@ struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id)
                                                   ath10k_get_arvif_iter,
                                                   &arvif_iter);
        if (!arvif_iter.arvif) {
-               ath10k_warn("No VIF found for vdev %d\n", vdev_id);
+               ath10k_warn(ar, "No VIF found for vdev %d\n", vdev_id);
                return NULL;
        }
 
@@ -4815,19 +4894,19 @@ int ath10k_mac_register(struct ath10k *ar)
                                                             NL80211_DFS_UNSET);
 
                if (!ar->dfs_detector)
-                       ath10k_warn("failed to initialise DFS pattern detector\n");
+                       ath10k_warn(ar, "failed to initialise DFS pattern detector\n");
        }
 
        ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy,
                            ath10k_reg_notifier);
        if (ret) {
-               ath10k_err("failed to initialise regulatory: %i\n", ret);
+               ath10k_err(ar, "failed to initialise regulatory: %i\n", ret);
                goto err_free;
        }
 
        ret = ieee80211_register_hw(ar->hw);
        if (ret) {
-               ath10k_err("failed to register ieee80211: %d\n", ret);
+               ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
                goto err_free;
        }
 
index ef4f84376d7c2fe7d16432621b7f067ccb620992..6c80eeada3e28863bb1fe22e753251b64f73608d 100644 (file)
@@ -26,12 +26,14 @@ struct ath10k_generic_iter {
        int ret;
 };
 
-struct ath10k *ath10k_mac_create(void);
+struct ath10k *ath10k_mac_create(size_t priv_size);
 void ath10k_mac_destroy(struct ath10k *ar);
 int ath10k_mac_register(struct ath10k *ar);
 void ath10k_mac_unregister(struct ath10k *ar);
 struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id);
-void ath10k_reset_scan(unsigned long ptr);
+void __ath10k_scan_finish(struct ath10k *ar);
+void ath10k_scan_finish(struct ath10k *ar);
+void ath10k_scan_timeout_work(struct work_struct *work);
 void ath10k_offchan_tx_purge(struct ath10k *ar);
 void ath10k_offchan_tx_work(struct work_struct *work);
 void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar);
index 3376963a4862db7f133064b6b8869c56b2c39c71..056a35a77133f5e1aee4f2ce8b4afb26859b02cb 100644 (file)
@@ -44,13 +44,9 @@ enum ath10k_pci_reset_mode {
        ATH10K_PCI_RESET_WARM_ONLY = 1,
 };
 
-static unsigned int ath10k_pci_target_ps;
 static unsigned int ath10k_pci_irq_mode = ATH10K_PCI_IRQ_AUTO;
 static unsigned int ath10k_pci_reset_mode = ATH10K_PCI_RESET_AUTO;
 
-module_param_named(target_ps, ath10k_pci_target_ps, uint, 0644);
-MODULE_PARM_DESC(target_ps, "Enable ath10k Target (SoC) PS option");
-
 module_param_named(irq_mode, ath10k_pci_irq_mode, uint, 0644);
 MODULE_PARM_DESC(irq_mode, "0: auto, 1: legacy, 2: msi (default: 0)");
 
@@ -71,10 +67,7 @@ static const struct pci_device_id ath10k_pci_id_table[] = {
 static int ath10k_pci_diag_read_access(struct ath10k *ar, u32 address,
                                       u32 *data);
 
-static int ath10k_pci_post_rx(struct ath10k *ar);
-static int ath10k_pci_post_rx_pipe(struct ath10k_pci_pipe *pipe_info,
-                                            int num);
-static void ath10k_pci_rx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info);
+static void ath10k_pci_buffer_cleanup(struct ath10k *ar);
 static int ath10k_pci_cold_reset(struct ath10k *ar);
 static int ath10k_pci_warm_reset(struct ath10k *ar);
 static int ath10k_pci_wait_for_target_init(struct ath10k *ar);
@@ -156,79 +149,175 @@ static const struct ce_attr host_ce_config_wlan[] = {
 static const struct ce_pipe_config target_ce_config_wlan[] = {
        /* CE0: host->target HTC control and raw streams */
        {
-               .pipenum = 0,
-               .pipedir = PIPEDIR_OUT,
-               .nentries = 32,
-               .nbytes_max = 256,
-               .flags = CE_ATTR_FLAGS,
-               .reserved = 0,
+               .pipenum = __cpu_to_le32(0),
+               .pipedir = __cpu_to_le32(PIPEDIR_OUT),
+               .nentries = __cpu_to_le32(32),
+               .nbytes_max = __cpu_to_le32(256),
+               .flags = __cpu_to_le32(CE_ATTR_FLAGS),
+               .reserved = __cpu_to_le32(0),
        },
 
        /* CE1: target->host HTT + HTC control */
        {
-               .pipenum = 1,
-               .pipedir = PIPEDIR_IN,
-               .nentries = 32,
-               .nbytes_max = 512,
-               .flags = CE_ATTR_FLAGS,
-               .reserved = 0,
+               .pipenum = __cpu_to_le32(1),
+               .pipedir = __cpu_to_le32(PIPEDIR_IN),
+               .nentries = __cpu_to_le32(32),
+               .nbytes_max = __cpu_to_le32(512),
+               .flags = __cpu_to_le32(CE_ATTR_FLAGS),
+               .reserved = __cpu_to_le32(0),
        },
 
        /* CE2: target->host WMI */
        {
-               .pipenum = 2,
-               .pipedir = PIPEDIR_IN,
-               .nentries = 32,
-               .nbytes_max = 2048,
-               .flags = CE_ATTR_FLAGS,
-               .reserved = 0,
+               .pipenum = __cpu_to_le32(2),
+               .pipedir = __cpu_to_le32(PIPEDIR_IN),
+               .nentries = __cpu_to_le32(32),
+               .nbytes_max = __cpu_to_le32(2048),
+               .flags = __cpu_to_le32(CE_ATTR_FLAGS),
+               .reserved = __cpu_to_le32(0),
        },
 
        /* CE3: host->target WMI */
        {
-               .pipenum = 3,
-               .pipedir = PIPEDIR_OUT,
-               .nentries = 32,
-               .nbytes_max = 2048,
-               .flags = CE_ATTR_FLAGS,
-               .reserved = 0,
+               .pipenum = __cpu_to_le32(3),
+               .pipedir = __cpu_to_le32(PIPEDIR_OUT),
+               .nentries = __cpu_to_le32(32),
+               .nbytes_max = __cpu_to_le32(2048),
+               .flags = __cpu_to_le32(CE_ATTR_FLAGS),
+               .reserved = __cpu_to_le32(0),
        },
 
        /* CE4: host->target HTT */
        {
-               .pipenum = 4,
-               .pipedir = PIPEDIR_OUT,
-               .nentries = 256,
-               .nbytes_max = 256,
-               .flags = CE_ATTR_FLAGS,
-               .reserved = 0,
+               .pipenum = __cpu_to_le32(4),
+               .pipedir = __cpu_to_le32(PIPEDIR_OUT),
+               .nentries = __cpu_to_le32(256),
+               .nbytes_max = __cpu_to_le32(256),
+               .flags = __cpu_to_le32(CE_ATTR_FLAGS),
+               .reserved = __cpu_to_le32(0),
        },
 
        /* NB: 50% of src nentries, since tx has 2 frags */
 
        /* CE5: unused */
        {
-               .pipenum = 5,
-               .pipedir = PIPEDIR_OUT,
-               .nentries = 32,
-               .nbytes_max = 2048,
-               .flags = CE_ATTR_FLAGS,
-               .reserved = 0,
+               .pipenum = __cpu_to_le32(5),
+               .pipedir = __cpu_to_le32(PIPEDIR_OUT),
+               .nentries = __cpu_to_le32(32),
+               .nbytes_max = __cpu_to_le32(2048),
+               .flags = __cpu_to_le32(CE_ATTR_FLAGS),
+               .reserved = __cpu_to_le32(0),
        },
 
        /* CE6: Reserved for target autonomous hif_memcpy */
        {
-               .pipenum = 6,
-               .pipedir = PIPEDIR_INOUT,
-               .nentries = 32,
-               .nbytes_max = 4096,
-               .flags = CE_ATTR_FLAGS,
-               .reserved = 0,
+               .pipenum = __cpu_to_le32(6),
+               .pipedir = __cpu_to_le32(PIPEDIR_INOUT),
+               .nentries = __cpu_to_le32(32),
+               .nbytes_max = __cpu_to_le32(4096),
+               .flags = __cpu_to_le32(CE_ATTR_FLAGS),
+               .reserved = __cpu_to_le32(0),
        },
 
        /* CE7 used only by Host */
 };
 
+/*
+ * Map from service/endpoint to Copy Engine.
+ * This table is derived from the CE_PCI TABLE, above.
+ * It is passed to the Target at startup for use by firmware.
+ */
+static const struct service_to_pipe target_service_to_ce_map_wlan[] = {
+       {
+               __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO),
+               __cpu_to_le32(PIPEDIR_OUT),     /* out = UL = host -> target */
+               __cpu_to_le32(3),
+       },
+       {
+               __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO),
+               __cpu_to_le32(PIPEDIR_IN),      /* in = DL = target -> host */
+               __cpu_to_le32(2),
+       },
+       {
+               __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BK),
+               __cpu_to_le32(PIPEDIR_OUT),     /* out = UL = host -> target */
+               __cpu_to_le32(3),
+       },
+       {
+               __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BK),
+               __cpu_to_le32(PIPEDIR_IN),      /* in = DL = target -> host */
+               __cpu_to_le32(2),
+       },
+       {
+               __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BE),
+               __cpu_to_le32(PIPEDIR_OUT),     /* out = UL = host -> target */
+               __cpu_to_le32(3),
+       },
+       {
+               __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BE),
+               __cpu_to_le32(PIPEDIR_IN),      /* in = DL = target -> host */
+               __cpu_to_le32(2),
+       },
+       {
+               __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VI),
+      &nbs