]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge tag 'for-linville-20130318' of git://github.com/kvalo/ath6kl
authorJohn W. Linville <linville@tuxdriver.com>
Mon, 18 Mar 2013 20:34:55 +0000 (16:34 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 18 Mar 2013 20:34:55 +0000 (16:34 -0400)
18 files changed:
drivers/net/wireless/ath/ath6kl/Kconfig
drivers/net/wireless/ath/ath6kl/Makefile
drivers/net/wireless/ath/ath6kl/cfg80211.c
drivers/net/wireless/ath/ath6kl/core.h
drivers/net/wireless/ath/ath6kl/debug.c
drivers/net/wireless/ath/ath6kl/debug.h
drivers/net/wireless/ath/ath6kl/hif.c
drivers/net/wireless/ath/ath6kl/htc_mbox.c
drivers/net/wireless/ath/ath6kl/htc_pipe.c
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/target.h
drivers/net/wireless/ath/ath6kl/trace.c [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/trace.h [new file with mode: 0644]
drivers/net/wireless/ath/ath6kl/txrx.c
drivers/net/wireless/ath/ath6kl/usb.c
drivers/net/wireless/ath/ath6kl/wmi.c

index 630c83db056e8cf45e2a7839b7f64345170217f5..e39e5860a2e9347a2d44318e69b07410c4bd2dc5 100644 (file)
@@ -30,6 +30,15 @@ config ATH6KL_DEBUG
        ---help---
          Enables debug support
 
+config ATH6KL_TRACING
+       bool "Atheros ath6kl tracing support"
+       depends on ATH6KL
+       depends on EVENT_TRACING
+       ---help---
+         Select this to ath6kl use tracing infrastructure.
+
+         If unsure, say Y to make it easier to debug problems.
+
 config ATH6KL_REGDOMAIN
        bool "Atheros ath6kl regdomain support"
        depends on ATH6KL
index cab0ec0d5380afde712ac83bf23a2eaab514cbb8..dc2b3b46781e190a59558b41d8cbd87b3e409df6 100644 (file)
@@ -35,10 +35,15 @@ ath6kl_core-y += txrx.o
 ath6kl_core-y += wmi.o
 ath6kl_core-y += core.o
 ath6kl_core-y += recovery.o
+
 ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o
+ath6kl_core-$(CONFIG_ATH6KL_TRACING) += trace.o
 
 obj-$(CONFIG_ATH6KL_SDIO) += ath6kl_sdio.o
 ath6kl_sdio-y += sdio.o
 
 obj-$(CONFIG_ATH6KL_USB) += ath6kl_usb.o
 ath6kl_usb-y += usb.o
+
+# for tracing framework to find trace.h
+CFLAGS_trace.o := -I$(src)
index 28c413f861a2a78185d642a916a1282424d90935..5c9736a94e544d0c9008480ac994c593d1b4d269 100644 (file)
@@ -402,7 +402,7 @@ static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type,
        if (type == NL80211_IFTYPE_STATION ||
            type == NL80211_IFTYPE_AP || type == NL80211_IFTYPE_ADHOC) {
                for (i = 0; i < ar->vif_max; i++) {
-                       if ((ar->avail_idx_map >> i) & BIT(0)) {
+                       if ((ar->avail_idx_map) & BIT(i)) {
                                *if_idx = i;
                                return true;
                        }
@@ -412,7 +412,7 @@ static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type,
        if (type == NL80211_IFTYPE_P2P_CLIENT ||
            type == NL80211_IFTYPE_P2P_GO) {
                for (i = ar->max_norm_iface; i < ar->vif_max; i++) {
-                       if ((ar->avail_idx_map >> i) & BIT(0)) {
+                       if ((ar->avail_idx_map) & BIT(i)) {
                                *if_idx = i;
                                return true;
                        }
@@ -1535,7 +1535,9 @@ static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
 
        ath6kl_cfg80211_vif_stop(vif, test_bit(WMI_READY, &ar->flag));
 
+       rtnl_lock();
        ath6kl_cfg80211_vif_cleanup(vif);
+       rtnl_unlock();
 
        return 0;
 }
@@ -3661,7 +3663,6 @@ struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name,
        vif->sme_state = SME_DISCONNECTED;
        set_bit(WLAN_ENABLED, &vif->flags);
        ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
-       set_bit(NETDEV_REGISTERED, &vif->flags);
 
        if (type == NL80211_IFTYPE_ADHOC)
                ar->ibss_if_active = true;
index 61b2f98b4e775afb9f0f4b17e4af8bed68baa59d..26b0f92424e16fb91beca55f3f07e9d907a9db04 100644 (file)
@@ -560,7 +560,6 @@ enum ath6kl_vif_state {
        WMM_ENABLED,
        NETQ_STOPPED,
        DTIM_EXPIRED,
-       NETDEV_REGISTERED,
        CLEAR_BSSFILTER_ON_BEACON,
        DTIM_PERIOD_AVAIL,
        WLAN_ENABLED,
@@ -936,8 +935,6 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no,
                             u8 win_sz);
 void ath6kl_wakeup_event(void *dev);
 
-void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
-                        bool wait_fot_compltn, bool cold_reset);
 void ath6kl_init_control_info(struct ath6kl_vif *vif);
 struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar);
 void ath6kl_cfg80211_vif_stop(struct ath6kl_vif *vif, bool wmi_ready);
index 15cfe30e54fdf1dfb8a8c8548a2c6826bc0de98e..fe38b836cb2651a77726af4e3d7772b591d46427 100644 (file)
@@ -56,6 +56,60 @@ int ath6kl_printk(const char *level, const char *fmt, ...)
 }
 EXPORT_SYMBOL(ath6kl_printk);
 
+int ath6kl_info(const char *fmt, ...)
+{
+       struct va_format vaf = {
+               .fmt = fmt,
+       };
+       va_list args;
+       int ret;
+
+       va_start(args, fmt);
+       vaf.va = &args;
+       ret = ath6kl_printk(KERN_INFO, "%pV", &vaf);
+       trace_ath6kl_log_info(&vaf);
+       va_end(args);
+
+       return ret;
+}
+EXPORT_SYMBOL(ath6kl_info);
+
+int ath6kl_err(const char *fmt, ...)
+{
+       struct va_format vaf = {
+               .fmt = fmt,
+       };
+       va_list args;
+       int ret;
+
+       va_start(args, fmt);
+       vaf.va = &args;
+       ret = ath6kl_printk(KERN_ERR, "%pV", &vaf);
+       trace_ath6kl_log_err(&vaf);
+       va_end(args);
+
+       return ret;
+}
+EXPORT_SYMBOL(ath6kl_err);
+
+int ath6kl_warn(const char *fmt, ...)
+{
+       struct va_format vaf = {
+               .fmt = fmt,
+       };
+       va_list args;
+       int ret;
+
+       va_start(args, fmt);
+       vaf.va = &args;
+       ret = ath6kl_printk(KERN_WARNING, "%pV", &vaf);
+       trace_ath6kl_log_warn(&vaf);
+       va_end(args);
+
+       return ret;
+}
+EXPORT_SYMBOL(ath6kl_warn);
+
 #ifdef CONFIG_ATH6KL_DEBUG
 
 void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...)
@@ -63,15 +117,15 @@ void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...)
        struct va_format vaf;
        va_list args;
 
-       if (!(debug_mask & mask))
-               return;
-
        va_start(args, fmt);
 
        vaf.fmt = fmt;
        vaf.va = &args;
 
-       ath6kl_printk(KERN_DEBUG, "%pV", &vaf);
+       if (debug_mask & mask)
+               ath6kl_printk(KERN_DEBUG, "%pV", &vaf);
+
+       trace_ath6kl_log_dbg(mask, &vaf);
 
        va_end(args);
 }
@@ -87,6 +141,10 @@ void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
 
                print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len);
        }
