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 | 14 +++++++
net/mac80211/status.c | 24 +++++++++++
5 files changed, 102 insertions(+), 4 deletions(-)
--
1.7.9.5
Anilkumar Kolli <[email protected]> writes:
> On 2018-09-20 21:40, Toke H=C3=B8iland-J=C3=B8rgensen wrote:
>> Anilkumar Kolli <[email protected]> writes:
>>=20
>>> 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.
>>>=20
>>> Using ieee80211_tx_status_ext() in two different paths
>>> - (one for the stats, one for the tx rate) will duplicate the stats.
>>>=20
>>> To avoid this stats duplication, ieee80211_tx_rate_update() is=20
>>> implemented.
>>>=20
>>> Signed-off-by: Anilkumar Kolli <[email protected]>
>>> ---
>>> V3:
>>> - Added new API in mac80211 to update tx rate(Johannes)
>>>=20
>>> include/net/mac80211.h | 14 ++++++++++++++
>>> net/mac80211/status.c | 24 ++++++++++++++++++++++++
>>> 2 files changed, 38 insertions(+)
>>>=20
>>> diff --git a/include/net/mac80211.h b/include/net/mac80211.h
>>> index 8c26d2d36cbe..042186a21770 100644
>>> --- a/include/net/mac80211.h
>>> +++ b/include/net/mac80211.h
>>> @@ -4331,6 +4331,20 @@ void=20
>>> ieee80211_sta_set_expected_throughput(struct ieee80211_sta *pubsta,
>>> u32 thr);
>>>=20
>>> /**
>>> + * ieee80211_tx_rate_update - transmit rate update callback
>>> + *
>>> + * 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
>>> + * @status: tx status information
>>> + * @pubsta: the station to update the tx rate for.
>>> + */
>>> +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..232297ddaa02 100644
>>> --- a/net/mac80211/status.c
>>> +++ b/net/mac80211/status.c
>>> @@ -988,6 +988,30 @@ void ieee80211_tx_status_ext(struct ieee80211_hw=20
>>> *hw,
>>> }
>>> EXPORT_SYMBOL(ieee80211_tx_status_ext);
>>>=20
>>> +void ieee80211_tx_rate_update(struct ieee80211_hw *hw,
>>> + struct ieee80211_sta *pubsta,
>>> + struct ieee80211_tx_info *info)
>>> +{
>>> + struct ieee80211_local *local =3D hw_to_local(hw);
>>> + struct ieee80211_supported_band *sband;
>>> + struct sta_info *sta;
>>> + struct ieee80211_tx_status status;
>>> +
>>> + sband =3D hw->wiphy->bands[info->band];
>>> +
>>> + if (pubsta) {
>>=20
>> The function does nothing if pubsta is NULL; wouldn't it make more=20
>> sense
>> to just mandate that it isn't NULL rather than have this check?
>>=20
>
> ATH10K driver always calls this function with a valid STA [not NULL].
Yeah, so why the check for non-NULL? :)
-Toke
On 2018-09-21 17:51, Toke Høiland-Jørgensen wrote:
> Anilkumar Kolli <[email protected]> writes:
>
>> On 2018-09-20 21:40, Toke Høiland-Jørgensen wrote:
>>> Anilkumar Kolli <[email protected]> writes:
>>>
>>>> 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 <[email protected]>
>>>> ---
>>>> V3:
>>>> - Added new API in mac80211 to update tx rate(Johannes)
>>>>
>>>> include/net/mac80211.h | 14 ++++++++++++++
>>>> net/mac80211/status.c | 24 ++++++++++++++++++++++++
>>>> 2 files changed, 38 insertions(+)
>>>>
>>>> diff --git a/include/net/mac80211.h b/include/net/mac80211.h
>>>> index 8c26d2d36cbe..042186a21770 100644
>>>> --- a/include/net/mac80211.h
>>>> +++ b/include/net/mac80211.h
>>>> @@ -4331,6 +4331,20 @@ void
>>>> ieee80211_sta_set_expected_throughput(struct ieee80211_sta *pubsta,
>>>> u32 thr);
>>>>
>>>> /**
>>>> + * ieee80211_tx_rate_update - transmit rate update callback
>>>> + *
>>>> + * 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
>>>> + * @status: tx status information
>>>> + * @pubsta: the station to update the tx rate for.
>>>> + */
>>>> +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..232297ddaa02 100644
>>>> --- a/net/mac80211/status.c
>>>> +++ b/net/mac80211/status.c
>>>> @@ -988,6 +988,30 @@ 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];
>>>> +
>>>> + if (pubsta) {
>>>
>>> The function does nothing if pubsta is NULL; wouldn't it make more
>>> sense
>>> to just mandate that it isn't NULL rather than have this check?
>>>
>>
>> ATH10K driver always calls this function with a valid STA [not NULL].
>
> Yeah, so why the check for non-NULL? :)
>
Agreed we can remove this check since ath10k driver calls
ieee80211_tx_rate_update()
with a valid STA. This adds a sanity check to avoid NULL dereference on
pubsta.
I will update the comments on ieee80211_tx_rate_update() and send RFCv4.
Thanks
Anil.
On 2018-09-20 21:40, Toke Høiland-Jørgensen wrote:
> Anilkumar Kolli <[email protected]> writes:
>
>> 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 <[email protected]>
>> ---
>> V3:
>> - Added new API in mac80211 to update tx rate(Johannes)
>>
>> include/net/mac80211.h | 14 ++++++++++++++
>> net/mac80211/status.c | 24 ++++++++++++++++++++++++
>> 2 files changed, 38 insertions(+)
>>
>> diff --git a/include/net/mac80211.h b/include/net/mac80211.h
>> index 8c26d2d36cbe..042186a21770 100644
>> --- a/include/net/mac80211.h
>> +++ b/include/net/mac80211.h
>> @@ -4331,6 +4331,20 @@ void
>> ieee80211_sta_set_expected_throughput(struct ieee80211_sta *pubsta,
>> u32 thr);
>>
>> /**
>> + * ieee80211_tx_rate_update - transmit rate update callback
>> + *
>> + * 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
>> + * @status: tx status information
>> + * @pubsta: the station to update the tx rate for.
>> + */
>> +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..232297ddaa02 100644
>> --- a/net/mac80211/status.c
>> +++ b/net/mac80211/status.c
>> @@ -988,6 +988,30 @@ 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];
>> +
>> + if (pubsta) {
>
> The function does nothing if pubsta is NULL; wouldn't it make more
> sense
> to just mandate that it isn't NULL rather than have this check?
>
ATH10K driver always calls this function with a valid STA [not NULL].
Thanks
Anil.
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 <[email protected]>
---
V3:
- Added new API in mac80211 to update tx rate(Johannes)
include/net/mac80211.h | 14 ++++++++++++++
net/mac80211/status.c | 24 ++++++++++++++++++++++++
2 files changed, 38 insertions(+)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 8c26d2d36cbe..042186a21770 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -4331,6 +4331,20 @@ void ieee80211_sta_set_expected_throughput(struct ieee80211_sta *pubsta,
u32 thr);
/**
+ * ieee80211_tx_rate_update - transmit rate update callback
+ *
+ * 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
+ * @status: tx status information
+ * @pubsta: the station to update the tx rate for.
+ */
+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..232297ddaa02 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -988,6 +988,30 @@ 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];
+
+ if (pubsta) {
+ 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
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 <[email protected]>
---
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 |=
+ IEEE80211_TX_RC_SHORT_GI;
+ arsta->tx_info.status.rates[0].flags |= IEEE80211_TX_RC_VHT_MCS;
+ break;
+ }
arsta->txrate.nss = txrate.nss;
arsta->txrate.bw = ath10k_bw_to_mac80211_bw(txrate.bw);
+ if (sgi)
+ arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+
+ switch (arsta->txrate.bw) {
+ case RATE_INFO_BW_40:
+ arsta->tx_info.status.rates[0].flags |=
+ IEEE80211_TX_RC_40_MHZ_WIDTH;
+ break;
+ case RATE_INFO_BW_80:
+ arsta->tx_info.status.rates[0].flags |=
+ IEEE80211_TX_RC_80_MHZ_WIDTH;
+ break;
+ }
+
+ if (peer_stats->succ_pkts) {
+ arsta->tx_info.flags = IEEE80211_TX_STAT_ACK;
+ arsta->tx_info.status.rates[0].count = 1;
+ ieee80211_tx_rate_update(ar->hw, sta, &arsta->tx_info);
+ }
if (ath10k_debug_is_extd_tx_stats_enabled(ar))
ath10k_accumulate_per_peer_tx_stats(ar, arsta, peer_stats,
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 15622943a885..f6799f3939bd 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -4968,6 +4968,7 @@ enum wmi_rate_preamble {
(((preamble) << 6) | ((nss) << 4) | (rate))
#define ATH10K_HW_AMPDU(flags) ((flags) & 0x1)
#define ATH10K_HW_BA_FAIL(flags) (((flags) >> 1) & 0x3)
+#define ATH10K_FW_SKIPPED_RATE_CTRL(flags) (((flags) >> 6) & 0x1)
#define ATH10K_VHT_MCS_NUM 10
#define ATH10K_BW_NUM 4
--
1.7.9.5
Anilkumar Kolli <[email protected]> writes:
> 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 <[email protected]>
> ---
> V3:
> - Added new API in mac80211 to update tx rate(Johannes)
>
> include/net/mac80211.h | 14 ++++++++++++++
> net/mac80211/status.c | 24 ++++++++++++++++++++++++
> 2 files changed, 38 insertions(+)
>
> diff --git a/include/net/mac80211.h b/include/net/mac80211.h
> index 8c26d2d36cbe..042186a21770 100644
> --- a/include/net/mac80211.h
> +++ b/include/net/mac80211.h
> @@ -4331,6 +4331,20 @@ void ieee80211_sta_set_expected_throughput(struct ieee80211_sta *pubsta,
> u32 thr);
>
> /**
> + * ieee80211_tx_rate_update - transmit rate update callback
> + *
> + * 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
> + * @status: tx status information
> + * @pubsta: the station to update the tx rate for.
> + */
> +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..232297ddaa02 100644
> --- a/net/mac80211/status.c
> +++ b/net/mac80211/status.c
> @@ -988,6 +988,30 @@ 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];
> +
> + if (pubsta) {
The function does nothing if pubsta is NULL; wouldn't it make more sense
to just mandate that it isn't NULL rather than have this check?
-Toke