diff mbox

cfg80211: Add cumulative channel survey dump support.

Message ID 1526980556-26707-1-git-send-email-vnaralas@codeaurora.org (mailing list archive)
State Changes Requested
Delegated to: Johannes Berg
Headers show

Commit Message

Venkateswara Naralasetty May 22, 2018, 9:15 a.m. UTC
This patch provides support to send accumulated survey data to
user if low level drivers provides non-accumulated survey data.

Signed-off-by: Venkateswara Naralasetty <vnaralas@codeaurora.org>
---
 include/net/cfg80211.h |  5 +++++
 net/wireless/core.c    | 21 +++++++++++++++++++++
 net/wireless/nl80211.c | 34 +++++++++++++++++++++++++++++++++-
 3 files changed, 59 insertions(+), 1 deletion(-)

Comments

Johannes Berg May 23, 2018, 9:54 a.m. UTC | #1
On Tue, 2018-05-22 at 14:45 +0530, Venkateswara Naralasetty wrote:
> This patch provides support to send accumulated survey data to
> user if low level drivers provides non-accumulated survey data.

I think the commit log should say what you need this for?

It's simultaneously a new flag, and a lot of code, but it's not clear
what the point is?

johannes
Venkateswara Naralasetty May 31, 2018, 9:06 a.m. UTC | #2
On 2018-05-23 15:24, Johannes Berg wrote:
> On Tue, 2018-05-22 at 14:45 +0530, Venkateswara Naralasetty wrote:
>> This patch provides support to send accumulated survey data to
>> user if low level drivers provides non-accumulated survey data.
> 
> I think the commit log should say what you need this for?
> 
> It's simultaneously a new flag, and a lot of code, but it's not clear
> what the point is?
> 
> johannes

I will sent next version of patch with updated commit log.

Providing you the earlier discussion of this patch to give quick 
overview about this patch.
https://patchwork.kernel.org/patch/9701459/


Thanks,
Venkatesh.
Ben Greear May 31, 2018, 3:52 p.m. UTC | #3
On 05/31/2018 02:06 AM, vnaralas@codeaurora.org wrote:
> On 2018-05-23 15:24, Johannes Berg wrote:
>> On Tue, 2018-05-22 at 14:45 +0530, Venkateswara Naralasetty wrote:
>>> This patch provides support to send accumulated survey data to
>>> user if low level drivers provides non-accumulated survey data.
>>
>> I think the commit log should say what you need this for?
>>
>> It's simultaneously a new flag, and a lot of code, but it's not clear
>> what the point is?
>>
>> johannes
>
> I will sent next version of patch with updated commit log.
>
> Providing you the earlier discussion of this patch to give quick overview about this patch.
> https://patchwork.kernel.org/patch/9701459/

It is simple to fix the firmware, it just has several bugs related to clearing the
accumulator as well as the 'real' values.  If you can find a QCA firmware engineer
that will accept patches I can show them how to fix this easily.  I recently
fixed this in my wave-1 firmware.  I posted patches to the ath10k driver to
support this a week or so ago, but not sure if Kalle will apply them.

And, it is likely that even if you don't use the 'clear' option, you are going to
get wraps in the firmware and that will just be other harder to debug bugs.

Thanks,
Ben
Johannes Berg June 18, 2018, 8:45 p.m. UTC | #4
On Thu, 2018-05-31 at 14:36 +0530, vnaralas@codeaurora.org wrote:
> On 2018-05-23 15:24, Johannes Berg wrote:
> > On Tue, 2018-05-22 at 14:45 +0530, Venkateswara Naralasetty wrote:
> > > This patch provides support to send accumulated survey data to
> > > user if low level drivers provides non-accumulated survey data.
> > 
> > I think the commit log should say what you need this for?
> > 
> > It's simultaneously a new flag, and a lot of code, but it's not clear
> > what the point is?
> > 
> > johannes
> 
> I will sent next version of patch with updated commit log.
> 
> Providing you the earlier discussion of this patch to give quick 
> overview about this patch.
> https://patchwork.kernel.org/patch/9701459/

