Merge tag 'for-linville-20140717' of git://github.com/kvalo/ath
authorJohn W. Linville <linville@tuxdriver.com>
Fri, 18 Jul 2014 17:44:50 +0000 (13:44 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 18 Jul 2014 17:44:50 +0000 (13:44 -0400)
19 files changed:
drivers/net/wireless/ath/ath10k/ce.c
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/htt.h
drivers/net/wireless/ath/ath10k/htt_tx.c
drivers/net/wireless/ath/ath10k/pci.c
drivers/net/wireless/ath/ath10k/pci.h
drivers/net/wireless/ath/ath10k/wmi.c
drivers/net/wireless/ath/ath6kl/bmi.h
drivers/net/wireless/ath/ath6kl/cfg80211.c
drivers/net/wireless/ath/ath6kl/core.c
drivers/net/wireless/ath/ath6kl/core.h
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/usb.c
drivers/net/wireless/ath/ath6kl/wmi.c
drivers/net/wireless/ath/ath6kl/wmi.h

index d185dc0cd12b2f739535a6bc6fe77020b0764133..4333107ecf37b8325c55f31569361a9b537dddc6 100644 (file)
@@ -603,16 +603,19 @@ static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
                if (ret)
                        return ret;
 
-               src_ring->hw_index =
-                       ath10k_ce_src_ring_read_index_get(ar, ctrl_addr);
-               src_ring->hw_index &= nentries_mask;
+               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;
 
-       if ((read_index == sw_index) || (read_index == 0xffffffff))
+       if (read_index == sw_index)
                return -EIO;
 
        sbase = src_ring->shadow_base;
index e6c56c5bb0f608c3c7377b06cb9d3ff491caee42..93adb8c5896926c787bb80e6c0869cd7f5fd4672 100644 (file)
@@ -802,7 +802,7 @@ int ath10k_core_start(struct ath10k *ar)
 
        INIT_LIST_HEAD(&ar->arvifs);
 
-       if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags))
+       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,
@@ -811,6 +811,12 @@ int ath10k_core_start(struct ath10k *ar)
                            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);
 
@@ -988,7 +994,9 @@ err_unregister_mac:
 err_release_fw:
        ath10k_core_free_firmware_files(ar);
 err:
-       device_release_driver(ar->dev);
+       /* TODO: It's probably a good idea to release device from the driver
+        * but calling device_release_driver() here will cause a deadlock.
+        */
        return;
 }
 
