[RFC v4 0/2] ath10k: Add support to update tx rate to mac80211

2018-09-24 Thread Anilkumar Kolli
Tx rate was updated to nl80211/user using sta_statistics callback.
This rate can not be used for mac80211 mesh and ATF.

This patch adds support to update tx rate to mac80211

Anilkumar Kolli (2):
  mac80211: implement ieee80211_tx_rate_update to update rate
  ath10k: report tx rate using ieee80211_tx_rate_update()

 drivers/net/wireless/ath/ath10k/core.h   |1 +
 drivers/net/wireless/ath/ath10k/htt_rx.c |   66 --
 drivers/net/wireless/ath/ath10k/wmi.h|1 +
 include/net/mac80211.h   |   15 +++
 net/mac80211/status.c|   22 ++
 5 files changed, 101 insertions(+), 4 deletions(-)

-- 
1.7.9.5


___
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k


[RFC v4 1/2] mac80211: implement ieee80211_tx_rate_update to update rate

2018-09-24 Thread Anilkumar Kolli
Current mac80211 has provision to update tx status through
ieee80211_tx_status() and ieee80211_tx_status_ext(). But
drivers like ath10k updates the tx status from the skb except
txrate, txrate will be updated from a different path, peer stats.

Using ieee80211_tx_status_ext() in two different paths
  - (one for the stats, one for the tx rate) will duplicate the stats.

To avoid this stats duplication, ieee80211_tx_rate_update() is implemented.

Signed-off-by: Anilkumar Kolli 
---
V3:
  - Added new API in mac80211 to update tx rate(Johannes)
V4:
  - Removed non NULL check on pubsta and updated comments on