Haha. I guess it's too long ago :)

johannes
Johannes Berg June 18, 2018, 8:46 p.m. UTC | #5
On Thu, 2018-05-31 at 08:52 -0700, Ben Greear wrote:
> 
> On 05/31/2018 02:06 AM, vnaralas@codeaurora.org wrote:
> > On 2018-05-23 15:24, Johannes Berg wrote:
> > > On Tue, 2018-05-22 at 14:45 +0530, Venkateswara Naralasetty wrote:
> > > > This patch provides support to send accumulated survey data to
> > > > user if low level drivers provides non-accumulated survey data.
> > > 
> > > I think the commit log should say what you need this for?
> > > 
> > > It's simultaneously a new flag, and a lot of code, but it's not clear
> > > what the point is?
> > > 
> > > johannes
> > 
> > I will sent next version of patch with updated commit log.
> > 
> > Providing you the earlier discussion of this patch to give quick overview about this patch.
> > https://patchwork.kernel.org/patch/9701459/
> 
> It is simple to fix the firmware, it just has several bugs related to clearing the
> accumulator as well as the 'real' values.  If you can find a QCA firmware engineer
> that will accept patches I can show them how to fix this easily.  I recently
> fixed this in my wave-1 firmware.  I posted patches to the ath10k driver to
> support this a week or so ago, but not sure if Kalle will apply them.

That would be nicer even, but I guess we still have to worry about older
firmware? Perhaps not for survey support? Dunno.

Obviously less code is better, but I can't really say how easy it would
be to get firmware updates rolled out to people who'd need them ...

> And, it is likely that even if you don't use the 'clear' option, you are going to
> get wraps in the firmware and that will just be other harder to debug bugs.

You have to use clear if you don't accumulate completely in fw, no?

johannes
Ben Greear June 18, 2018, 8:57 p.m. UTC | #6
On 06/18/2018 01:46 PM, Johannes Berg wrote:
> On Thu, 2018-05-31 at 08:52 -0700, Ben Greear wrote:
>>
>> On 05/31/2018 02:06 AM, vnaralas@codeaurora.org wrote:
>>> On 2018-05-23 15:24, Johannes Berg wrote:
>>>> On Tue, 2018-05-22 at 14:45 +0530, Venkateswara Naralasetty wrote:
>>>>> This patch provides support to send accumulated survey data to
>>>>> user if low level drivers provides non-accumulated survey data.
>>>>
>>>> I think the commit log should say what you need this for?
>>>>
>>>> It's simultaneously a new flag, and a lot of code, but it's not clear
>>>> what the point is?
>>>>
>>>> johannes
>>>
>>> I will sent next version of patch with updated commit log.
>>>
>>> Providing you the earlier discussion of this patch to give quick overview about this patch.
>>> https://patchwork.kernel.org/patch/9701459/
>>
>> It is simple to fix the firmware, it just has several bugs related to clearing the
>> accumulator as well as the 'real' values.  If you can find a QCA firmware engineer
>> that will accept patches I can show them how to fix this easily.  I recently
>> fixed this in my wave-1 firmware.  I posted patches to the ath10k driver to
>> support this a week or so ago, but not sure if Kalle will apply them.
>
> That would be nicer even, but I guess we still have to worry about older
> firmware? Perhaps not for survey support? Dunno.
>
> Obviously less code is better, but I can't really say how easy it would
> be to get firmware updates rolled out to people who'd need them ...
>
>> And, it is likely that even if you don't use the 'clear' option, you are going to
>> get wraps in the firmware and that will just be other harder to debug bugs.
>
> You have to use clear if you don't accumulate completely in fw, no?

At least some firmware is broken in numerous ways, and there is no clear way to
tell which firmware is broken how as far as I can tell.  It does appear to be fixed in
recent 10.4 (wave-2) firmware, so maybe they will fix 10.2 as well.

