On Thu, 2010-09-23 at 10:22 -0700, greearb@xxxxxxxxxxxxxxx wrote: > From: Ben Greear <greearb@xxxxxxxxxxxxxxx> > > When using multiple STA interfaces on the same radio, some > data packets need to be received on all interfaces > (broadcast, for instance). > > Make the STA loop look similar to the mgt-data loop. > > Also, add logic to check RX_FLAG_MMIC_ERROR for last > interface in mgt-data loop. > > Signed-off-by: Ben Greear <greearb@xxxxxxxxxxxxxxx> Acked-by: Johannes Berg <johannes@xxxxxxxxxxxxxxxx> > --- > :100644 100644 c036815... 29a582d... M net/mac80211/rx.c > net/mac80211/rx.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++------ > 1 files changed, 70 insertions(+), 10 deletions(-) > > diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c > index c036815..29a582d 100644 > --- a/net/mac80211/rx.c > +++ b/net/mac80211/rx.c > @@ -2613,7 +2613,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, > int prepares; > struct ieee80211_sub_if_data *prev = NULL; > struct sk_buff *skb_new; > - struct sta_info *sta, *tmp; > + struct sta_info *sta, *tmp, *prev_sta; > bool found_sta = false; > int err = 0; > > @@ -2644,22 +2644,74 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, > ieee80211_verify_alignment(&rx); > > if (ieee80211_is_data(fc)) { > + prev_sta = NULL; > for_each_sta_info(local, hdr->addr2, sta, tmp) { > - rx.sta = sta; > found_sta = true; > - rx.sdata = sta->sdata; > + if (!prev_sta) { > + prev_sta = sta; > + continue; > + } > + > + rx.sta = prev_sta; > + rx.sdata = prev_sta->sdata; > > rx.flags |= IEEE80211_RX_RA_MATCH; > prepares = prepare_for_handlers(rx.sdata, &rx, hdr); > - if (prepares) { > - if (status->flag & RX_FLAG_MMIC_ERROR) { > - if (rx.flags & IEEE80211_RX_RA_MATCH) > - ieee80211_rx_michael_mic_report(hdr, &rx); > - } else > - prev = rx.sdata; > + if (!prepares) > + goto next_sta; > + > + if (status->flag & RX_FLAG_MMIC_ERROR) { > + if (rx.flags & IEEE80211_RX_RA_MATCH) > + ieee80211_rx_michael_mic_report(hdr, &rx); > + goto next_sta; > + } > + > + /* > + * frame was destined for the previous interface > + * so invoke RX handlers for it > + */ > + skb_new = skb_copy(skb, GFP_ATOMIC); > + if (!skb_new) { > + if (net_ratelimit()) > + wiphy_debug(local->hw.wiphy, > + "failed to copy multicast" > + " frame for %s\n", > + prev_sta->sdata->name); > + goto next_sta; > + } > + ieee80211_invoke_rx_handlers(prev_sta->sdata, &rx, > + skb_new); > +next_sta: > + prev_sta = sta; > + } /* for all STA info */ > + > + if (prev_sta) { > + rx.sta = prev_sta; > + rx.sdata = prev_sta->sdata; > + > + rx.flags |= IEEE80211_RX_RA_MATCH; > + prepares = prepare_for_handlers(rx.sdata, &rx, hdr); > + if (!prepares) > + prev_sta = NULL; > + > + if (prev_sta && status->flag & RX_FLAG_MMIC_ERROR) { > + if (rx.flags & IEEE80211_RX_RA_MATCH) > + ieee80211_rx_michael_mic_report(hdr, &rx); > + prev_sta = NULL; > } > } > - } > + > + > + if (prev_sta) { > + ieee80211_invoke_rx_handlers(prev_sta->sdata, &rx, skb); > + return; > + } else { > + if (found_sta) { > + dev_kfree_skb(skb); > + return; > + } > + } > + } /* if data frame */ > if (!found_sta) { > list_for_each_entry_rcu(sdata, &local->interfaces, list) { > if (!ieee80211_sdata_running(sdata)) > @@ -2722,6 +2774,14 @@ next: > > if (!prepares) > prev = NULL; > + > + if (prev && status->flag & RX_FLAG_MMIC_ERROR) { > + rx.sdata = prev; > + if (rx.flags & IEEE80211_RX_RA_MATCH) > + ieee80211_rx_michael_mic_report(hdr, > + &rx); > + prev = NULL; > + } > } > } > if (prev) -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html