ieee80211_tx_rate_update()

 include/net/mac80211.h |   15 +++
 net/mac80211/status.c  |   22 ++
 2 files changed, 37 insertions(+)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 8c26d2d36cbe..86f6253a68c4 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -4331,6 +4331,21 @@ void ieee80211_sta_set_expected_throughput(struct 
ieee80211_sta *pubsta,
   u32 thr);
 
 /**
+ * ieee80211_tx_rate_update - transmit rate update callback
+ *
+ * Drivers should call this functions with a non-NULL pubsta
+ * This function can be used in drivers that does not have provision
+ * in updating the tx rate in data path.
+ *
+ * @hw: the hardware the frame was transmitted by
+ * @pubsta: the station to update the tx rate for.
+ * @info: tx status information
+ */
+void ieee80211_tx_rate_update(struct ieee80211_hw *hw,
+ struct ieee80211_sta *pubsta,
+ struct ieee80211_tx_info *info);
+
+/**
  * ieee80211_tx_status - transmit status callback
  *
  * Call this function for all transmitted frames after they have been
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 9a6d7208bf4f..a67547970a36 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -988,6 +988,28 @@ void ieee80211_tx_status_ext(struct ieee80211_hw *hw,
 }
 EXPORT_SYMBOL(ieee80211_tx_status_ext);
 
+void ieee80211_tx_rate_update(struct ieee80211_hw *hw,
+ struct ieee80211_sta *pubsta,
+ struct ieee80211_tx_info *info)
+{
+   struct ieee80211_local *local = hw_to_local(hw);
+   struct ieee80211_supported_band *sband;
+   struct sta_info *sta;
+   struct ieee80211_tx_status status;
+
+   sband = hw->wiphy->bands[info->band];
+
+   sta = container_of(pubsta, struct sta_info, sta);
+   status.skb = NULL;
+   status.info = info;
+   status.sta = pubsta;
+
+   rate_control_tx_status(local, sband, &status);
+   if (ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL))
+   sta->tx_stats.last_rate = info->status.rates[0];
+}
+EXPORT_SYMBOL(ieee80211_tx_rate_update);
+
 void ieee80211_report_low_ack(struct ieee80211_sta *pubsta, u32 num_packets)
 {
struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
-- 
1.7.9.5


___
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k


[RFC v4 2/2] ath10k: report tx rate using ieee80211_tx_rate_update()

2018-09-24 Thread Anilkumar Kolli
Mesh path metric needs tx rate information from ieee80211_tx_status()
call but in ath10k there is no mechanism to report tx rate information
via ieee80211_tx_status(), the tx rate is only accessible via
sta_statiscs() op.

Per peer tx stats has tx rate info available, Tx rate is available
to ath10k driver after every 4 PPDU sent in the air. For each PPDU,
ath10k driver updates rate informattion to mac80211 using
ieee80211_tx_rate_update().

Per peer txrate information is updated through per peer statistics
and is available for QCA9888/QCA9984/QCA4019/QCA998X only

Tested on QCA9984 with firmware-5.bin_10.4-3.5.3-00053
Tested on QCA998X with firmware-5.bin_10.2.4-1.0-00036

Signed-off-by: Anilkumar Kolli 
---
V3:
  - added new API to update tx rate alone.
  - Tx rate is updated for each PPDUs sent

 drivers/net/wireless/ath/ath10k/core.h   |1 +
 drivers/net/wireless/ath/ath10k/htt_rx.c |   66 --
 drivers/net/wireless/ath/ath10k/wmi.h|1 +
 3 files changed, 64 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/core.h 
b/drivers/net/wireless/ath/ath10k/core.h
index f6e5c29f74e7..abeed6cdc4ae 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -493,6 +493,7 @@ struct ath10k_sta {
u32 smps;
u16 peer_id;
struct rate_info txrate;
+   struct ieee80211_tx_info tx_info;
 
struct work_struct update_wk;
u64 rx_duration;
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c 
b/drivers/net/wireless/ath/ath10k/htt_rx.c
index f2405258a6d3..355c39a0486c 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -2753,8 +2753,11 @@ static inline int ath10k_get_legacy_rate_idx(struct 
ath10k *ar, u8 rate)
struct ath10k_per_peer_tx_stats *peer_stats)
 {
struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv;
-   u8 rate = 0, rate_idx = 0, sgi;
+   struct ieee80211_chanctx_conf *conf = NULL;
struct rate_info txrate;
+   u8 rate = 0, sgi;
+   int rate_idx = 0;
+   bool skip_auto_rate;
 
lockdep_assert_held(&ar->data_lock);
 
@@ -2763,6 +2766,13 @@ static inline int ath10k_get_legacy_rate_idx(struct 
ath10k *ar, u8 rate)
txrate.nss = ATH10K_HW_NSS(peer_stats->ratecode);
txrate.mcs = ATH10K_HW_MCS_RATE(peer_stats->ratecode);
sgi = ATH10K_HW_GI(peer_stats->flags);
+   skip_auto_rate = ATH10K_FW_SKIPPED_RATE_CTRL(peer_stats->flags);
+
+   /* Firmware's rate control skips broadcast/management frames,
+* if host has configure fixed rates and in some other special cases.
+*/
+   if (skip_auto_rate)
+   return;
 
if (txrate.flags == WMI_RATE_PREAMBLE_VHT && txrate.mcs > 9) {
ath10k_warn(ar, "Invalid VHT mcs %hhd peer stats",  txrate.mcs);
@@ -2777,7 +2787,7 @@ static inline int ath10k_get_legacy_rate_idx(struct 
ath10k *ar, u8 rate)
}
 
memset(&arsta->txrate, 0, sizeof(arsta->txrate));
-
+   memset(&arsta->tx_info.status, 0, sizeof(arsta->tx_info.status));
if (txrate.flags == WMI_RATE_PREAMBLE_CCK ||
txrate.flags == WMI_RATE_PREAMBLE_OFDM) {
rate = ATH10K_HW_LEGACY_RATE(peer_stats->ratecode);
@@ -2796,11 +2806,59 @@ static inline int ath10k_get_legacy_rate_idx(struct 
ath10k *ar, u8 rate)
arsta->txrate.mcs = txrate.mcs;
}
 
