[PATCH] ath10k: fix PCIE device wake up failed

2019-05-29 Thread Miaoqing Pan
Observed PCIE device wake up failed after ~120 iterations of
soft-reboot test. The error message is
"ath10k_pci :01:00.0: failed to wake up device : -110"

The call trace as below:
ath10k_pci_probe -> ath10k_pci_force_wake -> ath10k_pci_wake_wait ->
ath10k_pci_is_awake

Once trigger the device to wake up, we will continuously check the RTC
state until it returns RTC_STATE_V_ON or timeout.

But for QCA99x0 chips, we use wrong value for RTC_STATE_V_ON.
Occasionally, we get 0x7 on the fist read, we thought as a failure
case, but actually is the right value, also verified with the spec.
So fix the issue by changing RTC_STATE_V_ON from 0x5 to 0x7, passed
~2000 iterations.

Tested HW: QCA9984

Signed-off-by: Miaoqing Pan 
---
 drivers/net/wireless/ath/ath10k/hw.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/ath10k/hw.c 
b/drivers/net/wireless/ath/ath10k/hw.c
index ad082b7..b242085 100644
--- a/drivers/net/wireless/ath/ath10k/hw.c
+++ b/drivers/net/wireless/ath/ath10k/hw.c
@@ -158,7 +158,7 @@
 };
 
 const struct ath10k_hw_values qca99x0_values = {
-   .rtc_state_val_on   = 5,
+   .rtc_state_val_on   = 7,
.ce_count   = 12,
.msi_assign_ce_max  = 12,
.num_target_ce_config_wlan  = 10,
-- 
1.9.1



[PATCH v2] ath10k: fix failure to set multiple fixed rate

2019-05-29 Thread Miaoqing Pan
Currently, below fixed rate commands are broken,
iw wlanx set bitrates legacy-<2.4|5> ht-mcs-<2.4|5> vht-mcs-<2.4|5> \

iw wlanx set bitrates legacy-<2.4|5>  ht-mcs-<2.4|5> \
vht-mcs-<2.4|5> 

There are two methods to set fixed rate, both failed,
- Use vdev fixed rate command
  This command only support one single rate, but it's broken due to
  mac80211 change commit e8e4f5280ddd ("mac80211: reject/clear user
  rate mask if not usable"), which requires user to specify at least
  one legacy rate. So we can't use this command to set ht/vht single
  rate any more.
- Use peer_assoc command
  This command can update rx capability for multiple rates, it will
  work fine for ht mcs rates, as each supported mcs can be advertised
  in ht_mcs index mask. But this will not work with vht rates because,
  as per the vht mcs capability advertisement, there are only two bits
  to indicate the supported mcs. E.g. only support 0-7, 0-8, 0-9.

So introduced new WMI command: WMI_PEER_PARAM_FIXED_RATE. After peer
assoc, the peer fixed rate cmd will work for that specific peer.
Remaining peers will use auto rate. If both vdev fixed rate and peer
fixed rates are given, peer fixed rate will take effect to peers for
which this cmd is given. Remaining peers in that vdev, will use vdev
fixed rate.

Tested HW: QCA9984
Tested FW: 10.4-3.9.0.2-00035

Signed-off-by: Miaoqing Pan 
---
Changes since v1
- update commit message, remove 2nd broken command
---
 drivers/net/wireless/ath/ath10k/core.c |   1 +
 drivers/net/wireless/ath/ath10k/core.h |   7 +++
 drivers/net/wireless/ath/ath10k/mac.c  | 111 +
 drivers/net/wireless/ath/ath10k/wmi.h  |   1 +
 4 files changed, 108 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.c 
b/drivers/net/wireless/ath/ath10k/core.c
index 61ef903..811cf38 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -612,6 +612,7 @@
[ATH10K_FW_FEATURE_MGMT_TX_BY_REF] = "mgmt-tx-by-reference",
[ATH10K_FW_FEATURE_NON_BMI] = "non-bmi",
[ATH10K_FW_FEATURE_SINGLE_CHAN_INFO_PER_CHANNEL] = 
"single-chan-info-per-channel",
+   [ATH10K_FW_FEATURE_PEER_FIXED_RATE] = "peer-fixed-rate",
 };
 
 static unsigned int ath10k_core_get_fw_feature_str(char *buf,
diff --git a/drivers/net/wireless/ath/ath10k/core.h 
b/drivers/net/wireless/ath/ath10k/core.h
index 2d109c0..fe6e88d 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -579,6 +579,10 @@ struct ath10k_vif {
struct work_struct ap_csa_work;
struct delayed_work connection_loss_work;
struct cfg80211_bitrate_mask bitrate_mask;
+
+   /* For setting VHT peer fixed rate, protected by conf_mutex */
+   int vht_num_rates;
+   u8 vht_pfr;
 };
 
 struct ath10k_vif_iter {
@@ -770,6 +774,9 @@ enum ath10k_fw_features {
/* Firmware sends only one chan_info event per channel */
ATH10K_FW_FEATURE_SINGLE_CHAN_INFO_PER_CHANNEL = 20,
 
+   /* Firmware allows setting peer fixed rate */
+   ATH10K_FW_FEATURE_PEER_FIXED_RATE = 21,
+
/* keep last */
ATH10K_FW_FEATURE_COUNT,
 };
diff --git a/drivers/net/wireless/ath/ath10k/mac.c 
b/drivers/net/wireless/ath/ath10k/mac.c
index b500fd4..e555a22 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -7107,18 +7107,23 @@ static int ath10k_get_survey(struct ieee80211_hw *hw, 
int idx,
 static bool
 ath10k_mac_bitrate_mask_has_single_rate(struct ath10k *ar,
enum nl80211_band band,
-   const struct cfg80211_bitrate_mask 
*mask)
+   const struct cfg80211_bitrate_mask 
*mask,
+   int *vht_num_rates)
 {
int num_rates = 0;
-   int i;
+   int i, tmp;
 
num_rates += hweight32(mask->control[band].legacy);
 
for (i = 0; i < ARRAY_SIZE(mask->control[band].ht_mcs); i++)
num_rates += hweight8(mask->control[band].ht_mcs[i]);
 
-   for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++)
-   num_rates += hweight16(mask->control[band].vht_mcs[i]);
+   *vht_num_rates = 0;
+   for (i = 0; i < ARRAY_SIZE(mask->control[band].vht_mcs); i++) {
+   tmp = hweight16(mask->control[band].vht_mcs[i]);
+   num_rates += tmp;
+   *vht_num_rates += tmp;
+   }
 
return num_rates == 1;
 }
@@ -7176,7 +7181,7 @@ static int ath10k_get_survey(struct ieee80211_hw *hw, int 
idx,
 ath10k_mac_bitrate_mask_get_single_rate(struct ath10k *ar,
enum nl80211_band band,
const struct cfg80211_bitrate_mask 
*mask,
-   u8 *rate, u8 *nss)
+   u8 *rate, u8 *nss, bool vht_only)
 {
int rate_i