ath9k: Add support for multiple secondary virtual wiphys
The new struct ath_softc::sec_wiphy array is used to store information
about virtual wiphys and select which wiphy is used in calls to
mac80211. Each virtual wiphy will be assigned a different MAC address
based on the virtual wiphy index.
Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c
index 357d797..760f5b8 100644
--- a/drivers/net/wireless/ath9k/beacon.c
+++ b/drivers/net/wireless/ath9k/beacon.c
@@ -113,9 +113,11 @@
series, 4, 0);
}
-static struct ath_buf *ath_beacon_generate(struct ath_softc *sc,
+static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
+ struct ath_wiphy *aphy = hw->priv;
+ struct ath_softc *sc = aphy->sc;
struct ath_buf *bf;
struct ath_vif *avp;
struct sk_buff *skb;
@@ -144,7 +146,7 @@
/* Get a new beacon from mac80211 */
- skb = ieee80211_beacon_get(sc->hw, vif);
+ skb = ieee80211_beacon_get(hw, vif);
bf->bf_mpdu = skb;
if (skb == NULL)
return NULL;
@@ -171,7 +173,7 @@
return NULL;
}
- skb = ieee80211_get_buffered_bc(sc->hw, vif);
+ skb = ieee80211_get_buffered_bc(hw, vif);
/*
* if the CABQ traffic from previous DTIM is pending and the current
@@ -196,8 +198,8 @@
ath_beacon_setup(sc, avp, bf);
while (skb) {
- ath_tx_cabq(sc, skb);
- skb = ieee80211_get_buffered_bc(sc->hw, vif);
+ ath_tx_cabq(hw, skb);
+ skb = ieee80211_get_buffered_bc(hw, vif);
}
return bf;
@@ -244,8 +246,9 @@
return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
}
-int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif)
+int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
{
+ struct ath_softc *sc = aphy->sc;
struct ath_vif *avp;
struct ieee80211_hdr *hdr;
struct ath_buf *bf;
@@ -286,6 +289,7 @@
}
BUG_ON(sc->beacon.bslot[avp->av_bslot] != NULL);
sc->beacon.bslot[avp->av_bslot] = vif;
+ sc->beacon.bslot_aphy[avp->av_bslot] = aphy;
sc->nbcnvifs++;
}
}
@@ -368,6 +372,7 @@
if (avp->av_bslot != -1) {
sc->beacon.bslot[avp->av_bslot] = NULL;
+ sc->beacon.bslot_aphy[avp->av_bslot] = NULL;
sc->nbcnvifs--;
}
@@ -391,6 +396,7 @@
struct ath_hw *ah = sc->sc_ah;
struct ath_buf *bf = NULL;
struct ieee80211_vif *vif;
+ struct ath_wiphy *aphy;
int slot;
u32 bfaddr, bc = 0, tsftu;
u64 tsf;
@@ -439,6 +445,7 @@
tsftu = TSF_TO_TU(tsf>>32, tsf);
slot = ((tsftu % intval) * ATH_BCBUF) / intval;
vif = sc->beacon.bslot[(slot + 1) % ATH_BCBUF];
+ aphy = sc->beacon.bslot_aphy[(slot + 1) % ATH_BCBUF];
DPRINTF(sc, ATH_DBG_BEACON,
"slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
@@ -446,7 +453,7 @@
bfaddr = 0;
if (vif) {
- bf = ath_beacon_generate(sc, vif);
+ bf = ath_beacon_generate(aphy->hw, vif);
if (bf != NULL) {
bfaddr = bf->bf_daddr;
bc = 1;