2013-11-24 16:56:56

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH 0/3] ath9k: tx99 initialization fixes

This patchset fix two issues in ath9k tx99 code. In particular:
*[PATCH 1/3]: add ieee80211_get_vif_by_addr to get a reference to
vif data structure for a given mac address
*[PATCH 2/3]: initialize tx99_vif pointer in ath9k_tx99_init() since
ath9k_add_interface() is not run for monitor interfaces
*[PATCH 3/3]: initialize first chain attempt counter to 1 in
ath9k_build_tx99_skb()

This patchset has been applied on top of latest Sujith's tx99 patches

Lorenzo Bianconi (3):
mac80211: implement ieee80211_get_vif_by_addr
ath9k: get tx99_vif pointer in ath9k_tx99_init
ath9k: fix mrr initialization in tx99 code

drivers/net/wireless/ath/ath9k/main.c | 9 ---------
drivers/net/wireless/ath/ath9k/tx99.c | 7 +++++++
include/net/mac80211.h | 9 +++++++++
net/mac80211/util.c | 26 ++++++++++++++++++++++++++
4 files changed, 42 insertions(+), 9 deletions(-)

--
1.8.3.2



2013-11-25 10:15:49

by Lorenzo Bianconi

[permalink] [raw]
Subject: Re: [PATCH 1/3] mac80211: implement ieee80211_get_vif_by_addr

> On Sun, 2013-11-24 at 17:56 +0100, Lorenzo Bianconi wrote:
>> ieee80211_get_vif_by_addr allows low level drivers to get a reference to
>> vif data structure which is not added to the driver as monitor interface.
>> ieee80211_get_vif_by_addr will be used in ath9k tx99 code
>
> Is that really better than having the driver use the iteration
> functions?

first two patches are not really necessary since I was using an old
version of iw which does not allow to set monitor interface in active
mode

>
>> + */
>> +struct ieee80211_vif *ieee80211_get_vif_by_addr(struct ieee80211_hw *hw,
>> + const u8 *mac)
>> +{
>> + struct ieee80211_vif *vif = NULL;
>> + struct ieee80211_local *local = hw_to_local(hw);
>> + struct ieee80211_sub_if_data *sdata;
>> +
>> + rcu_read_lock();
>> + list_for_each_entry_rcu(sdata, &local->interfaces, list) {
>> + if (!compare_ether_addr(sdata->vif.addr, mac)) {
>> + vif = &sdata->vif;
>> + break;
>> + }
>> + }
>> + rcu_read_unlock();
>> +
>> + return vif;
>
> In any case, this is completely broken wrt. locking, so I'm not taking
> it.
>

sorry, I was wrong

> johannes
>



--
UNIX is Sexy: who | grep -i blonde | talk; cd ~; wine; talk; touch;
unzip; touch; strip; gasp; finger; gasp; mount; fsck; more; yes; gasp;
umount; make clean; sleep

2013-11-24 16:57:00

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH 3/3] ath9k: fix retry chain initialization in tx99 code

Initialize first chain attempt counter to 1 in ath9k_build_tx99_skb().
Otherwise multi-retry chain is initialized to {idx,count} = {-1, 0} in
rate_control_fill_sta_table() and tx99 transmission rate is not configured in
rate_control_apply_mask() since first chain idx is set to -1

Signed-off-by: Lorenzo Bianconi <[email protected]>
---
drivers/net/wireless/ath/ath9k/tx99.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/ath/ath9k/tx99.c b/drivers/net/wireless/ath/ath9k/tx99.c
index c90eca3..ab154fe 100644
--- a/drivers/net/wireless/ath/ath9k/tx99.c
+++ b/drivers/net/wireless/ath/ath9k/tx99.c
@@ -76,6 +76,7 @@ static struct sk_buff *ath9k_build_tx99_skb(struct ath_softc *sc)
tx_info->band = hw->conf.chandef.chan->band;
tx_info->flags = IEEE80211_TX_CTL_NO_ACK;
tx_info->control.vif = sc->tx99_vif;
+ tx_info->control.rates[0].count = 1;

memcpy(skb->data + sizeof(*hdr), PN9Data, sizeof(PN9Data));

--
1.8.3.2


2013-11-24 16:56:56

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH 1/3] mac80211: implement ieee80211_get_vif_by_addr

ieee80211_get_vif_by_addr allows low level drivers to get a reference to
vif data structure which is not added to the driver as monitor interface.
ieee80211_get_vif_by_addr will be used in ath9k tx99 code

Signed-off-by: Lorenzo Bianconi <[email protected]>
---
include/net/mac80211.h | 9 +++++++++
net/mac80211/util.c | 26 ++++++++++++++++++++++++++
2 files changed, 35 insertions(+)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 7ceed99..cdec60d 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -4585,4 +4585,13 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, struct sk_buff *skb,
int band, struct ieee80211_sta **sta);