Thanks,
Ben
Sven Eckelmann Sept. 17, 2019, 5:27 p.m. UTC | #7
On Thursday, 31 May 2018 11:06:59 CEST vnaralas@codeaurora.org wrote:
> I will sent next version of patch with updated commit log.

Can you please point me to the second version?

Btw. I've just checked the minimal changes in ath10k to get this working. It 
seems we need SURVEY_INFO_NON_ACC_DATA in ath10k's ath10k_get_survey + memset 
of ar->survey[idx].

But right now the total time looks (especially) wrong to me. At least it is 
rather unlikely that I can have around 30 second active time delta in
roughly 1 real world second.  Maybe a bug with the READ_CLEAR handling in
firmware 10.2.4-1.0-00043 or maybe all firmware version? More logs about
that at the end.

@Ben: Was this also what you've experience in the past with the 10.2 firmware
bss_chan_info counter bugs or am I just misusing the functionality of the
firmware?


And yes, I am aware that the minimal change in ath10k is not enough - but it 
was good enough for a simple test. I think ath10k_wmi_event_pdev_bss_chan_info 
+ ath10k_hw_fill_survey_time also have to be modified to accumulate .time, 
.time_busy, .time_rx, and .time_tx.  But it makes me wonder whether there is 
now any benefit from the cfg80211 patch (for ath10k). You can basically get 
the same functionality from

--- a/drivers/net/wireless/ath/ath10k/hw.c
+++ b/drivers/net/wireless/ath/ath10k/hw.c
@@ -216,8 +217,9 @@ void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
 	cc -= cc_prev - cc_fix;
 	rcc -= rcc_prev - rcc_fix;
 