index 68ceef61933db6b769122ab2500fa524619ac465..83a5fa91531d159b9095ef0fff37db55c38e0eeb 100644 (file)
@@ -290,6 +290,9 @@ struct ath10k_debug {
        struct ath_dfs_pool_stats dfs_pool_stats;
 
        u32 fw_dbglog_mask;
+
+       u8 htt_max_amsdu;
+       u8 htt_max_ampdu;
 };
 
 enum ath10k_state {
index 1b7ff4ba122ce42af61265eae30d8fb98d97201e..3030158c478e86cd9ee193af14b29da614f0d168 100644 (file)
@@ -671,6 +671,72 @@ static const struct file_operations fops_htt_stats_mask = {
        .llseek = default_llseek,
 };
 
+static ssize_t ath10k_read_htt_max_amsdu_ampdu(struct file *file,
+                                              char __user *user_buf,
+                                              size_t count, loff_t *ppos)
+{
+       struct ath10k *ar = file->private_data;
+       char buf[64];
+       u8 amsdu = 3, ampdu = 64;
+       unsigned int len;
+
+       mutex_lock(&ar->conf_mutex);
+
+       if (ar->debug.htt_max_amsdu)
+               amsdu = ar->debug.htt_max_amsdu;
+
+       if (ar->debug.htt_max_ampdu)
+               ampdu = ar->debug.htt_max_ampdu;
+
+       mutex_unlock(&ar->conf_mutex);
+
+       len = scnprintf(buf, sizeof(buf), "%u %u\n", amsdu, ampdu);
+
+       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t ath10k_write_htt_max_amsdu_ampdu(struct file *file,
+                                               const char __user *user_buf,
+                                               size_t count, loff_t *ppos)
+{
+       struct ath10k *ar = file->private_data;
+       int res;
+       char buf[64];
+       unsigned int amsdu, ampdu;
+
+       simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count);
+
+       /* make sure that buf is null terminated */
+       buf[sizeof(buf) - 1] = 0;
+
+       res = sscanf(buf, "%u %u", &amsdu, &ampdu);
+
+       if (res != 2)
+               return -EINVAL;
+
+       mutex_lock(&ar->conf_mutex);
+
+       res = ath10k_htt_h2t_aggr_cfg_msg(&ar->htt, ampdu, amsdu);
+       if (res)
+               goto out;
+
+       res = count;
+       ar->debug.htt_max_amsdu = amsdu;
+       ar->debug.htt_max_ampdu = ampdu;
+
+out:
+       mutex_unlock(&ar->conf_mutex);
+       return res;
+}
+
+static const struct file_operations fops_htt_max_amsdu_ampdu = {
+       .read = ath10k_read_htt_max_amsdu_ampdu,
+       .write = ath10k_write_htt_max_amsdu_ampdu,
+       .open = simple_open,
+       .owner = THIS_MODULE,
+       .llseek = default_llseek,
+};
+
 static ssize_t ath10k_read_fw_dbglog(struct file *file,
                                            char __user *user_buf,
                                            size_t count, loff_t *ppos)
@@ -757,6 +823,9 @@ void ath10k_debug_stop(struct ath10k *ar)
         * warning from del_timer(). */
        if (ar->debug.htt_stats_mask != 0)
                cancel_delayed_work(&ar->debug.htt_stats_dwork);
+
+       ar->debug.htt_max_amsdu = 0;
+       ar->debug.htt_max_ampdu = 0;
 }
 
 static ssize_t ath10k_write_simulate_radar(struct file *file,
@@ -867,6 +936,10 @@ int ath10k_debug_create(struct ath10k *ar)
        debugfs_create_file("htt_stats_mask", S_IRUSR, ar->debug.debugfs_phy,
                            ar, &fops_htt_stats_mask);
 
+       debugfs_create_file("htt_max_amsdu_ampdu", S_IRUSR | S_IWUSR,
+                           ar->debug.debugfs_phy, ar,
+                           &fops_htt_max_amsdu_ampdu);
+
        debugfs_create_file("fw_dbglog", S_IRUSR, ar->debug.debugfs_phy,
                            ar, &fops_fw_dbglog);
 
index 9a263462c79353fa4b6a3c646ff6d025087c9463..6c93f3885ee571097eeb59f59e9d72e772c97ab7 100644 (file)
@@ -240,16 +240,10 @@ struct htt_oob_sync_req {
        __le16 rsvd0;
 } __packed;
 
-#define HTT_AGGR_CONF_MAX_NUM_AMSDU_SUBFRAMES_MASK 0x1F
-#define HTT_AGGR_CONF_MAX_NUM_AMSDU_SUBFRAMES_LSB  0
-
 struct htt_aggr_conf {
        u8 max_num_ampdu_subframes;
-       union {
-               /* dont use bitfields; undefined behaviour */
-               u8 flags; /* see %HTT_AGGR_CONF_MAX_NUM_AMSDU_SUBFRAMES_ */
-               u8 max_num_amsdu_subframes:5;
-       } __packed;
+       /* amsdu_subframes is limited by 0x1F mask */
+       u8 max_num_amsdu_subframes;
 } __packed;
 
 #define HTT_MGMT_FRM_HDR_DOWNLOAD_LEN 32
@@ -1343,6 +1337,9 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb);
 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);
 int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt);
+int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
+                               u8 max_subfrms_ampdu,
+                               u8 max_subfrms_amsdu);
 
 void __ath10k_htt_tx_dec_pending(struct ath10k_htt *htt);
 int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt);
index 7064354d1f4f0aa82f4624a7d878dea220aa4b2a..accb6b4f6fafedea2a2102b5c43c39e4835840b8 100644 (file)
@@ -307,6 +307,52 @@ int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt)
        return 0;
 }
 
+int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt,
+                               u8 max_subfrms_ampdu,
+                               u8 max_subfrms_amsdu)
+{
+       struct htt_aggr_conf *aggr_conf;
+       struct sk_buff *skb;
+       struct htt_cmd *cmd;
+       int len;
+       int ret;
+
+       /* Firmware defaults are: amsdu = 3 and ampdu = 64 */
+
+       if (max_subfrms_ampdu == 0 || max_subfrms_ampdu > 64)
+               return -EINVAL;
+
+       if (max_subfrms_amsdu == 0 || max_subfrms_amsdu > 31)
+               return -EINVAL;
+
+       len = sizeof(cmd->hdr);
+       len += sizeof(cmd->aggr_conf);
+
+       skb = ath10k_htc_alloc_skb(len);
+       if (!skb)
+               return -ENOMEM;
+
+       skb_put(skb, len);
+       cmd = (struct htt_cmd *)skb->data;
+       cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_AGGR_CFG;
+
+       aggr_conf = &cmd->aggr_conf;
+       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",
+                  aggr_conf->max_num_amsdu_subframes,
+                  aggr_conf->max_num_ampdu_subframes);
+
+       ret = ath10k_htc_send(&htt->ar->htc, htt->eid, skb);
+       if (ret) {
+               dev_kfree_skb_any(skb);
+               return ret;
+       }
+
+       return 0;
+}
+
 int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
 {
        struct device *dev = htt->ar->dev;
index d0004d59c97ec6c9292266662d9fd93cdd9eaf5e..06840d101c45cb74c9fd0655fa943b623cf1f7c6 100644 (file)
@@ -1362,8 +1362,6 @@ static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar,
                ath10k_ce_recv_buf_enqueue(ce_rx, &xfer, resp_paddr);
        }
 