-   if (sgi)
-   arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+   switch (txrate.flags) {
+   case WMI_RATE_PREAMBLE_OFDM:
+   if (arsta->arvif && arsta->arvif->vif)
+   conf = rcu_dereference(arsta->arvif->vif->chanctx_conf);
+   if (conf && conf->def.chan->band == NL80211_BAND_5GHZ)
+   arsta->tx_info.status.rates[0].idx = rate_idx - 4;
+   break;
+   case WMI_RATE_PREAMBLE_CCK:
+   arsta->tx_info.status.rates[0].idx = rate_idx;
+   if (sgi)
+   arsta->tx_info.status.rates[0].flags |=
+   (IEEE80211_TX_RC_USE_SHORT_PREAMBLE |
+IEEE80211_TX_RC_SHORT_GI);
+   break;
+   case WMI_RATE_PREAMBLE_HT:
+   arsta->tx_info.status.rates[0].idx =
+   txrate.mcs + ((txrate.nss - 1) * 8);
+   if (sgi)
+   arsta->tx_info.status.rates[0].flags |=
+   IEEE80211_TX_RC_SHORT_GI;
+   arsta->tx_info.status.rates[0].flags |= IEEE80211_TX_RC_MCS;
+   break;
+   case WMI_RATE_PREAMBLE_VHT:
+   ieee80211_rate_set_vht(&arsta->tx_info.status.rates[0],
+  txrate.mcs, txrate.nss);
+   if (sgi)
+   arsta->tx_info.status.rates[0].flags |=
+  

Re: [ath6kl:pending 39/55] drivers/net/wireless/ath/ath10k/mac.c:169 ath10k_mac_get_rate_hw_value() error: buffer overflow 'ath10k_rates' 12 <= 143

2018-09-24 Thread Kalle Valo
Dan Carpenter  writes:

> tree:   https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git pending
> head:   2305dc3c6b1d66a7bef752439919d61478e02893
> commit: 0c737c78082055ff589f6683e93b45f079c5d64e [39/55] ath10k: Add
> support for configuring management packet rate
>
> New smatch warnings:
> drivers/net/wireless/ath/ath10k/mac.c:169
> ath10k_mac_get_rate_hw_value() error: buffer overflow 'ath10k_rates'
> 12 <= 143
>
> Old smatch warnings:
> drivers/net/wireless/ath/ath10k/mac.c:170
> ath10k_mac_get_rate_hw_value() error: buffer overflow 'ath10k_rates'
> 12 <= 143
>
> #
> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?id=0c737c78082055ff589f6683e93b45f079c5d64e
> git remote add ath6kl 
> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
> git remote update ath6kl
> git checkout 0c737c78082055ff589f6683e93b45f079c5d64e
> vim +/ath10k_rates +169 drivers/net/wireless/ath/ath10k/mac.c
>
> 01cebe1c Michal Kazior 2015-03-30  159  
> 0c737c78 Sriram R  2018-09-10  160  static int 
> ath10k_mac_get_rate_hw_value(int bitrate)
> 0c737c78 Sriram R  2018-09-10  161  {
> 0c737c78 Sriram R  2018-09-10  162int i;
> 0c737c78 Sriram R  2018-09-10  163u8 hw_value_prefix = 0;
> 0c737c78 Sriram R  2018-09-10  164  
> 0c737c78 Sriram R  2018-09-10  165if 
> (ath10k_mac_bitrate_is_cck(bitrate))
> 0c737c78 Sriram R 2018-09-10 166 hw_value_prefix =
> WMI_RATE_PREAMBLE_CCK << 6;
> 0c737c78 Sriram R  2018-09-10  167  
> 0c737c78 Sriram R  2018-09-10  168for (i = 0; i < 
> sizeof(ath10k_rates); i++) {
> 
> 
> This should be ARRAY_SIZE(ath10k_rates) instead of sizeof().

Makes sense. Can someone submit a patch, please?

-- 
Kalle Valo

___
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k


Re: [PATCH 2/4] dts: arm64/sdm845: Add WCN3990 WLAN module device node

2018-09-24 Thread Brian Norris
Hi,

On Fri, Sep 21, 2018 at 02:39:05PM +0530, Govind Singh wrote:
> Add device node for the ath10k SNOC platform driver probe
> and add resources required for WCN3990 on SDM845 soc.
> 
> Signed-off-by: Govind Singh 
> ---
>  arch/arm64/boot/dts/qcom/sdm845-mtp.dts |  7 +++
>  arch/arm64/boot/dts/qcom/sdm845.dtsi| 25 +
>  2 files changed, 32 insertions(+)
> 
> diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts 
> b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
> index eedfaf8922e2..4de57f7df93c 100644
> --- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
> +++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
> @@ -440,3 +440,10 @@
>   bias-pull-up;
>   };
>  };
> +
> +&wifi {

As the bots have already told you, you missed adding a 'wifi' label to
sdm845.dtsi, so this reference doesn't compile.

> + vdd-0.8-cx-mx-supply = <&vreg_l5a_0p8>;
> + vdd-1.8-xo-supply = <&vreg_l7a_1p8>;
> + vdd-1.3-rfa-supply = <&vreg_l17a_1p3>;
> + vdd-3.3-ch0-supply = <&vreg_l25a_3p3>;
> +};
> diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi 
> b/arch/arm64/boot/dts/qcom/sdm845.dtsi
> index e080072cdfdb..b0b107641e74 100644
> --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
> @@ -86,6 +86,11 @@
>   reg = <0 0x8620 0 0x2d0>;
>   no-map;
>   };
> +
> + wlan_msa_mem: reserved-memory@9670 {
> + no-map;
> + reg = <0 0x9670 0 0x10>;
> + };
>   };
>  
>   cpus {
> @@ -1200,5 +1205,25 @@
>   status = "disabled";
>   };
>   };
> +
> + qcom,wifi {

That's not a legit node name. Nodes should (a) have a generic name and
(b) include a unit address when the node contains a 'reg' property. [1]

So, how about 'wifi@1880'? (And include the 'wifi:' label, since you
want to refer to it in other files.)

Also, this seems like the kind of device that should remain 'status =
"disabled"' in the top-level DTSI, and be overridden with 'status =
"okay"' in the child DTS.

Brian

[1] See:
https://elinux.org/Device_Tree_Usage#Node_Names
https://elinux.org/images/c/cf/Power_ePAPR_APPROVED_v1.1.pdf

> + compatible = "qcom,wcn3990-wifi";
> + reg = <0x1880 0x80>;
> + reg-names = "membase";
> + memory-region = <&wlan_msa_mem>;
> + interrupts =
> + <0 413 0 /* CE0 */ >,
> + <0 414 0 /* CE1 */ >,
> + <0 415 0 /* CE2 */ >,
> + <0 416 0 /* CE3 */ >,
> + <0 417 0 /* CE4 */ >,
> + <0 418 0 /* CE5 */ >,
> + <0 420 0 /* CE6 */ >,
> + <0 421 0 /* CE7 */ >,
> + <0 422 0 /* CE8 */ >,
> + <0 423 0 /* CE9 */ >,
> + <0 424 0 /* CE10 */ >,
> + <0 425 0 /* CE11 */ >;
> + };
>   };
>  };
> -- 
> 2.17.0
> 