+
+       /* tracing code doesn't like null strings :/ */
+       trace_ath6kl_log_dbg_dump(msg ? msg : "", prefix ? prefix : "",
+                                 buf, len);
 }
 EXPORT_SYMBOL(ath6kl_dbg_dump);
 
@@ -1752,8 +1810,10 @@ int ath6kl_debug_init_fs(struct ath6kl *ar)
        debugfs_create_file("tgt_stats", S_IRUSR, ar->debugfs_phy, ar,
                            &fops_tgt_stats);
 
-       debugfs_create_file("credit_dist_stats", S_IRUSR, ar->debugfs_phy, ar,
-                           &fops_credit_dist_stats);
+       if (ar->hif_type == ATH6KL_HIF_TYPE_SDIO)
+               debugfs_create_file("credit_dist_stats", S_IRUSR,
+                                   ar->debugfs_phy, ar,
+                                   &fops_credit_dist_stats);
 
        debugfs_create_file("endpoint_stats", S_IRUSR | S_IWUSR,
                            ar->debugfs_phy, ar, &fops_endpoint_stats);
index f97cd4ead543fdd239220372cc6846539343d1c6..74369de00fb57a40dcebd72ced2002d0cb571b24 100644 (file)
@@ -19,6 +19,7 @@
 #define DEBUG_H
 
 #include "hif.h"
