diff options
author | Jouni Malinen <jouni.malinen@atheros.com> | 2009-03-03 12:23:29 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-03-05 14:39:45 -0500 |
commit | c52f33d05e5f8d59f02722fbc308f5f391575ca5 (patch) | |
tree | 19c6d56f3594e8b43d725b5d919bb775921fde38 /drivers/net/wireless/ath9k/recv.c | |
parent | bce048d77dff3dcfd75d54dc38580c81baa95853 (diff) |
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>
Diffstat (limited to 'drivers/net/wireless/ath9k/recv.c')
-rw-r--r-- | drivers/net/wireless/ath9k/recv.c | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index ec535834f961..a9a55df500a4 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c | |||
@@ -19,7 +19,22 @@ | |||
19 | static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc, | 19 | static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc, |
20 | struct ieee80211_hdr *hdr) | 20 | struct ieee80211_hdr *hdr) |
21 | { | 21 | { |
22 | return sc->pri_wiphy->hw; | 22 | struct ieee80211_hw *hw = sc->pri_wiphy->hw; |
23 | int i; | ||
24 | |||
25 | spin_lock_bh(&sc->wiphy_lock); | ||
26 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
27 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | ||
28 | if (aphy == NULL) | ||
29 | continue; | ||
30 | if (compare_ether_addr(hdr->addr1, aphy->hw->wiphy->perm_addr) | ||
31 | == 0) { | ||
32 | hw = aphy->hw; | ||
33 | break; | ||
34 | } | ||
35 | } | ||
36 | spin_unlock_bh(&sc->wiphy_lock); | ||
37 | return hw; | ||
23 | } | 38 | } |
24 | 39 | ||
25 | /* | 40 | /* |
@@ -611,7 +626,29 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
611 | } | 626 | } |
612 | 627 | ||
613 | /* Send the frame to mac80211 */ | 628 | /* Send the frame to mac80211 */ |
614 | __ieee80211_rx(ath_get_virt_hw(sc, hdr), skb, &rx_status); | 629 | if (hdr->addr1[5] & 0x01) { |
630 | int i; | ||
631 | /* | ||
632 | * Deliver broadcast/multicast frames to all suitable | ||
633 | * virtual wiphys. | ||
634 | */ | ||
635 | /* TODO: filter based on channel configuration */ | ||
636 | for (i = 0; i < sc->num_sec_wiphy; i++) { | ||
637 | struct ath_wiphy *aphy = sc->sec_wiphy[i]; | ||
638 | struct sk_buff *nskb; | ||
639 | if (aphy == NULL) | ||
640 | continue; | ||
641 | nskb = skb_copy(skb, GFP_ATOMIC); | ||
642 | if (nskb) | ||
643 | __ieee80211_rx(aphy->hw, nskb, | ||
644 | &rx_status); | ||
645 | } | ||
646 | __ieee80211_rx(sc->hw, skb, &rx_status); | ||
647 | } else { | ||
648 | /* Deliver unicast frames based on receiver address */ | ||
649 | __ieee80211_rx(ath_get_virt_hw(sc, hdr), skb, | ||
650 | &rx_status); | ||
651 | } | ||
615 | 652 | ||
616 | /* We will now give hardware our shiny new allocated skb */ | 653 | /* We will now give hardware our shiny new allocated skb */ |
617 | bf->bf_mpdu = requeue_skb; | 654 | bf->bf_mpdu = requeue_skb; |