___
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k


[PATCH v2] ath10k: Add support for configuring management packet rate

2018-09-24 Thread Sriram R
By default the firmware uses 1Mbps and 6Mbps rate for management packets
in 2G and 5G bands respectively. But when the user selects different
basic rates from the userspace, we need to send the management
packets at the lowest basic rate selected by the user.

This change makes use of WMI_VDEV_PARAM_MGMT_RATE param for configuring the
management packets rate to the firmware.

Chipsets Tested : QCA988X, QCA9887, QCA9984
FW Tested   : 10.2.4-1.0-41, 10.4-3.6.104

Signed-off-by: Sriram R 
---
 v2:
 * Correction to ath10k_rates array indexing.
 * Usage of appropriate indent.

 drivers/net/wireless/ath/ath10k/mac.c | 45 +--
 1 file changed, 43 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/mac.c 
b/drivers/net/wireless/ath/ath10k/mac.c
index 97548f9..c0cde94 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -157,6 +157,22 @@ u8 ath10k_mac_bitrate_to_idx(const struct 
ieee80211_supported_band *sband,
return 0;
 }
 
+static int ath10k_mac_get_rate_hw_value(int bitrate)
+{
+   int i;
+   u8 hw_value_prefix = 0;
+
+   if (ath10k_mac_bitrate_is_cck(bitrate))
+   hw_value_prefix = WMI_RATE_PREAMBLE_CCK << 6;
+
+   for (i = 0; i < ARRAY_SIZE(ath10k_rates); i++) {
+   if (ath10k_rates[i].bitrate == bitrate)
+   return hw_value_prefix | ath10k_rates[i].hw_value;
+   }
+
+   return -EINVAL;
+}
+
 static int ath10k_mac_get_max_vht_mcs_map(u16 mcs_map, int nss)
 {
switch ((mcs_map >> (2 * nss)) & 0x3) {
@@ -5452,9 +5468,10 @@ static void ath10k_bss_info_changed(struct ieee80211_hw 
*hw,
struct cfg80211_chan_def def;
u32 vdev_param, pdev_param, slottime, preamble;
u16 bitrate, hw_value;
-   u8 rate;
-   int rateidx, ret = 0;
+   u8 rate, basic_rate_idx;
+   int rateidx, ret = 0, hw_rate_code;
enum nl80211_band band;
+   const struct ieee80211_supported_band *sband;
 
mutex_lock(&ar->conf_mutex);
 
@@ -5660,6 +5677,30 @@ static void ath10k_bss_info_changed(struct ieee80211_hw 
*hw,
arvif->vdev_id,  ret);
}
 
+   if (changed & BSS_CHANGED_BASIC_RATES) {
+   if (WARN_ON(ath10k_mac_vif_chan(vif, &def))) {
+   mutex_unlock(&ar->conf_mutex);
+   return;
+   }
+
+   sband = ar->hw->wiphy->bands[def.chan->band];
+   basic_rate_idx = ffs(vif->bss_conf.basic_rates) - 1;
+   bitrate = sband->bitrates[basic_rate_idx].bitrate;
+
+   hw_rate_code = ath10k_mac_get_rate_hw_value(bitrate);
+   if (hw_rate_code < 0) {
+   ath10k_warn(ar, "bitrate not supported %d\n", bitrate);
+   mutex_unlock(&ar->conf_mutex);
+   return;
+   }
+
+   vdev_param = ar->wmi.vdev_param->mgmt_rate;
+   ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
+   hw_rate_code);
+   if (ret)
+   ath10k_warn(ar, "failed to set mgmt tx rate %d\n", ret);
+   }
+
mutex_unlock(&ar->conf_mutex);
 }
 
