From 0e84f13bb3d2c05087ae99a9cf84b904a21fa5c5 Mon Sep 17 00:00:00 2001 From: Adam Williamson Date: Sep 10 2014 00:30:51 +0000 Subject: attempt to support Venue 8 Pro wireless (ath6kl backport + add ID) Backport the latest significant changes from ath6kl in 3.17, and add the SDIO ID of the V8P's wireless adapter. This should possibly make wireless work on the V8P. --- diff --git a/0001-ath6kl-Fix-ath6kl_bmi_read_hi32-macro.patch b/0001-ath6kl-Fix-ath6kl_bmi_read_hi32-macro.patch new file mode 100644 index 0000000..004f3ec --- /dev/null +++ b/0001-ath6kl-Fix-ath6kl_bmi_read_hi32-macro.patch @@ -0,0 +1,57 @@ +From 1c3d95edf026c6fb446f53913c61ff1036c469cd Mon Sep 17 00:00:00 2001 +From: Frederic Danis +Date: Mon, 2 Jun 2014 21:19:46 +0300 +Subject: [PATCH 1/8] ath6kl: Fix ath6kl_bmi_read_hi32 macro + +tmp may be used uninitialized if ath6kl_bmi_read() returns an error. + +Signed-off-by: Frederic Danis +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ath/ath6kl/bmi.h | 3 ++- + drivers/net/wireless/ath/ath6kl/init.c | 12 ++++++++++-- + 2 files changed, 12 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath6kl/bmi.h b/drivers/net/wireless/ath/ath6kl/bmi.h +index 18fdd69..397a52f 100644 +--- a/drivers/net/wireless/ath/ath6kl/bmi.h ++++ b/drivers/net/wireless/ath/ath6kl/bmi.h +@@ -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; \ + }) + +diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c +index d5ef211..6e1e699 100644 +--- a/drivers/net/wireless/ath/ath6kl/init.c ++++ b/drivers/net/wireless/ath/ath6kl/init.c +@@ -1161,11 +1161,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) { +-- +2.1.0 + diff --git a/0002-ath6kl-convert-ar6004-hardware-flags-to-firmware-fea.patch b/0002-ath6kl-convert-ar6004-hardware-flags-to-firmware-fea.patch new file mode 100644 index 0000000..31b7fc6 --- /dev/null +++ b/0002-ath6kl-convert-ar6004-hardware-flags-to-firmware-fea.patch @@ -0,0 +1,202 @@ +From eba95bceb4c9f537c6c8a5aeba4277e76599e269 Mon Sep 17 00:00:00 2001 +From: Kalle Valo +Date: Tue, 17 Jun 2014 12:40:52 +0300 +Subject: [PATCH 2/8] ath6kl: convert ar6004 hardware flags to firmware feature + flags + +The functionality defined through these flags were actually firmware features +which can change between firmware versions. To make it possible to support +different firmware versions with the same driver, convert the flags to firmware +feature flags. + +For backwards compatibility support for old ar6004 firmware FW +API 3 or smaller images we forcefully set the feature bits in the driver. +Starting from FW API 5 the firmware image needs to set them. + +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ath/ath6kl/cfg80211.c | 6 ++++-- + drivers/net/wireless/ath/ath6kl/core.c | 16 ++++++++++++++++ + drivers/net/wireless/ath/ath6kl/core.h | 12 +++++++++--- + drivers/net/wireless/ath/ath6kl/init.c | 16 +++++++--------- + drivers/net/wireless/ath/ath6kl/usb.c | 6 ++++-- + drivers/net/wireless/ath/ath6kl/wmi.c | 3 ++- + 6 files changed, 42 insertions(+), 17 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c +index 0e26f4a..d139f2a 100644 +--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c ++++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c +@@ -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; +diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c +index b0b6520..0df74b2 100644 +--- a/drivers/net/wireless/ath/ath6kl/core.c ++++ b/drivers/net/wireless/ath/ath6kl/core.c +@@ -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); +diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h +index 26b0f92..bd91c44 100644 +--- a/drivers/net/wireless/ath/ath6kl/core.h ++++ b/drivers/net/wireless/ath/ath6kl/core.h +@@ -136,6 +136,15 @@ 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, ++ + /* this needs to be last */ + ATH6KL_FW_CAPABILITY_MAX, + }; +@@ -149,9 +158,6 @@ 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), + }; + +diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c +index 6e1e699..ed086ea 100644 +--- a/drivers/net/wireless/ath/ath6kl/init.c ++++ b/drivers/net/wireless/ath/ath6kl/init.c +@@ -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, +@@ -154,9 +151,7 @@ static const struct ath6kl_hw hw_list[] = { + .board_addr = 0x436400, + .refclk_hz = 40000000, + .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, +@@ -1575,6 +1570,9 @@ 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" }, + }; + + static const char *ath6kl_init_get_fw_capa_name(unsigned int id) +diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c +index 3afc5a4..e5a9e7f 100644 +--- a/drivers/net/wireless/ath/ath6kl/usb.c ++++ b/drivers/net/wireless/ath/ath6kl/usb.c +@@ -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; +diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c +index 4d7f9e4..6ecc0a4 100644 +--- a/drivers/net/wireless/ath/ath6kl/wmi.c ++++ b/drivers/net/wireless/ath/ath6kl/wmi.c +@@ -2838,7 +2838,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); +-- +2.1.0 + diff --git a/0003-ath6kl-implement-rx-flush-for-htc-pipe.patch b/0003-ath6kl-implement-rx-flush-for-htc-pipe.patch new file mode 100644 index 0000000..77a1296 --- /dev/null +++ b/0003-ath6kl-implement-rx-flush-for-htc-pipe.patch @@ -0,0 +1,69 @@ +From b056397e98a9d7fb8fed9f5c837461f3dd8b0132 Mon Sep 17 00:00:00 2001 +From: Jessica Wu +Date: Tue, 17 Jun 2014 12:40:58 +0300 +Subject: [PATCH 3/8] ath6kl: implement rx flush for htc pipe + +rx flush was not implemented for htc pipe, add that now. Doesn't fix any known +issues. + +Also free the skb if htc control messages get canceled. + +Signed-off-by: Jessica Wu +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ath/ath6kl/htc_pipe.c | 32 +++++++++++++++++++++++++++--- + 1 file changed, 29 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath6kl/htc_pipe.c b/drivers/net/wireless/ath/ath6kl/htc_pipe.c +index 756fe52..ca1a18c 100644 +--- a/drivers/net/wireless/ath/ath6kl/htc_pipe.c ++++ b/drivers/net/wireless/ath/ath6kl/htc_pipe.c +@@ -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, +-- +2.1.0 + diff --git a/0004-ath6kl-don-t-set-hi_refclk_hz-if-hardware-version-do.patch b/0004-ath6kl-don-t-set-hi_refclk_hz-if-hardware-version-do.patch new file mode 100644 index 0000000..d000807 --- /dev/null +++ b/0004-ath6kl-don-t-set-hi_refclk_hz-if-hardware-version-do.patch @@ -0,0 +1,36 @@ +From 958e1be848c92006ee4b95190d3725daf3a70034 Mon Sep 17 00:00:00 2001 +From: Kalle Valo +Date: Tue, 17 Jun 2014 12:41:04 +0300 +Subject: [PATCH 4/8] ath6kl: don't set hi_refclk_hz if hardware version + doesn't need it + +Needed for ar6004 hw3.0 support. + +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ath/ath6kl/init.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c +index ed086ea..a0400a1 100644 +--- a/drivers/net/wireless/ath/ath6kl/init.c ++++ b/drivers/net/wireless/ath/ath6kl/init.c +@@ -624,9 +624,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; + } +-- +2.1.0 + diff --git a/0005-ath6kl-add-support-wmi-rate-tables-with-mcs15.patch b/0005-ath6kl-add-support-wmi-rate-tables-with-mcs15.patch new file mode 100644 index 0000000..41aa498 --- /dev/null +++ b/0005-ath6kl-add-support-wmi-rate-tables-with-mcs15.patch @@ -0,0 +1,193 @@ +From c1d32d3038ff4d366b837cedb95aeb1801730f2c Mon Sep 17 00:00:00 2001 +From: Jessica Wu +Date: Tue, 17 Jun 2014 12:41:10 +0300 +Subject: [PATCH 5/8] ath6kl: add support wmi rate tables with mcs15 + +Some of the firmware versions support rate tables up to mcs15, add support for +that. + +Signed-off-by: Jessica Wu +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ath/ath6kl/core.h | 3 ++ + drivers/net/wireless/ath/ath6kl/init.c | 1 + + drivers/net/wireless/ath/ath6kl/main.c | 11 ++++-- + drivers/net/wireless/ath/ath6kl/wmi.c | 69 ++++++++++++++++++++++++++++++++-- + drivers/net/wireless/ath/ath6kl/wmi.h | 2 +- + 5 files changed, 77 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h +index bd91c44..23a7763 100644 +--- a/drivers/net/wireless/ath/ath6kl/core.h ++++ b/drivers/net/wireless/ath/ath6kl/core.h +@@ -145,6 +145,9 @@ enum ath6kl_fw_capability { + /* 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, ++ + /* this needs to be last */ + ATH6KL_FW_CAPABILITY_MAX, + }; +diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c +index a0400a1..8cd0cdf 100644 +--- a/drivers/net/wireless/ath/ath6kl/init.c ++++ b/drivers/net/wireless/ath/ath6kl/init.c +@@ -1576,6 +1576,7 @@ static const struct fw_capa_str_map { + { 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" }, + }; + + static const char *ath6kl_init_get_fw_capa_name(unsigned int id) +diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c +index d565546..baa447f 100644 +--- a/drivers/net/wireless/ath/ath6kl/main.c ++++ b/drivers/net/wireless/ath/ath6kl/main.c +@@ -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; + +diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c +index 6ecc0a4..94df345 100644 +--- a/drivers/net/wireless/ath/ath6kl/wmi.c ++++ b/drivers/net/wireless/ath/ath6kl/wmi.c +@@ -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, +@@ -3280,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; +@@ -3293,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, +diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h +index 7809afb..8d4d885 100644 +--- a/drivers/net/wireless/ath/ath6kl/wmi.h ++++ b/drivers/net/wireless/ath/ath6kl/wmi.h +@@ -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); +-- +2.1.0 + diff --git a/0006-ath6kl-add-support-for-ar6004-hw3.0.patch b/0006-ath6kl-add-support-for-ar6004-hw3.0.patch new file mode 100644 index 0000000..461e025 --- /dev/null +++ b/0006-ath6kl-add-support-for-ar6004-hw3.0.patch @@ -0,0 +1,211 @@ +From 7880377012ef48bf75498648c3bcbcb60460ff28 Mon Sep 17 00:00:00 2001 +From: Jessica Wu +Date: Tue, 17 Jun 2014 12:41:16 +0300 +Subject: [PATCH 6/8] ath6kl: add support for ar6004 hw3.0 + +This change enables ath6kl driver to support ar6004 hw3.0. At the same time do +some fixes in firmware initialisation which applies to ar6004 hw1.3 as well. + +Signed-off-by: Jessica Wu +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ath/ath6kl/core.h | 21 ++++++++++++-- + drivers/net/wireless/ath/ath6kl/init.c | 52 +++++++++++++++++++++++++++++++--- + drivers/net/wireless/ath/ath6kl/main.c | 6 +++- + drivers/net/wireless/ath/ath6kl/usb.c | 1 + + 4 files changed, 73 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h +index 23a7763..2b78c86 100644 +--- a/drivers/net/wireless/ath/ath6kl/core.h ++++ b/drivers/net/wireless/ath/ath6kl/core.h +@@ -148,6 +148,9 @@ enum ath6kl_fw_capability { + /* 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, + }; +@@ -167,6 +170,7 @@ enum ath6kl_hw_flags { + #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 +@@ -224,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) +diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c +index 8cd0cdf..a6111848 100644 +--- a/drivers/net/wireless/ath/ath6kl/init.c ++++ b/drivers/net/wireless/ath/ath6kl/init.c +@@ -149,18 +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 = 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, ++ }, + }; + + /* +@@ -596,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; + +@@ -1110,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; +@@ -1236,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; + } +@@ -1367,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; +@@ -1577,6 +1620,7 @@ static const struct fw_capa_str_map { + { 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) +diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c +index baa447f..21516bc 100644 +--- a/drivers/net/wireless/ath/ath6kl/main.c ++++ b/drivers/net/wireless/ath/ath6kl/main.c +@@ -1293,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; +@@ -1304,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; + } +diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c +index e5a9e7f..c443258 100644 +--- a/drivers/net/wireless/ath/ath6kl/usb.c ++++ b/drivers/net/wireless/ath/ath6kl/usb.c +@@ -1210,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 */ }, + }; +-- +2.1.0 + diff --git a/kernel.spec b/kernel.spec index 77988b3..a094b6f 100644 --- a/kernel.spec +++ b/kernel.spec @@ -660,6 +660,17 @@ Patch31011: baytrail_gpio_quirk_v3.patch # Upstream 3.17 Patch31012: ASoC-Intel-update-baytrail-adsp-firmware-name.patch +# ath6kl series backported from 3.17, should make wireless work +Patch31101: 0001-ath6kl-Fix-ath6kl_bmi_read_hi32-macro.patch +Patch31102: 0002-ath6kl-convert-ar6004-hardware-flags-to-firmware-fea.patch +Patch31103: 0003-ath6kl-implement-rx-flush-for-htc-pipe.patch +Patch31104: 0004-ath6kl-don-t-set-hi_refclk_hz-if-hardware-version-do.patch +Patch31105: 0005-ath6kl-add-support-wmi-rate-tables-with-mcs15.patch +Patch31106: 0006-ath6kl-add-support-for-ar6004-hw3.0.patch + +# Add SDIO ID for the V8P wireless adapter to ath6kl driver +Patch31200: support-Dell-OEM-chipset-found-in-Venue-8-Pro-SDIO-I.patch + # END OF AWB PATCH DEFINITIONS # END OF PATCH DEFINITIONS @@ -1403,6 +1414,15 @@ ApplyPatch 0001-ACPI-temporary-dep-solution-for-battery-support.patch ApplyPatch ASoC-Intel-update-baytrail-adsp-firmware-name.patch +ApplyPatch 0001-ath6kl-Fix-ath6kl_bmi_read_hi32-macro.patch +ApplyPatch 0002-ath6kl-convert-ar6004-hardware-flags-to-firmware-fea.patch +ApplyPatch 0003-ath6kl-implement-rx-flush-for-htc-pipe.patch +ApplyPatch 0004-ath6kl-don-t-set-hi_refclk_hz-if-hardware-version-do.patch +ApplyPatch 0005-ath6kl-add-support-wmi-rate-tables-with-mcs15.patch +ApplyPatch 0006-ath6kl-add-support-for-ar6004-hw3.0.patch + +ApplyPatch support-Dell-OEM-chipset-found-in-Venue-8-Pro-SDIO-I.patch + # END OF AWB (BAYTRAIL) PATCH APPLICATIONS # END OF PATCH APPLICATIONS diff --git a/support-Dell-OEM-chipset-found-in-Venue-8-Pro-SDIO-I.patch b/support-Dell-OEM-chipset-found-in-Venue-8-Pro-SDIO-I.patch new file mode 100644 index 0000000..dbcd736 --- /dev/null +++ b/support-Dell-OEM-chipset-found-in-Venue-8-Pro-SDIO-I.patch @@ -0,0 +1,25 @@ +From da8b582fd0bf505d269d5d9e69f1607ea69d1d33 Mon Sep 17 00:00:00 2001 +From: Adam Williamson +Date: Tue, 9 Sep 2014 17:26:15 -0700 +Subject: [PATCH] support Dell OEM chipset found in Venue 8 Pro (SDIO ID + 0271:0418) + +--- + drivers/net/wireless/ath/ath6kl/sdio.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c +index 339d89f..5384f14 100644 +--- a/drivers/net/wireless/ath/ath6kl/sdio.c ++++ b/drivers/net/wireless/ath/ath6kl/sdio.c +@@ -1400,6 +1400,7 @@ static const struct sdio_device_id ath6kl_sdio_devices[] = { + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x1))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6004_BASE | 0x0))}, + {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6004_BASE | 0x1))}, ++ {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6004_BASE | 0x18))}, + {}, + }; + +-- +2.1.0 +