+#include "trace.h"
 
 enum ATH6K_DEBUG_MASK {
        ATH6KL_DBG_CREDIT       = BIT(0),
@@ -51,13 +52,9 @@ enum ATH6K_DEBUG_MASK {
 extern unsigned int debug_mask;
 extern __printf(2, 3)
 int ath6kl_printk(const char *level, const char *fmt, ...);
-
-#define ath6kl_info(fmt, ...)                          \
-       ath6kl_printk(KERN_INFO, fmt, ##__VA_ARGS__)
-#define ath6kl_err(fmt, ...)                                   \
-       ath6kl_printk(KERN_ERR, fmt, ##__VA_ARGS__)
-#define ath6kl_warn(fmt, ...)                                  \
-       ath6kl_printk(KERN_WARNING, fmt, ##__VA_ARGS__)
+extern __printf(1, 2) int ath6kl_info(const char *fmt, ...);
+extern __printf(1, 2) int ath6kl_err(const char *fmt, ...);
+extern __printf(1, 2) int ath6kl_warn(const char *fmt, ...);
 
 enum ath6kl_war {
        ATH6KL_WAR_INVALID_RATE,
index a6b614421fa409814e1662a78df1507da904b970..fea7709b5dda59aa26fa0fbc5eb70caccea77918 100644 (file)
@@ -22,6 +22,7 @@
 #include "target.h"
 #include "hif-ops.h"
 #include "debug.h"
+#include "trace.h"
 
 #define MAILBOX_FOR_BLOCK_SIZE          1
 
@@ -436,6 +437,8 @@ static int proc_pending_irqs(struct ath6kl_device *dev, bool *done)
 
                ath6kl_dump_registers(dev, &dev->irq_proc_reg,
                                      &dev->irq_en_reg);
+               trace_ath6kl_sdio_irq(&dev->irq_en_reg,
+                                     sizeof(dev->irq_en_reg));
 
                /* Update only those registers that are enabled */
                host_int_status = dev->irq_proc_reg.host_int_status &
index fbb78dfe078f692ad94c34d80bf9dbf7ec2e3a06..65e5b719093d47943b3135e902cf68001eefd988 100644 (file)
@@ -19,6 +19,8 @@
 #include "hif.h"
 #include "debug.h"
 #include "hif-ops.h"
+#include "trace.h"
+
 #include <asm/unaligned.h>
 
 #define CALC_TXRX_PADDED_LEN(dev, len)  (__ALIGN_MASK((len), (dev)->block_mask))
@@ -537,6 +539,8 @@ static int ath6kl_htc_tx_issue(struct htc_target *target,
                                packet->buf, padded_len,
                                HIF_WR_ASYNC_BLOCK_INC, packet);
 
+       trace_ath6kl_htc_tx(status, packet->endpoint, packet->buf, send_len);
+
        return status;
 }
 
@@ -757,7 +761,8 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint,
 {
        struct htc_target *target = endpoint->target;
        struct hif_scatter_req *scat_req = NULL;
-       int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0;
+       int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0, i;
+       struct htc_packet *packet;
        int status;
        u32 txb_mask;
        u8 ac = WMM_NUM_AC;
@@ -832,6 +837,13 @@ static void ath6kl_htc_tx_bundle(struct htc_endpoint *endpoint,
                ath6kl_dbg(ATH6KL_DBG_HTC,
                           "htc tx scatter bytes %d entries %d\n",
                           scat_req->len, scat_req->scat_entries);
+
+               for (i = 0; i < scat_req->scat_entries; i++) {
+                       packet = scat_req->scat_list[i].packet;
+                       trace_ath6kl_htc_tx(packet->status, packet->endpoint,
+                                           packet->buf, packet->act_len);
+               }
+
                ath6kl_hif_submit_scat_req(target->dev, scat_req, false);
 
                if (status)
@@ -1903,6 +1915,7 @@ static void ath6kl_htc_rx_complete(struct htc_endpoint *endpoint,
                ath6kl_dbg(ATH6KL_DBG_HTC,
                           "htc rx complete ep %d packet 0x%p\n",
                           endpoint->eid, packet);
+
                endpoint->ep_cb.rx(endpoint->target, packet);
 }
 
@@ -2011,6 +2024,9 @@ static int ath6kl_htc_rx_process_packets(struct htc_target *target,
        list_for_each_entry_safe(packet, tmp_pkt, comp_pktq, list) {
                ep = &target->endpoint[packet->endpoint];
 
+               trace_ath6kl_htc_rx(packet->status, packet->endpoint,
+                                   packet->buf, packet->act_len);
+
                /* process header for each of the recv packet */
                status = ath6kl_htc_rx_process_hdr(target, packet, lk_ahds,
                                                   n_lk_ahd);
@@ -2291,6 +2307,9 @@ static struct htc_packet *htc_wait_for_ctrl_msg(struct htc_target *target)
        if (ath6kl_htc_rx_packet(target, packet, packet->act_len))
                goto fail_ctrl_rx;
 
+       trace_ath6kl_htc_rx(packet->status, packet->endpoint,
+                           packet->buf, packet->act_len);
+
        /* process receive header */
        packet->status = ath6kl_htc_rx_process_hdr(target, packet, NULL, NULL);
 
index 9adb56741bc3fd13da6b0644fc52245dca7a3816..67aa924ed8b317f9d5240ad1560a820553790c24 100644 (file)
@@ -1167,8 +1167,8 @@ static int htc_wait_recv_ctrl_message(struct htc_target *target)
        }
 
        if (count <= 0) {
-               ath6kl_dbg(ATH6KL_DBG_HTC, "%s: Timeout!\n", __func__);
-               return -ECOMM;
+               ath6kl_warn("htc pipe control receive timeout!\n");
+               return -ETIMEDOUT;
        }
 
        return 0;
@@ -1581,16 +1581,16 @@ static int ath6kl_htc_pipe_wait_target(struct htc_target *target)
                return status;
 
        if (target->pipe.ctrl_response_len < sizeof(*ready_msg)) {
-               ath6kl_dbg(ATH6KL_DBG_HTC, "invalid htc ready msg len:%d!\n",
-                          target->pipe.ctrl_response_len);
+               ath6kl_warn("invalid htc pipe ready msg len: %d\n",
+                           target->pipe.ctrl_response_len);
                return -ECOMM;
        }
 
        ready_msg = (struct htc_ready_ext_msg *) target->pipe.ctrl_response_buf;
 
        if (ready_msg->ver2_0_info.msg_id != cpu_to_le16(HTC_MSG_READY_ID)) {
-               ath6kl_dbg(ATH6KL_DBG_HTC, "invalid htc ready msg : 0x%X !\n",
-                          ready_msg->ver2_0_info.msg_id);
+               ath6kl_warn("invalid htc pipe ready msg: 0x%x\n",
+                           ready_msg->ver2_0_info.msg_id);
                return -ECOMM;
        }
 
index 5d434cf88f35adb52e4d28cd37cf7ea1cc2c50e0..40ffee6184fd3b680037da63e0d35abcf44b4b6e 100644 (file)
@@ -201,8 +201,8 @@ struct sk_buff *ath6kl_buf_alloc(int size)
        u16 reserved;
 
        /* Add chacheline space at front and back of buffer */
-       reserved = (2 * L1_CACHE_BYTES) + ATH6KL_DATA_OFFSET +
-                  sizeof(struct htc_packet) + ATH6KL_HTC_ALIGN_BYTES;
+       reserved = roundup((2 * L1_CACHE_BYTES) + ATH6KL_DATA_OFFSET +
+                  sizeof(struct htc_packet) + ATH6KL_HTC_ALIGN_BYTES, 4);
        skb = dev_alloc_skb(size + reserved);
 
        if (skb)
@@ -1549,10 +1549,89 @@ static const char *ath6kl_init_get_hif_name(enum ath6kl_hif_type type)
        return NULL;
 }
 
+
+static const struct fw_capa_str_map {
+       int id;
+       const char *name;
+} fw_capa_map[] = {
+       { ATH6KL_FW_CAPABILITY_HOST_P2P, "host-p2p" },
+       { ATH6KL_FW_CAPABILITY_SCHED_SCAN, "sched-scan" },
+       { ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, "sta-p2pdev-duplex" },
+       { ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT, "inactivity-timeout" },
+       { ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE, "rsn-cap-override" },
+       { ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER, "wow-mc-filter" },
+       { ATH6KL_FW_CAPABILITY_BMISS_ENHANCE, "bmiss-enhance" },
+       { ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST, "sscan-match-list" },
+       { ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD, "rssi-scan-thold" },
+       { ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR, "custom-mac-addr" },
+       { ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, "tx-err-notify" },
+       { ATH6KL_FW_CAPABILITY_REGDOMAIN, "regdomain" },
+       { ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, "sched-scan-v2" },
+       { ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL, "hb-poll" },
+};
+
+static const char *ath6kl_init_get_fw_capa_name(unsigned int id)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(fw_capa_map); i++) {
+               if (fw_capa_map[i].id == id)
+                       return fw_capa_map[i].name;
+       }
+
+       return "<unknown>";
+}
+
+static void ath6kl_init_get_fwcaps(struct ath6kl *ar, char *buf, size_t buf_len)
+{
+       u8 *data = (u8 *) ar->fw_capabilities;
+       size_t trunc_len, len = 0;
+       int i, index, bit;
+       char *trunc = "...";
+
+       for (i = 0; i < ATH6KL_FW_CAPABILITY_MAX; i++) {
+               index = i / 8;
+               bit = i % 8;
+
+               if (index >= sizeof(ar->fw_capabilities) * 4)
+                       break;
+
+               if (buf_len - len < 4) {
+                       ath6kl_warn("firmware capability buffer too small!\n");
+
+                       /* add "..." to the end of string */
+                       trunc_len = strlen(trunc) + 1;
+                       strncpy(buf + buf_len - trunc_len, trunc, trunc_len);
+
+                       return;
+               }
+
+               if (data[index] & (1 << bit)) {
+                       len += scnprintf(buf + len, buf_len - len, "%s,",
+                                           ath6kl_init_get_fw_capa_name(i));
+               }
+       }
+
+       /* overwrite the last comma */
+       if (len > 0)
+               len--;
+
+       buf[len] = '\0';
+}
+
+static int ath6kl_init_hw_reset(struct ath6kl *ar)
+{
+       ath6kl_dbg(ATH6KL_DBG_BOOT, "cold resetting the device");
+
+       return ath6kl_diag_write32(ar, RESET_CONTROL_ADDRESS,
+                                  cpu_to_le32(RESET_CONTROL_COLD_RST));
+}
+
 static int __ath6kl_init_hw_start(struct ath6kl *ar)
 {
        long timeleft;
        int ret, i;
+       char buf[200];
 
        ath6kl_dbg(ATH6KL_DBG_BOOT, "hw start\n");
 
@@ -1569,24 +1648,35 @@ static int __ath6kl_init_hw_start(struct ath6kl *ar)
                goto err_power_off;
 
        /* Do we need to finish the BMI phase */
-       /* FIXME: return error from ath6kl_bmi_done() */
-       if (ath6kl_bmi_done(ar)) {
-               ret = -EIO;
+       ret = ath6kl_bmi_done(ar);
+       if (ret)
                goto err_power_off;
-       }
 
        /*
         * The reason we have to wait for the target here is that the
         * driver layer has to init BMI in order to set the host block
         * size.
         */
-       if (ath6kl_htc_wait_target(ar->htc_target)) {
-               ret = -EIO;
+       ret = ath6kl_htc_wait_target(ar->htc_target);
+
+       if (ret == -ETIMEDOUT) {
+               /*
+                * Most likely USB target is in odd state after reboot and
+                * needs a reset. A cold reset makes the whole device
+                * disappear from USB bus and initialisation starts from
+                * beginning.
+                */
+               ath6kl_warn("htc wait target timed out, resetting device\n");
+               ath6kl_init_hw_reset(ar);
+               goto err_power_off;
+       } else if (ret) {
+               ath6kl_err("htc wait target failed: %d\n", ret);
                goto err_power_off;
        }
 
-       if (ath6kl_init_service_ep(ar)) {
-               ret = -EIO;
+       ret = ath6kl_init_service_ep(ar);
+       if (ret) {
+               ath6kl_err("Endpoint service initilisation failed: %d\n", ret);
                goto err_cleanup_scatter;
        }
 
@@ -1617,6 +1707,8 @@ static int __ath6kl_init_hw_start(struct ath6kl *ar)
                            ar->wiphy->fw_version,
                            ar->fw_api,
                            test_bit(TESTMODE, &ar->flag) ? " testmode" : "");
+               ath6kl_init_get_fwcaps(ar, buf, sizeof(buf));
+               ath6kl_info("firmware supports: %s\n", buf);
        }
 
        if (ar->version.abi_ver != ATH6KL_ABI_VERSION) {
@@ -1765,9 +1857,7 @@ void ath6kl_stop_txrx(struct ath6kl *ar)
         * Try to reset the device if we can. The driver may have been
         * configure NOT to reset the target during a debug session.
         */
-       ath6kl_dbg(ATH6KL_DBG_TRC,
-                  "attempting to reset target on instance destroy\n");
-       ath6kl_reset_device(ar, ar->target_type, true, true);
+       ath6kl_init_hw_reset(ar);
 
        up(&ar->sem);
 }
index bd50b6b7b49267665e8854e388dd068fab63707b..d4fcfcad57d03df4d612708978286997c4c42a9e 100644 (file)
@@ -345,39 +345,6 @@ out:
        return ret;
 }
 
-/* FIXME: move to a better place, target.h? */
-#define AR6003_RESET_CONTROL_ADDRESS 0x00004000
-#define AR6004_RESET_CONTROL_ADDRESS 0x00004000
-
-void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
-                        bool wait_fot_compltn, bool cold_reset)
-{
-       int status = 0;
-       u32 address;
-       __le32 data;
-
-       if (target_type != TARGET_TYPE_AR6003 &&
-           target_type != TARGET_TYPE_AR6004)
-               return;
-
-       data = cold_reset ? cpu_to_le32(RESET_CONTROL_COLD_RST) :
-                           cpu_to_le32(RESET_CONTROL_MBOX_RST);
-
-       switch (target_type) {
-       case TARGET_TYPE_AR6003:
-               address = AR6003_RESET_CONTROL_ADDRESS;
-               break;
-       case TARGET_TYPE_AR6004:
-               address = AR6004_RESET_CONTROL_ADDRESS;
-               break;
-       }
-
-       status = ath6kl_diag_write32(ar, address, data);
-
-       if (status)
-               ath6kl_err("failed to reset target\n");
-}
-
 static void ath6kl_install_static_wep_keys(struct ath6kl_vif *vif)
 {
        u8 index;
@@ -1327,9 +1294,11 @@ void init_netdev(struct net_device *dev)
        dev->watchdog_timeo = ATH6KL_TX_TIMEOUT;
 
        dev->needed_headroom = ETH_HLEN;
-       dev->needed_headroom += sizeof(struct ath6kl_llc_snap_hdr) +
-                               sizeof(struct wmi_data_hdr) + HTC_HDR_LENGTH
-                               + WMI_MAX_TX_META_SZ + ATH6KL_HTC_ALIGN_BYTES;
+       dev->needed_headroom += roundup(sizeof(struct ath6kl_llc_snap_hdr) +
+                                       sizeof(struct wmi_data_hdr) +
+                                       HTC_HDR_LENGTH +
+                                       WMI_MAX_TX_META_SZ +
+                                       ATH6KL_HTC_ALIGN_BYTES, 4);
 
        dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
 
index d111980d44c0bb9b550b0733322b663a6842c6c8..fb141454c6d2f3c9de1d82135aeace81b69276fd 100644 (file)
@@ -28,6 +28,7 @@
 #include "target.h"
 #include "debug.h"
 #include "cfg80211.h"
+#include "trace.h"
 
 struct ath6kl_sdio {
        struct sdio_func *func;
@@ -179,6 +180,8 @@ static int ath6kl_sdio_io(struct sdio_func *func, u32 request, u32 addr,
                   request & HIF_FIXED_ADDRESS ? " (fixed)" : "", buf, len);
        ath6kl_dbg_dump(ATH6KL_DBG_SDIO_DUMP, NULL, "sdio ", buf, len);
 
+       trace_ath6kl_sdio(addr, request, buf, len);
+
        return ret;
 }
 
@@ -309,6 +312,13 @@ static int ath6kl_sdio_scat_rw(struct ath6kl_sdio *ar_sdio,
        sdio_claim_host(ar_sdio->func);
 
        mmc_set_data_timeout(&data, ar_sdio->func->card);
+
+       trace_ath6kl_sdio_scat(scat_req->addr,
+                              scat_req->req,
+                              scat_req->len,
+                              scat_req->scat_entries,
+                              scat_req->scat_list);
+
        /* synchronous call to process request */
        mmc_wait_for_req(ar_sdio->func->card->host, &mmc_req);
 
@@ -1123,10 +1133,12 @@ static int ath6kl_sdio_bmi_write(struct ath6kl *ar, u8 *buf, u32 len)
 
        ret = ath6kl_sdio_read_write_sync(ar, addr, buf, len,
                                          HIF_WR_SYNC_BYTE_INC);
-       if (ret)
+       if (ret) {
                ath6kl_err("unable to send the bmi data to the device\n");
+               return ret;
+       }
 
-       return ret;
+       return 0;
 }
 
 static int ath6kl_sdio_bmi_read(struct ath6kl *ar, u8 *buf, u32 len)
index a98c12ba70c1dfa32aa0d3fbd25a76852d5df22b..a580a629a0da6ba24b251dab8147e7de74c34f7c 100644 (file)
@@ -25,7 +25,7 @@
 #define AR6004_BOARD_DATA_SZ     6144
 #define AR6004_BOARD_EXT_DATA_SZ 0
 
-#define RESET_CONTROL_ADDRESS          0x00000000
+#define RESET_CONTROL_ADDRESS          0x00004000
 #define RESET_CONTROL_COLD_RST         0x00000100
 #define RESET_CONTROL_MBOX_RST         0x00000004
 
diff --git a/drivers/net/wireless/ath/ath6kl/trace.c b/drivers/net/wireless/ath/ath6kl/trace.c
new file mode 100644 (file)
index 0000000..e7d64b1
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2012 Qualcomm Atheros, Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/module.h>
+
+#define CREATE_TRACE_POINTS
+#include "trace.h"
+
+EXPORT_TRACEPOINT_SYMBOL(ath6kl_sdio);
+EXPORT_TRACEPOINT_SYMBOL(ath6kl_sdio_scat);
diff --git a/drivers/net/wireless/ath/ath6kl/trace.h b/drivers/net/wireless/ath/ath6kl/trace.h
new file mode 100644 (file)
index 0000000..6af6fa0
--- /dev/null
@@ -0,0 +1,332 @@
+#if !defined(_ATH6KL_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
+
+#include <net/cfg80211.h>
+#include <linux/skbuff.h>
+#include <linux/tracepoint.h>
+#include "wmi.h"
+#include "hif.h"
+
+#if !defined(_ATH6KL_TRACE_H)
+static inline unsigned int ath6kl_get_wmi_id(void *buf, size_t buf_len)
+{
+       struct wmi_cmd_hdr *hdr = buf;
+
+       if (buf_len < sizeof(*hdr))
+               return 0;
+
+       return le16_to_cpu(hdr->cmd_id);
+}
+#endif /* __ATH6KL_TRACE_H */
+
+#define _ATH6KL_TRACE_H
+
+/* create empty functions when tracing is disabled */
+#if !defined(CONFIG_ATH6KL_TRACING)
+#undef TRACE_EVENT
+#define TRACE_EVENT(name, proto, ...) \
+static inline void trace_ ## name(proto) {}
+#undef DECLARE_EVENT_CLASS
+#define DECLARE_EVENT_CLASS(...)
+#undef DEFINE_EVENT
+#define DEFINE_EVENT(evt_class, name, proto, ...) \
+static inline void trace_ ## name(proto) {}
+#endif /* !CONFIG_ATH6KL_TRACING || __CHECKER__ */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM ath6kl
+
+TRACE_EVENT(ath6kl_wmi_cmd,
+       TP_PROTO(void *buf, size_t buf_len),
+
+       TP_ARGS(buf, buf_len),
+
+       TP_STRUCT__entry(
+               __field(unsigned int, id)
+               __field(size_t, buf_len)
+               __dynamic_array(u8, buf, buf_len)
+       ),
+
+       TP_fast_assign(
+               __entry->id = ath6kl_get_wmi_id(buf, buf_len);
+               __entry->buf_len = buf_len;
+               memcpy(__get_dynamic_array(buf), buf, buf_len);
+       ),
+
+       TP_printk(
+               "id %d len %d",
+               __entry->id, __entry->buf_len
+       )
+);
+
+TRACE_EVENT(ath6kl_wmi_event,
+       TP_PROTO(void *buf, size_t buf_len),
+
+       TP_ARGS(buf, buf_len),
+
+       TP_STRUCT__entry(
+               __field(unsigned int, id)
+               __field(size_t, buf_len)
+               __dynamic_array(u8, buf, buf_len)
+       ),
+
+       TP_fast_assign(
+               __entry->id = ath6kl_get_wmi_id(buf, buf_len);
+               __entry->buf_len = buf_len;
+               memcpy(__get_dynamic_array(buf), buf, buf_len);
+       ),
+
+       TP_printk(
+               "id %d len %d",
+               __entry->id, __entry->buf_len
+       )
+);
+
+TRACE_EVENT(ath6kl_sdio,
+       TP_PROTO(unsigned int addr, int flags,
+                void *buf, size_t buf_len),
+
+       TP_ARGS(addr, flags, buf, buf_len),
+
+       TP_STRUCT__entry(
+               __field(unsigned int, tx)
+               __field(unsigned int, addr)
+               __field(int, flags)
+               __field(size_t, buf_len)
+               __dynamic_array(u8, buf, buf_len)
+       ),
+
+       TP_fast_assign(
+               __entry->addr = addr;
+               __entry->flags = flags;
+               __entry->buf_len = buf_len;
+               memcpy(__get_dynamic_array(buf), buf, buf_len);
+
+               if (flags & HIF_WRITE)
+                       __entry->tx = 1;
+               else
+                       __entry->tx = 0;
+       ),
+
+       TP_printk(
+               "%s addr 0x%x flags 0x%x len %d\n",
+               __entry->tx ? "tx" : "rx",
+               __entry->addr,
+               __entry->flags,
+               __entry->buf_len
+       )
+);
+
+TRACE_EVENT(ath6kl_sdio_scat,
+       TP_PROTO(unsigned int addr, int flags, unsigned int total_len,
+                unsigned int entries, struct hif_scatter_item *list),
+
+       TP_ARGS(addr, flags, total_len, entries, list),
+
+       TP_STRUCT__entry(
+               __field(unsigned int, tx)
+               __field(unsigned int, addr)
+               __field(int, flags)
+               __field(unsigned int, entries)
+               __field(size_t, total_len)
+               __dynamic_array(unsigned int, len_array, entries)
+               __dynamic_array(u8, data, total_len)
+       ),
+
+       TP_fast_assign(
+               unsigned int *len_array;
+               int i, offset = 0;
+               size_t len;
+
+               __entry->addr = addr;
+               __entry->flags = flags;
+               __entry->entries = entries;
+               __entry->total_len = total_len;
+
+               if (flags & HIF_WRITE)
+                       __entry->tx = 1;
+               else
+                       __entry->tx = 0;
+
+               len_array = __get_dynamic_array(len_array);
+
+               for (i = 0; i < entries; i++) {
+                       len = list[i].len;
+
+                       memcpy((u8 *) __get_dynamic_array(data) + offset,
+                              list[i].buf, len);
+
+                       len_array[i] = len;
+                       offset += len;
+               }
+       ),
+
+       TP_printk(
+               "%s addr 0x%x flags 0x%x entries %d total_len %d\n",
+               __entry->tx ? "tx" : "rx",
+               __entry->addr,
+               __entry->flags,
+               __entry->entries,
+               __entry->total_len
+       )
+);
+
+TRACE_EVENT(ath6kl_sdio_irq,
+       TP_PROTO(void *buf, size_t buf_len),
+
+       TP_ARGS(buf, buf_len),
+
+       TP_STRUCT__entry(
+               __field(size_t, buf_len)
+               __dynamic_array(u8, buf, buf_len)
+       ),
+
+       TP_fast_assign(
+               __entry->buf_len = buf_len;
+               memcpy(__get_dynamic_array(buf), buf, buf_len);
+       ),
+
+       TP_printk(
+               "irq len %d\n", __entry->buf_len
+       )
+);
+
+TRACE_EVENT(ath6kl_htc_rx,
+       TP_PROTO(int status, int endpoint, void *buf,
+                size_t buf_len),
+
+       TP_ARGS(status, endpoint, buf, buf_len),
+
+       TP_STRUCT__entry(
+               __field(int, status)
+               __field(int, endpoint)
+               __field(size_t, buf_len)
+               __dynamic_array(u8, buf, buf_len)
+       ),
+
+       TP_fast_assign(
+               __entry->status = status;
+               __entry->endpoint = endpoint;
+               __entry->buf_len = buf_len;
+               memcpy(__get_dynamic_array(buf), buf, buf_len);
+       ),
+
+       TP_printk(
+               "status %d endpoint %d len %d\n",
+               __entry->status,
+               __entry->endpoint,
+               __entry->buf_len
+       )
+);
+
+TRACE_EVENT(ath6kl_htc_tx,
+       TP_PROTO(int status, int endpoint, void *buf,
+                size_t buf_len),
+
+       TP_ARGS(status, endpoint, buf, buf_len),
+
+       TP_STRUCT__entry(
+               __field(int, status)
+               __field(int, endpoint)
+               __field(size_t, buf_len)
+               __dynamic_array(u8, buf, buf_len)
+       ),
+
+       TP_fast_assign(
+               __entry->status = status;
+               __entry->endpoint = endpoint;
+               __entry->buf_len = buf_len;
+               memcpy(__get_dynamic_array(buf), buf, buf_len);
+       ),
+
+       TP_printk(
+               "status %d endpoint %d len %d\n",
+               __entry->status,
+               __entry->endpoint,
+               __entry->buf_len
+       )
+);
+
+#define ATH6KL_MSG_MAX 200
+
+DECLARE_EVENT_CLASS(ath6kl_log_event,
+       TP_PROTO(struct va_format *vaf),
+       TP_ARGS(vaf),
+       TP_STRUCT__entry(
+               __dynamic_array(char, msg, ATH6KL_MSG_MAX)
+       ),
+       TP_fast_assign(
+               WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
+                                      ATH6KL_MSG_MAX,
+                                      vaf->fmt,
+                                      *vaf->va) >= ATH6KL_MSG_MAX);
+       ),
+       TP_printk("%s", __get_str(msg))
+);
+
+DEFINE_EVENT(ath6kl_log_event, ath6kl_log_err,
+            TP_PROTO(struct va_format *vaf),
+            TP_ARGS(vaf)
+);
+
+DEFINE_EVENT(ath6kl_log_event, ath6kl_log_warn,
+            TP_PROTO(struct va_format *vaf),
+            TP_ARGS(vaf)
+);
+
+DEFINE_EVENT(ath6kl_log_event, ath6kl_log_info,
+            TP_PROTO(struct va_format *vaf),
+            TP_ARGS(vaf)
+);
+
+TRACE_EVENT(ath6kl_log_dbg,
+       TP_PROTO(unsigned int level, struct va_format *vaf),
+       TP_ARGS(level, vaf),
+       TP_STRUCT__entry(
+               __field(unsigned int, level)
+               __dynamic_array(char, msg, ATH6KL_MSG_MAX)
+       ),
+       TP_fast_assign(
+               __entry->level = level;
+               WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
+                                      ATH6KL_MSG_MAX,
+                                      vaf->fmt,
+                                      *vaf->va) >= ATH6KL_MSG_MAX);
+       ),
+       TP_printk("%s", __get_str(msg))
+);
+
+TRACE_EVENT(ath6kl_log_dbg_dump,
+       TP_PROTO(const char *msg, const char *prefix,
+                const void *buf, size_t buf_len),
+
+       TP_ARGS(msg, prefix, buf, buf_len),
+
+       TP_STRUCT__entry(
+               __string(msg, msg)
+               __string(prefix, prefix)
+               __field(size_t, buf_len)
+               __dynamic_array(u8, buf, buf_len)
+       ),
+
+       TP_fast_assign(
+               __assign_str(msg, msg);
+               __assign_str(prefix, prefix);
+               __entry->buf_len = buf_len;
+               memcpy(__get_dynamic_array(buf), buf, buf_len);
+       ),
+
+       TP_printk(
+               "%s/%s\n", __get_str(prefix), __get_str(msg)
+       )
+);
+
+#endif /* _ ATH6KL_TRACE_H || TRACE_HEADER_MULTI_READ*/
+
+/* we don't want to use include/trace/events */
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE trace
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
index 78b369286579dd954f98243a24e948db2a4f3c2b..ebb24045a8ae6cbcac844a239d11a05ee6f86e14 100644 (file)
@@ -20,6 +20,7 @@
 #include "core.h"
 #include "debug.h"
 #include "htc-ops.h"
+#include "trace.h"
 
 /*
  * tid - tid_mux0..tid_mux3
@@ -288,6 +289,8 @@ int ath6kl_control_tx(void *devt, struct sk_buff *skb,
        int status = 0;
        struct ath6kl_cookie *cookie = NULL;
 
+       trace_ath6kl_wmi_cmd(skb->data, skb->len);
+
        if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW)) {
                dev_kfree_skb(skb);
                return -EACCES;
@@ -1324,7 +1327,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
                   __func__, ar, ept, skb, packet->buf,
                   packet->act_len, status);
 
-       if (status || !(skb->data + HTC_HDR_LENGTH)) {
+       if (status || packet->act_len < HTC_HDR_LENGTH) {
                dev_kfree_skb(skb);
                return;
        }
index 5fcd342762dedfee03bfe899cd7dd2e3d2bd6382..bed0d337712d3a6427fe5cee0a66e585fbd92fa9 100644 (file)
@@ -856,11 +856,9 @@ static int ath6kl_usb_submit_ctrl_out(struct ath6kl_usb *ar_usb,
        int ret;
 
        if (size > 0) {
-               buf = kmalloc(size, GFP_KERNEL);
+               buf = kmemdup(data, size, GFP_KERNEL);
                if (buf == NULL)
                        return -ENOMEM;
-
-               memcpy(buf, data, size);
        }
 
        /* note: if successful returns number of bytes transfered */
@@ -872,8 +870,9 @@ static int ath6kl_usb_submit_ctrl_out(struct ath6kl_usb *ar_usb,
                              size, 1000);
 
        if (ret < 0) {
-               ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n",
-                          __func__, ret);
+               ath6kl_warn("Failed to submit usb control message: %d\n", ret);
+               kfree(buf);
+               return ret;
        }
 
        kfree(buf);
