mac80211: backport and update patches for ath10k
This commit refreshes and updates the VHT160 ath10k support fix patches and adds a number of backports from ath-next: * 8ed05ed06fca ath10k: handle tdls peer events * 229329ff345f ath10k: wmi: modify svc bitmap parsing for wcn3990 * 14d65775687c ath10k: advertise TDLS wider bandwidth support for 5GHz * bc64d05220f3 ath10k: debugfs support to get final TPC stats for 10.4 variants * 8b2d93dd2261 ath10k: Fix kernel panic while using worker (ath10k_sta_rc_update_wk) * 4b190675ad06 ath10k: fix kernel panic while reading tpc_stats * be8cce96f14d ath10k: add support to configure channel dwell time * f40105e67478 ath: add support to get the detected radar specifications * 6f6eb1bcbeff ath10k: DFS Host Confirmation * 260e629bbf44 ath10k: fix memory leak of tpc_stats * 38441fb6fcbb ath10k: support use of channel 173 * 2e9bcd0d7324 ath10k: fix spectral scan for QCA9984 and QCA9888 chipsets Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com> [move backported patches in the 3xx number space, bring in upstream order, replace incomplete patch files with git format-patch ones, rewrite commit message, fix subject] Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
parent
57b808ec88
commit
2dcd955aea
19 changed files with 2508 additions and 74 deletions
|
@ -0,0 +1,115 @@
|
|||
From 8ed05ed06fca0136cf4546e804318f57ef823348 Mon Sep 17 00:00:00 2001
|
||||
From: Manikanta Pubbisetty <mpubbise@qti.qualcomm.com>
|
||||
Date: Mon, 6 Nov 2017 13:39:32 +0530
|
||||
Subject: [PATCH] ath10k: handle tdls peer events
|
||||
|
||||
Handle tdls peer events from the target. TDLS events for the peer
|
||||
could be discover, teardown, etc. As of now, adding the logic to
|
||||
handle tdls teardown events alone.
|
||||
|
||||
Teardown due to peer traffic indication(PTR) timeout is one such
|
||||
teardown event from the target.
|
||||
|
||||
Tested this change on QCA9888 with 10.4-3.5.1-00018 fw version.
|
||||
|
||||
Signed-off-by: Manikanta Pubbisetty <mpubbise@qti.qualcomm.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
|
||||
---
|
||||
drivers/net/wireless/ath/ath10k/wmi.c | 72 +++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 72 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "p2p.h"
|
||||
#include "hw.h"
|
||||
#include "hif.h"
|
||||
+#include "txrx.h"
|
||||
|
||||
#define ATH10K_WMI_BARRIER_ECHO_ID 0xBA991E9
|
||||
#define ATH10K_WMI_BARRIER_TIMEOUT_HZ (3 * HZ)
|
||||
@@ -4456,6 +4457,74 @@ void ath10k_wmi_event_pdev_tpc_config(st
|
||||
__le32_to_cpu(ev->rate_max));
|
||||
}
|
||||
|
||||
+static void
|
||||
+ath10k_wmi_handle_tdls_peer_event(struct ath10k *ar, struct sk_buff *skb)
|
||||
+{
|
||||
+ struct wmi_tdls_peer_event *ev;
|
||||
+ struct ath10k_peer *peer;
|
||||
+ struct ath10k_vif *arvif;
|
||||
+ int vdev_id;
|
||||
+ int peer_status;
|
||||
+ int peer_reason;
|
||||
+ u8 reason;
|
||||
+
|
||||
+ if (skb->len < sizeof(*ev)) {
|
||||
+ ath10k_err(ar, "received tdls peer event with invalid size (%d bytes)\n",
|
||||
+ skb->len);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ev = (struct wmi_tdls_peer_event *)skb->data;
|
||||
+ vdev_id = __le32_to_cpu(ev->vdev_id);
|
||||
+ peer_status = __le32_to_cpu(ev->peer_status);
|
||||
+ peer_reason = __le32_to_cpu(ev->peer_reason);
|
||||
+
|
||||
+ spin_lock_bh(&ar->data_lock);
|
||||
+ peer = ath10k_peer_find(ar, vdev_id, ev->peer_macaddr.addr);
|
||||
+ spin_unlock_bh(&ar->data_lock);
|
||||
+
|
||||
+ if (!peer) {
|
||||
+ ath10k_warn(ar, "failed to find peer entry for %pM\n",
|
||||
+ ev->peer_macaddr.addr);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ switch (peer_status) {
|
||||
+ case WMI_TDLS_SHOULD_TEARDOWN:
|
||||
+ switch (peer_reason) {
|
||||
+ case WMI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT:
|
||||
+ case WMI_TDLS_TEARDOWN_REASON_NO_RESPONSE:
|
||||
+ case WMI_TDLS_TEARDOWN_REASON_RSSI:
|
||||
+ reason = WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE;
|
||||
+ break;
|
||||
+ default:
|
||||
+ reason = WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ arvif = ath10k_get_arvif(ar, vdev_id);
|
||||
+ if (!arvif) {
|
||||
+ ath10k_warn(ar, "received tdls peer event for invalid vdev id %u\n",
|
||||
+ vdev_id);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ieee80211_tdls_oper_request(arvif->vif, ev->peer_macaddr.addr,
|
||||
+ NL80211_TDLS_TEARDOWN, reason,
|
||||
+ GFP_ATOMIC);
|
||||
+
|
||||
+ ath10k_dbg(ar, ATH10K_DBG_WMI,
|
||||
+ "received tdls teardown event for peer %pM reason %u\n",
|
||||
+ ev->peer_macaddr.addr, peer_reason);
|
||||
+ break;
|
||||
+ default:
|
||||
+ ath10k_dbg(ar, ATH10K_DBG_WMI,
|
||||
+ "received unknown tdls peer event %u\n",
|
||||
+ peer_status);
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void ath10k_wmi_event_pdev_ftm_intg(struct ath10k *ar, struct sk_buff *skb)
|
||||
{
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_FTM_INTG_EVENTID\n");
|
||||
@@ -5478,6 +5547,9 @@ static void ath10k_wmi_10_4_op_rx(struct
|
||||
case WMI_10_4_PDEV_TPC_CONFIG_EVENTID:
|
||||
ath10k_wmi_event_pdev_tpc_config(ar, skb);
|
||||
break;
|
||||
+ case WMI_10_4_TDLS_PEER_EVENTID:
|
||||
+ ath10k_wmi_handle_tdls_peer_event(ar, skb);
|
||||
+ break;
|
||||
default:
|
||||
ath10k_warn(ar, "Unknown eventid: %d\n", id);
|
||||
break;
|
|
@ -0,0 +1,215 @@
|
|||
From 229329ff345f80c95202eaf2d7a0f2910c06144e Mon Sep 17 00:00:00 2001
|
||||
From: Rakesh Pillai <pillair@qti.qualcomm.com>
|
||||
Date: Mon, 11 Dec 2017 19:52:52 +0530
|
||||
Subject: [PATCH] ath10k: wmi: modify svc bitmap parsing for wcn3990
|
||||
|
||||
Due to the limitation of wmi tlv parsing logic, if there are
|
||||
two parameters in a wmi event with same tlv tag, we can get only
|
||||
the last value, as it overwrites the prev value of the same tlv tag.
|
||||
|
||||
The service ready event in wcn3990 contains two parameters of the
|
||||
same tag UINT32, due to which the svc bitmap is overwritten with the
|
||||
DBS support parameter.
|
||||
|
||||
Refactor the service ready event parsing to allow parsing two tlv
|
||||
of the same tag UINT32 for wcn3990.
|
||||
|
||||
Signed-off-by: Rakesh Pillai <pillair@qti.qualcomm.com>
|
||||
Signed-off-by: Govind Singh <govinds@qti.qualcomm.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
|
||||
---
|
||||
drivers/net/wireless/ath/ath10k/mac.c | 4 +-
|
||||
drivers/net/wireless/ath/ath10k/wmi-tlv.c | 61 ++++++++++++++++++++++++-------
|
||||
drivers/net/wireless/ath/ath10k/wmi-tlv.h | 46 +++++++++++++++++++++++
|
||||
drivers/net/wireless/ath/ath10k/wmi.h | 1 +
|
||||
4 files changed, 97 insertions(+), 15 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -3574,7 +3574,9 @@ ath10k_mac_tx_h_get_txpath(struct ath10k
|
||||
return ATH10K_MAC_TX_HTT;
|
||||
case ATH10K_HW_TXRX_MGMT:
|
||||
if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
|
||||
- ar->running_fw->fw_file.fw_features))
|
||||
+ ar->running_fw->fw_file.fw_features) ||
|
||||
+ test_bit(WMI_SERVICE_MGMT_TX_WMI,
|
||||
+ ar->wmi.svc_map))
|
||||
return ATH10K_MAC_TX_WMI_MGMT;
|
||||
else if (ar->htt.target_version_major >= 3)
|
||||
return ATH10K_MAC_TX_HTT;
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
|
||||
@@ -917,33 +917,69 @@ ath10k_wmi_tlv_parse_mem_reqs(struct ath
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
+struct wmi_tlv_svc_rdy_parse {
|
||||
+ const struct hal_reg_capabilities *reg;
|
||||
+ const struct wmi_tlv_svc_rdy_ev *ev;
|
||||
+ const __le32 *svc_bmap;
|
||||
+ const struct wlan_host_mem_req *mem_reqs;
|
||||
+ bool svc_bmap_done;
|
||||
+ bool dbs_hw_mode_done;
|
||||
+};
|
||||
+
|
||||
+static int ath10k_wmi_tlv_svc_rdy_parse(struct ath10k *ar, u16 tag, u16 len,
|
||||
+ const void *ptr, void *data)
|
||||
+{
|
||||
+ struct wmi_tlv_svc_rdy_parse *svc_rdy = data;
|
||||
+
|
||||
+ switch (tag) {
|
||||
+ case WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT:
|
||||
+ svc_rdy->ev = ptr;
|
||||
+ break;
|
||||
+ case WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES:
|
||||
+ svc_rdy->reg = ptr;
|
||||
+ break;
|
||||
+ case WMI_TLV_TAG_ARRAY_STRUCT:
|
||||
+ svc_rdy->mem_reqs = ptr;
|
||||
+ break;
|
||||
+ case WMI_TLV_TAG_ARRAY_UINT32:
|
||||
+ if (!svc_rdy->svc_bmap_done) {
|
||||
+ svc_rdy->svc_bmap_done = true;
|
||||
+ svc_rdy->svc_bmap = ptr;
|
||||
+ } else if (!svc_rdy->dbs_hw_mode_done) {
|
||||
+ svc_rdy->dbs_hw_mode_done = true;
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int ath10k_wmi_tlv_op_pull_svc_rdy_ev(struct ath10k *ar,
|
||||
struct sk_buff *skb,
|
||||
struct wmi_svc_rdy_ev_arg *arg)
|
||||
{
|
||||
- const void **tb;
|
||||
const struct hal_reg_capabilities *reg;
|
||||
const struct wmi_tlv_svc_rdy_ev *ev;
|
||||
const __le32 *svc_bmap;
|
||||
const struct wlan_host_mem_req *mem_reqs;
|
||||
+ struct wmi_tlv_svc_rdy_parse svc_rdy = { };
|
||||
int ret;
|
||||
|
||||
- tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
|
||||
- if (IS_ERR(tb)) {
|
||||
- ret = PTR_ERR(tb);
|
||||
+ ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len,
|
||||
+ ath10k_wmi_tlv_svc_rdy_parse, &svc_rdy);
|
||||
+ if (ret) {
|
||||
ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
- ev = tb[WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT];
|
||||
- reg = tb[WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES];
|
||||
- svc_bmap = tb[WMI_TLV_TAG_ARRAY_UINT32];
|
||||
- mem_reqs = tb[WMI_TLV_TAG_ARRAY_STRUCT];
|
||||
+ ev = svc_rdy.ev;
|
||||
+ reg = svc_rdy.reg;
|
||||
+ svc_bmap = svc_rdy.svc_bmap;
|
||||
+ mem_reqs = svc_rdy.mem_reqs;
|
||||
|
||||
- if (!ev || !reg || !svc_bmap || !mem_reqs) {
|
||||
- kfree(tb);
|
||||
+ if (!ev || !reg || !svc_bmap || !mem_reqs)
|
||||
return -EPROTO;
|
||||
- }
|
||||
|
||||
/* This is an internal ABI compatibility check for WMI TLV so check it
|
||||
* here instead of the generic WMI code.
|
||||
@@ -961,7 +997,6 @@ static int ath10k_wmi_tlv_op_pull_svc_rd
|
||||
__le32_to_cpu(ev->abi.abi_ver_ns1) != WMI_TLV_ABI_VER_NS1 ||
|
||||
__le32_to_cpu(ev->abi.abi_ver_ns2) != WMI_TLV_ABI_VER_NS2 ||
|
||||
__le32_to_cpu(ev->abi.abi_ver_ns3) != WMI_TLV_ABI_VER_NS3) {
|
||||
- kfree(tb);
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
@@ -982,12 +1017,10 @@ static int ath10k_wmi_tlv_op_pull_svc_rd
|
||||
ret = ath10k_wmi_tlv_iter(ar, mem_reqs, ath10k_wmi_tlv_len(mem_reqs),
|
||||
ath10k_wmi_tlv_parse_mem_reqs, arg);
|
||||
if (ret) {
|
||||
- kfree(tb);
|
||||
ath10k_warn(ar, "failed to parse mem_reqs tlv: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
- kfree(tb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h
|
||||
@@ -965,6 +965,50 @@ enum wmi_tlv_service {
|
||||
WMI_TLV_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT,
|
||||
WMI_TLV_SERVICE_MDNS_OFFLOAD,
|
||||
WMI_TLV_SERVICE_SAP_AUTH_OFFLOAD,
|
||||
+ WMI_TLV_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT,
|
||||
+ WMI_TLV_SERVICE_OCB,
|
||||
+ WMI_TLV_SERVICE_AP_ARPNS_OFFLOAD,
|
||||
+ WMI_TLV_SERVICE_PER_BAND_CHAINMASK_SUPPORT,
|
||||
+ WMI_TLV_SERVICE_PACKET_FILTER_OFFLOAD,
|
||||
+ WMI_TLV_SERVICE_MGMT_TX_HTT,
|
||||
+ WMI_TLV_SERVICE_MGMT_TX_WMI,
|
||||
+ WMI_TLV_SERVICE_EXT_MSG,
|
||||
+ WMI_TLV_SERVICE_MAWC,
|
||||
+ WMI_TLV_SERVICE_PEER_ASSOC_CONF,
|
||||
+ WMI_TLV_SERVICE_EGAP,
|
||||
+ WMI_TLV_SERVICE_STA_PMF_OFFLOAD,
|
||||
+ WMI_TLV_SERVICE_UNIFIED_WOW_CAPABILITY,
|
||||
+ WMI_TLV_SERVICE_ENHANCED_PROXY_STA,
|
||||
+ WMI_TLV_SERVICE_ATF,
|
||||
+ WMI_TLV_SERVICE_COEX_GPIO,
|
||||
+ WMI_TLV_SERVICE_AUX_SPECTRAL_INTF,
|
||||
+ WMI_TLV_SERVICE_AUX_CHAN_LOAD_INTF,
|
||||
+ WMI_TLV_SERVICE_BSS_CHANNEL_INFO_64,
|
||||
+ WMI_TLV_SERVICE_ENTERPRISE_MESH,
|
||||
+ WMI_TLV_SERVICE_RESTRT_CHNL_SUPPORT,
|
||||
+ WMI_TLV_SERVICE_BPF_OFFLOAD,
|
||||
+ WMI_TLV_SERVICE_SYNC_DELETE_CMDS,
|
||||
+ WMI_TLV_SERVICE_SMART_ANTENNA_SW_SUPPORT,
|
||||
+ WMI_TLV_SERVICE_SMART_ANTENNA_HW_SUPPORT,
|
||||
+ WMI_TLV_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES,
|
||||
+ WMI_TLV_SERVICE_NAN_DATA,
|
||||
+ WMI_TLV_SERVICE_NAN_RTT,
|
||||
+ WMI_TLV_SERVICE_11AX,
|
||||
+ WMI_TLV_SERVICE_DEPRECATED_REPLACE,
|
||||
+ WMI_TLV_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE,
|
||||
+ WMI_TLV_SERVICE_ENHANCED_MCAST_FILTER,
|
||||
+ WMI_TLV_SERVICE_PERIODIC_CHAN_STAT_SUPPORT,
|
||||
+ WMI_TLV_SERVICE_MESH_11S,
|
||||
+ WMI_TLV_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT,
|
||||
+ WMI_TLV_SERVICE_VDEV_RX_FILTER,
|
||||
+ WMI_TLV_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT,
|
||||
+ WMI_TLV_SERVICE_MARK_FIRST_WAKEUP_PACKET,
|
||||
+ WMI_TLV_SERVICE_MULTIPLE_MCAST_FILTER_SET,
|
||||
+ WMI_TLV_SERVICE_HOST_MANAGED_RX_REORDER,
|
||||
+ WMI_TLV_SERVICE_FLASH_RDWR_SUPPORT,
|
||||
+ WMI_TLV_SERVICE_WLAN_STATS_REPORT,
|
||||
+ WMI_TLV_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT,
|
||||
+ WMI_TLV_SERVICE_DFS_PHYERR_OFFLOAD,
|
||||
};
|
||||
|
||||
#define WMI_SERVICE_IS_ENABLED(wmi_svc_bmap, svc_id, len) \
|
||||
@@ -1121,6 +1165,8 @@ wmi_tlv_svc_map(const __le32 *in, unsign
|
||||
WMI_SERVICE_MDNS_OFFLOAD, len);
|
||||
SVCMAP(WMI_TLV_SERVICE_SAP_AUTH_OFFLOAD,
|
||||
WMI_SERVICE_SAP_AUTH_OFFLOAD, len);
|
||||
+ SVCMAP(WMI_TLV_SERVICE_MGMT_TX_WMI,
|
||||
+ WMI_SERVICE_MGMT_TX_WMI, len);
|
||||
}
|
||||
|
||||
#undef SVCMAP
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
|
||||
@@ -195,6 +195,7 @@ enum wmi_service {
|
||||
WMI_SERVICE_SMART_LOGGING_SUPPORT,
|
||||
WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE,
|
||||
WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY,
|
||||
+ WMI_SERVICE_MGMT_TX_WMI,
|
||||
|
||||
/* keep last */
|
||||
WMI_SERVICE_MAX,
|
|
@ -0,0 +1,64 @@
|
|||
From 14d65775687cb3a6f76a52f48f4be27a522bb396 Mon Sep 17 00:00:00 2001
|
||||
From: Balaji Pothunoori <bpothuno@qti.qualcomm.com>
|
||||
Date: Thu, 21 Dec 2017 20:00:42 +0530
|
||||
Subject: [PATCH] ath10k: advertise TDLS wider bandwidth support for 5GHz
|
||||
|
||||
Enable TDLS wider bandwidth support for 5GHz based on firmware wmi capabilities.
|
||||
|
||||
This patch is required for chipset QCA9888. Tested with firmware version
|
||||
10.4-3.5.1-00018.
|
||||
|
||||
Signed-off-by: Balaji Pothunoori <bpothuno@qti.qualcomm.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
|
||||
---
|
||||
drivers/net/wireless/ath/ath10k/mac.c | 3 ++-
|
||||
drivers/net/wireless/ath/ath10k/wmi.h | 5 +++++
|
||||
2 files changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -8236,7 +8236,8 @@ int ath10k_mac_register(struct ath10k *a
|
||||
if (test_bit(WMI_SERVICE_TDLS, ar->wmi.svc_map) ||
|
||||
test_bit(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY, ar->wmi.svc_map)) {
|
||||
ar->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
|
||||
- ieee80211_hw_set(ar->hw, TDLS_WIDER_BW);
|
||||
+ if (test_bit(WMI_SERVICE_TDLS_WIDER_BANDWIDTH, ar->wmi.svc_map))
|
||||
+ ieee80211_hw_set(ar->hw, TDLS_WIDER_BW);
|
||||
}
|
||||
|
||||
ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
|
||||
@@ -196,6 +196,7 @@ enum wmi_service {
|
||||
WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE,
|
||||
WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY,
|
||||
WMI_SERVICE_MGMT_TX_WMI,
|
||||
+ WMI_SERVICE_TDLS_WIDER_BANDWIDTH,
|
||||
|
||||
/* keep last */
|
||||
WMI_SERVICE_MAX,
|
||||
@@ -337,6 +338,7 @@ enum wmi_10_4_service {
|
||||
WMI_10_4_SERVICE_TDLS_UAPSD_SLEEP_STA,
|
||||
WMI_10_4_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE,
|
||||
WMI_10_4_SERVICE_TDLS_EXPLICIT_MODE_ONLY,
|
||||
+ WMI_10_4_SERVICE_TDLS_WIDER_BANDWIDTH,
|
||||
};
|
||||
|
||||
static inline char *wmi_service_name(int service_id)
|
||||
@@ -445,6 +447,7 @@ static inline char *wmi_service_name(int
|
||||
SVCSTR(WMI_SERVICE_SMART_LOGGING_SUPPORT);
|
||||
SVCSTR(WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE);
|
||||
SVCSTR(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY);
|
||||
+ SVCSTR(WMI_SERVICE_TDLS_WIDER_BANDWIDTH);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
@@ -741,6 +744,8 @@ static inline void wmi_10_4_svc_map(cons
|
||||
WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE, len);
|
||||
SVCMAP(WMI_10_4_SERVICE_TDLS_EXPLICIT_MODE_ONLY,
|
||||
WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY, len);
|
||||
+ SVCMAP(WMI_10_4_SERVICE_TDLS_WIDER_BANDWIDTH,
|
||||
+ WMI_SERVICE_TDLS_WIDER_BANDWIDTH, len);
|
||||
}
|
||||
|
||||
#undef SVCMAP
|
|
@ -0,0 +1,824 @@
|
|||
From bc64d05220f3e34cf432a166b83c8fff14cd7a3d Mon Sep 17 00:00:00 2001
|
||||
From: Maharaja Kennadyrajan <mkenna@codeaurora.org>
|
||||
Date: Wed, 14 Mar 2018 12:14:08 +0200
|
||||
Subject: [PATCH] ath10k: debugfs support to get final TPC stats for 10.4
|
||||
variants
|
||||
|
||||
Export the final Transmit Power Control (TPC) value, which is the
|
||||
minimum of control power and existing TPC value to user space via
|
||||
a new debugfs file "tpc_stats_final" to help with debugging.
|
||||
It works with the new wmi cmd and event introduced in 10.4 firmware
|
||||
branch.
|
||||
|
||||
WMI command ID: WMI_PDEV_GET_TPC_TABLE_CMDID
|
||||
WMI event ID: WMI_PDEV_TPC_TABLE_EVENTID
|
||||
|
||||
cat /sys/kernel/debug/ieee80211/phyX/ath10k/tpc_stats_final
|
||||
|
||||
$ cat /sys/kernel/debug/ieee80211/phyX/ath10k/tpc_stats_final
|
||||
|
||||
TPC config for channel 5180 mode 10
|
||||
|
||||
CTL = 0x 0 Reg. Domain = 58
|
||||
Antenna Gain = 0 Reg. Max Antenna Gain = 0
|
||||
Power Limit = 60 Reg. Max Power = 60
|
||||
Num tx chains = 2 Num supported rates = 109
|
||||
|
||||
******************* CDD POWER TABLE ****************
|
||||
|
||||
No. Preamble Rate_code tpc_value1 tpc_value2 tpc_value3
|
||||
0 CCK 0x40 0 0
|
||||
1 CCK 0x41 0 0
|
||||
[...]
|
||||
107 HTCUP 0x 0 46 46
|
||||
108 HTCUP 0x 0 46 46
|
||||
|
||||
******************* STBC POWER TABLE ****************
|
||||
|
||||
No. Preamble Rate_code tpc_value1 tpc_value2 tpc_value3
|
||||
0 CCK 0x40 0 0
|
||||
1 CCK 0x41 0 0
|
||||
[...]
|
||||
107 HTCUP 0x 0 46 46
|
||||
108 HTCUP 0x 0 46 46
|
||||
|
||||
***********************************
|
||||
TXBF not supported
|
||||
**********************************
|
||||
|
||||
The existing tpc_stats debugfs file provides the dump
|
||||
which is minimum of target power and regulatory domain.
|
||||
|
||||
cat /sys/kernel/debug/ieee80211/phyX/ath10k/tpc_stats
|
||||
|
||||
Hardware_used: QCA4019
|
||||
Firmware version: firmware-5.bin_10.4-3.0-00209
|
||||
|
||||
Signed-off-by: Maharaja Kennadyrajan <mkenna@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ath/ath10k/core.h | 22 +++
|
||||
drivers/net/wireless/ath/ath10k/debug.c | 107 +++++++++++
|
||||
drivers/net/wireless/ath/ath10k/debug.h | 10 +
|
||||
drivers/net/wireless/ath/ath10k/wmi-ops.h | 20 ++
|
||||
drivers/net/wireless/ath/ath10k/wmi.c | 308 ++++++++++++++++++++++++++++--
|
||||
drivers/net/wireless/ath/ath10k/wmi.h | 66 +++++++
|
||||
6 files changed, 518 insertions(+), 15 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/core.h
|
||||
@@ -322,6 +322,27 @@ struct ath10k_tpc_stats {
|
||||
struct ath10k_tpc_table tpc_table[WMI_TPC_FLAG];
|
||||
};
|
||||
|
||||
+struct ath10k_tpc_table_final {
|
||||
+ u32 pream_idx[WMI_TPC_FINAL_RATE_MAX];
|
||||
+ u8 rate_code[WMI_TPC_FINAL_RATE_MAX];
|
||||
+ char tpc_value[WMI_TPC_FINAL_RATE_MAX][WMI_TPC_TX_N_CHAIN * WMI_TPC_BUF_SIZE];
|
||||
+};
|
||||
+
|
||||
+struct ath10k_tpc_stats_final {
|
||||
+ u32 reg_domain;
|
||||
+ u32 chan_freq;
|
||||
+ u32 phy_mode;
|
||||
+ u32 twice_antenna_reduction;
|
||||
+ u32 twice_max_rd_power;
|
||||
+ s32 twice_antenna_gain;
|
||||
+ u32 power_limit;
|
||||
+ u32 num_tx_chain;
|
||||
+ u32 ctl;
|
||||
+ u32 rate_max;
|
||||
+ u8 flag[WMI_TPC_FLAG];
|
||||
+ struct ath10k_tpc_table_final tpc_table_final[WMI_TPC_FLAG];
|
||||
+};
|
||||
+
|
||||
struct ath10k_dfs_stats {
|
||||
u32 phy_errors;
|
||||
u32 pulses_total;
|
||||
@@ -482,6 +503,7 @@ struct ath10k_debug {
|
||||
|
||||
/* used for tpc-dump storage, protected by data-lock */
|
||||
struct ath10k_tpc_stats *tpc_stats;
|
||||
+ struct ath10k_tpc_stats_final *tpc_stats_final;
|
||||
|
||||
struct completion tpc_complete;
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/debug.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/debug.c
|
||||
@@ -1737,6 +1737,19 @@ void ath10k_debug_tpc_stats_process(stru
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
}
|
||||
|
||||
+void
|
||||
+ath10k_debug_tpc_stats_final_process(struct ath10k *ar,
|
||||
+ struct ath10k_tpc_stats_final *tpc_stats)
|
||||
+{
|
||||
+ spin_lock_bh(&ar->data_lock);
|
||||
+
|
||||
+ kfree(ar->debug.tpc_stats_final);
|
||||
+ ar->debug.tpc_stats_final = tpc_stats;
|
||||
+ complete(&ar->debug.tpc_complete);
|
||||
+
|
||||
+ spin_unlock_bh(&ar->data_lock);
|
||||
+}
|
||||
+
|
||||
static void ath10k_tpc_stats_print(struct ath10k_tpc_stats *tpc_stats,
|
||||
unsigned int j, char *buf, size_t *len)
|
||||
{
|
||||
@@ -2400,6 +2413,95 @@ static const struct file_operations fops
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
+static int ath10k_debug_tpc_stats_final_request(struct ath10k *ar)
|
||||
+{
|
||||
+ int ret;
|
||||
+ unsigned long time_left;
|
||||
+
|
||||
+ lockdep_assert_held(&ar->conf_mutex);
|
||||
+
|
||||
+ reinit_completion(&ar->debug.tpc_complete);
|
||||
+
|
||||
+ ret = ath10k_wmi_pdev_get_tpc_table_cmdid(ar, WMI_TPC_CONFIG_PARAM);
|
||||
+ if (ret) {
|
||||
+ ath10k_warn(ar, "failed to request tpc table cmdid: %d\n", ret);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ time_left = wait_for_completion_timeout(&ar->debug.tpc_complete,
|
||||
+ 1 * HZ);
|
||||
+ if (time_left == 0)
|
||||
+ return -ETIMEDOUT;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int ath10k_tpc_stats_final_open(struct inode *inode, struct file *file)
|
||||
+{
|
||||
+ struct ath10k *ar = inode->i_private;
|
||||
+ void *buf;
|
||||
+ int ret;
|
||||
+
|
||||
+ mutex_lock(&ar->conf_mutex);
|
||||
+
|
||||
+ if (ar->state != ATH10K_STATE_ON) {
|
||||
+ ret = -ENETDOWN;
|
||||
+ goto err_unlock;
|
||||
+ }
|
||||
+
|
||||
+ buf = vmalloc(ATH10K_TPC_CONFIG_BUF_SIZE);
|
||||
+ if (!buf) {
|
||||
+ ret = -ENOMEM;
|
||||
+ goto err_unlock;
|
||||
+ }
|
||||
+
|
||||
+ ret = ath10k_debug_tpc_stats_final_request(ar);
|
||||
+ if (ret) {
|
||||
+ ath10k_warn(ar, "failed to request tpc stats final: %d\n",
|
||||
+ ret);
|
||||
+ goto err_free;
|
||||
+ }
|
||||
+
|
||||
+ ath10k_tpc_stats_fill(ar, ar->debug.tpc_stats, buf);
|
||||
+ file->private_data = buf;
|
||||
+
|
||||
+ mutex_unlock(&ar->conf_mutex);
|
||||
+ return 0;
|
||||
+
|
||||
+err_free:
|
||||
+ vfree(buf);
|
||||
+
|
||||
+err_unlock:
|
||||
+ mutex_unlock(&ar->conf_mutex);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int ath10k_tpc_stats_final_release(struct inode *inode,
|
||||
+ struct file *file)
|
||||
+{
|
||||
+ vfree(file->private_data);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static ssize_t ath10k_tpc_stats_final_read(struct file *file,
|
||||
+ char __user *user_buf,
|
||||
+ size_t count, loff_t *ppos)
|
||||
+{
|
||||
+ const char *buf = file->private_data;
|
||||
+ unsigned int len = strlen(buf);
|
||||
+
|
||||
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
+}
|
||||
+
|
||||
+static const struct file_operations fops_tpc_stats_final = {
|
||||
+ .open = ath10k_tpc_stats_final_open,
|
||||
+ .release = ath10k_tpc_stats_final_release,
|
||||
+ .read = ath10k_tpc_stats_final_read,
|
||||
+ .owner = THIS_MODULE,
|
||||
+ .llseek = default_llseek,
|
||||
+};
|
||||
+
|
||||
int ath10k_debug_create(struct ath10k *ar)
|
||||
{
|
||||
ar->debug.fw_crash_data = vzalloc(sizeof(*ar->debug.fw_crash_data));
|
||||
@@ -2525,6 +2627,11 @@ int ath10k_debug_register(struct ath10k
|
||||
debugfs_create_file("fw_checksums", 0400, ar->debug.debugfs_phy, ar,
|
||||
&fops_fw_checksums);
|
||||
|
||||
+ if (test_bit(WMI_SERVICE_TPC_STATS_FINAL, ar->wmi.svc_map))
|
||||
+ debugfs_create_file("tpc_stats_final", 0400,
|
||||
+ ar->debug.debugfs_phy, ar,
|
||||
+ &fops_tpc_stats_final);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/debug.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/debug.h
|
||||
@@ -84,6 +84,9 @@ void ath10k_debug_unregister(struct ath1
|
||||
void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_debug_tpc_stats_process(struct ath10k *ar,
|
||||
struct ath10k_tpc_stats *tpc_stats);
|
||||
+void
|
||||
+ath10k_debug_tpc_stats_final_process(struct ath10k *ar,
|
||||
+ struct ath10k_tpc_stats_final *tpc_stats);
|
||||
struct ath10k_fw_crash_data *
|
||||
ath10k_debug_get_new_fw_crash_data(struct ath10k *ar);
|
||||
|
||||
@@ -151,6 +154,13 @@ static inline void ath10k_debug_tpc_stat
|
||||
{
|
||||
kfree(tpc_stats);
|
||||
}
|
||||
+
|
||||
+static inline void
|
||||
+ath10k_debug_tpc_stats_final_process(struct ath10k *ar,
|
||||
+ struct ath10k_tpc_stats_final *tpc_stats)
|
||||
+{
|
||||
+ kfree(tpc_stats);
|
||||
+}
|
||||
|
||||
static inline void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer,
|
||||
int len)
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
|
||||
@@ -197,6 +197,9 @@ struct wmi_ops {
|
||||
(struct ath10k *ar,
|
||||
enum wmi_bss_survey_req_type type);
|
||||
struct sk_buff *(*gen_echo)(struct ath10k *ar, u32 value);
|
||||
+ struct sk_buff *(*gen_pdev_get_tpc_table_cmdid)(struct ath10k *ar,
|
||||
+ u32 param);
|
||||
+
|
||||
};
|
||||
|
||||
int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
|
||||
@@ -1418,4 +1421,21 @@ ath10k_wmi_echo(struct ath10k *ar, u32 v
|
||||
return ath10k_wmi_cmd_send(ar, skb, wmi->cmd->echo_cmdid);
|
||||
}
|
||||
|
||||
+static inline int
|
||||
+ath10k_wmi_pdev_get_tpc_table_cmdid(struct ath10k *ar, u32 param)
|
||||
+{
|
||||
+ struct sk_buff *skb;
|
||||
+
|
||||
+ if (!ar->wmi.ops->gen_pdev_get_tpc_table_cmdid)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ skb = ar->wmi.ops->gen_pdev_get_tpc_table_cmdid(ar, param);
|
||||
+
|
||||
+ if (IS_ERR(skb))
|
||||
+ return PTR_ERR(skb);
|
||||
+
|
||||
+ return ath10k_wmi_cmd_send(ar, skb,
|
||||
+ ar->wmi.cmd->pdev_get_tpc_table_cmdid);
|
||||
+}
|
||||
+
|
||||
#endif
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
|
||||
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -196,6 +197,7 @@ static struct wmi_cmd_map wmi_cmd_map =
|
||||
.mu_cal_start_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.set_cca_params_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.pdev_bss_chan_info_request_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
+ .pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
};
|
||||
|
||||
/* 10.X WMI cmd track */
|
||||
@@ -362,6 +364,7 @@ static struct wmi_cmd_map wmi_10x_cmd_ma
|
||||
.mu_cal_start_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.set_cca_params_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.pdev_bss_chan_info_request_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
+ .pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
};
|
||||
|
||||
/* 10.2.4 WMI cmd track */
|
||||
@@ -528,6 +531,7 @@ static struct wmi_cmd_map wmi_10_2_4_cmd
|
||||
.set_cca_params_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.pdev_bss_chan_info_request_cmdid =
|
||||
WMI_10_2_PDEV_BSS_CHAN_INFO_REQUEST_CMDID,
|
||||
+ .pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
};
|
||||
|
||||
/* 10.4 WMI cmd track */
|
||||
@@ -1480,6 +1484,7 @@ static struct wmi_cmd_map wmi_10_2_cmd_m
|
||||
.pdev_get_ani_cck_config_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.pdev_get_ani_ofdm_config_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.pdev_reserve_ast_entry_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
+ .pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
};
|
||||
|
||||
static struct wmi_pdev_param_map wmi_10_4_pdev_param_map = {
|
||||
@@ -4313,19 +4318,11 @@ static void ath10k_tpc_config_disp_table
|
||||
}
|
||||
}
|
||||
|
||||
-void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb)
|
||||
+void ath10k_wmi_tpc_config_get_rate_code(u8 *rate_code, u16 *pream_table,
|
||||
+ u32 num_tx_chain)
|
||||
{
|
||||
- u32 i, j, pream_idx, num_tx_chain;
|
||||
- u8 rate_code[WMI_TPC_RATE_MAX], rate_idx;
|
||||
- u16 pream_table[WMI_TPC_PREAM_TABLE_MAX];
|
||||
- struct wmi_pdev_tpc_config_event *ev;
|
||||
- struct ath10k_tpc_stats *tpc_stats;
|
||||
-
|
||||
- ev = (struct wmi_pdev_tpc_config_event *)skb->data;
|
||||
-
|
||||
- tpc_stats = kzalloc(sizeof(*tpc_stats), GFP_ATOMIC);
|
||||
- if (!tpc_stats)
|
||||
- return;
|
||||
+ u32 i, j, pream_idx;
|
||||
+ u8 rate_idx;
|
||||
|
||||
/* Create the rate code table based on the chains supported */
|
||||
rate_idx = 0;
|
||||
@@ -4349,8 +4346,6 @@ void ath10k_wmi_event_pdev_tpc_config(st
|
||||
pream_table[pream_idx] = rate_idx;
|
||||
pream_idx++;
|
||||
|
||||
- num_tx_chain = __le32_to_cpu(ev->num_tx_chain);
|
||||
-
|
||||
/* Fill HT20 rate code */
|
||||
for (i = 0; i < num_tx_chain; i++) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
@@ -4374,7 +4369,7 @@ void ath10k_wmi_event_pdev_tpc_config(st
|
||||
pream_idx++;
|
||||
|
||||
/* Fill VHT20 rate code */
|
||||
- for (i = 0; i < __le32_to_cpu(ev->num_tx_chain); i++) {
|
||||
+ for (i = 0; i < num_tx_chain; i++) {
|
||||
for (j = 0; j < 10; j++) {
|
||||
rate_code[rate_idx] =
|
||||
ATH10K_HW_RATECODE(j, i, WMI_RATE_PREAMBLE_VHT);
|
||||
@@ -4418,6 +4413,26 @@ void ath10k_wmi_event_pdev_tpc_config(st
|
||||
ATH10K_HW_RATECODE(0, 0, WMI_RATE_PREAMBLE_OFDM);
|
||||
|
||||
pream_table[pream_idx] = ATH10K_TPC_PREAM_TABLE_END;
|
||||
+}
|
||||
+
|
||||
+void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb)
|
||||
+{
|
||||
+ u32 num_tx_chain;
|
||||
+ u8 rate_code[WMI_TPC_RATE_MAX];
|
||||
+ u16 pream_table[WMI_TPC_PREAM_TABLE_MAX];
|
||||
+ struct wmi_pdev_tpc_config_event *ev;
|
||||
+ struct ath10k_tpc_stats *tpc_stats;
|
||||
+
|
||||
+ ev = (struct wmi_pdev_tpc_config_event *)skb->data;
|
||||
+
|
||||
+ tpc_stats = kzalloc(sizeof(*tpc_stats), GFP_ATOMIC);
|
||||
+ if (!tpc_stats)
|
||||
+ return;
|
||||
+
|
||||
+ num_tx_chain = __le32_to_cpu(ev->num_tx_chain);
|
||||
+
|
||||
+ ath10k_wmi_tpc_config_get_rate_code(rate_code, pream_table,
|
||||
+ num_tx_chain);
|
||||
|
||||
tpc_stats->chan_freq = __le32_to_cpu(ev->chan_freq);
|
||||
tpc_stats->phy_mode = __le32_to_cpu(ev->phy_mode);
|
||||
@@ -4457,6 +4472,246 @@ void ath10k_wmi_event_pdev_tpc_config(st
|
||||
__le32_to_cpu(ev->rate_max));
|
||||
}
|
||||
|
||||
+static u8
|
||||
+ath10k_wmi_tpc_final_get_rate(struct ath10k *ar,
|
||||
+ struct wmi_pdev_tpc_final_table_event *ev,
|
||||
+ u32 rate_idx, u32 num_chains,
|
||||
+ u32 rate_code, u8 type, u32 pream_idx)
|
||||
+{
|
||||
+ u8 tpc, num_streams, preamble, ch, stm_idx;
|
||||
+ s8 pow_agcdd, pow_agstbc, pow_agtxbf;
|
||||
+ int pream;
|
||||
+
|
||||
+ num_streams = ATH10K_HW_NSS(rate_code);
|
||||
+ preamble = ATH10K_HW_PREAMBLE(rate_code);
|
||||
+ ch = num_chains - 1;
|
||||
+ stm_idx = num_streams - 1;
|
||||
+ pream = -1;
|
||||
+
|
||||
+ if (__le32_to_cpu(ev->chan_freq) <= 2483) {
|
||||
+ switch (pream_idx) {
|
||||
+ case WMI_TPC_PREAM_2GHZ_CCK:
|
||||
+ pream = 0;
|
||||
+ break;
|
||||
+ case WMI_TPC_PREAM_2GHZ_OFDM:
|
||||
+ pream = 1;
|
||||
+ break;
|
||||
+ case WMI_TPC_PREAM_2GHZ_HT20:
|
||||
+ case WMI_TPC_PREAM_2GHZ_VHT20:
|
||||
+ pream = 2;
|
||||
+ break;
|
||||
+ case WMI_TPC_PREAM_2GHZ_HT40:
|
||||
+ case WMI_TPC_PREAM_2GHZ_VHT40:
|
||||
+ pream = 3;
|
||||
+ break;
|
||||
+ case WMI_TPC_PREAM_2GHZ_VHT80:
|
||||
+ pream = 4;
|
||||
+ break;
|
||||
+ default:
|
||||
+ pream = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (__le32_to_cpu(ev->chan_freq) >= 5180) {
|
||||
+ switch (pream_idx) {
|
||||
+ case WMI_TPC_PREAM_5GHZ_OFDM:
|
||||
+ pream = 0;
|
||||
+ break;
|
||||
+ case WMI_TPC_PREAM_5GHZ_HT20:
|
||||
+ case WMI_TPC_PREAM_5GHZ_VHT20:
|
||||
+ pream = 1;
|
||||
+ break;
|
||||
+ case WMI_TPC_PREAM_5GHZ_HT40:
|
||||
+ case WMI_TPC_PREAM_5GHZ_VHT40:
|
||||
+ pream = 2;
|
||||
+ break;
|
||||
+ case WMI_TPC_PREAM_5GHZ_VHT80:
|
||||
+ pream = 3;
|
||||
+ break;
|
||||
+ case WMI_TPC_PREAM_5GHZ_HTCUP:
|
||||
+ pream = 4;
|
||||
+ break;
|
||||
+ default:
|
||||
+ pream = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (pream == 4)
|
||||
+ tpc = min_t(u8, ev->rates_array[rate_idx],
|
||||
+ ev->max_reg_allow_pow[ch]);
|
||||
+ else
|
||||
+ tpc = min_t(u8, min_t(u8, ev->rates_array[rate_idx],
|
||||
+ ev->max_reg_allow_pow[ch]),
|
||||
+ ev->ctl_power_table[0][pream][stm_idx]);
|
||||
+
|
||||
+ if (__le32_to_cpu(ev->num_tx_chain) <= 1)
|
||||
+ goto out;
|
||||
+
|
||||
+ if (preamble == WMI_RATE_PREAMBLE_CCK)
|
||||
+ goto out;
|
||||
+
|
||||
+ if (num_chains <= num_streams)
|
||||
+ goto out;
|
||||
+
|
||||
+ switch (type) {
|
||||
+ case WMI_TPC_TABLE_TYPE_STBC:
|
||||
+ pow_agstbc = ev->max_reg_allow_pow_agstbc[ch - 1][stm_idx];
|
||||
+ if (pream == 4)
|
||||
+ tpc = min_t(u8, tpc, pow_agstbc);
|
||||
+ else
|
||||
+ tpc = min_t(u8, min_t(u8, tpc, pow_agstbc),
|
||||
+ ev->ctl_power_table[0][pream][stm_idx]);
|
||||
+ break;
|
||||
+ case WMI_TPC_TABLE_TYPE_TXBF:
|
||||
+ pow_agtxbf = ev->max_reg_allow_pow_agtxbf[ch - 1][stm_idx];
|
||||
+ if (pream == 4)
|
||||
+ tpc = min_t(u8, tpc, pow_agtxbf);
|
||||
+ else
|
||||
+ tpc = min_t(u8, min_t(u8, tpc, pow_agtxbf),
|
||||
+ ev->ctl_power_table[1][pream][stm_idx]);
|
||||
+ break;
|
||||
+ case WMI_TPC_TABLE_TYPE_CDD:
|
||||
+ pow_agcdd = ev->max_reg_allow_pow_agcdd[ch - 1][stm_idx];
|
||||
+ if (pream == 4)
|
||||
+ tpc = min_t(u8, tpc, pow_agcdd);
|
||||
+ else
|
||||
+ tpc = min_t(u8, min_t(u8, tpc, pow_agcdd),
|
||||
+ ev->ctl_power_table[0][pream][stm_idx]);
|
||||
+ break;
|
||||
+ default:
|
||||
+ ath10k_warn(ar, "unknown wmi tpc final table type: %d\n", type);
|
||||
+ tpc = 0;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ return tpc;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ath10k_wmi_tpc_stats_final_disp_tables(struct ath10k *ar,
|
||||
+ struct wmi_pdev_tpc_final_table_event *ev,
|
||||
+ struct ath10k_tpc_stats_final *tpc_stats,
|
||||
+ u8 *rate_code, u16 *pream_table, u8 type)
|
||||
+{
|
||||
+ u32 i, j, pream_idx, flags;
|
||||
+ u8 tpc[WMI_TPC_TX_N_CHAIN];
|
||||
+ char tpc_value[WMI_TPC_TX_N_CHAIN * WMI_TPC_BUF_SIZE];
|
||||
+ char buff[WMI_TPC_BUF_SIZE];
|
||||
+
|
||||
+ flags = __le32_to_cpu(ev->flags);
|
||||
+
|
||||
+ switch (type) {
|
||||
+ case WMI_TPC_TABLE_TYPE_CDD:
|
||||
+ if (!(flags & WMI_TPC_CONFIG_EVENT_FLAG_TABLE_CDD)) {
|
||||
+ ath10k_dbg(ar, ATH10K_DBG_WMI, "CDD not supported\n");
|
||||
+ tpc_stats->flag[type] = ATH10K_TPC_TABLE_TYPE_FLAG;
|
||||
+ return;
|
||||
+ }
|
||||
+ break;
|
||||
+ case WMI_TPC_TABLE_TYPE_STBC:
|
||||
+ if (!(flags & WMI_TPC_CONFIG_EVENT_FLAG_TABLE_STBC)) {
|
||||
+ ath10k_dbg(ar, ATH10K_DBG_WMI, "STBC not supported\n");
|
||||
+ tpc_stats->flag[type] = ATH10K_TPC_TABLE_TYPE_FLAG;
|
||||
+ return;
|
||||
+ }
|
||||
+ break;
|
||||
+ case WMI_TPC_TABLE_TYPE_TXBF:
|
||||
+ if (!(flags & WMI_TPC_CONFIG_EVENT_FLAG_TABLE_TXBF)) {
|
||||
+ ath10k_dbg(ar, ATH10K_DBG_WMI, "TXBF not supported\n");
|
||||
+ tpc_stats->flag[type] = ATH10K_TPC_TABLE_TYPE_FLAG;
|
||||
+ return;
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ ath10k_dbg(ar, ATH10K_DBG_WMI,
|
||||
+ "invalid table type in wmi tpc event: %d\n", type);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ pream_idx = 0;
|
||||
+ for (i = 0; i < __le32_to_cpu(ev->rate_max); i++) {
|
||||
+ memset(tpc_value, 0, sizeof(tpc_value));
|
||||
+ memset(buff, 0, sizeof(buff));
|
||||
+ if (i == pream_table[pream_idx])
|
||||
+ pream_idx++;
|
||||
+
|
||||
+ for (j = 0; j < WMI_TPC_TX_N_CHAIN; j++) {
|
||||
+ if (j >= __le32_to_cpu(ev->num_tx_chain))
|
||||
+ break;
|
||||
+
|
||||
+ tpc[j] = ath10k_wmi_tpc_final_get_rate(ar, ev, i, j + 1,
|
||||
+ rate_code[i],
|
||||
+ type, pream_idx);
|
||||
+ snprintf(buff, sizeof(buff), "%8d ", tpc[j]);
|
||||
+ strncat(tpc_value, buff, strlen(buff));
|
||||
+ }
|
||||
+ tpc_stats->tpc_table_final[type].pream_idx[i] = pream_idx;
|
||||
+ tpc_stats->tpc_table_final[type].rate_code[i] = rate_code[i];
|
||||
+ memcpy(tpc_stats->tpc_table_final[type].tpc_value[i],
|
||||
+ tpc_value, sizeof(tpc_value));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void ath10k_wmi_event_tpc_final_table(struct ath10k *ar, struct sk_buff *skb)
|
||||
+{
|
||||
+ u32 num_tx_chain;
|
||||
+ u8 rate_code[WMI_TPC_FINAL_RATE_MAX];
|
||||
+ u16 pream_table[WMI_TPC_PREAM_TABLE_MAX];
|
||||
+ struct wmi_pdev_tpc_final_table_event *ev;
|
||||
+ struct ath10k_tpc_stats_final *tpc_stats;
|
||||
+
|
||||
+ ev = (struct wmi_pdev_tpc_final_table_event *)skb->data;
|
||||
+
|
||||
+ tpc_stats = kzalloc(sizeof(*tpc_stats), GFP_ATOMIC);
|
||||
+ if (!tpc_stats)
|
||||
+ return;
|
||||
+
|
||||
+ num_tx_chain = __le32_to_cpu(ev->num_tx_chain);
|
||||
+
|
||||
+ ath10k_wmi_tpc_config_get_rate_code(rate_code, pream_table,
|
||||
+ num_tx_chain);
|
||||
+
|
||||
+ tpc_stats->chan_freq = __le32_to_cpu(ev->chan_freq);
|
||||
+ tpc_stats->phy_mode = __le32_to_cpu(ev->phy_mode);
|
||||
+ tpc_stats->ctl = __le32_to_cpu(ev->ctl);
|
||||
+ tpc_stats->reg_domain = __le32_to_cpu(ev->reg_domain);
|
||||
+ tpc_stats->twice_antenna_gain = a_sle32_to_cpu(ev->twice_antenna_gain);
|
||||
+ tpc_stats->twice_antenna_reduction =
|
||||
+ __le32_to_cpu(ev->twice_antenna_reduction);
|
||||
+ tpc_stats->power_limit = __le32_to_cpu(ev->power_limit);
|
||||
+ tpc_stats->twice_max_rd_power = __le32_to_cpu(ev->twice_max_rd_power);
|
||||
+ tpc_stats->num_tx_chain = __le32_to_cpu(ev->num_tx_chain);
|
||||
+ tpc_stats->rate_max = __le32_to_cpu(ev->rate_max);
|
||||
+
|
||||
+ ath10k_wmi_tpc_stats_final_disp_tables(ar, ev, tpc_stats,
|
||||
+ rate_code, pream_table,
|
||||
+ WMI_TPC_TABLE_TYPE_CDD);
|
||||
+ ath10k_wmi_tpc_stats_final_disp_tables(ar, ev, tpc_stats,
|
||||
+ rate_code, pream_table,
|
||||
+ WMI_TPC_TABLE_TYPE_STBC);
|
||||
+ ath10k_wmi_tpc_stats_final_disp_tables(ar, ev, tpc_stats,
|
||||
+ rate_code, pream_table,
|
||||
+ WMI_TPC_TABLE_TYPE_TXBF);
|
||||
+
|
||||
+ ath10k_debug_tpc_stats_final_process(ar, tpc_stats);
|
||||
+
|
||||
+ ath10k_dbg(ar, ATH10K_DBG_WMI,
|
||||
+ "wmi event tpc final table channel %d mode %d ctl %d regd %d gain %d %d limit %d max_power %d tx_chanins %d rates %d\n",
|
||||
+ __le32_to_cpu(ev->chan_freq),
|
||||
+ __le32_to_cpu(ev->phy_mode),
|
||||
+ __le32_to_cpu(ev->ctl),
|
||||
+ __le32_to_cpu(ev->reg_domain),
|
||||
+ a_sle32_to_cpu(ev->twice_antenna_gain),
|
||||
+ __le32_to_cpu(ev->twice_antenna_reduction),
|
||||
+ __le32_to_cpu(ev->power_limit),
|
||||
+ __le32_to_cpu(ev->twice_max_rd_power) / 2,
|
||||
+ __le32_to_cpu(ev->num_tx_chain),
|
||||
+ __le32_to_cpu(ev->rate_max));
|
||||
+}
|
||||
+
|
||||
static void
|
||||
ath10k_wmi_handle_tdls_peer_event(struct ath10k *ar, struct sk_buff *skb)
|
||||
{
|
||||
@@ -5550,6 +5805,9 @@ static void ath10k_wmi_10_4_op_rx(struct
|
||||
case WMI_10_4_TDLS_PEER_EVENTID:
|
||||
ath10k_wmi_handle_tdls_peer_event(ar, skb);
|
||||
break;
|
||||
+ case WMI_10_4_PDEV_TPC_TABLE_EVENTID:
|
||||
+ ath10k_wmi_event_tpc_final_table(ar, skb);
|
||||
+ break;
|
||||
default:
|
||||
ath10k_warn(ar, "Unknown eventid: %d\n", id);
|
||||
break;
|
||||
@@ -7990,6 +8248,24 @@ static u32 ath10k_wmi_prepare_peer_qos(u
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
+ath10k_wmi_10_4_op_gen_pdev_get_tpc_table_cmdid(struct ath10k *ar, u32 param)
|
||||
+{
|
||||
+ struct wmi_pdev_get_tpc_table_cmd *cmd;
|
||||
+ struct sk_buff *skb;
|
||||
+
|
||||
+ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
|
||||
+ if (!skb)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
+ cmd = (struct wmi_pdev_get_tpc_table_cmd *)skb->data;
|
||||
+ cmd->param = __cpu_to_le32(param);
|
||||
+
|
||||
+ ath10k_dbg(ar, ATH10K_DBG_WMI,
|
||||
+ "wmi pdev get tpc table param:%d\n", param);
|
||||
+ return skb;
|
||||
+}
|
||||
+
|
||||
+static struct sk_buff *
|
||||
ath10k_wmi_10_4_gen_tdls_peer_update(struct ath10k *ar,
|
||||
const struct wmi_tdls_peer_update_cmd_arg *arg,
|
||||
const struct wmi_tdls_peer_capab_arg *cap,
|
||||
@@ -8430,6 +8706,8 @@ static const struct wmi_ops wmi_10_4_ops
|
||||
.ext_resource_config = ath10k_wmi_10_4_ext_resource_config,
|
||||
.gen_update_fw_tdls_state = ath10k_wmi_10_4_gen_update_fw_tdls_state,
|
||||
.gen_tdls_peer_update = ath10k_wmi_10_4_gen_tdls_peer_update,
|
||||
+ .gen_pdev_get_tpc_table_cmdid =
|
||||
+ ath10k_wmi_10_4_op_gen_pdev_get_tpc_table_cmdid,
|
||||
|
||||
/* shared with 10.2 */
|
||||
.pull_echo_ev = ath10k_wmi_op_pull_echo_ev,
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
|
||||
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -197,6 +198,9 @@ enum wmi_service {
|
||||
WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY,
|
||||
WMI_SERVICE_MGMT_TX_WMI,
|
||||
WMI_SERVICE_TDLS_WIDER_BANDWIDTH,
|
||||
+ WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS,
|
||||
+ WMI_SERVICE_HOST_DFS_CHECK_SUPPORT,
|
||||
+ WMI_SERVICE_TPC_STATS_FINAL,
|
||||
|
||||
/* keep last */
|
||||
WMI_SERVICE_MAX,
|
||||
@@ -339,6 +343,9 @@ enum wmi_10_4_service {
|
||||
WMI_10_4_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE,
|
||||
WMI_10_4_SERVICE_TDLS_EXPLICIT_MODE_ONLY,
|
||||
WMI_10_4_SERVICE_TDLS_WIDER_BANDWIDTH,
|
||||
+ WMI_10_4_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS,
|
||||
+ WMI_10_4_SERVICE_HOST_DFS_CHECK_SUPPORT,
|
||||
+ WMI_10_4_SERVICE_TPC_STATS_FINAL,
|
||||
};
|
||||
|
||||
static inline char *wmi_service_name(int service_id)
|
||||
@@ -448,6 +455,9 @@ static inline char *wmi_service_name(int
|
||||
SVCSTR(WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE);
|
||||
SVCSTR(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY);
|
||||
SVCSTR(WMI_SERVICE_TDLS_WIDER_BANDWIDTH);
|
||||
+ SVCSTR(WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS);
|
||||
+ SVCSTR(WMI_SERVICE_HOST_DFS_CHECK_SUPPORT);
|
||||
+ SVCSTR(WMI_SERVICE_TPC_STATS_FINAL);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
@@ -746,6 +756,12 @@ static inline void wmi_10_4_svc_map(cons
|
||||
WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY, len);
|
||||
SVCMAP(WMI_10_4_SERVICE_TDLS_WIDER_BANDWIDTH,
|
||||
WMI_SERVICE_TDLS_WIDER_BANDWIDTH, len);
|
||||
+ SVCMAP(WMI_10_4_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS,
|
||||
+ WMI_SERVICE_HTT_MGMT_TX_COMP_VALID_FLAGS, len);
|
||||
+ SVCMAP(WMI_10_4_SERVICE_HOST_DFS_CHECK_SUPPORT,
|
||||
+ WMI_SERVICE_HOST_DFS_CHECK_SUPPORT, len);
|
||||
+ SVCMAP(WMI_10_4_SERVICE_TPC_STATS_FINAL,
|
||||
+ WMI_SERVICE_TPC_STATS_FINAL, len);
|
||||
}
|
||||
|
||||
#undef SVCMAP
|
||||
@@ -3992,10 +4008,12 @@ struct wmi_pdev_get_tpc_config_cmd {
|
||||
|
||||
#define WMI_TPC_CONFIG_PARAM 1
|
||||
#define WMI_TPC_RATE_MAX 160
|
||||
+#define WMI_TPC_FINAL_RATE_MAX 240
|
||||
#define WMI_TPC_TX_N_CHAIN 4
|
||||
#define WMI_TPC_PREAM_TABLE_MAX 10
|
||||
#define WMI_TPC_FLAG 3
|
||||
#define WMI_TPC_BUF_SIZE 10
|
||||
+#define WMI_TPC_BEAMFORMING 2
|
||||
|
||||
enum wmi_tpc_table_type {
|
||||
WMI_TPC_TABLE_TYPE_CDD = 0,
|
||||
@@ -4038,6 +4056,51 @@ enum wmi_tp_scale {
|
||||
WMI_TP_SCALE_SIZE = 5, /* max num of enum */
|
||||
};
|
||||
|
||||
+struct wmi_pdev_tpc_final_table_event {
|
||||
+ __le32 reg_domain;
|
||||
+ __le32 chan_freq;
|
||||
+ __le32 phy_mode;
|
||||
+ __le32 twice_antenna_reduction;
|
||||
+ __le32 twice_max_rd_power;
|
||||
+ a_sle32 twice_antenna_gain;
|
||||
+ __le32 power_limit;
|
||||
+ __le32 rate_max;
|
||||
+ __le32 num_tx_chain;
|
||||
+ __le32 ctl;
|
||||
+ __le32 flags;
|
||||
+ s8 max_reg_allow_pow[WMI_TPC_TX_N_CHAIN];
|
||||
+ s8 max_reg_allow_pow_agcdd[WMI_TPC_TX_N_CHAIN][WMI_TPC_TX_N_CHAIN];
|
||||
+ s8 max_reg_allow_pow_agstbc[WMI_TPC_TX_N_CHAIN][WMI_TPC_TX_N_CHAIN];
|
||||
+ s8 max_reg_allow_pow_agtxbf[WMI_TPC_TX_N_CHAIN][WMI_TPC_TX_N_CHAIN];
|
||||
+ u8 rates_array[WMI_TPC_FINAL_RATE_MAX];
|
||||
+ u8 ctl_power_table[WMI_TPC_BEAMFORMING][WMI_TPC_TX_N_CHAIN]
|
||||
+ [WMI_TPC_TX_N_CHAIN];
|
||||
+} __packed;
|
||||
+
|
||||
+struct wmi_pdev_get_tpc_table_cmd {
|
||||
+ __le32 param;
|
||||
+} __packed;
|
||||
+
|
||||
+enum wmi_tpc_pream_2ghz {
|
||||
+ WMI_TPC_PREAM_2GHZ_CCK = 0,
|
||||
+ WMI_TPC_PREAM_2GHZ_OFDM,
|
||||
+ WMI_TPC_PREAM_2GHZ_HT20,
|
||||
+ WMI_TPC_PREAM_2GHZ_HT40,
|
||||
+ WMI_TPC_PREAM_2GHZ_VHT20,
|
||||
+ WMI_TPC_PREAM_2GHZ_VHT40,
|
||||
+ WMI_TPC_PREAM_2GHZ_VHT80,
|
||||
+};
|
||||
+
|
||||
+enum wmi_tpc_pream_5ghz {
|
||||
+ WMI_TPC_PREAM_5GHZ_OFDM = 1,
|
||||
+ WMI_TPC_PREAM_5GHZ_HT20,
|
||||
+ WMI_TPC_PREAM_5GHZ_HT40,
|
||||
+ WMI_TPC_PREAM_5GHZ_VHT20,
|
||||
+ WMI_TPC_PREAM_5GHZ_VHT40,
|
||||
+ WMI_TPC_PREAM_5GHZ_VHT80,
|
||||
+ WMI_TPC_PREAM_5GHZ_HTCUP,
|
||||
+};
|
||||
+
|
||||
struct wmi_pdev_chanlist_update_event {
|
||||
/* number of channels */
|
||||
__le32 num_chan;
|
||||
@@ -6977,5 +7040,8 @@ void ath10k_wmi_10_4_op_fw_stats_fill(st
|
||||
int ath10k_wmi_op_get_vdev_subtype(struct ath10k *ar,
|
||||
enum wmi_vdev_subtype subtype);
|
||||
int ath10k_wmi_barrier(struct ath10k *ar);
|
||||
+void ath10k_wmi_tpc_config_get_rate_code(u8 *rate_code, u16 *pream_table,
|
||||
+ u32 num_tx_chain);
|
||||
+void ath10k_wmi_event_tpc_final_table(struct ath10k *ar, struct sk_buff *skb);
|
||||
|
||||
#endif /* _WMI_H_ */
|
|
@ -0,0 +1,99 @@
|
|||
From 8b2d93dd22615cb7f3046a5a2083a6f8bb8052ed Mon Sep 17 00:00:00 2001
|
||||
From: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
||||
Date: Mon, 12 Mar 2018 17:09:40 +0530
|
||||
Subject: [PATCH] ath10k: Fix kernel panic while using worker
|
||||
(ath10k_sta_rc_update_wk)
|
||||
|
||||
When attempt to run worker (ath10k_sta_rc_update_wk) after the station object
|
||||
(ieee80211_sta) delete will trigger the kernel panic.
|
||||
|
||||
This problem arise in AP + Mesh configuration, Where the current node AP VAP
|
||||
and neighbor node mesh VAP MAC address are same. When the current mesh node
|
||||
try to establish the mesh link with neighbor node, driver peer creation for
|
||||
the neighbor mesh node fails due to duplication MAC address. Already the AP
|
||||
VAP created with same MAC address.
|
||||
|
||||
It is caused by the following scenario steps.
|
||||
|
||||
Steps:
|
||||
1. In above condition, ath10k driver sta_state callback (ath10k_sta_state)
|
||||
fails to do the state change for a station from IEEE80211_STA_NOTEXIST
|
||||
to IEEE80211_STA_NONE due to peer creation fails. Sta_state callback is
|
||||
called from ieee80211_add_station() to handle the new station
|
||||
(neighbor mesh node) request from the wpa_supplicant.
|
||||
2. Concurrently ath10k receive the sta_rc_update callback notification from
|
||||
the mesh_neighbour_update() to handle the beacon frames of the above
|
||||
neighbor mesh node. since its atomic callback, ath10k driver queue the
|
||||
work (ath10k_sta_rc_update_wk) to handle rc update.
|
||||
3. Due to driver sta_state callback fails (step 1), mac80211 free the station
|
||||
object.
|
||||
4. When the worker (ath10k_sta_rc_update_wk) scheduled to run, it will access
|
||||
the station object which is already deleted. so it will trigger kernel
|
||||
panic.
|
||||
|
||||
Added the peer exist check in sta_rc_update callback before queue the work.
|
||||
|
||||
Kernel Panic log:
|
||||
|
||||
Unable to handle kernel NULL pointer dereference at virtual address 00000000
|
||||
pgd = c0204000
|
||||
[00000000] *pgd=00000000
|
||||
Internal error: Oops: 17 [#1] PREEMPT SMP ARM
|
||||
CPU: 1 PID: 1833 Comm: kworker/u4:2 Not tainted 3.14.77 #1
|
||||
task: dcef0000 ti: d72b6000 task.ti: d72b6000
|
||||
PC is at pwq_activate_delayed_work+0x10/0x40
|
||||
LR is at pwq_activate_delayed_work+0xc/0x40
|
||||
pc : [<c023f988>] lr : [<c023f984>] psr: 40000193
|
||||
sp : d72b7f18 ip : 0000007a fp : d72b6000
|
||||
r10: 00000000 r9 : dd404414 r8 : d8c31998
|
||||
r7 : d72b6038 r6 : 00000004 r5 : d4907ec8 r4 : dcee1300
|
||||
r3 : ffffffe0 r2 : 00000000 r1 : 00000001 r0 : 00000000
|
||||
Flags: nZcv IRQs off FIQs on Mode SVC_32 ISA ARM Segment kernel
|
||||
Control: 10c5787d Table: 595bc06a DAC: 00000015
|
||||
...
|
||||
Process kworker/u4:2 (pid: 1833, stack limit = 0xd72b6238)
|
||||
Stack: (0xd72b7f18 to 0xd72b8000)
|
||||
7f00: 00000001 dcee1300
|
||||
7f20: 00000001 c02410dc d8c31980 dd404400 dd404400 c0242790 d8c31980 00000089
|
||||
7f40: 00000000 d93e1340 00000000 d8c31980 c0242568 00000000 00000000 00000000
|
||||
7f60: 00000000 c02474dc 00000000 00000000 000000f8 d8c31980 00000000 00000000
|
||||
7f80: d72b7f80 d72b7f80 00000000 00000000 d72b7f90 d72b7f90 d72b7fac d93e1340
|
||||
7fa0: c0247404 00000000 00000000 c0208d20 00000000 00000000 00000000 00000000
|
||||
7fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
|
||||
7fe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
|
||||
[<c023f988>] (pwq_activate_delayed_work) from [<c02410dc>] (pwq_dec_nr_in_flight+0x58/0xc4)
|
||||
[<c02410dc>] (pwq_dec_nr_in_flight) from [<c0242790>] (worker_thread+0x228/0x360)
|
||||
[<c0242790>] (worker_thread) from [<c02474dc>] (kthread+0xd8/0xec)
|
||||
[<c02474dc>] (kthread) from [<c0208d20>] (ret_from_fork+0x14/0x34)
|
||||
Code: e92d4038 e1a05000 ebffffbc[69210.619376] SMP: failed to stop secondary CPUs
|
||||
Rebooting in 3 seconds..
|
||||
|
||||
Signed-off-by: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ath/ath10k/mac.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -7065,10 +7065,20 @@ static void ath10k_sta_rc_update(struct
|
||||
{
|
||||
struct ath10k *ar = hw->priv;
|
||||
struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
|
||||
+ struct ath10k_vif *arvif = (void *)vif->drv_priv;
|
||||
+ struct ath10k_peer *peer;
|
||||
u32 bw, smps;
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
|
||||
+ peer = ath10k_peer_find(ar, arvif->vdev_id, sta->addr);
|
||||
+ if (!peer) {
|
||||
+ spin_unlock_bh(&ar->data_lock);
|
||||
+ ath10k_warn(ar, "mac sta rc update failed to find peer %pM on vdev %i\n",
|
||||
+ sta->addr, arvif->vdev_id);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC,
|
||||
"mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n",
|
||||
sta->addr, changed, sta->bandwidth, sta->rx_nss,
|
|
@ -0,0 +1,119 @@
|
|||
From 4b190675ad06f5a6ecbeef0b01890c5fb372e3eb Mon Sep 17 00:00:00 2001
|
||||
From: Tamizh Chelvam <tamizhr@codeaurora.org>
|
||||
Date: Wed, 25 Apr 2018 11:36:44 +0300
|
||||
Subject: [PATCH] ath10k: fix kernel panic while reading tpc_stats
|
||||
|
||||
When attempt to read tpc_stats for the chipsets which support
|
||||
more than 3 tx chain will trigger kernel panic(kernel stack is corrupted)
|
||||
due to writing values on rate_code array out of range.
|
||||
This patch changes the array size depends on the WMI_TPC_TX_N_CHAIN and
|
||||
added check to avoid write values on the array if the num tx chain
|
||||
get in tpc config event is greater than WMI_TPC_TX_N_CHAIN.
|
||||
|
||||
Tested on QCA9984 with firmware-5.bin_10.4-3.5.3-00057
|
||||
|
||||
Kernel panic log :
|
||||
|
||||
[ 323.510944] Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: bf90c654
|
||||
[ 323.510944]
|
||||
[ 323.524390] CPU: 0 PID: 1908 Comm: cat Not tainted 3.14.77 #31
|
||||
[ 323.530224] [<c021db48>] (unwind_backtrace) from [<c021ac08>] (show_stack+0x10/0x14)
|
||||
[ 323.537941] [<c021ac08>] (show_stack) from [<c03c53c0>] (dump_stack+0x80/0xa0)
|
||||
[ 323.545146] [<c03c53c0>] (dump_stack) from [<c022e4ac>] (panic+0x84/0x1e4)
|
||||
[ 323.552000] [<c022e4ac>] (panic) from [<c022e61c>] (__stack_chk_fail+0x10/0x14)
|
||||
[ 323.559350] [<c022e61c>] (__stack_chk_fail) from [<bf90c654>] (ath10k_wmi_event_pdev_tpc_config+0x424/0x438 [ath10k_core])
|
||||
[ 323.570471] [<bf90c654>] (ath10k_wmi_event_pdev_tpc_config [ath10k_core]) from [<bf90d800>] (ath10k_wmi_10_4_op_rx+0x2f0/0x39c [ath10k_core])
|
||||
[ 323.583047] [<bf90d800>] (ath10k_wmi_10_4_op_rx [ath10k_core]) from [<bf8fcc18>] (ath10k_htc_rx_completion_handler+0x170/0x1a0 [ath10k_core])
|
||||
[ 323.595702] [<bf8fcc18>] (ath10k_htc_rx_completion_handler [ath10k_core]) from [<bf961f44>] (ath10k_pci_hif_send_complete_check+0x1f0/0x220 [ath10k_pci])
|
||||
[ 323.609421] [<bf961f44>] (ath10k_pci_hif_send_complete_check [ath10k_pci]) from [<bf96562c>] (ath10k_ce_per_engine_service+0x74/0xc4 [ath10k_pci])
|
||||
[ 323.622490] [<bf96562c>] (ath10k_ce_per_engine_service [ath10k_pci]) from [<bf9656f0>] (ath10k_ce_per_engine_service_any+0x74/0x80 [ath10k_pci])
|
||||
[ 323.635423] [<bf9656f0>] (ath10k_ce_per_engine_service_any [ath10k_pci]) from [<bf96365c>] (ath10k_pci_napi_poll+0x44/0xe8 [ath10k_pci])
|
||||
[ 323.647665] [<bf96365c>] (ath10k_pci_napi_poll [ath10k_pci]) from [<c0599994>] (net_rx_action+0xac/0x160)
|
||||
[ 323.657208] [<c0599994>] (net_rx_action) from [<c02324a4>] (__do_softirq+0x104/0x294)
|
||||
[ 323.665017] [<c02324a4>] (__do_softirq) from [<c0232920>] (irq_exit+0x9c/0x11c)
|
||||
[ 323.672314] [<c0232920>] (irq_exit) from [<c0217fc0>] (handle_IRQ+0x6c/0x90)
|
||||
[ 323.679341] [<c0217fc0>] (handle_IRQ) from [<c02084e0>] (gic_handle_irq+0x3c/0x60)
|
||||
[ 323.686893] [<c02084e0>] (gic_handle_irq) from [<c02095c0>] (__irq_svc+0x40/0x70)
|
||||
[ 323.694349] Exception stack(0xdd489c58 to 0xdd489ca0)
|
||||
[ 323.699384] 9c40: 00000000 a0000013
|
||||
[ 323.707547] 9c60: 00000000 dc4bce40 60000013 ddc1d800 dd488000 00000990 00000000 c085c800
|
||||
[ 323.715707] 9c80: 00000000 dd489d44 0000092d dd489ca0 c026e664 c026e668 60000013 ffffffff
|
||||
[ 323.723877] [<c02095c0>] (__irq_svc) from [<c026e668>] (rcu_note_context_switch+0x170/0x184)
|
||||
[ 323.732298] [<c026e668>] (rcu_note_context_switch) from [<c020e928>] (__schedule+0x50/0x4d4)
|
||||
[ 323.740716] [<c020e928>] (__schedule) from [<c020e490>] (schedule_timeout+0x148/0x178)
|
||||
[ 323.748611] [<c020e490>] (schedule_timeout) from [<c020f804>] (wait_for_common+0x114/0x154)
|
||||
[ 323.756972] [<c020f804>] (wait_for_common) from [<bf8f6ef0>] (ath10k_tpc_stats_open+0xc8/0x340 [ath10k_core])
|
||||
[ 323.766873] [<bf8f6ef0>] (ath10k_tpc_stats_open [ath10k_core]) from [<c02bb598>] (do_dentry_open+0x1ac/0x274)
|
||||
[ 323.776741] [<c02bb598>] (do_dentry_open) from [<c02c838c>] (do_last+0x8c0/0xb08)
|
||||
[ 323.784201] [<c02c838c>] (do_last) from [<c02c87e4>] (path_openat+0x210/0x598)
|
||||
[ 323.791408] [<c02c87e4>] (path_openat) from [<c02c9d1c>] (do_filp_open+0x2c/0x78)
|
||||
[ 323.798873] [<c02c9d1c>] (do_filp_open) from [<c02bc85c>] (do_sys_open+0x114/0x1b4)
|
||||
[ 323.806509] [<c02bc85c>] (do_sys_open) from [<c0208c80>] (ret_fast_syscall+0x0/0x44)
|
||||
[ 323.814241] CPU1: stopping
|
||||
[ 323.816927] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 3.14.77 #31
|
||||
[ 323.823008] [<c021db48>] (unwind_backtrace) from [<c021ac08>] (show_stack+0x10/0x14)
|
||||
[ 323.830731] [<c021ac08>] (show_stack) from [<c03c53c0>] (dump_stack+0x80/0xa0)
|
||||
[ 323.837934] [<c03c53c0>] (dump_stack) from [<c021cfac>] (handle_IPI+0xb8/0x140)
|
||||
[ 323.845224] [<c021cfac>] (handle_IPI) from [<c02084fc>] (gic_handle_irq+0x58/0x60)
|
||||
[ 323.852774] [<c02084fc>] (gic_handle_irq) from [<c02095c0>] (__irq_svc+0x40/0x70)
|
||||
[ 323.860233] Exception stack(0xdd499fa0 to 0xdd499fe8)
|
||||
[ 323.865273] 9fa0: ffffffed 00000000 1d3c9000 00000000 dd498000 dd498030 10c0387d c08b62c8
|
||||
[ 323.873432] 9fc0: 4220406a 512f04d0 00000000 00000000 00000001 dd499fe8 c021838c c0218390
|
||||
[ 323.881588] 9fe0: 60000013 ffffffff
|
||||
[ 323.885070] [<c02095c0>] (__irq_svc) from [<c0218390>] (arch_cpu_idle+0x30/0x50)
|
||||
[ 323.892454] [<c0218390>] (arch_cpu_idle) from [<c026500c>] (cpu_startup_entry+0xa4/0x108)
|
||||
[ 323.900690] [<c026500c>] (cpu_startup_entry) from [<422085a4>] (0x422085a4)
|
||||
|
||||
Signed-off-by: Tamizh chelvam <tamizhr@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ath/ath10k/debug.c | 8 +++++++-
|
||||
drivers/net/wireless/ath/ath10k/wmi.c | 6 ++++++
|
||||
drivers/net/wireless/ath/ath10k/wmi.h | 2 +-
|
||||
3 files changed, 14 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/debug.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/debug.c
|
||||
@@ -1776,7 +1776,13 @@ static void ath10k_tpc_stats_print(struc
|
||||
*len += scnprintf(buf + *len, buf_len - *len,
|
||||
"********************************\n");
|
||||
*len += scnprintf(buf + *len, buf_len - *len,
|
||||
- "No. Preamble Rate_code tpc_value1 tpc_value2 tpc_value3\n");
|
||||
+ "No. Preamble Rate_code ");
|
||||
+
|
||||
+ for (i = 0; i < WMI_TPC_TX_N_CHAIN; i++)
|
||||
+ *len += scnprintf(buf + *len, buf_len - *len,
|
||||
+ "tpc_value%d ", i);
|
||||
+
|
||||
+ *len += scnprintf(buf + *len, buf_len - *len, "\n");
|
||||
|
||||
for (i = 0; i < tpc_stats->rate_max; i++) {
|
||||
*len += scnprintf(buf + *len, buf_len - *len,
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
@@ -4431,6 +4431,12 @@ void ath10k_wmi_event_pdev_tpc_config(st
|
||||
|
||||
num_tx_chain = __le32_to_cpu(ev->num_tx_chain);
|
||||
|
||||
+ if (num_tx_chain > WMI_TPC_TX_N_CHAIN) {
|
||||
+ ath10k_warn(ar, "number of tx chain is %d greater than TPC configured tx chain %d\n",
|
||||
+ num_tx_chain, WMI_TPC_TX_N_CHAIN);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
ath10k_wmi_tpc_config_get_rate_code(rate_code, pream_table,
|
||||
num_tx_chain);
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
|
||||
@@ -4007,9 +4007,9 @@ struct wmi_pdev_get_tpc_config_cmd {
|
||||
} __packed;
|
||||
|
||||
#define WMI_TPC_CONFIG_PARAM 1
|
||||
-#define WMI_TPC_RATE_MAX 160
|
||||
#define WMI_TPC_FINAL_RATE_MAX 240
|
||||
#define WMI_TPC_TX_N_CHAIN 4
|
||||
+#define WMI_TPC_RATE_MAX (WMI_TPC_TX_N_CHAIN * 65)
|
||||
#define WMI_TPC_PREAM_TABLE_MAX 10
|
||||
#define WMI_TPC_FLAG 3
|
||||
#define WMI_TPC_BUF_SIZE 10
|
|
@ -0,0 +1,92 @@
|
|||
From be8cce96f14dc925ecfb702be0392a52cf78adb5 Mon Sep 17 00:00:00 2001
|
||||
From: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
|
||||
Date: Wed, 23 May 2018 11:09:09 +0300
|
||||
Subject: [PATCH] ath10k: add support to configure channel dwell time
|
||||
|
||||
Configure channel dwell time from duration of the scan request
|
||||
received from mac80211 when the duration is non-zero. When the
|
||||
scan request does not have duration value, use the default ones,
|
||||
the current implementation.
|
||||
|
||||
Corresponding flag NL80211_EXT_FEATURE_SET_SCAN_DWELL is
|
||||
advertized.
|
||||
|
||||
Supported Chipsets:
|
||||
-QCA988X/QCA9887 PCI
|
||||
-QCA99X0/QCA9984/QCA9888/QCA4019 PCI
|
||||
-QCA6174/QCA9377 PCI/USB/SDIO
|
||||
-WCN3990 SNOC
|
||||
|
||||
Tested on QCA9984 with firmware ver 10.4-3.6-0010
|
||||
|
||||
Signed-off-by: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ath/ath10k/core.h | 1 +
|
||||
drivers/net/wireless/ath/ath10k/mac.c | 23 ++++++++++++++++++++---
|
||||
2 files changed, 21 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/core.h
|
||||
@@ -43,6 +43,7 @@
|
||||
#define WO(_f) ((_f##_OFFSET) >> 2)
|
||||
|
||||
#define ATH10K_SCAN_ID 0
|
||||
+#define ATH10K_SCAN_CHANNEL_SWITCH_WMI_EVT_OVERHEAD 10 /* msec */
|
||||
#define WMI_READY_TIMEOUT (5 * HZ)
|
||||
#define ATH10K_FLUSH_TIMEOUT_HZ (5 * HZ)
|
||||
#define ATH10K_CONNECTION_LOSS_HZ (3 * HZ)
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -5597,6 +5597,7 @@ static int ath10k_hw_scan(struct ieee802
|
||||
struct wmi_start_scan_arg arg;
|
||||
int ret = 0;
|
||||
int i;
|
||||
+ u32 scan_timeout;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
@@ -5647,6 +5648,22 @@ static int ath10k_hw_scan(struct ieee802
|
||||
arg.channels[i] = req->channels[i]->center_freq;
|
||||
}
|
||||
|
||||
+ /* if duration is set, default dwell times will be overwritten */
|
||||
+ if (req->duration) {
|
||||
+ arg.dwell_time_active = req->duration;
|
||||
+ arg.dwell_time_passive = req->duration;
|
||||
+ arg.burst_duration_ms = req->duration;
|
||||
+
|
||||
+ scan_timeout = min_t(u32, arg.max_rest_time *
|
||||
+ (arg.n_channels - 1) + (req->duration +
|
||||
+ ATH10K_SCAN_CHANNEL_SWITCH_WMI_EVT_OVERHEAD) *
|
||||
+ arg.n_channels, arg.max_scan_time + 200);
|
||||
+
|
||||
+ } else {
|
||||
+ /* Add a 200ms margin to account for event/command processing */
|
||||
+ scan_timeout = arg.max_scan_time + 200;
|
||||
+ }
|
||||
+
|
||||
ret = ath10k_start_scan(ar, &arg);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to start hw scan: %d\n", ret);
|
||||
@@ -5655,10 +5672,8 @@ static int ath10k_hw_scan(struct ieee802
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
}
|
||||
|
||||
- /* Add a 200ms margin to account for event/command processing */
|
||||
ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout,
|
||||
- msecs_to_jiffies(arg.max_scan_time +
|
||||
- 200));
|
||||
+ msecs_to_jiffies(scan_timeout));
|
||||
|
||||
exit:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
@@ -8267,6 +8282,8 @@ int ath10k_mac_register(struct ath10k *a
|
||||
}
|
||||
|
||||
wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
|
||||
+ wiphy_ext_feature_set(ar->hw->wiphy,
|
||||
+ NL80211_EXT_FEATURE_SET_SCAN_DWELL);
|
||||
|
||||
/*
|
||||
* on LL hardware queues are managed entirely by the FW
|
|
@ -0,0 +1,94 @@
|
|||
From f40105e6747892e8edab94020567c158c9bec0df Mon Sep 17 00:00:00 2001
|
||||
From: Sriram R <srirrama@codeaurora.org>
|
||||
Date: Tue, 15 May 2018 14:39:48 +0530
|
||||
Subject: [PATCH] ath: add support to get the detected radar specifications
|
||||
|
||||
This enables ath10k/ath9k drivers to collect the specifications of the
|
||||
radar type once it is detected by the dfs pattern detector unit.
|
||||
Usage of the collected info is specific to driver implementation.
|
||||
For example, collected radar info could be used by the host driver
|
||||
to send to co-processors for additional processing/validation.
|
||||
|
||||
Note: 'radar_detector_specs' data containing the specifications of
|
||||
different radar types which was private within dfs_pattern_detector/
|
||||
dfs_pri_detector is now shared with drivers as well for making use
|
||||
of this information.
|
||||
|
||||
Signed-off-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ath/ath10k/wmi.c | 2 +-
|
||||
drivers/net/wireless/ath/ath9k/dfs.c | 2 +-
|
||||
drivers/net/wireless/ath/dfs_pattern_detector.c | 5 ++++-
|
||||
drivers/net/wireless/ath/dfs_pattern_detector.h | 3 ++-
|
||||
drivers/net/wireless/ath/dfs_pri_detector.h | 3 ++-
|
||||
5 files changed, 10 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
@@ -3712,7 +3712,7 @@ static void ath10k_dfs_radar_report(stru
|
||||
|
||||
ATH10K_DFS_STAT_INC(ar, pulses_detected);
|
||||
|
||||
- if (!ar->dfs_detector->add_pulse(ar->dfs_detector, &pe)) {
|
||||
+ if (!ar->dfs_detector->add_pulse(ar->dfs_detector, &pe, NULL)) {
|
||||
ath10k_dbg(ar, ATH10K_DBG_REGULATORY,
|
||||
"dfs no pulse pattern detected, yet\n");
|
||||
return;
|
||||
--- a/drivers/net/wireless/ath/ath9k/dfs.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/dfs.c
|
||||
@@ -279,7 +279,7 @@ ath9k_dfs_process_radar_pulse(struct ath
|
||||
DFS_STAT_INC(sc, pulses_processed);
|
||||
if (pd == NULL)
|
||||
return;
|
||||
- if (!pd->add_pulse(pd, pe))
|
||||
+ if (!pd->add_pulse(pd, pe, NULL))
|
||||
return;
|
||||
DFS_STAT_INC(sc, radar_detected);
|
||||
ieee80211_radar_detected(sc->hw);
|
||||
--- a/drivers/net/wireless/ath/dfs_pattern_detector.c
|
||||
+++ b/drivers/net/wireless/ath/dfs_pattern_detector.c
|
||||
@@ -268,7 +268,8 @@ static void dpd_exit(struct dfs_pattern_
|
||||
}
|
||||
|
||||
static bool
|
||||
-dpd_add_pulse(struct dfs_pattern_detector *dpd, struct pulse_event *event)
|
||||
+dpd_add_pulse(struct dfs_pattern_detector *dpd, struct pulse_event *event,
|
||||
+ struct radar_detector_specs *rs)
|
||||
{
|
||||
u32 i;
|
||||
struct channel_detector *cd;
|
||||
@@ -294,6 +295,8 @@ dpd_add_pulse(struct dfs_pattern_detecto
|
||||
struct pri_detector *pd = cd->detectors[i];
|
||||
struct pri_sequence *ps = pd->add_pulse(pd, event);
|
||||
if (ps != NULL) {
|
||||
+ if (rs != NULL)
|
||||
+ memcpy(rs, pd->rs, sizeof(*rs));
|
||||
ath_dbg(dpd->common, DFS,
|
||||
"DFS: radar found on freq=%d: id=%d, pri=%d, "
|
||||
"count=%d, count_false=%d\n",
|
||||
--- a/drivers/net/wireless/ath/dfs_pattern_detector.h
|
||||
+++ b/drivers/net/wireless/ath/dfs_pattern_detector.h
|
||||
@@ -97,7 +97,8 @@ struct dfs_pattern_detector {
|
||||
bool (*set_dfs_domain)(struct dfs_pattern_detector *dpd,
|
||||
enum nl80211_dfs_regions region);
|
||||
bool (*add_pulse)(struct dfs_pattern_detector *dpd,
|
||||
- struct pulse_event *pe);
|
||||
+ struct pulse_event *pe,
|
||||
+ struct radar_detector_specs *rs);
|
||||
|
||||
struct ath_dfs_pool_stats (*get_stats)(struct dfs_pattern_detector *dpd);
|
||||
enum nl80211_dfs_regions region;
|
||||
--- a/drivers/net/wireless/ath/dfs_pri_detector.h
|
||||
+++ b/drivers/net/wireless/ath/dfs_pri_detector.h
|
||||
@@ -62,8 +62,9 @@ struct pri_detector {
|
||||
(*add_pulse)(struct pri_detector *de, struct pulse_event *e);
|
||||
void (*reset) (struct pri_detector *de, u64 ts);
|
||||
|
||||
-/* private: internal use only */
|
||||
const struct radar_detector_specs *rs;
|
||||
+
|
||||
+/* private: internal use only */
|
||||
u64 last_ts;
|
||||
struct list_head sequences;
|
||||
struct list_head pulses;
|
|
@ -0,0 +1,546 @@
|
|||
From 6f6eb1bcbeff48c875617b800f00f1c5d1b12290 Mon Sep 17 00:00:00 2001
|
||||
From: Sriram R <srirrama@codeaurora.org>
|
||||
Date: Tue, 15 May 2018 14:39:49 +0530
|
||||
Subject: [PATCH] ath10k: DFS Host Confirmation
|
||||
|
||||
In the 10.4-3.6 firmware branch there's a new DFS Host confirmation
|
||||
feature which is advertised using WMI_SERVICE_HOST_DFS_CHECK_SUPPORT flag.
|
||||
|
||||
This new features enables the ath10k host to send information to the
|
||||
firmware on the specifications of detected radar type. This allows the
|
||||
firmware to validate if the host's radar pattern detector unit is
|
||||
operational and check if the radar information shared by host matches
|
||||
the radar pulses sent as phy error events from firmware. If the check
|
||||
fails the firmware won't allow use of DFS channels on AP mode when using
|
||||
FCC regulatory region.
|
||||
|
||||
Hence this patch is mandatory when using a firmware from 10.4-3.6 branch.
|
||||
Else, DFS channels on FCC regions cannot be used.
|
||||
|
||||
Supported Chipsets : QCA9984/QCA9888/QCA4019
|
||||
Firmware Version : 10.4-3.6-00104
|
||||
|
||||
Signed-off-by: Sriram R <srirrama@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ath/ath10k/core.h | 21 ++++
|
||||
drivers/net/wireless/ath/ath10k/mac.c | 12 ++
|
||||
drivers/net/wireless/ath/ath10k/wmi-ops.h | 32 +++++
|
||||
drivers/net/wireless/ath/ath10k/wmi.c | 186 ++++++++++++++++++++++++++++--
|
||||
drivers/net/wireless/ath/ath10k/wmi.h | 32 +++++
|
||||
5 files changed, 273 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/core.h
|
||||
@@ -171,6 +171,7 @@ struct ath10k_wmi {
|
||||
struct completion service_ready;
|
||||
struct completion unified_ready;
|
||||
struct completion barrier;
|
||||
+ struct completion radar_confirm;
|
||||
wait_queue_head_t tx_credits_wq;
|
||||
DECLARE_BITMAP(svc_map, WMI_SERVICE_MAX);
|
||||
struct wmi_cmd_map *cmd;
|
||||
@@ -352,6 +353,21 @@ struct ath10k_dfs_stats {
|
||||
u32 radar_detected;
|
||||
};
|
||||
|
||||
+enum ath10k_radar_confirmation_state {
|
||||
+ ATH10K_RADAR_CONFIRMATION_IDLE = 0,
|
||||
+ ATH10K_RADAR_CONFIRMATION_INPROGRESS,
|
||||
+ ATH10K_RADAR_CONFIRMATION_STOPPED,
|
||||
+};
|
||||
+
|
||||
+struct ath10k_radar_found_info {
|
||||
+ u32 pri_min;
|
||||
+ u32 pri_max;
|
||||
+ u32 width_min;
|
||||
+ u32 width_max;
|
||||
+ u32 sidx_min;
|
||||
+ u32 sidx_max;
|
||||
+};
|
||||
+
|
||||
#define ATH10K_MAX_NUM_PEER_IDS (1 << 11) /* htt rx_desc limit */
|
||||
|
||||
struct ath10k_peer {
|
||||
@@ -1026,6 +1042,11 @@ struct ath10k {
|
||||
|
||||
void *ce_priv;
|
||||
|
||||
+ /* protected by data_lock */
|
||||
+ enum ath10k_radar_confirmation_state radar_conf_state;
|
||||
+ struct ath10k_radar_found_info last_radar_info;
|
||||
+ struct work_struct radar_confirmation_work;
|
||||
+
|
||||
/* must be last */
|
||||
u8 drv_priv[0] __aligned(sizeof(void *));
|
||||
};
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -3216,6 +3216,15 @@ static void ath10k_reg_notifier(struct w
|
||||
ar->hw->wiphy->bands[NL80211_BAND_5GHZ]);
|
||||
}
|
||||
|
||||
+static void ath10k_stop_radar_confirmation(struct ath10k *ar)
|
||||
+{
|
||||
+ spin_lock_bh(&ar->data_lock);
|
||||
+ ar->radar_conf_state = ATH10K_RADAR_CONFIRMATION_STOPPED;
|
||||
+ spin_unlock_bh(&ar->data_lock);
|
||||
+
|
||||
+ cancel_work_sync(&ar->radar_confirmation_work);
|
||||
+}
|
||||
+
|
||||
/***************/
|
||||
/* TX handlers */
|
||||
/***************/
|
||||
@@ -4315,6 +4324,7 @@ void ath10k_halt(struct ath10k *ar)
|
||||
|
||||
ath10k_scan_finish(ar);
|
||||
ath10k_peer_cleanup_all(ar);
|
||||
+ ath10k_stop_radar_confirmation(ar);
|
||||
ath10k_core_stop(ar);
|
||||
ath10k_hif_power_down(ar);
|
||||
|
||||
@@ -4733,6 +4743,8 @@ static int ath10k_start(struct ieee80211
|
||||
ath10k_spectral_start(ar);
|
||||
ath10k_thermal_set_throttling(ar);
|
||||
|
||||
+ ar->radar_conf_state = ATH10K_RADAR_CONFIRMATION_IDLE;
|
||||
+
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return 0;
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
|
||||
@@ -53,6 +53,8 @@ struct wmi_ops {
|
||||
struct wmi_wow_ev_arg *arg);
|
||||
int (*pull_echo_ev)(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_echo_ev_arg *arg);
|
||||
+ int (*pull_dfs_status_ev)(struct ath10k *ar, struct sk_buff *skb,
|
||||
+ struct wmi_dfs_status_ev_arg *arg);
|
||||
enum wmi_txbf_conf (*get_txbf_conf_scheme)(struct ath10k *ar);
|
||||
|
||||
struct sk_buff *(*gen_pdev_suspend)(struct ath10k *ar, u32 suspend_opt);
|
||||
@@ -178,6 +180,9 @@ struct wmi_ops {
|
||||
const struct wmi_tdls_peer_update_cmd_arg *arg,
|
||||
const struct wmi_tdls_peer_capab_arg *cap,
|
||||
const struct wmi_channel_arg *chan);
|
||||
+ struct sk_buff *(*gen_radar_found)
|
||||
+ (struct ath10k *ar,
|
||||
+ const struct ath10k_radar_found_info *arg);
|
||||
struct sk_buff *(*gen_adaptive_qcs)(struct ath10k *ar, bool enable);
|
||||
struct sk_buff *(*gen_pdev_get_tpc_config)(struct ath10k *ar,
|
||||
u32 param);
|
||||
@@ -365,6 +370,16 @@ ath10k_wmi_pull_echo_ev(struct ath10k *a
|
||||
return ar->wmi.ops->pull_echo_ev(ar, skb, arg);
|
||||
}
|
||||
|
||||
+static inline int
|
||||
+ath10k_wmi_pull_dfs_status(struct ath10k *ar, struct sk_buff *skb,
|
||||
+ struct wmi_dfs_status_ev_arg *arg)
|
||||
+{
|
||||
+ if (!ar->wmi.ops->pull_dfs_status_ev)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ return ar->wmi.ops->pull_dfs_status_ev(ar, skb, arg);
|
||||
+}
|
||||
+
|
||||
static inline enum wmi_txbf_conf
|
||||
ath10k_wmi_get_txbf_conf_scheme(struct ath10k *ar)
|
||||
{
|
||||
@@ -1438,4 +1453,21 @@ ath10k_wmi_pdev_get_tpc_table_cmdid(stru
|
||||
ar->wmi.cmd->pdev_get_tpc_table_cmdid);
|
||||
}
|
||||
|
||||
+static inline int
|
||||
+ath10k_wmi_report_radar_found(struct ath10k *ar,
|
||||
+ const struct ath10k_radar_found_info *arg)
|
||||
+{
|
||||
+ struct sk_buff *skb;
|
||||
+
|
||||
+ if (!ar->wmi.ops->gen_radar_found)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ skb = ar->wmi.ops->gen_radar_found(ar, arg);
|
||||
+ if (IS_ERR(skb))
|
||||
+ return PTR_ERR(skb);
|
||||
+
|
||||
+ return ath10k_wmi_cmd_send(ar, skb,
|
||||
+ ar->wmi.cmd->radar_found_cmdid);
|
||||
+}
|
||||
+
|
||||
#endif
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
#define ATH10K_WMI_BARRIER_ECHO_ID 0xBA991E9
|
||||
#define ATH10K_WMI_BARRIER_TIMEOUT_HZ (3 * HZ)
|
||||
+#define ATH10K_WMI_DFS_CONF_TIMEOUT_HZ (HZ / 6)
|
||||
|
||||
/* MAIN WMI cmd track */
|
||||
static struct wmi_cmd_map wmi_cmd_map = {
|
||||
@@ -198,6 +199,7 @@ static struct wmi_cmd_map wmi_cmd_map =
|
||||
.set_cca_params_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.pdev_bss_chan_info_request_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
+ .radar_found_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
};
|
||||
|
||||
/* 10.X WMI cmd track */
|
||||
@@ -365,6 +367,7 @@ static struct wmi_cmd_map wmi_10x_cmd_ma
|
||||
.set_cca_params_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.pdev_bss_chan_info_request_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
+ .radar_found_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
};
|
||||
|
||||
/* 10.2.4 WMI cmd track */
|
||||
@@ -532,6 +535,7 @@ static struct wmi_cmd_map wmi_10_2_4_cmd
|
||||
.pdev_bss_chan_info_request_cmdid =
|
||||
WMI_10_2_PDEV_BSS_CHAN_INFO_REQUEST_CMDID,
|
||||
.pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
+ .radar_found_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
};
|
||||
|
||||
/* 10.4 WMI cmd track */
|
||||
@@ -741,6 +745,7 @@ static struct wmi_cmd_map wmi_10_4_cmd_m
|
||||
.tdls_set_state_cmdid = WMI_10_4_TDLS_SET_STATE_CMDID,
|
||||
.tdls_peer_update_cmdid = WMI_10_4_TDLS_PEER_UPDATE_CMDID,
|
||||
.tdls_set_offchan_mode_cmdid = WMI_10_4_TDLS_SET_OFFCHAN_MODE_CMDID,
|
||||
+ .radar_found_cmdid = WMI_10_4_RADAR_FOUND_CMDID,
|
||||
};
|
||||
|
||||
/* MAIN WMI VDEV param map */
|
||||
@@ -1485,6 +1490,7 @@ static struct wmi_cmd_map wmi_10_2_cmd_m
|
||||
.pdev_get_ani_ofdm_config_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.pdev_reserve_ast_entry_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
.pdev_get_tpc_table_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
+ .radar_found_cmdid = WMI_CMD_UNSUPPORTED,
|
||||
};
|
||||
|
||||
static struct wmi_pdev_param_map wmi_10_4_pdev_param_map = {
|
||||
@@ -3638,6 +3644,68 @@ void ath10k_wmi_event_tbttoffset_update(
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TBTTOFFSET_UPDATE_EVENTID\n");
|
||||
}
|
||||
|
||||
+static void ath10k_radar_detected(struct ath10k *ar)
|
||||
+{
|
||||
+ ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs radar detected\n");
|
||||
+ ATH10K_DFS_STAT_INC(ar, radar_detected);
|
||||
+
|
||||
+ /* Control radar events reporting in debugfs file
|
||||
+ * dfs_block_radar_events
|
||||
+ */
|
||||
+ if (ar->dfs_block_radar_events)
|
||||
+ ath10k_info(ar, "DFS Radar detected, but ignored as requested\n");
|
||||
+ else
|
||||
+ ieee80211_radar_detected(ar->hw);
|
||||
+}
|
||||
+
|
||||
+static void ath10k_radar_confirmation_work(struct work_struct *work)
|
||||
+{
|
||||
+ struct ath10k *ar = container_of(work, struct ath10k,
|
||||
+ radar_confirmation_work);
|
||||
+ struct ath10k_radar_found_info radar_info;
|
||||
+ int ret, time_left;
|
||||
+
|
||||
+ reinit_completion(&ar->wmi.radar_confirm);
|
||||
+
|
||||
+ spin_lock_bh(&ar->data_lock);
|
||||
+ memcpy(&radar_info, &ar->last_radar_info, sizeof(radar_info));
|
||||
+ spin_unlock_bh(&ar->data_lock);
|
||||
+
|
||||
+ ret = ath10k_wmi_report_radar_found(ar, &radar_info);
|
||||
+ if (ret) {
|
||||
+ ath10k_warn(ar, "failed to send radar found %d\n", ret);
|
||||
+ goto wait_complete;
|
||||
+ }
|
||||
+
|
||||
+ time_left = wait_for_completion_timeout(&ar->wmi.radar_confirm,
|
||||
+ ATH10K_WMI_DFS_CONF_TIMEOUT_HZ);
|
||||
+ if (time_left) {
|
||||
+ /* DFS Confirmation status event received and
|
||||
+ * necessary action completed.
|
||||
+ */
|
||||
+ goto wait_complete;
|
||||
+ } else {
|
||||
+ /* DFS Confirmation event not received from FW.Considering this
|
||||
+ * as real radar.
|
||||
+ */
|
||||
+ ath10k_dbg(ar, ATH10K_DBG_REGULATORY,
|
||||
+ "dfs confirmation not received from fw, considering as radar\n");
|
||||
+ goto radar_detected;
|
||||
+ }
|
||||
+
|
||||
+radar_detected:
|
||||
+ ath10k_radar_detected(ar);
|
||||
+
|
||||
+ /* Reset state to allow sending confirmation on consecutive radar
|
||||
+ * detections, unless radar confirmation is disabled/stopped.
|
||||
+ */
|
||||
+wait_complete:
|
||||
+ spin_lock_bh(&ar->data_lock);
|
||||
+ if (ar->radar_conf_state != ATH10K_RADAR_CONFIRMATION_STOPPED)
|
||||
+ ar->radar_conf_state = ATH10K_RADAR_CONFIRMATION_IDLE;
|
||||
+ spin_unlock_bh(&ar->data_lock);
|
||||
+}
|
||||
+
|
||||
static void ath10k_dfs_radar_report(struct ath10k *ar,
|
||||
struct wmi_phyerr_ev_arg *phyerr,
|
||||
const struct phyerr_radar_report *rr,
|
||||
@@ -3646,8 +3714,10 @@ static void ath10k_dfs_radar_report(stru
|
||||
u32 reg0, reg1, tsf32l;
|
||||
struct ieee80211_channel *ch;
|
||||
struct pulse_event pe;
|
||||
+ struct radar_detector_specs rs;
|
||||
u64 tsf64;
|
||||
u8 rssi, width;
|
||||
+ struct ath10k_radar_found_info *radar_info;
|
||||
|
||||
reg0 = __le32_to_cpu(rr->reg0);
|
||||
reg1 = __le32_to_cpu(rr->reg1);
|
||||
@@ -3712,25 +3782,46 @@ static void ath10k_dfs_radar_report(stru
|
||||
|
||||
ATH10K_DFS_STAT_INC(ar, pulses_detected);
|
||||
|
||||
- if (!ar->dfs_detector->add_pulse(ar->dfs_detector, &pe, NULL)) {
|
||||
+ if (!ar->dfs_detector->add_pulse(ar->dfs_detector, &pe, &rs)) {
|
||||
ath10k_dbg(ar, ATH10K_DBG_REGULATORY,
|
||||
"dfs no pulse pattern detected, yet\n");
|
||||
return;
|
||||
}
|
||||
|
||||
-radar_detected:
|
||||
- ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs radar detected\n");
|
||||
- ATH10K_DFS_STAT_INC(ar, radar_detected);
|
||||
+ if ((test_bit(WMI_SERVICE_HOST_DFS_CHECK_SUPPORT, ar->wmi.svc_map)) &&
|
||||
+ ar->dfs_detector->region == NL80211_DFS_FCC) {
|
||||
+ /* Consecutive radar indications need not be
|
||||
+ * sent to the firmware until we get confirmation
|
||||
+ * for the previous detected radar.
|
||||
+ */
|
||||
+ spin_lock_bh(&ar->data_lock);
|
||||
+ if (ar->radar_conf_state != ATH10K_RADAR_CONFIRMATION_IDLE) {
|
||||
+ spin_unlock_bh(&ar->data_lock);
|
||||
+ return;
|
||||
+ }
|
||||
+ ar->radar_conf_state = ATH10K_RADAR_CONFIRMATION_INPROGRESS;
|
||||
+ radar_info = &ar->last_radar_info;
|
||||
|
||||
- /* Control radar events reporting in debugfs file
|
||||
- * dfs_block_radar_events
|
||||
- */
|
||||
- if (ar->dfs_block_radar_events) {
|
||||
- ath10k_info(ar, "DFS Radar detected, but ignored as requested\n");
|
||||
+ radar_info->pri_min = rs.pri_min;
|
||||
+ radar_info->pri_max = rs.pri_max;
|
||||
+ radar_info->width_min = rs.width_min;
|
||||
+ radar_info->width_max = rs.width_max;
|
||||
+ /*TODO Find sidx_min and sidx_max */
|
||||
+ radar_info->sidx_min = MS(reg0, RADAR_REPORT_REG0_PULSE_SIDX);
|
||||
+ radar_info->sidx_max = MS(reg0, RADAR_REPORT_REG0_PULSE_SIDX);
|
||||
+
|
||||
+ ath10k_dbg(ar, ATH10K_DBG_REGULATORY,
|
||||
+ "sending wmi radar found cmd pri_min %d pri_max %d width_min %d width_max %d sidx_min %d sidx_max %d\n",
|
||||
+ radar_info->pri_min, radar_info->pri_max,
|
||||
+ radar_info->width_min, radar_info->width_max,
|
||||
+ radar_info->sidx_min, radar_info->sidx_max);
|
||||
+ ieee80211_queue_work(ar->hw, &ar->radar_confirmation_work);
|
||||
+ spin_unlock_bh(&ar->data_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
- ieee80211_radar_detected(ar->hw);
|
||||
+radar_detected:
|
||||
+ ath10k_radar_detected(ar);
|
||||
}
|
||||
|
||||
static int ath10k_dfs_fft_report(struct ath10k *ar,
|
||||
@@ -4080,6 +4171,47 @@ void ath10k_wmi_event_phyerr(struct ath1
|
||||
}
|
||||
}
|
||||
|
||||
+static int
|
||||
+ath10k_wmi_10_4_op_pull_dfs_status_ev(struct ath10k *ar, struct sk_buff *skb,
|
||||
+ struct wmi_dfs_status_ev_arg *arg)
|
||||
+{
|
||||
+ struct wmi_dfs_status_ev_arg *ev = (void *)skb->data;
|
||||
+
|
||||
+ if (skb->len < sizeof(*ev))
|
||||
+ return -EPROTO;
|
||||
+
|
||||
+ arg->status = ev->status;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+ath10k_wmi_event_dfs_status_check(struct ath10k *ar, struct sk_buff *skb)
|
||||
+{
|
||||
+ struct wmi_dfs_status_ev_arg status_arg = {};
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = ath10k_wmi_pull_dfs_status(ar, skb, &status_arg);
|
||||
+
|
||||
+ if (ret) {
|
||||
+ ath10k_warn(ar, "failed to parse dfs status event: %d\n", ret);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ath10k_dbg(ar, ATH10K_DBG_REGULATORY,
|
||||
+ "dfs status event received from fw: %d\n",
|
||||
+ status_arg.status);
|
||||
+
|
||||
+ /* Even in case of radar detection failure we follow the same
|
||||
+ * behaviour as if radar is detected i.e to switch to a different
|
||||
+ * channel.
|
||||
+ */
|
||||
+ if (status_arg.status == WMI_HW_RADAR_DETECTED ||
|
||||
+ status_arg.status == WMI_RADAR_DETECTION_FAIL)
|
||||
+ ath10k_radar_detected(ar);
|
||||
+ complete(&ar->wmi.radar_confirm);
|
||||
+}
|
||||
+
|
||||
void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb)
|
||||
{
|
||||
struct wmi_roam_ev_arg arg = {};
|
||||
@@ -5814,6 +5946,9 @@ static void ath10k_wmi_10_4_op_rx(struct
|
||||
case WMI_10_4_PDEV_TPC_TABLE_EVENTID:
|
||||
ath10k_wmi_event_tpc_final_table(ar, skb);
|
||||
break;
|
||||
+ case WMI_10_4_DFS_STATUS_CHECK_EVENTID:
|
||||
+ ath10k_wmi_event_dfs_status_check(ar, skb);
|
||||
+ break;
|
||||
default:
|
||||
ath10k_warn(ar, "Unknown eventid: %d\n", id);
|
||||
break;
|
||||
@@ -8332,6 +8467,32 @@ ath10k_wmi_10_4_gen_tdls_peer_update(str
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
+ath10k_wmi_10_4_gen_radar_found(struct ath10k *ar,
|
||||
+ const struct ath10k_radar_found_info *arg)
|
||||
+{
|
||||
+ struct wmi_radar_found_info *cmd;
|
||||
+ struct sk_buff *skb;
|
||||
+
|
||||
+ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
|
||||
+ if (!skb)
|
||||
+ return ERR_PTR(-ENOMEM);
|
||||
+
|
||||
+ cmd = (struct wmi_radar_found_info *)skb->data;
|
||||
+ cmd->pri_min = __cpu_to_le32(arg->pri_min);
|
||||
+ cmd->pri_max = __cpu_to_le32(arg->pri_max);
|
||||
+ cmd->width_min = __cpu_to_le32(arg->width_min);
|
||||
+ cmd->width_max = __cpu_to_le32(arg->width_max);
|
||||
+ cmd->sidx_min = __cpu_to_le32(arg->sidx_min);
|
||||
+ cmd->sidx_max = __cpu_to_le32(arg->sidx_max);
|
||||
+
|
||||
+ ath10k_dbg(ar, ATH10K_DBG_WMI,
|
||||
+ "wmi radar found pri_min %d pri_max %d width_min %d width_max %d sidx_min %d sidx_max %d\n",
|
||||
+ arg->pri_min, arg->pri_max, arg->width_min,
|
||||
+ arg->width_max, arg->sidx_min, arg->sidx_max);
|
||||
+ return skb;
|
||||
+}
|
||||
+
|
||||
+static struct sk_buff *
|
||||
ath10k_wmi_op_gen_echo(struct ath10k *ar, u32 value)
|
||||
{
|
||||
struct wmi_echo_cmd *cmd;
|
||||
@@ -8668,6 +8829,7 @@ static const struct wmi_ops wmi_10_4_ops
|
||||
.pull_svc_rdy = ath10k_wmi_main_op_pull_svc_rdy_ev,
|
||||
.pull_rdy = ath10k_wmi_op_pull_rdy_ev,
|
||||
.pull_roam_ev = ath10k_wmi_op_pull_roam_ev,
|
||||
+ .pull_dfs_status_ev = ath10k_wmi_10_4_op_pull_dfs_status_ev,
|
||||
.get_txbf_conf_scheme = ath10k_wmi_10_4_txbf_conf_scheme,
|
||||
|
||||
.gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend,
|
||||
@@ -8714,6 +8876,7 @@ static const struct wmi_ops wmi_10_4_ops
|
||||
.gen_tdls_peer_update = ath10k_wmi_10_4_gen_tdls_peer_update,
|
||||
.gen_pdev_get_tpc_table_cmdid =
|
||||
ath10k_wmi_10_4_op_gen_pdev_get_tpc_table_cmdid,
|
||||
+ .gen_radar_found = ath10k_wmi_10_4_gen_radar_found,
|
||||
|
||||
/* shared with 10.2 */
|
||||
.pull_echo_ev = ath10k_wmi_op_pull_echo_ev,
|
||||
@@ -8776,8 +8939,11 @@ int ath10k_wmi_attach(struct ath10k *ar)
|
||||
init_completion(&ar->wmi.service_ready);
|
||||
init_completion(&ar->wmi.unified_ready);
|
||||
init_completion(&ar->wmi.barrier);
|
||||
+ init_completion(&ar->wmi.radar_confirm);
|
||||
|
||||
INIT_WORK(&ar->svc_rdy_work, ath10k_wmi_event_service_ready_work);
|
||||
+ INIT_WORK(&ar->radar_confirmation_work,
|
||||
+ ath10k_radar_confirmation_work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
|
||||
@@ -959,6 +959,7 @@ struct wmi_cmd_map {
|
||||
u32 vdev_sifs_trigger_time_cmdid;
|
||||
u32 pdev_wds_entry_list_cmdid;
|
||||
u32 tdls_set_offchan_mode_cmdid;
|
||||
+ u32 radar_found_cmdid;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1792,6 +1793,11 @@ enum wmi_10_4_cmd_id {
|
||||
WMI_10_4_TDLS_SET_STATE_CMDID,
|
||||
WMI_10_4_TDLS_PEER_UPDATE_CMDID,
|
||||
WMI_10_4_TDLS_SET_OFFCHAN_MODE_CMDID,
|
||||
+ WMI_10_4_PDEV_SEND_FD_CMDID,
|
||||
+ WMI_10_4_ENABLE_FILS_CMDID,
|
||||
+ WMI_10_4_PDEV_SET_BRIDGE_MACADDR_CMDID,
|
||||
+ WMI_10_4_ATF_GROUP_WMM_AC_CONFIG_REQUEST_CMDID,
|
||||
+ WMI_10_4_RADAR_FOUND_CMDID,
|
||||
WMI_10_4_PDEV_UTF_CMDID = WMI_10_4_END_CMDID - 1,
|
||||
};
|
||||
|
||||
@@ -1867,6 +1873,9 @@ enum wmi_10_4_event_id {
|
||||
WMI_10_4_PDEV_TPC_TABLE_EVENTID,
|
||||
WMI_10_4_PDEV_WDS_ENTRY_LIST_EVENTID,
|
||||
WMI_10_4_TDLS_PEER_EVENTID,
|
||||
+ WMI_10_4_HOST_SWFDA_EVENTID,
|
||||
+ WMI_10_4_ESP_ESTIMATE_EVENTID,
|
||||
+ WMI_10_4_DFS_STATUS_CHECK_EVENTID,
|
||||
WMI_10_4_PDEV_UTF_EVENTID = WMI_10_4_END_EVENTID - 1,
|
||||
};
|
||||
|
||||
@@ -3379,6 +3388,25 @@ struct wmi_10_4_phyerr_event {
|
||||
u8 buf[0];
|
||||
} __packed;
|
||||
|
||||
+struct wmi_radar_found_info {
|
||||
+ __le32 pri_min;
|
||||
+ __le32 pri_max;
|
||||
+ __le32 width_min;
|
||||
+ __le32 width_max;
|
||||
+ __le32 sidx_min;
|
||||
+ __le32 sidx_max;
|
||||
+} __packed;
|
||||
+
|
||||
+enum wmi_radar_confirmation_status {
|
||||
+ /* Detected radar was due to SW pulses */
|
||||
+ WMI_SW_RADAR_DETECTED = 0,
|
||||
+
|
||||
+ WMI_RADAR_DETECTION_FAIL = 1,
|
||||
+
|
||||
+ /* Real radar detected */
|
||||
+ WMI_HW_RADAR_DETECTED = 2,
|
||||
+};
|
||||
+
|
||||
#define PHYERR_TLV_SIG 0xBB
|
||||
#define PHYERR_TLV_TAG_SEARCH_FFT_REPORT 0xFB
|
||||
#define PHYERR_TLV_TAG_RADAR_PULSE_SUMMARY 0xF8
|
||||
@@ -6586,6 +6614,10 @@ struct wmi_phyerr_hdr_arg {
|
||||
const void *phyerrs;
|
||||
};
|
||||
|
||||
+struct wmi_dfs_status_ev_arg {
|
||||
+ u32 status;
|
||||
+};
|
||||
+
|
||||
struct wmi_svc_rdy_ev_arg {
|
||||
__le32 min_tx_power;
|
||||
__le32 max_tx_power;
|
|
@ -0,0 +1,43 @@
|
|||
From 260e629bbf441585860e21d5e10d2e88437f47c8 Mon Sep 17 00:00:00 2001
|
||||
From: Colin Ian King <colin.king@canonical.com>
|
||||
Date: Sun, 27 May 2018 22:17:02 +0100
|
||||
Subject: [PATCH] ath10k: fix memory leak of tpc_stats
|
||||
|
||||
Currently tpc_stats is allocated and is leaked on the return
|
||||
path if num_tx_chain is greater than WMI_TPC_TX_N_CHAIN. Avoid
|
||||
this leak by performing the check on num_tx_chain before the
|
||||
allocation of tpc_stats.
|
||||
|
||||
Detected by CoverityScan, CID#1469422 ("Resource Leak")
|
||||
Fixes: 4b190675ad06 ("ath10k: fix kernel panic while reading tpc_stats")
|
||||
|
||||
Signed-off-by: Colin Ian King <colin.king@canonical.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ath/ath10k/wmi.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
@@ -4557,10 +4557,6 @@ void ath10k_wmi_event_pdev_tpc_config(st
|
||||
|
||||
ev = (struct wmi_pdev_tpc_config_event *)skb->data;
|
||||
|
||||
- tpc_stats = kzalloc(sizeof(*tpc_stats), GFP_ATOMIC);
|
||||
- if (!tpc_stats)
|
||||
- return;
|
||||
-
|
||||
num_tx_chain = __le32_to_cpu(ev->num_tx_chain);
|
||||
|
||||
if (num_tx_chain > WMI_TPC_TX_N_CHAIN) {
|
||||
@@ -4569,6 +4565,10 @@ void ath10k_wmi_event_pdev_tpc_config(st
|
||||
return;
|
||||
}
|
||||
|
||||
+ tpc_stats = kzalloc(sizeof(*tpc_stats), GFP_ATOMIC);
|
||||
+ if (!tpc_stats)
|
||||
+ return;
|
||||
+
|
||||
ath10k_wmi_tpc_config_get_rate_code(rate_code, pream_table,
|
||||
num_tx_chain);
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
From 38441fb6fcbb97817dff5c012609860a2b39c3e9 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Greear <greearb@candelatech.com>
|
||||
Date: Tue, 2 Jan 2018 16:51:01 -0800
|
||||
Subject: [PATCH] ath10k: support use of channel 173
|
||||
|
||||
The India regulatory domain allows CH 173, so add that to the
|
||||
available channel list. I verified basic connectivity between
|
||||
a 9880 and 9984 NIC.
|
||||
|
||||
Signed-off-by: Ben Greear <greearb@candelatech.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ath/ath10k/core.h | 3 ++-
|
||||
drivers/net/wireless/ath/ath10k/mac.c | 3 +++
|
||||
drivers/net/wireless/ath/ath10k/wmi.c | 2 +-
|
||||
3 files changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/core.h
|
||||
@@ -47,7 +47,8 @@
|
||||
#define WMI_READY_TIMEOUT (5 * HZ)
|
||||
#define ATH10K_FLUSH_TIMEOUT_HZ (5 * HZ)
|
||||
#define ATH10K_CONNECTION_LOSS_HZ (3 * HZ)
|
||||
-#define ATH10K_NUM_CHANS 40
|
||||
+#define ATH10K_NUM_CHANS 41
|
||||
+#define ATH10K_MAX_5G_CHAN 173
|
||||
|
||||
/* Antenna noise floor */
|
||||
#define ATH10K_DEFAULT_NOISE_FLOOR -95
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -7766,6 +7766,9 @@ static const struct ieee80211_channel at
|
||||
CHAN5G(161, 5805, 0),
|
||||
CHAN5G(165, 5825, 0),
|
||||
CHAN5G(169, 5845, 0),
|
||||
+ CHAN5G(173, 5865, 0),
|
||||
+ /* If you add more, you may need to change ATH10K_MAX_5G_CHAN */
|
||||
+ /* And you will definitely need to change ATH10K_NUM_CHANS in core.h */
|
||||
};
|
||||
|
||||
struct ath10k *ath10k_mac_create(size_t priv_size)
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
@@ -2363,7 +2363,7 @@ int ath10k_wmi_event_mgmt_rx(struct ath1
|
||||
*/
|
||||
if (channel >= 1 && channel <= 14) {
|
||||
status->band = NL80211_BAND_2GHZ;
|
||||
- } else if (channel >= 36 && channel <= 169) {
|
||||
+ } else if (channel >= 36 && channel <= ATH10K_MAX_5G_CHAN) {
|
||||
status->band = NL80211_BAND_5GHZ;
|
||||
} else {
|
||||
/* Shouldn't happen unless list of advertised channels to
|
|
@ -0,0 +1,156 @@
|
|||
From 2e9bcd0d73243f5e49daf92508d64cc33c30da01 Mon Sep 17 00:00:00 2001
|
||||
From: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
||||
Date: Tue, 29 May 2018 17:01:13 +0530
|
||||
Subject: [PATCH] ath10k: fix spectral scan for QCA9984 and QCA9888 chipsets
|
||||
|
||||
The spectral scan has been always broken on QCA9984 and QCA9888.
|
||||
|
||||
Introduce a hardware parameter 'spectral_bin_offset' to resolve this issue for
|
||||
QCA9984 and QCA9888 chipsets. For other chipsets, the hardware parameter
|
||||
'spectral_bin_offset' is zero so that existing behaviour is retained as it is.
|
||||
|
||||
In QCA9984 and QCA9888 chipsets, hardware param value 'spectral_bin_discard'
|
||||
is 12 bytes. This 12 bytes is derived as the sum of segment index (4 bytes),
|
||||
extra bins before the actual data (4 bytes) and extra bins after the actual
|
||||
data (4 bytes). Always discarding (12 bytes) happens at end of the samples and
|
||||
incorrect samples got dumped, so that user can find incorrect arrangement
|
||||
samples in spectral scan dump.
|
||||
|
||||
To fix this issue, we have to discard first 8 bytes and last 4 bytes in every
|
||||
samples, so totally 12 bytes are discarded. In every sample we need to consider
|
||||
the offset while taking the actual spectral data. For QCA9984, QCA9888 the
|
||||
offset is 8 bytes (segment index + extra bins before actual data).
|
||||
|
||||
Hardware tested: QCA9984 and QCA9888
|
||||
Firmware tested: 10.4-3.5.3-00053
|
||||
|
||||
Signed-off-by: Karthikeyan Periyasamy <periyasa@codeaurora.org>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ath/ath10k/core.c | 13 +++++++++++++
|
||||
drivers/net/wireless/ath/ath10k/hw.h | 3 +++
|
||||
drivers/net/wireless/ath/ath10k/spectral.c | 2 +-
|
||||
3 files changed, 17 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath10k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/core.c
|
||||
@@ -72,6 +72,7 @@ static const struct ath10k_hw_params ath
|
||||
.hw_ops = &qca988x_ops,
|
||||
.decap_align_bytes = 4,
|
||||
.spectral_bin_discard = 0,
|
||||
+ .spectral_bin_offset = 0,
|
||||
.vht160_mcs_rx_highest = 0,
|
||||
.vht160_mcs_tx_highest = 0,
|
||||
.n_cipher_suites = 8,
|
||||
@@ -96,6 +97,7 @@ static const struct ath10k_hw_params ath
|
||||
.hw_ops = &qca988x_ops,
|
||||
.decap_align_bytes = 4,
|
||||
.spectral_bin_discard = 0,
|
||||
+ .spectral_bin_offset = 0,
|
||||
.vht160_mcs_rx_highest = 0,
|
||||
.vht160_mcs_tx_highest = 0,
|
||||
.n_cipher_suites = 8,
|
||||
@@ -119,6 +121,7 @@ static const struct ath10k_hw_params ath
|
||||
.hw_ops = &qca988x_ops,
|
||||
.decap_align_bytes = 4,
|
||||
.spectral_bin_discard = 0,
|
||||
+ .spectral_bin_offset = 0,
|
||||
.vht160_mcs_rx_highest = 0,
|
||||
.vht160_mcs_tx_highest = 0,
|
||||
.n_cipher_suites = 8,
|
||||
@@ -142,6 +145,7 @@ static const struct ath10k_hw_params ath
|
||||
.hw_ops = &qca988x_ops,
|
||||
.decap_align_bytes = 4,
|
||||
.spectral_bin_discard = 0,
|
||||
+ .spectral_bin_offset = 0,
|
||||
.vht160_mcs_rx_highest = 0,
|
||||
.vht160_mcs_tx_highest = 0,
|
||||
.n_cipher_suites = 8,
|
||||
@@ -165,6 +169,8 @@ static const struct ath10k_hw_params ath
|
||||
.hw_ops = &qca988x_ops,
|
||||
.decap_align_bytes = 4,
|
||||
.spectral_bin_discard = 0,
|
||||
+ .spectral_bin_offset = 0,
|
||||
+ .spectral_bin_offset = 0,
|
||||
.vht160_mcs_rx_highest = 0,
|
||||
.vht160_mcs_tx_highest = 0,
|
||||
.n_cipher_suites = 8,
|
||||
@@ -191,6 +197,7 @@ static const struct ath10k_hw_params ath
|
||||
.target_cpu_freq = 176000000,
|
||||
.decap_align_bytes = 4,
|
||||
.spectral_bin_discard = 0,
|
||||
+ .spectral_bin_offset = 0,
|
||||
.vht160_mcs_rx_highest = 0,
|
||||
.vht160_mcs_tx_highest = 0,
|
||||
.n_cipher_suites = 8,
|
||||
@@ -220,6 +227,7 @@ static const struct ath10k_hw_params ath
|
||||
.hw_ops = &qca99x0_ops,
|
||||
.decap_align_bytes = 1,
|
||||
.spectral_bin_discard = 4,
|
||||
+ .spectral_bin_offset = 0,
|
||||
.vht160_mcs_rx_highest = 0,
|
||||
.vht160_mcs_tx_highest = 0,
|
||||
.n_cipher_suites = 11,
|
||||
@@ -250,6 +258,7 @@ static const struct ath10k_hw_params ath
|
||||
.hw_ops = &qca99x0_ops,
|
||||
.decap_align_bytes = 1,
|
||||
.spectral_bin_discard = 12,
|
||||
+ .spectral_bin_offset = 8,
|
||||
|
||||
/* Can do only 2x2 VHT160 or 80+80. 1560Mbps is 4x4 80Mhz
|
||||
* or 2x2 160Mhz, long-guard-interval.
|
||||
@@ -283,6 +292,7 @@ static const struct ath10k_hw_params ath
|
||||
.hw_ops = &qca99x0_ops,
|
||||
.decap_align_bytes = 1,
|
||||
.spectral_bin_discard = 12,
|
||||
+ .spectral_bin_offset = 8,
|
||||
|
||||
/* Can do only 1x1 VHT160 or 80+80. 780Mbps is 2x2 80Mhz or
|
||||
* 1x1 160Mhz, long-guard-interval.
|
||||
@@ -310,6 +320,7 @@ static const struct ath10k_hw_params ath
|
||||
.hw_ops = &qca988x_ops,
|
||||
.decap_align_bytes = 4,
|
||||
.spectral_bin_discard = 0,
|
||||
+ .spectral_bin_offset = 0,
|
||||
.vht160_mcs_rx_highest = 0,
|
||||
.vht160_mcs_tx_highest = 0,
|
||||
.n_cipher_suites = 8,
|
||||
@@ -335,6 +346,7 @@ static const struct ath10k_hw_params ath
|
||||
.target_cpu_freq = 176000000,
|
||||
.decap_align_bytes = 4,
|
||||
.spectral_bin_discard = 0,
|
||||
+ .spectral_bin_offset = 0,
|
||||
.vht160_mcs_rx_highest = 0,
|
||||
.vht160_mcs_tx_highest = 0,
|
||||
.n_cipher_suites = 8,
|
||||
@@ -365,6 +377,7 @@ static const struct ath10k_hw_params ath
|
||||
.hw_ops = &qca99x0_ops,
|
||||
.decap_align_bytes = 1,
|
||||
.spectral_bin_discard = 4,
|
||||
+ .spectral_bin_offset = 0,
|
||||
.vht160_mcs_rx_highest = 0,
|
||||
.vht160_mcs_tx_highest = 0,
|
||||
.n_cipher_suites = 11,
|
||||
--- a/drivers/net/wireless/ath/ath10k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/hw.h
|
||||
@@ -553,6 +553,9 @@ struct ath10k_hw_params {
|
||||
|
||||
/* Number of ciphers supported (i.e First N) in cipher_suites array */
|
||||
int n_cipher_suites;
|
||||
+
|
||||
+ /* Number of bytes to be the offset for each FFT sample */
|
||||
+ int spectral_bin_offset;
|
||||
};
|
||||
|
||||
struct htt_rx_desc;
|
||||
--- a/drivers/net/wireless/ath/ath10k/spectral.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/spectral.c
|
||||
@@ -145,7 +145,7 @@ int ath10k_spectral_process_fft(struct a
|
||||
fft_sample->noise = __cpu_to_be16(phyerr->nf_chains[chain_idx]);
|
||||
|
||||
bins = (u8 *)fftr;
|
||||
- bins += sizeof(*fftr);
|
||||
+ bins += sizeof(*fftr) + ar->hw_params.spectral_bin_offset;
|
||||
|
||||
fft_sample->tsf = __cpu_to_be64(tsf);
|
||||
|
|
@ -14,7 +14,7 @@ Signed-off-by: Sven Eckelmann <sven@open-mesh.com>
|
|||
|
||||
--- a/drivers/net/wireless/ath/ath10k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/core.c
|
||||
@@ -2494,6 +2494,16 @@ int ath10k_core_register(struct ath10k *
|
||||
@@ -2507,6 +2507,16 @@ int ath10k_core_register(struct ath10k *
|
||||
ar->chip_id = chip_id;
|
||||
queue_work(ar->workqueue, &ar->register_work);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -8080,6 +8080,21 @@ static int ath10k_mac_init_rd(struct ath
|
||||
@@ -8122,6 +8122,21 @@ static int ath10k_mac_init_rd(struct ath
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
|||
int ath10k_mac_register(struct ath10k *ar)
|
||||
{
|
||||
static const u32 cipher_suites[] = {
|
||||
@@ -8352,6 +8367,12 @@ int ath10k_mac_register(struct ath10k *a
|
||||
@@ -8397,6 +8412,12 @@ int ath10k_mac_register(struct ath10k *a
|
||||
|
||||
wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- a/drivers/net/wireless/ath/ath10k/core.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/core.c
|
||||
@@ -770,7 +770,7 @@ static int ath10k_core_get_board_id_from
|
||||
@@ -783,7 +783,7 @@ static int ath10k_core_get_board_id_from
|
||||
if (ret) {
|
||||
ath10k_err(ar, "could not execute otp for board id check: %d\n",
|
||||
ret);
|
||||
|
|
|
@ -1,31 +1,26 @@
|
|||
From: Sebastian Gottschall <s.gottsch...@dd-wrt.com>
|
||||
From: Sebastian Gottschall <s.gottschall@dd-wrt.com>
|
||||
|
||||
current handling of peer_bw_rxnss_override parameter is based on guessing the
|
||||
VHT160/8080 capability by rx rate. this is wrong and may lead
|
||||
to a non initialized peer_bw_rxnss_override parameter which is required since
|
||||
VHT160 operation mode only supports 2x2 chainmasks in addition the original code
|
||||
current handling of peer_bw_rxnss_override parameter is based on guessing the VHT160/8080 capability by rx rate. this is wrong and may lead
|
||||
to a non initialized peer_bw_rxnss_override parameter which is required since VHT160 operation mode only supports 2x2 chainmasks in addition the original code
|
||||
initialized the parameter with wrong masked values.
|
||||
This patch uses the peer phymode and peer nss information for correct
|
||||
initialisation of the peer_bw_rxnss_override parameter.
|
||||
if this peer information is not available, we initialize the parameter by
|
||||
minimum nss which is suggested by QCA as temporary workaround according
|
||||
This patch uses the peer phymode and peer nss information for correct initialisation of the peer_bw_rxnss_override parameter.
|
||||
if this peer information is not available, we initialize the parameter by minimum nss which is suggested by QCA as temporary workaround according
|
||||
to the QCA sourcecodes.
|
||||
|
||||
Signed-off-by: Sebastian Gottschall <s.gottsch...@dd-wrt.com>
|
||||
Signed-off-by: Sebastian Gottschall <s.gottschall@dd-wrt.com>
|
||||
|
||||
v2: remove debug messages
|
||||
v3: apply some cosmetics, update documentation
|
||||
v4: fix compile warning and truncate nss to maximum of 2x2 since current
|
||||
chipsets only support 2x2 at vht160
|
||||
v4: fix compile warning and truncate nss to maximum of 2x2 since current chipsets only support 2x2 at vht160
|
||||
v5: handle maximum nss for chipsets supportig vht160 with 1x1 only
|
||||
v7: use more simple code variant and take care about hw/sw chainmask
|
||||
configuration
|
||||
v7: use more simple code variant and take care about hw/sw chainmask configuration
|
||||
v8: fix some code style issues
|
||||
v9: use SM/MS macros from code.h to simplify shift/mask handling
|
||||
---
|
||||
drivers/net/wireless/ath/ath10k/mac.c | 40 +++++++++++++++------------
|
||||
drivers/net/wireless/ath/ath10k/wmi.c | 7 +----
|
||||
drivers/net/wireless/ath/ath10k/wmi.h | 14 +++++++++-
|
||||
3 files changed, 36 insertions(+), 25 deletions(-)
|
||||
|
||||
drivers/net/wireless/ath/ath10k/mac.c | 54 +++++++++++++++++++--------
|
||||
drivers/net/wireless/ath/ath10k/wmi.c | 7 +---
|
||||
drivers/net/wireless/ath/ath10k/wmi.h | 14 ++++++-
|
||||
3 files changed, 52 insertions(+), 23 deletions(-)
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -2466,7 +2466,7 @@ static void ath10k_peer_assoc_h_vht(stru
|
||||
|
@ -37,7 +32,7 @@ configuration
|
|||
|
||||
if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
|
||||
return;
|
||||
@@ -2526,23 +2526,27 @@ static void ath10k_peer_assoc_h_vht(stru
|
||||
@@ -2526,23 +2526,45 @@ static void ath10k_peer_assoc_h_vht(stru
|
||||
__le16_to_cpu(vht_cap->vht_mcs.tx_highest);
|
||||
arg->peer_vht_rates.tx_mcs_set = ath10k_peer_assoc_h_vht_limit(
|
||||
__le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask);
|
||||
|
@ -46,7 +41,10 @@ configuration
|
|||
|
||||
- ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
|
||||
- sta->addr, arg->peer_max_mpdu, arg->peer_flags);
|
||||
-
|
||||
+ /* only local 4x4 configuration do support 2x2 for VHT160,
|
||||
+ * everything else must use 1x1
|
||||
+ */
|
||||
|
||||
- if (arg->peer_vht_rates.rx_max_rate &&
|
||||
- (sta->vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK)) {
|
||||
- switch (arg->peer_vht_rates.rx_max_rate) {
|
||||
|
@ -59,28 +57,42 @@ configuration
|
|||
- arg->peer_bw_rxnss_override = 1;
|
||||
- break;
|
||||
- }
|
||||
+ /* only 4x4 configuration do support 2x2 for VHT160, everything else must use 1x1 */
|
||||
+ if (ar->cfg_rx_chainmask == 15)
|
||||
+ nss160 = arg->peer_num_spatial_streams <= 2 ? arg->peer_num_spatial_streams : 2;
|
||||
+ nss160 = arg->peer_num_spatial_streams <= 2 ? 1 : 2;
|
||||
+
|
||||
+ /* in case if peer is connected with vht160 or vht80+80, we need to properly adjust rxnss parameters otherwise firmware will raise a assert */
|
||||
+ switch(arg->peer_phymode) {
|
||||
+ /* if peer provides 1x1 nss160 information using max rate
|
||||
+ * vht information, we reduce local nss160 to 1x1.
|
||||
+ * consider that it has been observed that some client
|
||||
+ * devices provide zero here, no matter which transmission
|
||||
+ * rate is possible. in that case the local nss configuration
|
||||
+ * will be used at maxmimum configuration possible. (see above)
|
||||
+ */
|
||||
+
|
||||
+ if (arg->peer_vht_rates.rx_max_rate == 780)
|
||||
+ nss160 = 1;
|
||||
+
|
||||
+ /* in case if peer is connected with vht160 or vht80+80,
|
||||
+ * we need to properly adjust rxnss parameters otherwise
|
||||
+ * firmware will raise a assert
|
||||
+ */
|
||||
+ switch (arg->peer_phymode) {
|
||||
+ case MODE_11AC_VHT80_80:
|
||||
+ arg->peer_bw_rxnss_override = BW_NSS_FWCONF_80_80(nss160);
|
||||
+ /* fall through */
|
||||
+ case MODE_11AC_VHT160:
|
||||
+ arg->peer_bw_rxnss_override |= BW_NSS_FWCONF_160(nss160);
|
||||
+ break;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ break;
|
||||
}
|
||||
+
|
||||
+ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x peer_bw_rxnss_override 0x%x\n",
|
||||
+ sta->addr, arg->peer_max_mpdu, arg->peer_flags, arg->peer_bw_rxnss_override);
|
||||
+ sta->addr, arg->peer_max_mpdu, arg->peer_flags,
|
||||
+ arg->peer_bw_rxnss_override);
|
||||
}
|
||||
|
||||
static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
|
||||
@@ -2694,9 +2698,9 @@ static int ath10k_peer_assoc_prepare(str
|
||||
@@ -2694,9 +2716,9 @@ static int ath10k_peer_assoc_prepare(str
|
||||
ath10k_peer_assoc_h_crypto(ar, vif, sta, arg);
|
||||
ath10k_peer_assoc_h_rates(ar, vif, sta, arg);
|
||||
ath10k_peer_assoc_h_ht(ar, vif, sta, arg);
|
||||
|
@ -93,7 +105,7 @@ configuration
|
|||
}
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
@@ -6760,12 +6760,7 @@ ath10k_wmi_peer_assoc_fill_10_4(struct a
|
||||
@@ -7231,12 +7231,7 @@ ath10k_wmi_peer_assoc_fill_10_4(struct a
|
||||
struct wmi_10_4_peer_assoc_complete_cmd *cmd = buf;
|
||||
|
||||
ath10k_wmi_peer_assoc_fill_10_2(ar, buf, arg);
|
||||
|
@ -109,24 +121,24 @@ configuration
|
|||
static int
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
|
||||
@@ -6209,7 +6209,19 @@ struct wmi_10_2_peer_assoc_complete_cmd
|
||||
@@ -6306,7 +6306,19 @@ struct wmi_10_2_peer_assoc_complete_cmd
|
||||
__le32 info0; /* WMI_PEER_ASSOC_INFO0_ */
|
||||
} __packed;
|
||||
|
||||
-#define PEER_BW_RXNSS_OVERRIDE_OFFSET 31
|
||||
+#define BW_NSS_FWCONF_MAP_ENABLE (1 << 31)
|
||||
+#define BW_NSS_FWCONF_MAP_160MHZ_S (0)
|
||||
+#define BW_NSS_FWCONF_MAP_160MHZ_M (0x00000007)
|
||||
+#define BW_NSS_FWCONF_MAP_80_80MHZ_S (3)
|
||||
+#define BW_NSS_FWCONF_MAP_80_80MHZ_M (0x00000038)
|
||||
+#define BW_NSS_FWCONF_MAP_M (0x0000003F)
|
||||
+#define BW_NSS_FWCONF_MAP_ENABLE BIT(31)
|
||||
+#define BW_NSS_FWCONF_MAP_160MHZ_LSB (0)
|
||||
+#define BW_NSS_FWCONF_MAP_160MHZ_MASK (0x00000007)
|
||||
+#define BW_NSS_FWCONF_MAP_80_80MHZ_LSB (3)
|
||||
+#define BW_NSS_FWCONF_MAP_80_80MHZ_MASK (0x00000038)
|
||||
+#define BW_NSS_FWCONF_MAP_MASK (0x0000003F)
|
||||
+
|
||||
+#define GET_BW_NSS_FWCONF_160(x) ((((x) & BW_NSS_FWCONF_MAP_160MHZ_M) >> BW_NSS_FWCONF_MAP_160MHZ_S) + 1)
|
||||
+#define GET_BW_NSS_FWCONF_80_80(x) ((((x) & BW_NSS_FWCONF_MAP_80_80MHZ_M) >> BW_NSS_FWCONF_MAP_80_80MHZ_S) + 1)
|
||||
+#define GET_BW_NSS_FWCONF_160(x) (MS(x, BW_NSS_FWCONF_MAP_160MHZ) + 1)
|
||||
+#define GET_BW_NSS_FWCONF_80_80(x) (MS(x, BW_NSS_FWCONF_MAP_80_80MHZ) + 1)
|
||||
+
|
||||
+/* Values defined to set 160 MHz Bandwidth NSS Mapping into FW*/
|
||||
+#define BW_NSS_FWCONF_160(x) (BW_NSS_FWCONF_MAP_ENABLE | (((x - 1) << BW_NSS_FWCONF_MAP_160MHZ_S) & BW_NSS_FWCONF_MAP_160MHZ_M))
|
||||
+#define BW_NSS_FWCONF_80_80(x) (BW_NSS_FWCONF_MAP_ENABLE | (((x - 1) << BW_NSS_FWCONF_MAP_80_80MHZ_S) & BW_NSS_FWCONF_MAP_80_80MHZ_M))
|
||||
+#define BW_NSS_FWCONF_160(x) (BW_NSS_FWCONF_MAP_ENABLE | SM(x - 1, BW_NSS_FWCONF_MAP_160MHZ))
|
||||
+#define BW_NSS_FWCONF_80_80(x) (BW_NSS_FWCONF_MAP_ENABLE | SM(x - 1, BW_NSS_FWCONF_MAP_80_80MHZ))
|
||||
|
||||
struct wmi_10_4_peer_assoc_complete_cmd {
|
||||
struct wmi_10_2_peer_assoc_complete_cmd cmd;
|
||||
|
|
|
@ -4,13 +4,16 @@ starting with firmware 10.4.3.4.x series QCA changed the handling of the channel
|
|||
likelly for backward compatiblity with vht80 only capable clients.
|
||||
this patch adjusts the handling to get vht160 to work again with official qca firmwares newer than 3.3
|
||||
consider that this patch will not work with older firmwares anymore. to avoid undefined behaviour this we disable vht160 capability for outdated firmwares
|
||||
Signed-off-by: Sebastian Gottschall <s.gottschall@dd-wrt.com>
|
||||
|
||||
v2: fix trailing whitespace issue and fix some typos within the commit note
|
||||
---
|
||||
drivers/net/wireless/ath/ath10k/mac.c | 7 -------
|
||||
drivers/net/wireless/ath/ath10k/wmi.c | 11 ++++++++---
|
||||
2 files changed, 8 insertions(+), 10 deletions(-)
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -4415,13 +4415,6 @@ static struct ieee80211_sta_vht_cap ath1
|
||||
@@ -4445,13 +4445,6 @@ static struct ieee80211_sta_vht_cap ath1
|
||||
vht_cap.cap |= val;
|
||||
}
|
||||
|
||||
|
@ -26,7 +29,7 @@ consider that this patch will not work with older firmwares anymore. to avoid un
|
|||
if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
@@ -1660,13 +1660,18 @@ void ath10k_wmi_put_wmi_channel(struct w
|
||||
@@ -1672,13 +1672,18 @@ void ath10k_wmi_put_wmi_channel(struct w
|
||||
flags |= WMI_CHAN_FLAG_HT40_PLUS;
|
||||
if (arg->chan_radar)
|
||||
flags |= WMI_CHAN_FLAG_DFS;
|
||||
|
|
|
@ -140,7 +140,7 @@ v13:
|
|||
.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
|
||||
@@ -80,6 +82,7 @@ static const struct ath10k_hw_params ath
|
||||
@@ -81,6 +83,7 @@ static const struct ath10k_hw_params ath
|
||||
.id = QCA9887_HW_1_0_VERSION,
|
||||
.dev_id = QCA9887_1_0_DEVICE_ID,
|
||||
.name = "qca9887 hw1.0",
|
||||
|
@ -148,7 +148,7 @@ v13:
|
|||
.patch_load_addr = QCA9887_HW_1_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
|
||||
@@ -199,6 +202,7 @@ static const struct ath10k_hw_params ath
|
||||
@@ -206,6 +209,7 @@ static const struct ath10k_hw_params ath
|
||||
.id = QCA99X0_HW_2_0_DEV_VERSION,
|
||||
.dev_id = QCA99X0_2_0_DEVICE_ID,
|
||||
.name = "qca99x0 hw2.0",
|
||||
|
@ -156,7 +156,7 @@ v13:
|
|||
.patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.otp_exe_param = 0x00000700,
|
||||
@@ -228,6 +232,7 @@ static const struct ath10k_hw_params ath
|
||||
@@ -236,6 +240,7 @@ static const struct ath10k_hw_params ath
|
||||
.id = QCA9984_HW_1_0_DEV_VERSION,
|
||||
.dev_id = QCA9984_1_0_DEVICE_ID,
|
||||
.name = "qca9984/qca9994 hw1.0",
|
||||
|
@ -164,7 +164,7 @@ v13:
|
|||
.patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
|
||||
@@ -262,6 +267,7 @@ static const struct ath10k_hw_params ath
|
||||
@@ -271,6 +276,7 @@ static const struct ath10k_hw_params ath
|
||||
.id = QCA9888_HW_2_0_DEV_VERSION,
|
||||
.dev_id = QCA9888_2_0_DEVICE_ID,
|
||||
.name = "qca9888 hw2.0",
|
||||
|
@ -172,7 +172,7 @@ v13:
|
|||
.patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
|
||||
@@ -2254,6 +2260,10 @@ int ath10k_core_start(struct ath10k *ar,
|
||||
@@ -2267,6 +2273,10 @@ int ath10k_core_start(struct ath10k *ar,
|
||||
if (status)
|
||||
goto err_hif_stop;
|
||||
|
||||
|
@ -183,7 +183,7 @@ v13:
|
|||
return 0;
|
||||
|
||||
err_hif_stop:
|
||||
@@ -2471,9 +2481,18 @@ static void ath10k_core_register_work(st
|
||||
@@ -2484,9 +2494,18 @@ static void ath10k_core_register_work(st
|
||||
goto err_spectral_destroy;
|
||||
}
|
||||
|
||||
|
@ -202,7 +202,7 @@ v13:
|
|||
err_spectral_destroy:
|
||||
ath10k_spectral_destroy(ar);
|
||||
err_debug_destroy:
|
||||
@@ -2515,6 +2534,8 @@ void ath10k_core_unregister(struct ath10
|
||||
@@ -2528,6 +2547,8 @@ void ath10k_core_unregister(struct ath10
|
||||
if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags))
|
||||
return;
|
||||
|
||||
|
@ -221,7 +221,7 @@ v13:
|
|||
|
||||
#include "htt.h"
|
||||
#include "htc.h"
|
||||
@@ -789,7 +790,6 @@ struct ath10k {
|
||||
@@ -829,7 +830,6 @@ struct ath10k {
|
||||
u32 low_5ghz_chan;
|
||||
u32 high_5ghz_chan;
|
||||
bool ani_enabled;
|
||||
|
@ -229,7 +229,7 @@ v13:
|
|||
bool p2p;
|
||||
|
||||
struct {
|
||||
@@ -972,6 +972,13 @@ struct ath10k {
|
||||
@@ -1012,6 +1012,13 @@ struct ath10k {
|
||||
} testmode;
|
||||
|
||||
struct {
|
||||
|
@ -415,18 +415,18 @@ v13:
|
|||
/* Rates */
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
|
||||
@@ -197,6 +197,10 @@ struct wmi_ops {
|
||||
(struct ath10k *ar,
|
||||
enum wmi_bss_survey_req_type type);
|
||||
@@ -204,7 +204,10 @@ struct wmi_ops {
|
||||
struct sk_buff *(*gen_echo)(struct ath10k *ar, u32 value);
|
||||
struct sk_buff *(*gen_pdev_get_tpc_table_cmdid)(struct ath10k *ar,
|
||||
u32 param);
|
||||
+ struct sk_buff *(*gen_gpio_config)(struct ath10k *ar, u32 gpio_num,
|
||||
+ u32 input, u32 pull_type, u32 intr_mode);
|
||||
+
|
||||
|
||||
+ struct sk_buff *(*gen_gpio_output)(struct ath10k *ar, u32 gpio_num, u32 set);
|
||||
};
|
||||
|
||||
int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
|
||||
@@ -951,6 +955,35 @@ ath10k_wmi_force_fw_hang(struct ath10k *
|
||||
@@ -969,6 +972,35 @@ ath10k_wmi_force_fw_hang(struct ath10k *
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid);
|
||||
}
|
||||
|
||||
|
@ -464,7 +464,7 @@ v13:
|
|||
{
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
|
||||
@@ -3619,6 +3619,8 @@ static const struct wmi_ops wmi_tlv_ops
|
||||
@@ -3652,6 +3652,8 @@ static const struct wmi_ops wmi_tlv_ops
|
||||
.gen_echo = ath10k_wmi_tlv_op_gen_echo,
|
||||
.gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf,
|
||||
.gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable,
|
||||
|
@ -475,7 +475,7 @@ v13:
|
|||
static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = {
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
|
||||
@@ -6580,6 +6580,49 @@ ath10k_wmi_op_gen_peer_set_param(struct
|
||||
@@ -7051,6 +7051,49 @@ ath10k_wmi_op_gen_peer_set_param(struct
|
||||
return skb;
|
||||
}
|
||||
|
||||
|
@ -525,7 +525,7 @@ v13:
|
|||
static struct sk_buff *
|
||||
ath10k_wmi_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id,
|
||||
enum wmi_sta_ps_mode psmode)
|
||||
@@ -8081,6 +8124,9 @@ static const struct wmi_ops wmi_ops = {
|
||||
@@ -8596,6 +8639,9 @@ static const struct wmi_ops wmi_ops = {
|
||||
.fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
|
||||
.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
|
||||
.gen_echo = ath10k_wmi_op_gen_echo,
|
||||
|
@ -535,7 +535,7 @@ v13:
|
|||
/* .gen_bcn_tmpl not implemented */
|
||||
/* .gen_prb_tmpl not implemented */
|
||||
/* .gen_p2p_go_bcn_ie not implemented */
|
||||
@@ -8151,6 +8197,8 @@ static const struct wmi_ops wmi_10_1_ops
|
||||
@@ -8666,6 +8712,8 @@ static const struct wmi_ops wmi_10_1_ops
|
||||
.fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
|
||||
.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
|
||||
.gen_echo = ath10k_wmi_op_gen_echo,
|
||||
|
@ -544,7 +544,7 @@ v13:
|
|||
/* .gen_bcn_tmpl not implemented */
|
||||
/* .gen_prb_tmpl not implemented */
|
||||
/* .gen_p2p_go_bcn_ie not implemented */
|
||||
@@ -8222,6 +8270,8 @@ static const struct wmi_ops wmi_10_2_ops
|
||||
@@ -8737,6 +8785,8 @@ static const struct wmi_ops wmi_10_2_ops
|
||||
.gen_delba_send = ath10k_wmi_op_gen_delba_send,
|
||||
.fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
|
||||
.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
|
||||
|
@ -553,7 +553,7 @@ v13:
|
|||
/* .gen_pdev_enable_adaptive_cca not implemented */
|
||||
};
|
||||
|
||||
@@ -8292,6 +8342,8 @@ static const struct wmi_ops wmi_10_2_4_o
|
||||
@@ -8807,6 +8857,8 @@ static const struct wmi_ops wmi_10_2_4_o
|
||||
.gen_pdev_enable_adaptive_cca =
|
||||
ath10k_wmi_op_gen_pdev_enable_adaptive_cca,
|
||||
.get_vdev_subtype = ath10k_wmi_10_2_4_op_get_vdev_subtype,
|
||||
|
@ -562,7 +562,7 @@ v13:
|
|||
/* .gen_bcn_tmpl not implemented */
|
||||
/* .gen_prb_tmpl not implemented */
|
||||
/* .gen_p2p_go_bcn_ie not implemented */
|
||||
@@ -8367,6 +8419,8 @@ static const struct wmi_ops wmi_10_4_ops
|
||||
@@ -8886,6 +8938,8 @@ static const struct wmi_ops wmi_10_4_ops
|
||||
.gen_pdev_bss_chan_info_req = ath10k_wmi_10_2_op_gen_pdev_bss_chan_info,
|
||||
.gen_echo = ath10k_wmi_op_gen_echo,
|
||||
.gen_pdev_get_tpc_config = ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config,
|
||||
|
@ -573,7 +573,7 @@ v13:
|
|||
int ath10k_wmi_attach(struct ath10k *ar)
|
||||
--- a/drivers/net/wireless/ath/ath10k/wmi.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
|
||||
@@ -2899,6 +2899,41 @@ enum wmi_10_4_feature_mask {
|
||||
@@ -2930,6 +2930,41 @@ enum wmi_10_4_feature_mask {
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -16,9 +16,9 @@ Signed-off-by: Mathias Kresin <dev@kresin.me>
|
|||
|
||||
--- a/drivers/net/wireless/ath/ath10k/core.h
|
||||
+++ b/drivers/net/wireless/ath/ath10k/core.h
|
||||
@@ -1010,6 +1010,10 @@ struct ath10k {
|
||||
|
||||
void *ce_priv;
|
||||
@@ -1055,6 +1055,10 @@ struct ath10k {
|
||||
struct ath10k_radar_found_info last_radar_info;
|
||||
struct work_struct radar_confirmation_work;
|
||||
|
||||
+#ifdef CPTCFG_MAC80211_LEDS
|
||||
+ const char *led_default_trigger;
|
||||
|
@ -42,7 +42,7 @@ Signed-off-by: Mathias Kresin <dev@kresin.me>
|
|||
if (ret)
|
||||
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
||||
@@ -8366,7 +8366,7 @@ int ath10k_mac_register(struct ath10k *a
|
||||
@@ -8429,7 +8429,7 @@ int ath10k_mac_register(struct ath10k *a
|
||||
wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
|
||||
|
||||
#ifdef CPTCFG_MAC80211_LEDS
|
||||
|
|
Loading…
Reference in a new issue