* [mac80211] mac80211: Support receiving data frames on multiple vifs.
@ 2010-09-20 17:52 greearb
2010-09-20 19:10 ` Johannes Berg
0 siblings, 1 reply; 12+ messages in thread
From: greearb @ 2010-09-20 17:52 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
From: Ben Greear <greearb@candelatech.com>
When using multiple STA interfaces on the same radio, some
data packets need to be received on all interfaces
(broadcast, for instance).
Remove special loop for data-only packets and just process all
packets in the big loop that previously only handled non-data
packets.
This needs review.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 c036815... 63baa04... M net/mac80211/rx.c
net/mac80211/rx.c | 121 ++++++++++++++++++++++-------------------------------
1 files changed, 50 insertions(+), 71 deletions(-)
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index c036815..63baa04 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2613,8 +2613,6 @@ 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;
- bool found_sta = false;
int err = 0;
fc = ((struct ieee80211_hdr *)skb->data)->frame_control;
@@ -2643,87 +2641,68 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
ieee80211_parse_qos(&rx);
ieee80211_verify_alignment(&rx);
- if (ieee80211_is_data(fc)) {
- for_each_sta_info(local, hdr->addr2, sta, tmp) {
- rx.sta = sta;
- found_sta = true;
- rx.sdata = 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 (!found_sta) {
- list_for_each_entry_rcu(sdata, &local->interfaces, list) {
- if (!ieee80211_sdata_running(sdata))
- continue;
-
- if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
- sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
- continue;
+ list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+ if (!ieee80211_sdata_running(sdata))
+ continue;
- /*
- * frame is destined for this interface, but if it's
- * not also for the previous one we handle that after
- * the loop to avoid copying the SKB once too much
- */
+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR ||
+ sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+ continue;
- if (!prev) {
- prev = sdata;
- continue;
- }
+ /*
+ * frame is destined for this interface, but if it's
+ * not also for the previous one we handle that after
+ * the loop to avoid copying the SKB once too much
+ */
- rx.sta = sta_info_get_bss(prev, hdr->addr2);
+ if (!prev) {
+ prev = sdata;
+ continue;
+ }
- rx.flags |= IEEE80211_RX_RA_MATCH;
- prepares = prepare_for_handlers(prev, &rx, hdr);
+ rx.sta = sta_info_get_bss(prev, hdr->addr2);
+ rx.sdata = prev;
+ rx.flags |= IEEE80211_RX_RA_MATCH;
+ prepares = prepare_for_handlers(prev, &rx, hdr);
- if (!prepares)
- goto next;
+ if (!prepares)
+ goto next;
- if (status->flag & RX_FLAG_MMIC_ERROR) {
- rx.sdata = prev;
- if (rx.flags & IEEE80211_RX_RA_MATCH)
- ieee80211_rx_michael_mic_report(hdr,
- &rx);
- goto next;
- }
+ if (status->flag & RX_FLAG_MMIC_ERROR) {
+ rx.sdata = prev;
+ if (rx.flags & IEEE80211_RX_RA_MATCH)
+ ieee80211_rx_michael_mic_report(hdr, &rx);
+ goto next;
+ }
- /*
- * frame was destined for the previous interface
- * so invoke RX handlers for it
- */
+ /*
+ * 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->name);
- goto next;
- }
- ieee80211_invoke_rx_handlers(prev, &rx, skb_new);
-next:
- prev = sdata;
+ 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->name);
+ goto next;
}
+ ieee80211_invoke_rx_handlers(prev, &rx, skb_new);
+next:
+ prev = sdata;
+ } /* for all interfaces */
- if (prev) {
- rx.sta = sta_info_get_bss(prev, hdr->addr2);
-
- rx.flags |= IEEE80211_RX_RA_MATCH;
- prepares = prepare_for_handlers(prev, &rx, hdr);
+ if (prev) {
+ rx.sta = sta_info_get_bss(prev, hdr->addr2);
+ rx.sdata = prev;
+ rx.flags |= IEEE80211_RX_RA_MATCH;
+ prepares = prepare_for_handlers(prev, &rx, hdr);
- if (!prepares)
- prev = NULL;
- }
+ if (!prepares)
+ prev = NULL;
}
+
if (prev)
ieee80211_invoke_rx_handlers(prev, &rx, skb);
else
--
1.7.2.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [mac80211] mac80211: Support receiving data frames on multiple vifs.
2010-09-20 17:52 greearb
@ 2010-09-20 19:10 ` Johannes Berg
2010-09-20 19:56 ` Ben Greear
0 siblings, 1 reply; 12+ messages in thread
From: Johannes Berg @ 2010-09-20 19:10 UTC (permalink / raw)
To: greearb; +Cc: linux-wireless
On Mon, 2010-09-20 at 10:52 -0700, greearb@candelatech.com wrote:
> From: Ben Greear <greearb@candelatech.com>
>
> When using multiple STA interfaces on the same radio, some
> data packets need to be received on all interfaces
> (broadcast, for instance).
>
> Remove special loop for data-only packets and just process all
> packets in the big loop that previously only handled non-data
> packets.
I'd prefer keeping different for_each_*, but maybe we can make the loops
just call a common function, say with &prev pointer or something? The
station loop will typically be iterating over fewer things here.
johannes
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [mac80211] mac80211: Support receiving data frames on multiple vifs.
2010-09-20 19:10 ` Johannes Berg
@ 2010-09-20 19:56 ` Ben Greear
2010-09-21 6:32 ` Johannes Berg
0 siblings, 1 reply; 12+ messages in thread
From: Ben Greear @ 2010-09-20 19:56 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
On 09/20/2010 12:10 PM, Johannes Berg wrote:
> On Mon, 2010-09-20 at 10:52 -0700, greearb@candelatech.com wrote:
>> From: Ben Greear<greearb@candelatech.com>
>>
>> When using multiple STA interfaces on the same radio, some
>> data packets need to be received on all interfaces
>> (broadcast, for instance).
>>
>> Remove special loop for data-only packets and just process all
>> packets in the big loop that previously only handled non-data
>> packets.
>
> I'd prefer keeping different for_each_*, but maybe we can make the loops
> just call a common function, say with&prev pointer or something? The
> station loop will typically be iterating over fewer things here.
While attempting this, I see something strange. It appears that
for the last interface (in the non-data loop), the
if (status->flag & RX_FLAG_MMIC_ERROR)
logic will not be run?
Is that on purpose?
Thanks,
Ben
>
> johannes
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply [flat|nested] 12+ messages in thread
* [mac80211] mac80211: Support receiving data frames on multiple vifs.
@ 2010-09-20 21:39 greearb
2010-09-21 6:47 ` Johannes Berg
0 siblings, 1 reply; 12+ messages in thread
From: greearb @ 2010-09-20 21:39 UTC (permalink / raw)
To: linux-wireless; +Cc: Ben Greear
From: Ben Greear <greearb@candelatech.com>
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.
This needs review.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
:100644 100644 c036815... a7847e1... 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..a7847e1 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 (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 (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)
--
1.7.2.2
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [mac80211] mac80211: Support receiving data frames on multiple vifs.
2010-09-20 19:56 ` Ben Greear
@ 2010-09-21 6:32 ` Johannes Berg
0 siblings, 0 replies; 12+ messages in thread
From: Johannes Berg @ 2010-09-21 6:32 UTC (permalink / raw)
To: Ben Greear; +Cc: linux-wireless
On Mon, 2010-09-20 at 12:56 -0700, Ben Greear wrote:
> On 09/20/2010 12:10 PM, Johannes Berg wrote:
> > On Mon, 2010-09-20 at 10:52 -0700, greearb@candelatech.com wrote:
> >> From: Ben Greear<greearb@candelatech.com>
> >>
> >> When using multiple STA interfaces on the same radio, some
> >> data packets need to be received on all interfaces
> >> (broadcast, for instance).
> >>
> >> Remove special loop for data-only packets and just process all
> >> packets in the big loop that previously only handled non-data
> >> packets.
> >
> > I'd prefer keeping different for_each_*, but maybe we can make the loops
> > just call a common function, say with&prev pointer or something? The
> > station loop will typically be iterating over fewer things here.
>
> While attempting this, I see something strange. It appears that
> for the last interface (in the non-data loop), the
> if (status->flag & RX_FLAG_MMIC_ERROR)
> logic will not be run?
>
> Is that on purpose?
No, certainly not.
johannes
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [mac80211] mac80211: Support receiving data frames on multiple vifs.
2010-09-20 21:39 [mac80211] mac80211: Support receiving data frames on multiple vifs greearb
@ 2010-09-21 6:47 ` Johannes Berg
2010-09-23 13:57 ` Ben Greear
0 siblings, 1 reply; 12+ messages in thread
From: Johannes Berg @ 2010-09-21 6:47 UTC (permalink / raw)
To: greearb; +Cc: linux-wireless
On Mon, 2010-09-20 at 14:39 -0700, greearb@candelatech.com wrote:
> From: Ben Greear <greearb@candelatech.com>
>
> 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.
>
> This needs review.
Looks fine to me, I think.
johannes
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [mac80211] mac80211: Support receiving data frames on multiple vifs.
2010-09-21 6:47 ` Johannes Berg
@ 2010-09-23 13:57 ` Ben Greear
2010-09-23 14:06 ` Johannes Berg
0 siblings, 1 reply; 12+ messages in thread
From: Ben Greear @ 2010-09-23 13:57 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
On 09/20/2010 11:47 PM, Johannes Berg wrote:
> On Mon, 2010-09-20 at 14:39 -0700, greearb@candelatech.com wrote:
>> From: Ben Greear<greearb@candelatech.com>
>>
>> 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.
>>
>> This needs review.
>
> Looks fine to me, I think.
Does this need any more work before being accepted upstream?
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [mac80211] mac80211: Support receiving data frames on multiple vifs.
2010-09-23 13:57 ` Ben Greear
@ 2010-09-23 14:06 ` Johannes Berg
2010-09-23 16:57 ` Ben Greear
0 siblings, 1 reply; 12+ messages in thread
From: Johannes Berg @ 2010-09-23 14:06 UTC (permalink / raw)
To: Ben Greear; +Cc: linux-wireless
On Thu, 2010-09-23 at 06:57 -0700, Ben Greear wrote:
> On 09/20/2010 11:47 PM, Johannes Berg wrote:
> > On Mon, 2010-09-20 at 14:39 -0700, greearb@candelatech.com wrote:
> >> From: Ben Greear<greearb@candelatech.com>
> >>
> >> 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.
> >>
> >> This needs review.
> >
> > Looks fine to me, I think.
>
> Does this need any more work before being accepted upstream?
Well, I personally would've tried to reduce the code duplication between
the two loops, but right now I'm not sure I see how to.
johannes
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [mac80211] mac80211: Support receiving data frames on multiple vifs.
2010-09-23 14:06 ` Johannes Berg
@ 2010-09-23 16:57 ` Ben Greear
2010-09-23 18:42 ` Johannes Berg
0 siblings, 1 reply; 12+ messages in thread
From: Ben Greear @ 2010-09-23 16:57 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
On 09/23/2010 07:06 AM, Johannes Berg wrote:
> On Thu, 2010-09-23 at 06:57 -0700, Ben Greear wrote:
>> On 09/20/2010 11:47 PM, Johannes Berg wrote:
>>> On Mon, 2010-09-20 at 14:39 -0700, greearb@candelatech.com wrote:
>>>> From: Ben Greear<greearb@candelatech.com>
>>>>
>>>> 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.
>>>>
>>>> This needs review.
>>>
>>> Looks fine to me, I think.
>>
>> Does this need any more work before being accepted upstream?
>
> Well, I personally would've tried to reduce the code duplication between
> the two loops, but right now I'm not sure I see how to.
I could move some of the rx setup code into prepare_for_handlers,
but not sure how much that would help readability.
In my opinion, that would be a good candidate for a followup
patch instead of adding that to this patch, though.
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [mac80211] mac80211: Support receiving data frames on multiple vifs.
2010-09-23 16:57 ` Ben Greear
@ 2010-09-23 18:42 ` Johannes Berg
2010-09-23 18:48 ` Ben Greear
0 siblings, 1 reply; 12+ messages in thread
From: Johannes Berg @ 2010-09-23 18:42 UTC (permalink / raw)
To: Ben Greear; +Cc: linux-wireless
On Thu, 2010-09-23 at 09:57 -0700, Ben Greear wrote:
> > Well, I personally would've tried to reduce the code duplication between
> > the two loops, but right now I'm not sure I see how to.
>
> I could move some of the rx setup code into prepare_for_handlers,
> but not sure how much that would help readability.
>
> In my opinion, that would be a good candidate for a followup
> patch instead of adding that to this patch, though.
Yeah, I can agree with that.
I have a patch that also touches this area, I'll let you get this one in
first and rebase it.
Thanks,
Johannes
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [mac80211] mac80211: Support receiving data frames on multiple vifs.
2010-09-23 18:42 ` Johannes Berg
@ 2010-09-23 18:48 ` Ben Greear
2010-09-23 19:07 ` Johannes Berg
0 siblings, 1 reply; 12+ messages in thread
From: Ben Greear @ 2010-09-23 18:48 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless
On 09/23/2010 11:42 AM, Johannes Berg wrote:
> On Thu, 2010-09-23 at 09:57 -0700, Ben Greear wrote:
>
>>> Well, I personally would've tried to reduce the code duplication between
>>> the two loops, but right now I'm not sure I see how to.
>>
>> I could move some of the rx setup code into prepare_for_handlers,
>> but not sure how much that would help readability.
>>
>> In my opinion, that would be a good candidate for a followup
>> patch instead of adding that to this patch, though.
>
> Yeah, I can agree with that.
>
> I have a patch that also touches this area, I'll let you get this one in
> first and rebase it.
Thanks!
I'm currently testing VAP + STA on same hardware concurrently with
ath5k, and seems the VAP doesn't receive any packets.
When I get that sorted, I'll work on the rx setup code minimization
patch.
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [mac80211] mac80211: Support receiving data frames on multiple vifs.
2010-09-23 18:48 ` Ben Greear
@ 2010-09-23 19:07 ` Johannes Berg
0 siblings, 0 replies; 12+ messages in thread
From: Johannes Berg @ 2010-09-23 19:07 UTC (permalink / raw)
To: Ben Greear; +Cc: linux-wireless
On Thu, 2010-09-23 at 11:48 -0700, Ben Greear wrote:
> When I get that sorted, I'll work on the rx setup code minimization
> patch.
working on it, will have something for review in a minute
johannes
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2010-09-23 19:07 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-09-20 21:39 [mac80211] mac80211: Support receiving data frames on multiple vifs greearb
2010-09-21 6:47 ` Johannes Berg
2010-09-23 13:57 ` Ben Greear
2010-09-23 14:06 ` Johannes Berg
2010-09-23 16:57 ` Ben Greear
2010-09-23 18:42 ` Johannes Berg
2010-09-23 18:48 ` Ben Greear
2010-09-23 19:07 ` Johannes Berg
-- strict thread matches above, loose matches on Subject: below --
2010-09-20 17:52 greearb
2010-09-20 19:10 ` Johannes Berg
2010-09-20 19:56 ` Ben Greear
2010-09-21 6:32 ` Johannes Berg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).