@@ -903,8 +902,9 @@ static int ath6kl_usb_submit_ctrl_in(struct ath6kl_usb *ar_usb,
                                 size, 2 * HZ);
 
        if (ret < 0) {
-               ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n",
-                          __func__, ret);
+               ath6kl_warn("Failed to read usb control message: %d\n", ret);
+               kfree(buf);
+               return ret;
        }
 
        memcpy((u8 *) data, buf, size);
@@ -961,8 +961,10 @@ static int ath6kl_usb_diag_read32(struct ath6kl *ar, u32 address, u32 *data)
                                ATH6KL_USB_CONTROL_REQ_DIAG_RESP,
                                ar_usb->diag_resp_buffer, &resp_len);
 
-       if (ret)
+       if (ret) {
+               ath6kl_warn("diag read32 failed: %d\n", ret);
                return ret;
+       }
 
        resp = (struct ath6kl_usb_ctrl_diag_resp_read *)
                ar_usb->diag_resp_buffer;
@@ -976,6 +978,7 @@ static int ath6kl_usb_diag_write32(struct ath6kl *ar, u32 address, __le32 data)
 {
        struct ath6kl_usb *ar_usb = ar->hif_priv;
        struct ath6kl_usb_ctrl_diag_cmd_write *cmd;
+       int ret;
 
        cmd = (struct ath6kl_usb_ctrl_diag_cmd_write *) ar_usb->diag_cmd_buffer;
 
@@ -984,12 +987,17 @@ static int ath6kl_usb_diag_write32(struct ath6kl *ar, u32 address, __le32 data)
        cmd->address = cpu_to_le32(address);
        cmd->value = data;
 
-       return ath6kl_usb_ctrl_msg_exchange(ar_usb,
-                                           ATH6KL_USB_CONTROL_REQ_DIAG_CMD,
-                                           (u8 *) cmd,
-                                           sizeof(*cmd),
-                                           0, NULL, NULL);
+       ret = ath6kl_usb_ctrl_msg_exchange(ar_usb,
+                                          ATH6KL_USB_CONTROL_REQ_DIAG_CMD,
+                                          (u8 *) cmd,
+                                          sizeof(*cmd),
+                                          0, NULL, NULL);
+       if (ret) {
+               ath6kl_warn("diag_write32 failed: %d\n", ret);
+               return ret;
+       }
 
+       return 0;
 }
 
 static int ath6kl_usb_bmi_read(struct ath6kl *ar, u8 *buf, u32 len)