-	survey->time = CCNT_TO_MSEC(ar, cc);
-	survey->time_busy = CCNT_TO_MSEC(ar, rcc);
+	survey->time += CCNT_TO_MSEC(ar, cc);
+	if (survey->filled & SURVEY_INFO_TIME_BUSY)
+		survey->time_busy += CCNT_TO_MSEC(ar, rcc);
 }
 
 const struct ath10k_hw_ops qca988x_ops = {
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -4905,6 +4905,13 @@ static int ath10k_wmi_event_pdev_bss_chan_info(struct ath10k *ar,
 		   "wmi event pdev bss chan info:\n freq: %d noise: %d cycle: busy %llu total %llu tx %llu rx %llu rx_bss %llu\n",
 		   freq, noise_floor, busy, total, tx, rx, rx_bss);
 
+	/* everything zero means invalid data -> drop it to avoid ruining the
+	 * noisefloor
+	 */
+	if (noise_floor == 0 && busy == 0 && total == 0 && tx == 0 && rx == 0 &&
+	    rx_bss == 0)
+		return -EPROTO;
+
 	spin_lock_bh(&ar->data_lock);
 	idx = freq_to_idx(ar, freq);
 	if (idx >= ARRAY_SIZE(ar->survey)) {
@@ -4916,10 +4923,10 @@ static int ath10k_wmi_event_pdev_bss_chan_info(struct ath10k *ar,
 	survey = &ar->survey[idx];
 
 	survey->noise     = noise_floor;
-	survey->time      = div_u64(total, cc_freq_hz);
-	survey->time_busy = div_u64(busy, cc_freq_hz);
-	survey->time_rx   = div_u64(rx_bss, cc_freq_hz);
-	survey->time_tx   = div_u64(tx, cc_freq_hz);
+	survey->time      += div_u64(total, cc_freq_hz);
+	survey->time_busy += div_u64(busy, cc_freq_hz);
+	survey->time_rx   += div_u64(rx_bss, cc_freq_hz);
+	survey->time_tx   += div_u64(tx, cc_freq_hz);
 	survey->filled   |= (SURVEY_INFO_NOISE_DBM |
 			     SURVEY_INFO_TIME |
 			     SURVEY_INFO_TIME_BUSY |


Both version get to the same (incorrect) timing results :)

Here is the time data I get reported from the firmware (entries
with 0 in each field were removed)

    [  162.875008] wmi event pdev bss chan info:  freq: 5180 noise: -102 cycle: busy 83895506 total 3801904834 tx 267520 rx 71507709 rx_bss 0
    [  163.917612] wmi event pdev bss chan info:  freq: 5180 noise: -102 cycle: busy 85745287 total 3889908918 tx 214016 rx 73140278 rx_bss 0
    [  164.960733] wmi event pdev bss chan info:  freq: 5180 noise: -102 cycle: busy 87612741 total 3977912729 tx 221408 rx 74750020 rx_bss 22880
    [  166.004348] wmi event pdev bss chan info:  freq: 5180 noise: -102 cycle: busy 89489393 total 4065916182 tx 214016 rx 76383244 rx_bss 0
    [  167.048330] wmi event pdev bss chan info:  freq: 5180 noise: -102 cycle: busy 91292949 total 4153919205 tx 214016 rx 77942266 rx_bss 0
    [  168.091828] wmi event pdev bss chan info:  freq: 5180 noise: -102 cycle: busy 93118897 total 4241923018 tx 187264 rx 79551036 rx_bss 0
    [  169.134349] wmi event pdev bss chan info:  freq: 5180 noise: -102 cycle: busy 47834553 total 2182443012 tx 160512 rx 40879686 rx_bss 0
    [  170.177511] wmi event pdev bss chan info:  freq: 5180 noise: -102 cycle: busy 49751910 total 2270447314 tx 167904 rx 42539598 rx_bss 22880
    [  171.221156] wmi event pdev bss chan info:  freq: 5180 noise: -102 cycle: busy 51639827 total 2358451435 tx 160512 rx 44184146 rx_bss 0
    [  172.262426] wmi event pdev bss chan info:  freq: 5180 noise: -102 cycle: busy 53420475 total 2446455772 tx 133760 rx 45746866 rx_bss 0
    [  173.309067] wmi event pdev bss chan info:  freq: 5180 noise: -103 cycle: busy 55218240 total 2534459001 tx 107008 rx 47327088 rx_bss 0

The well trained observer might already have noticed that some of the values 
are steadily increasing until they suddenly decrease again. And the delta for 
total is mostly around 1s - besides when it isn't. Then it can also be -23403 
seconds (while the absolute value *doesn't* return to a value near zero but
to a value near 0x7fffffff). The rx value also jumps around in a similar way 
(just by a completely different value).

So whatever the firmware does when it gets a 
WMI_BSS_SURVEY_REQ_TYPE_READ_CLEAR -  it is not a CLEAR after read. And they 
also don't simply wrap around but there all values have to get some kind of 
"fix" like the active time one shown in ath10k_hw_fill_survey_time.
Just that the actual "fixes" for them are unknown. To me it looks like
firmware ATH10K_HW_CC_WRAP_SHIFTED_ALL have busy and rx interlinked with
the overflow of total. But the tx and rx_bss are actually cleared.

Other than that, the counters are wrapping every ~14-30 seconds. So we
also need also some worker for ath10k which every couple of seconds
requests new values for all the channel from the firmware. Which already
sounds problematic because I get
"ath10k_pci 0000:00:00.0: bss channelsurvey timed out" all the time
when requesting surveys manually.

Kind regards,
	Sven
Ben Greear Sept. 17, 2019, 5:44 p.m. UTC | #8
On 9/17/19 10:27 AM, Sven Eckelmann wrote:
> On Thursday, 31 May 2018 11:06:59 CEST vnaralas@codeaurora.org wrote:
>> I will sent next version of patch with updated commit log.
> 
> Can you please point me to the second version?
> 
> Btw. I've just checked the minimal changes in ath10k to get this working. It
> seems we need SURVEY_INFO_NON_ACC_DATA in ath10k's ath10k_get_survey + memset
> of ar->survey[idx].
> 
> But right now the total time looks (especially) wrong to me. At least it is
> rather unlikely that I can have around 30 second active time delta in
> roughly 1 real world second.  Maybe a bug with the READ_CLEAR handling in
> firmware 10.2.4-1.0-00043 or maybe all firmware version? More logs about
> that at the end.
> 
> @Ben: Was this also what you've experience in the past with the 10.2 firmware
> bss_chan_info counter bugs or am I just misusing the functionality of the
> firmware?

Last I recall, the upstream code had several bugs.  Maybe some QCA
firmware person can let you know if they fixed the upstream firmware.

If you want to test against ath10k-ct driver/firmware, and if you still see bogus values, then
I can debug and fix it.

Thanks,
Ben
Sven Eckelmann Sept. 18, 2019, 8:46 a.m. UTC | #9
On Tuesday, 17 September 2019 19:27:50 CEST Sven Eckelmann wrote:
[...]
> So whatever the firmware does when it gets a 
> WMI_BSS_SURVEY_REQ_TYPE_READ_CLEAR -  it is not a CLEAR after read. And they 
> also don't simply wrap around but there all values have to get some kind of 
> "fix" like the active time one shown in ath10k_hw_fill_survey_time.
> Just that the actual "fixes" for them are unknown. To me it looks like
> firmware ATH10K_HW_CC_WRAP_SHIFTED_ALL have busy and rx interlinked with
> the overflow of total. But the tx and rx_bss are actually cleared.
> 
> Other than that, the counters are wrapping every ~14-30 seconds. So we
> also need also some worker for ath10k which every couple of seconds
> requests new values for all the channel from the firmware. Which already
> sounds problematic because I get
> "ath10k_pci 0000:00:00.0: bss channelsurvey timed out" all the time
> when requesting surveys manually.

I've just tested it on 10.4 (wave-2) cards and it seems like it is cleared as 
expected on them. So the change I posted earlier (with a minor fix for 
ath10k_hw_fill_survey_time) returns now useful (accumulated) values. This can 
be seen in 
https://stats.freifunk-vogtland.net/d/ffv_node/nodeinfo?orgId=1&var-node=ac86749f4d60&fullscreen&panelId=5&from=1568782046974&to=1568807068706 
(after the reboot at 10:15 UTC+2)

So as Ben Greear said, the 10.4 firmware version is fixed and 10.2.* (for
the wave-1 cards) is still broken and we need a QCA firmware engineer to
fix it. Or to work around it by polling every couple of seconds and 
manually do the cleanup of the values from the firmware.

Kind regards,
	Sven
Ben Greear Sept. 18, 2019, 12:58 p.m. UTC | #10
On 09/18/2019 01:46 AM, Sven Eckelmann wrote:
> On Tuesday, 17 September 2019 19:27:50 CEST Sven Eckelmann wrote:
> [...]
>> So whatever the firmware does when it gets a
>> WMI_BSS_SURVEY_REQ_TYPE_READ_CLEAR -  it is not a CLEAR after read. And they
>> also don't simply wrap around but there all values have to get some kind of
>> "fix" like the active time one shown in ath10k_hw_fill_survey_time.
>> Just that the actual "fixes" for them are unknown. To me it looks like
>> firmware ATH10K_HW_CC_WRAP_SHIFTED_ALL have busy and rx interlinked with
>> the overflow of total. But the tx and rx_bss are actually cleared.
>>
>> Other than that, the counters are wrapping every ~14-30 seconds. So we
>> also need also some worker for ath10k which every couple of seconds
>> requests new values for all the channel from the firmware. Which already
>> sounds problematic because I get
>> "ath10k_pci 0000:00:00.0: bss channelsurvey timed out" all the time
>> when requesting surveys manually.
>
> I've just tested it on 10.4 (wave-2) cards and it seems like it is cleared as
> expected on them. So the change I posted earlier (with a minor fix for
> ath10k_hw_fill_survey_time) returns now useful (accumulated) values. This can
> be seen in
> https://stats.freifunk-vogtland.net/d/ffv_node/nodeinfo?orgId=1&var-node=ac86749f4d60&fullscreen&panelId=5&from=1568782046974&to=1568807068706
> (after the reboot at 10:15 UTC+2)
>
> So as Ben Greear said, the 10.4 firmware version is fixed and 10.2.* (for
> the wave-1 cards) is still broken and we need a QCA firmware engineer to
> fix it. Or to work around it by polling every couple of seconds and
> manually do the cleanup of the values from the firmware.

Have you tried probing very fast, like every 100ms, to see if returned values
look sane?  I seem to recall that there was some firmware issue with this, like
it only updates internal counters every second or so.

Polling slow would have the same off-by-a-second's-worth-of-data, but you would not
easily notice it at slower polling intervals.

Thanks,
Ben
Sven Eckelmann Sept. 18, 2019, 1:07 p.m. UTC | #11
On Wednesday, 18 September 2019 14:58:46 CEST Ben Greear wrote:
[...]
> > So as Ben Greear said, the 10.4 firmware version is fixed and 10.2.* (for
> > the wave-1 cards) is still broken and we need a QCA firmware engineer to
> > fix it. Or to work around it by polling every couple of seconds and
> > manually do the cleanup of the values from the firmware.
> 
> Have you tried probing very fast, like every 100ms, to see if returned values
> look sane?  I seem to recall that there was some firmware issue with this, like
> it only updates internal counters every second or so.
> 
> Polling slow would have the same off-by-a-second's-worth-of-data, but you would not
> easily notice it at slower polling intervals.

Yes, I've polled at ~100ms intervals at some point. And it looked like I get 
most of the time only 0 values (for everything - including noisefloor) from 
the firmware when I do this. And the actual values are only send every second 
or so (I didn't actual make precise calculations here).

I have now prepared a test patch [1] to get the data every 10 seconds. This 
was a compromise between having useful information over time and the 
overflowing problem. While it is not the perfect solution (QCA *cough*), it is 
at least more bearable for me.

Kind regards,
	Sven

[1] https://patchwork.kernel.org/patch/11150289/
Sven Eckelmann Sept. 18, 2019, 1:13 p.m. UTC | #12
On Wednesday, 18 September 2019 15:07:11 CEST Sven Eckelmann wrote:
[...]
> I have now prepared a test patch [1] to get the data every 10 seconds. This 
> was a compromise between having useful information over time and the 
> overflowing problem. 

...over time without too many "bss channel survey timed out" errors and...

Kind regards,
	Sven
diff mbox

Patch

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index fc40843..e0ecd7d 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -580,6 +580,7 @@  ieee80211_chandef_max_power(struct cfg80211_chan_def *chandef)
  * @SURVEY_INFO_TIME_RX: receive time was filled in
  * @SURVEY_INFO_TIME_TX: transmit time was filled in
  * @SURVEY_INFO_TIME_SCAN: scan time was filled in
+ * @SURVEY_INFO_NON_ACC_DATA: non accumulated survey data filled in
  *
  * Used by the driver to indicate which info in &struct survey_info
  * it has filled in during the get_survey().
@@ -593,6 +594,7 @@  enum survey_info_flags {
 	SURVEY_INFO_TIME_RX		= BIT(5),
 	SURVEY_INFO_TIME_TX		= BIT(6),
 	SURVEY_INFO_TIME_SCAN		= BIT(7),
+	SURVEY_INFO_NON_ACC_DATA        = BIT(8),
 };
 
 /**
@@ -3787,6 +3789,7 @@  struct wiphy_iftype_ext_capab {
  *	bitmap of &enum nl80211_band values.  For instance, for
  *	NL80211_BAND_2GHZ, bit 0 would be set
  *	(i.e. BIT(NL80211_BAND_2GHZ)).
+ * @cumulative_survey: cumulated survey information for all channels.
  */
 struct wiphy {
 	/* assign these fields before you register the wiphy */
@@ -3921,6 +3924,8 @@  struct wiphy {
 
 	u8 nan_supported_bands;
 
+	struct survey_info *cumulative_survey;
+
 	char priv[0] __aligned(NETDEV_ALIGN);
 };
 
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 670aa229..4646769 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -633,6 +633,9 @@  int wiphy_register(struct wiphy *wiphy)
 	struct ieee80211_supported_band *sband;
 	bool have_band = false;
 	int i;
+	int n_channels = 0;
+	int idx = 0;
+
 	u16 ifmodes = wiphy->interface_modes;
 
 #ifdef CONFIG_PM
@@ -782,6 +785,7 @@  int wiphy_register(struct wiphy *wiphy)
 		}
 
 		have_band = true;
+		n_channels += sband->n_channels;
 	}
 
 	if (!have_band) {
@@ -866,6 +870,21 @@  int wiphy_register(struct wiphy *wiphy)
 		}
 	}
 
+	wiphy->cumulative_survey = kcalloc(n_channels,
+					   sizeof(struct survey_info),
+					   GFP_KERNEL);
+	if (!wiphy->cumulative_survey)
+		return -ENOMEM;
+
+	for (band = 0; band < NUM_NL80211_BANDS; band++) {
+		sband = wiphy->bands[band];
+		if (!sband)
+			continue;
+		for (i = 0; i < sband->n_channels; i++)
+			wiphy->cumulative_survey[idx++].channel =
+				&sband->channels[i];
+	}
+
 	rdev->wiphy.registered = true;
 	rtnl_unlock();
 
@@ -955,6 +974,8 @@  void wiphy_unregister(struct wiphy *wiphy)
 #endif
 	cfg80211_rdev_free_wowlan(rdev);
 	cfg80211_rdev_free_coalesce(rdev);
+
+	kfree(wiphy->cumulative_survey);
 }
 EXPORT_SYMBOL(wiphy_unregister);
 
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index fe27ab4..2f22d74 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -8024,11 +8024,13 @@  static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
 {
 	struct nlattr **attrbuf = genl_family_attrbuf(&nl80211_fam);
 	struct survey_info survey;
+	struct survey_info *survey_data = &survey;
 	struct cfg80211_registered_device *rdev;
 	struct wireless_dev *wdev;
 	int survey_idx = cb->args[2];
 	int res;
 	bool radio_stats;
+	int n_channels;
 
 	rtnl_lock();
 	res = nl80211_prepare_wdev_dump(skb, cb, &rdev, &wdev);
@@ -8048,7 +8050,12 @@  static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
 		goto out_err;
 	}
 
+	n_channels = ieee80211_get_num_supported_channels(wdev->wiphy);
+
 	while (1) {
+		if (n_channels <= survey_idx)
+			break;
+
 		res = rdev_dump_survey(rdev, wdev->netdev, survey_idx, &survey);
 		if (res == -ENOENT)
 			break;
@@ -8062,10 +8069,35 @@  static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
 			continue;
 		}
 
+		if (survey.filled & SURVEY_INFO_NON_ACC_DATA) {
+			struct survey_info *cumulative_survey =
+				&wdev->wiphy->cumulative_survey[survey_idx];
+
+			if (cumulative_survey->channel->center_freq !=
+					survey.channel->center_freq) {
+				survey_idx++;
+				continue;
+			}
+			if (survey.filled & SURVEY_INFO_NOISE_DBM)
+				cumulative_survey->noise = survey.noise;
+			if (survey.filled & SURVEY_INFO_TIME)
+				cumulative_survey->time += survey.time;
+			if (survey.filled & SURVEY_INFO_TIME_BUSY)
+				cumulative_survey->time_busy +=
+							survey.time_busy;
+			if (survey.filled & SURVEY_INFO_TIME_RX)
+				cumulative_survey->time_rx += survey.time_rx;
+			if (survey.filled & SURVEY_INFO_TIME_TX)
+				cumulative_survey->time_tx += survey.time_tx;
+
+			cumulative_survey->filled |= survey.filled;
+			survey_data = cumulative_survey;
+		}
+
 		if (nl80211_send_survey(skb,
 				NETLINK_CB(cb->skb).portid,
 				cb->nlh->nlmsg_seq, NLM_F_MULTI,
-				wdev->netdev, radio_stats, &survey) < 0)
+				wdev->netdev, radio_stats, survey_data) < 0)
 			goto out;
 		survey_idx++;
 	}