-- 
2.7.4


___
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k


Re: [ath6kl:pending 39/55] drivers/net/wireless/ath/ath10k/mac.c:169 ath10k_mac_get_rate_hw_value() error: buffer overflow 'ath10k_rates' 12 <= 143

2018-09-24 Thread Sriram R

On 2018-09-24 16:39, Kalle Valo wrote:

Dan Carpenter  writes:

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git 
pending

head:   2305dc3c6b1d66a7bef752439919d61478e02893
commit: 0c737c78082055ff589f6683e93b45f079c5d64e [39/55] ath10k: Add
support for configuring management packet rate

New smatch warnings:
drivers/net/wireless/ath/ath10k/mac.c:169
ath10k_mac_get_rate_hw_value() error: buffer overflow 'ath10k_rates'
12 <= 143

Old smatch warnings:
drivers/net/wireless/ath/ath10k/mac.c:170
ath10k_mac_get_rate_hw_value() error: buffer overflow 'ath10k_rates'
12 <= 143

#
https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?id=0c737c78082055ff589f6683e93b45f079c5d64e
git remote add ath6kl 
https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git

git remote update ath6kl
git checkout 0c737c78082055ff589f6683e93b45f079c5d64e
vim +/ath10k_rates +169 drivers/net/wireless/ath/ath10k/mac.c

01cebe1c Michal Kazior 2015-03-30  159
0c737c78 Sriram R  2018-09-10  160  static int 
ath10k_mac_get_rate_hw_value(int bitrate)