-       init_completion(&xfer.done);
-
        ret = ath10k_ce_send(ce_tx, &xfer, req_paddr, req_len, -1, 0);
        if (ret)
                goto err_resp;
@@ -1414,10 +1412,7 @@ static void ath10k_pci_bmi_send_done(struct ath10k_ce_pipe *ce_state)
                                          &nbytes, &transfer_id))
                return;
 
-       if (xfer->wait_for_resp)
-               return;
-
-       complete(&xfer->done);
+       xfer->tx_done = true;
 }
 
 static void ath10k_pci_bmi_recv_data(struct ath10k_ce_pipe *ce_state)
@@ -1438,7 +1433,7 @@ static void ath10k_pci_bmi_recv_data(struct ath10k_ce_pipe *ce_state)
        }
 
        xfer->resp_len = nbytes;
-       complete(&xfer->done);
+       xfer->rx_done = true;
 }
 
 static int ath10k_pci_bmi_wait(struct ath10k_ce_pipe *tx_pipe,
@@ -1451,7 +1446,7 @@ static int ath10k_pci_bmi_wait(struct ath10k_ce_pipe *tx_pipe,
                ath10k_pci_bmi_send_done(tx_pipe);
                ath10k_pci_bmi_recv_data(rx_pipe);
 
-               if (completion_done(&xfer->done))
+               if (xfer->tx_done && (xfer->rx_done == xfer->wait_for_resp))
                        return 0;
 
                schedule();
index dfdebb4157aa177acde13ea1149b5a7490c5593e..940129209990337a1a99f79599014abc48b6b605 100644 (file)
@@ -38,7 +38,8 @@
 #define DIAG_TRANSFER_LIMIT 2048
 
 struct bmi_xfer {
-       struct completion done;
+       bool tx_done;
+       bool rx_done;
        bool wait_for_resp;
        u32 resp_len;
 };
index 4b7782a529ac6b03c6a1bcd764dabc6568b70a6b..6f83cae5765513eeb6b3efb803a657faa6bc5703 100644 (file)
@@ -2106,7 +2106,6 @@ static void ath10k_wmi_main_process_rx(struct ath10k *ar, struct sk_buff *skb)
 {
        struct wmi_cmd_hdr *cmd_hdr;
        enum wmi_event_id id;
-       u16 len;
 
        cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
        id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
@@ -2114,8 +2113,6 @@ static void ath10k_wmi_main_process_rx(struct ath10k *ar, struct sk_buff *skb)
        if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
                return;
 
-       len = skb->len;
-
        trace_ath10k_wmi_event(id, skb->data, skb->len);
 
        switch (id) {
@@ -2225,7 +2222,6 @@ static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb)
 {
        struct wmi_cmd_hdr *cmd_hdr;
        enum wmi_10x_event_id id;
-       u16 len;
 
        cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
        id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
@@ -2233,8 +2229,6 @@ static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb)
        if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
                return;
 
-       len = skb->len;
-
        trace_ath10k_wmi_event(id, skb->data, skb->len);
 
        switch (id) {
index 18fdd69e1f718dfd8eae5551d8fad9131613651f..397a52f2628b74e1f42a63c9a67d93f9c2407ffc 100644 (file)
@@ -242,7 +242,8 @@ struct ath6kl_bmi_target_info {
                (void) (check_type == val);                             \
                addr = ath6kl_get_hi_item_addr(ar, HI_ITEM(item));      \
                ret = ath6kl_bmi_read(ar, addr, (u8 *) &tmp, 4);        \
-               *val = le32_to_cpu(tmp);                                \
+               if (!ret)                                               \
+                       *val = le32_to_cpu(tmp);                        \
                ret;                                                    \
        })
 
index 0e26f4a34fda329910ecc278de9fe7bea8fa6c57..d139f2a7160a28120d423483070616529630e950 100644 (file)
@@ -2899,7 +2899,8 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
        if (info->inactivity_timeout) {
                inactivity_timeout = info->inactivity_timeout;
 
-               if (ar->hw.flags & ATH6KL_HW_AP_INACTIVITY_MINS)
+               if (test_bit(ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS,
+                            ar->fw_capabilities))
                        inactivity_timeout = DIV_ROUND_UP(inactivity_timeout,
                                                          60);
 
@@ -3782,7 +3783,8 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
                ath6kl_band_5ghz.ht_cap.ht_supported = false;
        }
 
-       if (ar->hw.flags & ATH6KL_HW_64BIT_RATES) {
+       if (test_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
+                    ar->fw_capabilities)) {
                ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
                ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
                ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff;
index b0b6520427600a05687e299318f78f873e3fd948..0df74b245af4c0180ea9219c8765453241aea9f0 100644 (file)
@@ -123,6 +123,22 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type)
 
        /* FIXME: we should free all firmwares in the error cases below */
 
+       /*
+        * Backwards compatibility support for older ar6004 firmware images
+        * which do not set these feature flags.
+        */
+       if (ar->target_type == TARGET_TYPE_AR6004 &&
+           ar->fw_api <= 4) {
+               __set_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
+                         ar->fw_capabilities);
+               __set_bit(ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS,
+                         ar->fw_capabilities);
+
+               if (ar->hw.id == AR6004_HW_1_3_VERSION)
+                       __set_bit(ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
+                                 ar->fw_capabilities);
+       }
+
        /* Indicate that WMI is enabled (although not ready yet) */
        set_bit(WMI_ENABLED, &ar->flag);
        ar->wmi = ath6kl_wmi_init(ar);
index 26b0f92424e16fb91beca55f3f07e9d907a9db04..2b78c863d03095b035991d3d123ea375b35a4cb6 100644 (file)
@@ -136,6 +136,21 @@ enum ath6kl_fw_capability {
         */
        ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL,
 
+       /* WMI_SET_TX_SELECT_RATES_CMDID uses 64 bit size rate table */
+       ATH6KL_FW_CAPABILITY_64BIT_RATES,
+
+       /* WMI_AP_CONN_INACT_CMDID uses minutes as units */
+       ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS,
+
+       /* use low priority endpoint for all data */
+       ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
+
+       /* ratetable is the 2 stream version (max MCS15) */
+       ATH6KL_FW_CAPABILITY_RATETABLE_MCS15,
+
+       /* firmare doesn't support IP checksumming */
+       ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM,
+
        /* this needs to be last */
        ATH6KL_FW_CAPABILITY_MAX,
 };
@@ -149,15 +164,13 @@ struct ath6kl_fw_ie {
 };
 
 enum ath6kl_hw_flags {
-       ATH6KL_HW_64BIT_RATES           = BIT(0),
-       ATH6KL_HW_AP_INACTIVITY_MINS    = BIT(1),
-       ATH6KL_HW_MAP_LP_ENDPOINT       = BIT(2),
        ATH6KL_HW_SDIO_CRC_ERROR_WAR    = BIT(3),
 };
 
 #define ATH6KL_FW_API2_FILE "fw-2.bin"
 #define ATH6KL_FW_API3_FILE "fw-3.bin"
 #define ATH6KL_FW_API4_FILE "fw-4.bin"
+#define ATH6KL_FW_API5_FILE "fw-5.bin"
 
 /* AR6003 1.0 definitions */
 #define AR6003_HW_1_0_VERSION                 0x300002ba
@@ -215,8 +228,21 @@ enum ath6kl_hw_flags {
 #define AR6004_HW_1_3_VERSION                  0x31c8088a
 #define AR6004_HW_1_3_FW_DIR                   "ath6k/AR6004/hw1.3"
 #define AR6004_HW_1_3_FIRMWARE_FILE            "fw.ram.bin"
-#define AR6004_HW_1_3_BOARD_DATA_FILE          "ath6k/AR6004/hw1.3/bdata.bin"
-#define AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE  "ath6k/AR6004/hw1.3/bdata.bin"
+#define AR6004_HW_1_3_TCMD_FIRMWARE_FILE       "utf.bin"
+#define AR6004_HW_1_3_UTF_FIRMWARE_FILE                "utf.bin"
+#define AR6004_HW_1_3_TESTSCRIPT_FILE          "nullTestFlow.bin"
+#define AR6004_HW_1_3_BOARD_DATA_FILE        AR6004_HW_1_3_FW_DIR "/bdata.bin"
+#define AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE AR6004_HW_1_3_FW_DIR "/bdata.bin"
+
+/* AR6004 3.0 definitions */
+#define AR6004_HW_3_0_VERSION                  0x31C809F8
+#define AR6004_HW_3_0_FW_DIR                   "ath6k/AR6004/hw3.0"
+#define AR6004_HW_3_0_FIRMWARE_FILE            "fw.ram.bin"
+#define AR6004_HW_3_0_TCMD_FIRMWARE_FILE       "utf.bin"
+#define AR6004_HW_3_0_UTF_FIRMWARE_FILE                "utf.bin"
+#define AR6004_HW_3_0_TESTSCRIPT_FILE          "nullTestFlow.bin"
+#define AR6004_HW_3_0_BOARD_DATA_FILE        AR6004_HW_3_0_FW_DIR "/bdata.bin"
+#define AR6004_HW_3_0_DEFAULT_BOARD_DATA_FILE AR6004_HW_3_0_FW_DIR "/bdata.bin"
 
 /* Per STA data, used in AP mode */
 #define STA_PS_AWAKE           BIT(0)
index 756fe52a12c8ad5a3496de58bbfec01d0ad9820b..ca1a18c86c0d79d64ad93f26f42fdaf87bcb6411 100644 (file)
@@ -1170,8 +1170,12 @@ static int htc_wait_recv_ctrl_message(struct htc_target *target)
 static void htc_rxctrl_complete(struct htc_target *context,
                                struct htc_packet *packet)
 {
-       /* TODO, can't really receive HTC control messages yet.... */
-       ath6kl_dbg(ATH6KL_DBG_HTC, "%s: invalid call function\n", __func__);
+       struct sk_buff *skb = packet->skb;
+
+       if (packet->endpoint == ENDPOINT_0 &&
+           packet->status == -ECANCELED &&
+           skb != NULL)
+               dev_kfree_skb(skb);
 }
 
 /* htc pipe initialization */
@@ -1678,7 +1682,29 @@ static void ath6kl_htc_pipe_activity_changed(struct htc_target *target,
 
 static void ath6kl_htc_pipe_flush_rx_buf(struct htc_target *target)
 {
-       /* TODO */
+       struct htc_endpoint *endpoint;
+       struct htc_packet *packet, *tmp_pkt;
+       int i;
+
+       for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
+               endpoint = &target->endpoint[i];
+
+               spin_lock_bh(&target->rx_lock);
+
+               list_for_each_entry_safe(packet, tmp_pkt,
+                                        &endpoint->rx_bufq, list) {
+                       list_del(&packet->list);
+                       spin_unlock_bh(&target->rx_lock);
+                       ath6kl_dbg(ATH6KL_DBG_HTC,
+                                  "htc rx flush pkt 0x%p len %d ep %d\n",
+                                  packet, packet->buf_len,
+                                  packet->endpoint);
+                       dev_kfree_skb(packet->pkt_cntxt);
+                       spin_lock_bh(&target->rx_lock);
+               }
+
+               spin_unlock_bh(&target->rx_lock);
+       }
 }
 
 static int ath6kl_htc_pipe_credit_setup(struct htc_target *target,
index d5ef211f261c2c19e6e8deeef985dc2b83130794..a61118484de6171b04ad004a0bb3a1be73d12c29 100644 (file)
@@ -93,8 +93,7 @@ static const struct ath6kl_hw hw_list[] = {
                .board_addr                     = 0x433900,
                .refclk_hz                      = 26000000,
                .uarttx_pin                     = 11,
-               .flags                          = ATH6KL_HW_64BIT_RATES |
-                                                 ATH6KL_HW_AP_INACTIVITY_MINS,
+               .flags                          = 0,
 
                .fw = {
                        .dir            = AR6004_HW_1_0_FW_DIR,
@@ -114,8 +113,7 @@ static const struct ath6kl_hw hw_list[] = {
                .board_addr                     = 0x43d400,
                .refclk_hz                      = 40000000,
                .uarttx_pin                     = 11,
-               .flags                          = ATH6KL_HW_64BIT_RATES |
-                                                 ATH6KL_HW_AP_INACTIVITY_MINS,
+               .flags                          = 0,
                .fw = {
                        .dir            = AR6004_HW_1_1_FW_DIR,
                        .fw             = AR6004_HW_1_1_FIRMWARE_FILE,
@@ -134,8 +132,7 @@ static const struct ath6kl_hw hw_list[] = {
                .board_addr                     = 0x435c00,
                .refclk_hz                      = 40000000,
                .uarttx_pin                     = 11,
-               .flags                          = ATH6KL_HW_64BIT_RATES |
-                                                 ATH6KL_HW_AP_INACTIVITY_MINS,
+               .flags                          = 0,
 
                .fw = {
                        .dir            = AR6004_HW_1_2_FW_DIR,
@@ -152,20 +149,43 @@ static const struct ath6kl_hw hw_list[] = {
                .board_ext_data_addr            = 0x437000,
                .reserved_ram_size              = 7168,
                .board_addr                     = 0x436400,
-               .refclk_hz                      = 40000000,
+               .refclk_hz                      = 0,
                .uarttx_pin                     = 11,
-               .flags                          = ATH6KL_HW_64BIT_RATES |
-                                                 ATH6KL_HW_AP_INACTIVITY_MINS |
-                                                 ATH6KL_HW_MAP_LP_ENDPOINT,
+               .flags                          = 0,
 
                .fw = {
                        .dir            = AR6004_HW_1_3_FW_DIR,
                        .fw             = AR6004_HW_1_3_FIRMWARE_FILE,
+                       .tcmd           = AR6004_HW_1_3_TCMD_FIRMWARE_FILE,
+                       .utf            = AR6004_HW_1_3_UTF_FIRMWARE_FILE,
+                       .testscript     = AR6004_HW_1_3_TESTSCRIPT_FILE,
                },
 
                .fw_board               = AR6004_HW_1_3_BOARD_DATA_FILE,
                .fw_default_board       = AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE,
        },
+       {
+               .id                             = AR6004_HW_3_0_VERSION,
+               .name                           = "ar6004 hw 3.0",
+               .dataset_patch_addr             = 0,
+               .app_load_addr                  = 0x1234,
+               .board_ext_data_addr            = 0,
+               .reserved_ram_size              = 7168,
+               .board_addr                     = 0x436400,
+               .testscript_addr                = 0,
+               .flags                          = 0,
+
+               .fw = {
+                       .dir            = AR6004_HW_3_0_FW_DIR,
+                       .fw             = AR6004_HW_3_0_FIRMWARE_FILE,
+                       .tcmd           = AR6004_HW_3_0_TCMD_FIRMWARE_FILE,
+                       .utf            = AR6004_HW_3_0_UTF_FIRMWARE_FILE,
+                       .testscript     = AR6004_HW_3_0_TESTSCRIPT_FILE,
+               },
+
+               .fw_board               = AR6004_HW_3_0_BOARD_DATA_FILE,
+               .fw_default_board       = AR6004_HW_3_0_DEFAULT_BOARD_DATA_FILE,
+       },
 };
 
 /*
@@ -601,7 +621,9 @@ int ath6kl_configure_target(struct ath6kl *ar)
         * but possible in theory.
         */
 
-       if (ar->target_type == TARGET_TYPE_AR6003) {
+       if ((ar->target_type == TARGET_TYPE_AR6003) ||
+           (ar->version.target_ver == AR6004_HW_1_3_VERSION) ||
+           (ar->version.target_ver == AR6004_HW_3_0_VERSION)) {
                param = ar->hw.board_ext_data_addr;
                ram_reserved_size = ar->hw.reserved_ram_size;
 
@@ -629,9 +651,12 @@ int ath6kl_configure_target(struct ath6kl *ar)
                return status;
 
        /* Configure target refclk_hz */
-       status = ath6kl_bmi_write_hi32(ar, hi_refclk_hz, ar->hw.refclk_hz);
-       if (status)
-               return status;
+       if (ar->hw.refclk_hz != 0) {
+               status = ath6kl_bmi_write_hi32(ar, hi_refclk_hz,
+                                              ar->hw.refclk_hz);
+               if (status)
+                       return status;
+       }
 
        return 0;
 }
@@ -1112,6 +1137,12 @@ int ath6kl_init_fetch_firmwares(struct ath6kl *ar)
        if (ret)
                return ret;
 
+       ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API5_FILE);
+       if (ret == 0) {
+               ar->fw_api = 5;
+               goto out;
+       }
+
        ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API4_FILE);
        if (ret == 0) {
                ar->fw_api = 4;
@@ -1161,11 +1192,19 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
                ath6kl_bmi_write_hi32(ar, hi_board_data,
                                      board_address);
        } else {
-               ath6kl_bmi_read_hi32(ar, hi_board_data, &board_address);
+               ret = ath6kl_bmi_read_hi32(ar, hi_board_data, &board_address);
+               if (ret) {
+                       ath6kl_err("Failed to get board file target address.\n");
+                       return ret;
+               }
        }
 
        /* determine where in target ram to write extended board data */
-       ath6kl_bmi_read_hi32(ar, hi_board_ext_data, &board_ext_address);
+       ret = ath6kl_bmi_read_hi32(ar, hi_board_ext_data, &board_ext_address);
+       if (ret) {
+               ath6kl_err("Failed to get extended board file target address.\n");
+               return ret;
+       }
 
        if (ar->target_type == TARGET_TYPE_AR6003 &&
            board_ext_address == 0) {
@@ -1230,7 +1269,13 @@ static int ath6kl_upload_board_file(struct ath6kl *ar)
        }
 
        /* record the fact that Board Data IS initialized */
-       ath6kl_bmi_write_hi32(ar, hi_board_data_initialized, 1);
+       if ((ar->version.target_ver == AR6004_HW_1_3_VERSION) ||
+           (ar->version.target_ver == AR6004_HW_3_0_VERSION))
+               param = board_data_size;
+       else
+               param = 1;
+
+       ath6kl_bmi_write_hi32(ar, hi_board_data_initialized, param);
 
        return ret;
 }
@@ -1361,7 +1406,11 @@ static int ath6kl_upload_testscript(struct ath6kl *ar)
        }
 
        ath6kl_bmi_write_hi32(ar, hi_ota_testscript, address);
-       ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, 4096);
+
+       if ((ar->version.target_ver != AR6004_HW_1_3_VERSION) &&
+           (ar->version.target_ver != AR6004_HW_3_0_VERSION))
+               ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, 4096);
+
        ath6kl_bmi_write_hi32(ar, hi_test_apps_related, 1);
 
        return 0;
@@ -1567,6 +1616,11 @@ static const struct fw_capa_str_map {
        { ATH6KL_FW_CAPABILITY_REGDOMAIN, "regdomain" },
        { ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, "sched-scan-v2" },
        { ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL, "hb-poll" },
+       { ATH6KL_FW_CAPABILITY_64BIT_RATES, "64bit-rates" },
+       { ATH6KL_FW_CAPABILITY_AP_INACTIVITY_MINS, "ap-inactivity-mins" },
+       { ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT, "map-lp-endpoint" },
+       { ATH6KL_FW_CAPABILITY_RATETABLE_MCS15, "ratetable-mcs15" },
+       { ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM, "no-ip-checksum" },
 };
 
 static const char *ath6kl_init_get_fw_capa_name(unsigned int id)
index d56554674da47924477c02423ad08c50caef2918..21516bc657857b8a44405c5c22944a275271e5f2 100644 (file)
@@ -702,6 +702,7 @@ static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
        struct ath6kl *ar = vif->ar;
        struct target_stats *stats = &vif->target_stats;
        struct tkip_ccmp_stats *ccmp_stats;
+       s32 rate;
        u8 ac;
 
        if (len < sizeof(*tgt_stats))
@@ -731,8 +732,9 @@ static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
                le32_to_cpu(tgt_stats->stats.tx.mult_retry_cnt);
        stats->tx_rts_fail_cnt +=
                le32_to_cpu(tgt_stats->stats.tx.rts_fail_cnt);
-       stats->tx_ucast_rate =
-           ath6kl_wmi_get_rate(a_sle32_to_cpu(tgt_stats->stats.tx.ucast_rate));
+
+       rate = a_sle32_to_cpu(tgt_stats->stats.tx.ucast_rate);
+       stats->tx_ucast_rate = ath6kl_wmi_get_rate(ar->wmi, rate);
 
        stats->rx_pkt += le32_to_cpu(tgt_stats->stats.rx.pkt);
        stats->rx_byte += le32_to_cpu(tgt_stats->stats.rx.byte);
@@ -749,8 +751,9 @@ static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)
                le32_to_cpu(tgt_stats->stats.rx.key_cache_miss);
        stats->rx_decrypt_err += le32_to_cpu(tgt_stats->stats.rx.decrypt_err);
        stats->rx_dupl_frame += le32_to_cpu(tgt_stats->stats.rx.dupl_frame);
-       stats->rx_ucast_rate =
-           ath6kl_wmi_get_rate(a_sle32_to_cpu(tgt_stats->stats.rx.ucast_rate));
+
+       rate = a_sle32_to_cpu(tgt_stats->stats.rx.ucast_rate);
+       stats->rx_ucast_rate = ath6kl_wmi_get_rate(ar->wmi, rate);
 
        ccmp_stats = &tgt_stats->stats.tkip_ccmp_stats;
 
@@ -1290,6 +1293,8 @@ static const struct net_device_ops ath6kl_netdev_ops = {
 
 void init_netdev(struct net_device *dev)
 {
+       struct ath6kl *ar = ath6kl_priv(dev);
+
        dev->netdev_ops = &ath6kl_netdev_ops;
        dev->destructor = free_netdev;
        dev->watchdog_timeo = ATH6KL_TX_TIMEOUT;
@@ -1301,7 +1306,9 @@ void init_netdev(struct net_device *dev)
                                        WMI_MAX_TX_META_SZ +
                                        ATH6KL_HTC_ALIGN_BYTES, 4);
 
-       dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
+       if (!test_bit(ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM,
+                     ar->fw_capabilities))
+               dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
 
        return;
 }
index 3afc5a463d06f822f339250deecfb1cefadea592..c44325856b81fc4cee191ec9aceb2102f2f0b23b 100644 (file)
@@ -802,7 +802,8 @@ static int ath6kl_usb_map_service_pipe(struct ath6kl *ar, u16 svc_id,
                break;
        case WMI_DATA_VI_SVC:
 
-               if (ar->hw.flags & ATH6KL_HW_MAP_LP_ENDPOINT)
+               if (test_bit(ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
+                            ar->fw_capabilities))
                        *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP;
                else
                        *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP;
@@ -814,7 +815,8 @@ static int ath6kl_usb_map_service_pipe(struct ath6kl *ar, u16 svc_id,
                break;
        case WMI_DATA_VO_SVC:
 
-               if (ar->hw.flags & ATH6KL_HW_MAP_LP_ENDPOINT)
+               if (test_bit(ATH6KL_FW_CAPABILITY_MAP_LP_ENDPOINT,
+                            ar->fw_capabilities))
                        *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP;
                else
                        *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP;
@@ -1208,6 +1210,7 @@ static int ath6kl_usb_pm_reset_resume(struct usb_interface *intf)
 
 /* table of devices that work with this driver */
 static struct usb_device_id ath6kl_usb_ids[] = {
+       {USB_DEVICE(0x0cf3, 0x9375)},
        {USB_DEVICE(0x0cf3, 0x9374)},
        { /* Terminating entry */ },
 };
index 4d7f9e4712e991deea8553f7505a7f79b9a6f6e7..94df345d08c24210fefe4b707079f85fe75e386f 100644 (file)
@@ -59,6 +59,55 @@ static const s32 wmi_rate_tbl[][2] = {
        {0, 0}
 };
 
+static const s32 wmi_rate_tbl_mcs15[][2] = {
+       /* {W/O SGI, with SGI} */
+       {1000, 1000},
+       {2000, 2000},
+       {5500, 5500},
+       {11000, 11000},
+       {6000, 6000},
+       {9000, 9000},
+       {12000, 12000},
+       {18000, 18000},
+       {24000, 24000},
+       {36000, 36000},
+       {48000, 48000},
+       {54000, 54000},
+       {6500, 7200},     /* HT 20, MCS 0 */
+       {13000, 14400},
+       {19500, 21700},
+       {26000, 28900},
+       {39000, 43300},
+       {52000, 57800},
+       {58500, 65000},
+       {65000, 72200},
+       {13000, 14400},   /* HT 20, MCS 8 */
+       {26000, 28900},
+       {39000, 43300},
+       {52000, 57800},
+       {78000, 86700},
+       {104000, 115600},
+       {117000, 130000},
+       {130000, 144400}, /* HT 20, MCS 15 */
+       {13500, 15000},   /*HT 40, MCS 0 */
+       {27000, 30000},
+       {40500, 45000},
+       {54000, 60000},
+       {81000, 90000},
+       {108000, 120000},
+       {121500, 135000},
+       {135000, 150000},
+       {27000, 30000},   /*HT 40, MCS 8 */
+       {54000, 60000},
+       {81000, 90000},
+       {108000, 120000},
+       {162000, 180000},
+       {216000, 240000},
+       {243000, 270000},
+       {270000, 300000}, /*HT 40, MCS 15 */
+       {0, 0}
+};
+
 /* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */
 static const u8 up_to_ac[] = {
        WMM_AC_BE,
@@ -2838,7 +2887,8 @@ int ath6kl_wmi_set_bitrate_mask(struct wmi *wmi, u8 if_idx,
 {
        struct ath6kl *ar = wmi->parent_dev;
 
-       if (ar->hw.flags & ATH6KL_HW_64BIT_RATES)
+       if (test_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES,
+                    ar->fw_capabilities))
                return ath6kl_set_bitrate_mask64(wmi, if_idx, mask);
        else
                return ath6kl_set_bitrate_mask32(wmi, if_idx, mask);
@@ -3279,9 +3329,11 @@ int ath6kl_wmi_set_regdomain_cmd(struct wmi *wmi, const char *alpha2)
                                   NO_SYNC_WMIFLAG);
 }
 
-s32 ath6kl_wmi_get_rate(s8 rate_index)
+s32 ath6kl_wmi_get_rate(struct wmi *wmi, s8 rate_index)
 {
+       struct ath6kl *ar = wmi->parent_dev;
        u8 sgi = 0;
+       s32 ret;
 
        if (rate_index == RATE_AUTO)
                return 0;
@@ -3292,10 +3344,20 @@ s32 ath6kl_wmi_get_rate(s8 rate_index)
                sgi = 1;
        }
 
-       if (WARN_ON(rate_index > RATE_MCS_7_40))
-               rate_index = RATE_MCS_7_40;
+       if (test_bit(ATH6KL_FW_CAPABILITY_RATETABLE_MCS15,
+                    ar->fw_capabilities)) {
+               if (WARN_ON(rate_index >= ARRAY_SIZE(wmi_rate_tbl_mcs15)))
+                       return 0;
+
+               ret = wmi_rate_tbl_mcs15[(u32) rate_index][sgi];
+       } else {
+               if (WARN_ON(rate_index >= ARRAY_SIZE(wmi_rate_tbl)))
+                       return 0;
 
-       return wmi_rate_tbl[(u32) rate_index][sgi];
+               ret = wmi_rate_tbl[(u32) rate_index][sgi];
+       }
+
+       return ret;
 }
 
 static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap,
index bb23fc00111dc6c3329762ee976ce93489015b90..19f88b4a24fbcef48bb31888abcd92a5bb0ce354 100644 (file)
@@ -2632,7 +2632,7 @@ int ath6kl_wmi_set_htcap_cmd(struct wmi *wmi, u8 if_idx,
                             struct ath6kl_htcap *htcap);
 int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len);
 
-s32 ath6kl_wmi_get_rate(s8 rate_index);
+s32 ath6kl_wmi_get_rate(struct wmi *wmi, s8 rate_index);
 
 int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx,
                          __be32 ips0, __be32 ips1);
This page took 0.044507 seconds and 5 git commands to generate.