diff options
author | Jouni Malinen <jouni.malinen@atheros.com> | 2009-12-04 12:10:34 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-12-22 13:55:54 -0500 |
commit | 265dc7f0964e4df95ab57a9d1618689301d39a55 (patch) | |
tree | fe34bb4005b991b21fcdf7c9046c94f77ba4295e /drivers/net | |
parent | 2c7e6bc9ac7cb518cf037495932d80f71a1596f2 (diff) |
mac80211_hwsim: Check all local addresses for TX Ack status
Since mac80211_hwsim supports multiple virtual interfaces, we need to
iterate through all active interfaces when figuring out whether there
is a match during TX Ack status checking. This fixes TX status
reporting for cases where secondary interfaces are used.
Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/mac80211_hwsim.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 89f527ee1a10..718a5f198c30 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -436,6 +436,38 @@ static bool hwsim_ps_rx_ok(struct mac80211_hwsim_data *data, | |||
436 | } | 436 | } |
437 | 437 | ||
438 | 438 | ||
439 | struct mac80211_hwsim_addr_match_data { | ||
440 | bool ret; | ||
441 | const u8 *addr; | ||
442 | }; | ||
443 | |||
444 | static void mac80211_hwsim_addr_iter(void *data, u8 *mac, | ||
445 | struct ieee80211_vif *vif) | ||
446 | { | ||
447 | struct mac80211_hwsim_addr_match_data *md = data; | ||
448 | if (memcmp(mac, md->addr, ETH_ALEN) == 0) | ||
449 | md->ret = true; | ||
450 | } | ||
451 | |||
452 | |||
453 | static bool mac80211_hwsim_addr_match(struct mac80211_hwsim_data *data, | ||
454 | const u8 *addr) | ||
455 | { | ||
456 | struct mac80211_hwsim_addr_match_data md; | ||
457 | |||
458 | if (memcmp(addr, data->hw->wiphy->perm_addr, ETH_ALEN) == 0) | ||
459 | return true; | ||
460 | |||
461 | md.ret = false; | ||
462 | md.addr = addr; | ||
463 | ieee80211_iterate_active_interfaces_atomic(data->hw, | ||
464 | mac80211_hwsim_addr_iter, | ||
465 | &md); | ||
466 | |||
467 | return md.ret; | ||
468 | } | ||
469 | |||
470 | |||
439 | static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, | 471 | static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, |
440 | struct sk_buff *skb) | 472 | struct sk_buff *skb) |
441 | { | 473 | { |
@@ -488,8 +520,7 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, | |||
488 | if (nskb == NULL) | 520 | if (nskb == NULL) |
489 | continue; | 521 | continue; |
490 | 522 | ||
491 | if (memcmp(hdr->addr1, data2->hw->wiphy->perm_addr, | 523 | if (mac80211_hwsim_addr_match(data2, hdr->addr1)) |
492 | ETH_ALEN) == 0) | ||
493 | ack = true; | 524 | ack = true; |
494 | memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status)); | 525 | memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status)); |
495 | ieee80211_rx_irqsafe(data2->hw, nskb); | 526 | ieee80211_rx_irqsafe(data2->hw, nskb); |