@@ -1001,7 +1009,7 @@ static int ath6kl_usb_bmi_read(struct ath6kl *ar, u8 *buf, u32 len)
        ret = ath6kl_usb_submit_ctrl_in(ar_usb,
                                        ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP,
                                        0, 0, buf, len);
-       if (ret != 0) {
+       if (ret) {
                ath6kl_err("Unable to read the bmi data from the device: %d\n",
                           ret);
                return ret;
@@ -1019,7 +1027,7 @@ static int ath6kl_usb_bmi_write(struct ath6kl *ar, u8 *buf, u32 len)
        ret = ath6kl_usb_submit_ctrl_out(ar_usb,
                                         ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD,
                                         0, 0, buf, len);
-       if (ret != 0) {
+       if (ret) {
                ath6kl_err("unable to send the bmi data to the device: %d\n",
                           ret);
                return ret;
index d76b5bd81a0d50288633e6899ac9ba0f15f1746f..87aefb4c4c23c5d8355df9e3c30ba08a6855278e 100644 (file)
@@ -20,6 +20,7 @@
 #include "core.h"
 #include "debug.h"
 #include "testmode.h"
+#include "trace.h"
 #include "../regd.h"
 #include "../regd_common.h"
 
@@ -2028,6 +2029,9 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx,
                if (!sband)
                        continue;
 
+               if (WARN_ON(band >= ATH6KL_NUM_BANDS))
+                       break;
+
                ratemask = rates[band];
                supp_rates = sc->supp_rates[band].rates;
                num_rates = 0;
@@ -4086,6 +4090,8 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
                return -EINVAL;
        }
 
+       trace_ath6kl_wmi_event(skb->data, skb->len);
+
        return ath6kl_wmi_proc_events(wmi, skb);
 }