0c737c78 Sriram R  2018-09-10  161  {
0c737c78 Sriram R  2018-09-10  162  int i;
0c737c78 Sriram R  2018-09-10  163  u8 hw_value_prefix = 0;
0c737c78 Sriram R  2018-09-10  164
0c737c78 Sriram R  2018-09-10  165  	if 
(ath10k_mac_bitrate_is_cck(bitrate))

0c737c78 Sriram R 2018-09-10 166 hw_value_prefix =
WMI_RATE_PREAMBLE_CCK << 6;
0c737c78 Sriram R  2018-09-10  167
0c737c78 Sriram R  2018-09-10  168  	for (i = 0; i < 
sizeof(ath10k_rates); i++) {



This should be ARRAY_SIZE(ath10k_rates) instead of sizeof().


Makes sense. Can someone submit a patch, please?

Hi Kalle,  I've sent a v2 Patch with this change.

Thanks,
Sriram.R

___
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k


Re: [PATCH 3/3] ath10k: download firmware via diag Copy Engine for QCA6174 and QCA9377.

2018-09-24 Thread Carl Huang

On 2018-09-22 08:53, Brian Norris wrote:

Hi again!

One last (?) comment:

On Thu, Aug 30, 2018 at 10:29:42AM +0800, Carl Huang wrote:

diff --git a/drivers/net/wireless/ath/ath10k/hw.c 
b/drivers/net/wireless/ath/ath10k/hw.c

index 677535b..25ee1c6 100644
--- a/drivers/net/wireless/ath/ath10k/hw.c
+++ b/drivers/net/wireless/ath/ath10k/hw.c


@@ -918,6 +919,190 @@ static int 
ath10k_hw_qca6174_enable_pll_clock(struct ath10k *ar)



+static int ath10k_hw_diag_segment_download(struct ath10k *ar,
+  const void *buffer,
+  u32 address,
+  u32 length)
+{
+   if (address >= DRAM_BASE_ADDRESS + REGION_ACCESS_SIZE_LIMIT)
+   /* Needs to change MSB for memory write */
+   return ath10k_hw_diag_segment_msb_download(ar, buffer,
+  address, length);
+   else
+   return ath10k_hif_diag_write(ar, address, buffer, length);
+}
+
+int ath10k_hw_diag_fast_download(struct ath10k *ar,
+u32 address,
+const void *buffer,
+u32 length)
+{
+   const u8 *buf = buffer;
+   bool sgmt_end = false;
+   u32 base_addr = 0;
+   u32 base_len = 0;
+   u32 left = 0;
+   struct bmi_segmented_file_header *hdr;
+   struct bmi_segmented_metadata *metadata;
+   int ret = 0;
+
+   if (length < sizeof(*hdr))
+   return -EINVAL;
+
+   /* check firmware header. If it has no correct magic number
+* or it's compressed, returns error.
+*/
+   hdr = (struct bmi_segmented_file_header *)buf;
+   if (hdr->magic_num != BMI_SGMTFILE_MAGIC_NUM) {
+   ath10k_dbg(ar, ATH10K_DBG_BOOT,
+  "Not a supported firmware, magic_num:0x%x\n",
+  hdr->magic_num);
+   return -EINVAL;
+   }
+
+   if (hdr->file_flags != 0) {
+   ath10k_dbg(ar, ATH10K_DBG_BOOT,
+  "Not a supported firmware, file_flags:0x%x\n",
+  hdr->file_flags);
+   return -EINVAL;
+   }
+
+   metadata = (struct bmi_segmented_metadata *)hdr->data;
+   left = length - sizeof(*hdr);
+
+   while (left > 0) {
+   base_addr = metadata->addr;
+   base_len = metadata->length;
+   buf = metadata->data;
+   left -= sizeof(*metadata);
+
+   switch (base_len) {

...

+   default:
+   if (base_len > left) {
+   /* sanity check */
+   ath10k_warn(ar,
+   "firmware has invalid segment length, %d 
> %d\n",
+   base_len, left);
+   ret = -EINVAL;
+   break;
+   }
+
+   ret = ath10k_hw_diag_segment_download(ar,
+ buf,
+ base_addr,
+ base_len);


This 'base_len' is determined by the firmware blob and in common cases
is over 500K. The PCI implementation currently tries to
dma_alloc_coherent() a bounce buffer for this. Many systems can't
acquire that large of contiguous DMA memory reliably, so this is isn't
very effective. Can we improve the strategy here? Do you lose a lot of
speed if you do this in smaller (a few pages?) chunks instead?



It's a sound complaint. I'll submit a patch for it.



Brian


+
+   if (ret)
+   ath10k_warn(ar,
+   "failed to download firmware via diag 
interface:%d\n",
+   ret);
+   break;

...


___
ath10k mailing list
ath10k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath10k