+/**
+ * ieee80211_get_vif_by_addr - get vif for given mac address
+ * @hw: pointer as obtained from ieee80211_alloc_hw()
+ * @mac: mac address
+ *
+ */
+struct ieee80211_vif *ieee80211_get_vif_by_addr(struct ieee80211_hw *hw,
+ const u8 *mac);
+
#endif /* MAC80211_H */
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 592a181..6a7a3df 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2472,3 +2472,29 @@ int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
ieee80211_tx_skb(sdata, skb);
return 0;
}
+
+/**
+ * ieee80211_get_vif_by_addr - get vif for given mac address
+ * @hw: pointer as obtained from ieee80211_alloc_hw()
+ * @mac: mac address
+ *
+ */
+struct ieee80211_vif *ieee80211_get_vif_by_addr(struct ieee80211_hw *hw,
+ const u8 *mac)
+{
+ struct ieee80211_vif *vif = NULL;
+ struct ieee80211_local *local = hw_to_local(hw);
+ struct ieee80211_sub_if_data *sdata;
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+ if (!compare_ether_addr(sdata->vif.addr, mac)) {
+ vif = &sdata->vif;
+ break;
+ }
+ }
+ rcu_read_unlock();
+
+ return vif;
+}
+EXPORT_SYMBOL(ieee80211_get_vif_by_addr);
--
1.8.3.2


2013-11-24 18:37:16

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 1/3] mac80211: implement ieee80211_get_vif_by_addr

PS: I also don't care about ath9k patches, splitting the series would
have been nice.

johannes


2013-11-24 16:56:58

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH 2/3] ath9k: get tx99_vif pointer in ath9k_tx99_init

Get vif reference in ath9k_tx99_init() since mac80211 does not run
ath9k_add_interface() for monitor interfaces

Signed-off-by: Lorenzo Bianconi <[email protected]>
---
drivers/net/wireless/ath/ath9k/main.c | 9 ---------
drivers/net/wireless/ath/ath9k/tx99.c | 6 ++++++
2 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 3d17398..7cb2ad9 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1046,14 +1046,6 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,

mutex_lock(&sc->mutex);

- if (config_enabled(CONFIG_ATH9K_TX99)) {
- if (sc->nvifs >= 1) {
- mutex_unlock(&sc->mutex);
- return -EOPNOTSUPP;
- }
- sc->tx99_vif = vif;
- }
-
ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type);
sc->nvifs++;

@@ -1120,7 +1112,6 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
mutex_lock(&sc->mutex);

sc->nvifs--;
- sc->tx99_vif = NULL;

if (ath9k_uses_beacons(vif->type))
ath9k_beacon_remove_slot(sc, vif);
diff --git a/drivers/net/wireless/ath/ath9k/tx99.c b/drivers/net/wireless/ath/ath9k/tx99.c
index c65c37f..c90eca3 100644
--- a/drivers/net/wireless/ath/ath9k/tx99.c
+++ b/drivers/net/wireless/ath/ath9k/tx99.c
@@ -89,6 +89,8 @@ static void ath9k_tx99_deinit(struct ath_softc *sc)
ath9k_ps_wakeup(sc);
ath9k_tx99_stop(sc);
ath9k_ps_restore(sc);
+
+ sc->tx99_vif = NULL;
}

static int ath9k_tx99_init(struct ath_softc *sc)
@@ -105,6 +107,10 @@ static int ath9k_tx99_init(struct ath_softc *sc)
return -EINVAL;
}

+ sc->tx99_vif = ieee80211_get_vif_by_addr(hw, hw->wiphy->perm_addr);
+ if (!sc->tx99_vif)
+ return -EINVAL;
+
sc->tx99_skb = ath9k_build_tx99_skb(sc);
if (!sc->tx99_skb)
return -ENOMEM;
--
1.8.3.2


2013-11-24 18:35:36

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 1/3] mac80211: implement ieee80211_get_vif_by_addr

On Sun, 2013-11-24 at 17:56 +0100, Lorenzo Bianconi wrote:
> ieee80211_get_vif_by_addr allows low level drivers to get a reference to
> vif data structure which is not added to the driver as monitor interface.
> ieee80211_get_vif_by_addr will be used in ath9k tx99 code

Is that really better than having the driver use the iteration
functions?

> + */
> +struct ieee80211_vif *ieee80211_get_vif_by_addr(struct ieee80211_hw *hw,
> + const u8 *mac)
> +{
> + struct ieee80211_vif *vif = NULL;
> + struct ieee80211_local *local = hw_to_local(hw);
> + struct ieee80211_sub_if_data *sdata;
> +
> + rcu_read_lock();
> + list_for_each_entry_rcu(sdata, &local->interfaces, list) {
> + if (!compare_ether_addr(sdata->vif.addr, mac)) {
> + vif = &sdata->vif;
> + break;
> + }
> + }
> + rcu_read_unlock();
> +
> + return vif;

In any case, this is completely broken wrt. locking, so I'm not taking
it.

johannes