* Re: [PATCH] cfg80211: Add new helper function for channels
From: Arend Van Spriel @ 2019-08-30 10:40 UTC (permalink / raw)
To: Amar Singhal, jouni; +Cc: johannes, linux-wireless, jjohnson, rmanohar
In-Reply-To: <1567115381-7831-1-git-send-email-asinghal@codeaurora.org>
On 8/29/2019 11:49 PM, Amar Singhal wrote:
> Add new helper function to convert (chan_number, oper_class) pair to
> frequency. Call this function ieee80211_channel_op_class_to_frequency.
> This function would be very useful in the context of 6 GHz channels,
> where channel number is not unique.
That 'unique' statement does not apply to 6GHz by itself. The addition
of 6GHz channels makes channel numbers across bands not unique.
The funcion
> Signed-off-by: Amar Singhal <asinghal@codeaurora.org>
> ---
> include/net/cfg80211.h | 10 ++++++++++
> net/wireless/util.c | 23 +++++++++++++++++++++++
> 2 files changed, 33 insertions(+)
>
> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
> index 6467b60..decafba 100644
> --- a/include/net/cfg80211.h
> +++ b/include/net/cfg80211.h
> @@ -4914,1 +4914,1 @@ static inline void *wdev_priv(struct wireless_dev *wdev)
> int ieee80211_channel_to_frequency(int chan, enum nl80211_band band);
>
> /**
> + * ieee80211_channel_op_class_to_frequency - convert
> + * (channel, operating class) to frequency
> + * @chan_num: channel number
> + * @global_op_class: global operating class
> + *
> + * Return: The corresponding frequency, or 0 if the conversion failed.
> + */
> +int ieee80211_channel_op_class_to_frequency(u8 chan_num, u8 global_op_class);
> +
> +/**
> * ieee80211_frequency_to_channel - convert frequency to channel number
> * @freq: center frequency
> * Return: The corresponding channel, or 0 if the conversion failed.
> diff --git a/net/wireless/util.c b/net/wireless/util.c
> index 9aba8d54..7f64b4a 100644
> --- a/net/wireless/util.c
> +++ b/net/wireless/util.c
> @@ -144,6 +144,29 @@ struct ieee80211_channel *ieee80211_get_channel(struct wiphy *wiphy, int freq)
> }
> EXPORT_SYMBOL(ieee80211_get_channel);
>
> +int ieee80211_channel_op_class_to_frequency(u8 chan_num, u8 global_op_class)
> +{
> + if (global_op_class >= 131 && global_op_class <= 135)
> + return (5940 + 5 * chan_num);
> + else if (global_op_class >= 115 && global_op_class <= 130)
> + return (5000 + 5 * chan_num);
> + else if (global_op_class >= 112 && global_op_class <= 113)
> + return (5000 + 5 * chan_num);
> + else if (global_op_class >= 109 && global_op_class <= 110)
> + return (4000 + 5 * chan_num);
> + else if (global_op_class >= 83 && global_op_class <= 84)
> + return (2407 + 5 * chan_num);
> + else if (global_op_class == 81)
> + return (2407 + 5 * chan_num);
> + else if (global_op_class == 82)
> + return (2414 + 5 * chan_num);
> + else if (global_op_class == 180)
> + return (56160 + 5 * chan_num);
> + else
> + return 0;
> +}
> +EXPORT_SYMBOL(ieee80211_channel_op_class_to_frequency);
The function ieee80211_operating_class_to_band() uses ranges within
switch statement, eg.:
case 128 ... 130:
*band = NL80211_BAND_5GHZ;
return true;
For consistency it might be good to do the same here.
Regards,
Arend
^ permalink raw reply
* Re: [PATCH] cfg80211: inspect off channel operation only when off channel given
From: Johannes Berg @ 2019-08-30 10:40 UTC (permalink / raw)
To: peter.oh, linux-wireless
In-Reply-To: <1530880295.3197.39.camel@sipsolutions.net>
On Fri, 2018-07-06 at 14:31 +0200, Johannes Berg wrote:
> On Tue, 2018-07-03 at 16:04 -0700, peter.oh@bowerswilkins.com wrote:
> > From: Peter Oh <peter.oh@bowerswilkins.com>
> >
> > NL80211_ATTR_OFFCHANNEL_TX_OK does not mean given channel is always
> > off channel, but it means the channel given could be off channel.
> > Hence it should not block the given channel to be used if given
> > channel does not require off channel mgmt tx although regulatory
> > domain is non-ETSI.
> >
> > Signed-off-by: Peter Oh <peter.oh@bowerswilkins.com>
> > ---
> > net/wireless/nl80211.c | 4 +++-
> > 1 file changed, 3 insertions(+), 1 deletion(-)
> >
> > diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
> > index 4eece06..991042b 100644
> > --- a/net/wireless/nl80211.c
> > +++ b/net/wireless/nl80211.c
> > @@ -9915,7 +9915,9 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
> > return -EINVAL;
> >
> > wdev_lock(wdev);
> > - if (params.offchan && !cfg80211_off_channel_oper_allowed(wdev)) {
> > + if (params.offchan &&
> > + !cfg80211_chandef_identical(&chandef, &wdev->chandef) &&
> > + !cfg80211_off_channel_oper_allowed(wdev)) {
> > wdev_unlock(wdev);
>
> Hmm. That seems fine, but can we be sure that wdev->chandef is always
> valid? ISTR that it isn't necessarily updated all the time, but I can't
> really say right now.
For the record, in addition to this question, the commit log might need
some rewording since the whole regulatory/non-ETSI part isn't really
obvious (and not clear to me right now).
I've had this patch waiting for about a year now, I'll drop it. Please
resend if it's still relevant.
johannes
^ permalink raw reply
* Re: [PATCH v6] mac80211_hwsim: Register support for HE meshpoint
From: Johannes Berg @ 2019-08-30 10:38 UTC (permalink / raw)
To: Sven Eckelmann, Jouni Malinen; +Cc: linux-wireless
In-Reply-To: <3127506.552nsDcnha@bentobox>
Hi,
> > mesh_secure_ocv_mix_legacy
> > wpas_mesh_open_ht40
> > mesh_secure_ocv_mix_ht
> No, these also failed for me without the mac80211_hwsim patch [3] in a full
> test run. And thus not analyzed further by me.
I also see these fail if (and only if) I have this patch applied.
I'm going to drop this patch (again) for now, even if the situation is
now better I still don't want to knowingly break things there.
Please resend once that's all sorted out.
johannes
^ permalink raw reply
* Re: [PATCH] cfg80211: Convert 6 GHz channel frequency to channel number
From: Johannes Berg @ 2019-08-30 10:32 UTC (permalink / raw)
To: Amar Singhal, jouni; +Cc: linux-wireless, jjohnson, rmanohar
In-Reply-To: <1567117290-19295-1-git-send-email-asinghal@codeaurora.org>
On Thu, 2019-08-29 at 15:21 -0700, Amar Singhal wrote:
> Enhance function ieee80211_frequency_to_channel by adding 6 GHz
> channels.
Wait, this is already supported, no? Just implemented slightly
differently?
johannes
^ permalink raw reply
* Re: [PATCH 1/2] nl80211: Add NL80211_EXT_FEATURE_LIVE_IFTYPE_CHANGE
From: Johannes Berg @ 2019-08-30 10:19 UTC (permalink / raw)
To: Denis Kenzior, linux-wireless
In-Reply-To: <20190826162637.7535-1-denkenz@gmail.com>
On Mon, 2019-08-26 at 11:26 -0500, Denis Kenzior wrote:
>
> + * Prior to Kernel 5.4, userspace applications should implement the
> + * following behavior:
I'm not sure mentioning the kernel version here does us any good? I
mean, you really need to implement that behaviour regardless of kernel
version, if NL80211_EXT_FEATURE_LIVE_IFTYPE_CHANGE isn't set.
> + * @NL80211_EXT_FEATURE_LIVE_IFTYPE_CHANGE: This device supports switching
> + * the IFTYPE of an interface without having to bring the device DOWN
> + * first via RTNL. Exact semantics of this feature is driver
> + * implementation dependent.
That's not really nice.
> For mac80211, the following restrictions
> + * apply:
> + * - Only devices currently in IFTYPE AP, P2P_GO, P2P_CLIENT,
> + * STATION, ADHOC and OCB can be switched.
> + * - The target IFTYPE must be one of: AP, P2P_GO, P2P_CLIENT,
> + * STATION, ADHOC or OCB.
> + * Other drivers are expected to follow similar restrictions.
Maybe we should instead have a "bitmask of interface types that can be
switched while live" or something like that?
johannes
^ permalink raw reply
* Re: [RFCv2 4/4] nl80211: Send large new_wiphy events
From: Johannes Berg @ 2019-08-30 10:14 UTC (permalink / raw)
To: Denis Kenzior, linux-wireless
In-Reply-To: <20190816192703.12445-4-denkenz@gmail.com>
On Fri, 2019-08-16 at 14:27 -0500, Denis Kenzior wrote:
> Send large NEW_WIPHY events on a new multicast group so that clients
> that can accept larger messages do not need to round-trip to the kernel
> and perform extra filtered wiphy dumps.
>
> A new multicast group is introduced and the large message is sent before
> the legacy message. This way clients that listen on both multicast
> groups can ignore duplicate legacy messages if needed.
Since I just did the digging, it seems that this would affect (old)
applications with libnl up to 3.2.22, unless they changed the default
recvmsg() buffer size.
I think this is a pretty decent approach, but I'm slightly worried about
hitting the new limits (16k) eventually. It seems far off now, but who
knows what kind of data we'll add. HE is (and likely will be) adding
quite a bit since it has everything for each interface type - something
drivers have for the most part not implemented yet. That trend will only
continue, as complexity in the spec doesn't seem to be going down.
And I don't really want to see "config3" a couple of years down the
road...
So can we at least mandate (document) that "config2" basically has no
message limit, and you will use MSG_PEEK/handle MSG_TRUNC with it?
That way, we can later bump the 8192 even beyond 16k if needed, and not
run into problems.
> + if (cmd == NL80211_CMD_NEW_WIPHY) {
> + state.large_message = true;
> + alloc_size = 8192UL;
> + } else
> + alloc_size = NLMSG_DEFAULT_SIZE;
> +
nit: there should be braces on both branches
> + if (nl80211_send_wiphy(rdev, cmd, msg, 0, 0, 0, &state) < 0) {
> + nlmsg_free(msg);
> + goto legacy;
> + }
I think that'd be worth a WARN_ON(), it should never happen that you
actually run out of space, it means that the above wasn't big enough.
Now, on the previous patches I actually thought that you could set
"state->split" (and you should) and not need "state->large_message" in
order to indicate that the sub-functions are allowed to create larger
data - just keep filling the SKBs as much as possible for the dump.
Here, it seems like we do need it. It might be possible to get away
without it (by setting split here, and then having some special code to
handle the case of it not getting to the end), but that doesn't seem
worth it.
> @@ -14763,6 +14787,8 @@ void nl80211_notify_iface(struct cfg80211_registered_device *rdev,
> return;
> }
>
> + genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
> + NL80211_MCGRP_CONFIG2, GFP_KERNEL);
Hmm. That seems only needed if you don't want to listen on "config" at
all, but in the patch description you explicitly said that you send it
on "config2" *before* "config" for compatibility reasons (which makes
sense) - so what is it?
I'm having a hard time seeing anyone get away with only listening on
config2 since that'd basically require very recent (as of now future)
kernel. Are you planning this for a world where you can ditch support
for kernel<5.4 (or so)?
johannes
^ permalink raw reply
* Re: [RFCv2 1/4] nl80211: Fix broken non-split wiphy dumps
From: Johannes Berg @ 2019-08-30 9:53 UTC (permalink / raw)
To: Denis Kenzior, linux-wireless
In-Reply-To: <ec3b9fd84fb8c5d333445d872bb0f864a4655a6b.camel@sipsolutions.net>
On Fri, 2019-08-30 at 11:40 +0200, Johannes Berg wrote:
> On Fri, 2019-08-30 at 11:10 +0200, Johannes Berg wrote:
> > On Fri, 2019-08-30 at 11:03 +0200, Johannes Berg wrote:
> > > On Fri, 2019-08-16 at 14:27 -0500, Denis Kenzior wrote:
> > > > If a (legacy) client requested a wiphy dump but did not provide the
> > > > NL80211_ATTR_SPLIT_WIPHY_DUMP attribute, the dump was supposed to be
> > > > composed of purely non-split NEW_WIPHY messages, with 1 wiphy per
> > > > message. At least this was the intent after commit:
> > > > 3713b4e364ef ("nl80211: allow splitting wiphy information in dumps")
> > > >
> > > > However, in reality the non-split dumps were broken very shortly after.
> > > > Perhaps around commit:
> > > > fe1abafd942f ("nl80211: re-add channel width and extended capa advertising")
> > >
> > > Fun. I guess we updated all userspace quickly enough to not actually
> > > have any issues there. As far as I remember, nobody ever complained, so
> > > I guess people just updated their userspace.
> >
> > Actually, going back in time to the code there (e.g. iw and hostap), it
> > seems that it quite possibly never was a userspace issue, just an issue
> > with netlink allocating a 4k SKB by default for dumps.
> >
> > Even then, libnl would've defaulted to a 16k recvmsg() buffer size, and
> > we didn't override that anywhere.
>
> Ah, also not quite true, at the time it still had a 4k default, until
> commit 807fddc4cd9e ("nl: Increase receive buffer size to 4 pages")
> dated May 8, 2013.
However, even before that, it would have supported responding to
MSG_TRUNC by retrying the recvmsg(), but hostap/iw wouldn't have set
nl_socket_enable_msg_peek()... oh well.
johannes
^ permalink raw reply
* Re: [RFCv2 1/4] nl80211: Fix broken non-split wiphy dumps
From: Johannes Berg @ 2019-08-30 9:40 UTC (permalink / raw)
To: Denis Kenzior, linux-wireless
In-Reply-To: <00161d6069cda67dbd8b918dd987e01dc1a3dab3.camel@sipsolutions.net>
On Fri, 2019-08-30 at 11:10 +0200, Johannes Berg wrote:
> On Fri, 2019-08-30 at 11:03 +0200, Johannes Berg wrote:
> > On Fri, 2019-08-16 at 14:27 -0500, Denis Kenzior wrote:
> > > If a (legacy) client requested a wiphy dump but did not provide the
> > > NL80211_ATTR_SPLIT_WIPHY_DUMP attribute, the dump was supposed to be
> > > composed of purely non-split NEW_WIPHY messages, with 1 wiphy per
> > > message. At least this was the intent after commit:
> > > 3713b4e364ef ("nl80211: allow splitting wiphy information in dumps")
> > >
> > > However, in reality the non-split dumps were broken very shortly after.
> > > Perhaps around commit:
> > > fe1abafd942f ("nl80211: re-add channel width and extended capa advertising")
> >
> > Fun. I guess we updated all userspace quickly enough to not actually
> > have any issues there. As far as I remember, nobody ever complained, so
> > I guess people just updated their userspace.
>
> Actually, going back in time to the code there (e.g. iw and hostap), it
> seems that it quite possibly never was a userspace issue, just an issue
> with netlink allocating a 4k SKB by default for dumps.
>
> Even then, libnl would've defaulted to a 16k recvmsg() buffer size, and
> we didn't override that anywhere.
Ah, also not quite true, at the time it still had a 4k default, until
commit 807fddc4cd9e ("nl: Increase receive buffer size to 4 pages")
dated May 8, 2013.
johannes
^ permalink raw reply
* Re: [RFCv2 2/4] nl80211: Support >4096 byte NEW_WIPHY event nlmsg
From: Johannes Berg @ 2019-08-30 9:36 UTC (permalink / raw)
To: Denis Kenzior, linux-wireless
In-Reply-To: <20190816192703.12445-2-denkenz@gmail.com>
On Fri, 2019-08-16 at 14:27 -0500, Denis Kenzior wrote:
> For historical reasons, NEW_WIPHY messages generated by dumps or
> GET_WIPHY commands were limited to 4096 bytes due to userspace tools
> using limited buffers.
I think now that I've figured out why, it'd be good to note that it
wasn't due to userspace tools, but rather due to the default netlink
dump skb allocation at the time, prior to commit 9063e21fb026
("netlink: autosize skb lengthes").
> Once the sizes NEW_WIPHY messages exceeded these
> sizes, split dumps were introduced. All any non-legacy data was added
> only to messages using split-dumps (including filtered dumps).
>
> However, split-dumping has quite a significant overhead. On cards
> tested, split dumps generated message sizes 1.7-1.8x compared to
> non-split dumps, while still comfortably fitting into an 8k buffer. The
> kernel now expects userspace to provide 16k buffers by default, and 32k
> buffers are possible.
>
> Introduce a concept of a large message, so that if the kernel detects
> that userspace has provided a buffer of sufficient size, a non-split
> message could be generated.
So, there's still a wrinkle with this. Larger SKB allocation can fail,
and instead of returning an error to userspace, the kernel will allocate
a smaller SKB instead.
With genetlink, we currently don't even have a way of controlling the
minimum allocation that's always required.
Since we already have basically all of the mechanics, I'd say perhaps a
better concept would be to "split when necessary", aborting if split
isn't supported.
IOW, do something like
... nl80211_send_wiphy(...)
{
[...]
switch (state->split_start) {
[...]
case <N>:
[...] // put stuff
state->split_start++;
state->skb_end = nlmsg_get_pos(skb);
/* fall through */
case <N+1>:
[...]
}
finish:
genlmsg_end(msg, hdr);
return 0;
nla_put_failure:
if (state->split_start < 9) {
genlmsg_cancel(msg, hdr);
return -EMSGSIZE;
}
nlmsg_trim(msg, state->skb_end);
goto finish;
}
That way, we fill each SKB as much as possible, up to 32k if userspace
provided big enough buffers *and* we could allocate the SKB.
Your userspace would still set the split flag, and thus be compatible
with all kinds of options:
* really old kernel not supporting split
* older kernel sending many messages
* kernel after this change packing more into one message
* even if allocating big SKBs failed
johannes
^ permalink raw reply
* Re: [RFCv2 1/4] nl80211: Fix broken non-split wiphy dumps
From: Johannes Berg @ 2019-08-30 9:10 UTC (permalink / raw)
To: Denis Kenzior, linux-wireless
In-Reply-To: <f7c98da178677cbb0cad3568f4ea4ab85171edd8.camel@sipsolutions.net>
On Fri, 2019-08-30 at 11:03 +0200, Johannes Berg wrote:
> On Fri, 2019-08-16 at 14:27 -0500, Denis Kenzior wrote:
> > If a (legacy) client requested a wiphy dump but did not provide the
> > NL80211_ATTR_SPLIT_WIPHY_DUMP attribute, the dump was supposed to be
> > composed of purely non-split NEW_WIPHY messages, with 1 wiphy per
> > message. At least this was the intent after commit:
> > 3713b4e364ef ("nl80211: allow splitting wiphy information in dumps")
> >
> > However, in reality the non-split dumps were broken very shortly after.
> > Perhaps around commit:
> > fe1abafd942f ("nl80211: re-add channel width and extended capa advertising")
>
> Fun. I guess we updated all userspace quickly enough to not actually
> have any issues there. As far as I remember, nobody ever complained, so
> I guess people just updated their userspace.
Actually, going back in time to the code there (e.g. iw and hostap), it
seems that it quite possibly never was a userspace issue, just an issue
with netlink allocating a 4k SKB by default for dumps.
Even then, libnl would've defaulted to a 16k recvmsg() buffer size, and
we didn't override that anywhere.
So more likely, this was all fixed by kernel 9063e21fb026 ("netlink:
autosize skb lengthes") about a year after we ran into the problem.
johannes
^ permalink raw reply
* Re: [RFCv2 1/4] nl80211: Fix broken non-split wiphy dumps
From: Johannes Berg @ 2019-08-30 9:03 UTC (permalink / raw)
To: Denis Kenzior, linux-wireless
In-Reply-To: <20190816192703.12445-1-denkenz@gmail.com>
On Fri, 2019-08-16 at 14:27 -0500, Denis Kenzior wrote:
> If a (legacy) client requested a wiphy dump but did not provide the
> NL80211_ATTR_SPLIT_WIPHY_DUMP attribute, the dump was supposed to be
> composed of purely non-split NEW_WIPHY messages, with 1 wiphy per
> message. At least this was the intent after commit:
> 3713b4e364ef ("nl80211: allow splitting wiphy information in dumps")
>
> However, in reality the non-split dumps were broken very shortly after.
> Perhaps around commit:
> fe1abafd942f ("nl80211: re-add channel width and extended capa advertising")
Fun. I guess we updated all userspace quickly enough to not actually
have any issues there. As far as I remember, nobody ever complained, so
I guess people just updated their userspace.
Given that it's been 6+ years, maybe we're better off just removing the
whole non-split thing then, instead of fixing it. Seems even less likely
now that somebody would run a 6+yo supplicant (from before its commit
c30a4ab045ce ("nl80211: Fix mode settings with split wiphy dump")).
OTOH, this is a simple fix, would removing the non-split mode result in
any appreciable cleanups? Perhaps not, and we'd have to insert something
instead to reject non-split and log a warning, or whatnot.
johannes
^ permalink raw reply
* Re: [PATCH] cfg80211: Purge frame registrations on iftype change
From: Johannes Berg @ 2019-08-30 8:53 UTC (permalink / raw)
To: Denis Kenzior, linux-wireless; +Cc: stable
In-Reply-To: <20190828211110.15005-1-denkenz@gmail.com>
On Wed, 2019-08-28 at 16:11 -0500, Denis Kenzior wrote:
> Currently frame registrations are not purged, even when changing the
> interface type. This can lead to potentially weird / dangerous
> situations where frames possibly not relevant to a given interface
> type remain registered and mgmt_frame_register is not called for the
> no-longer-relevant frame types.
I'd argue really just "weird and non-working", hardly dangerous. Even in
the mac80211 design where we want to not let you intercept e.g. AUTH
frames in client mode - if you did, then you'd just end up with a non-
working interface. Not sure I see any "dangerous situation". Not really
an all that important distinction though.
Depending on the design, it may also just be that those registrations
are *ignored*, because e.g. firmware intercepts the AUTH frame already,
which would just (maybe) confuse userspace - but that seems unlikely
since it switched interface type and has no real need for those frames
then.
> The kernel currently relies on userspace apps to actually purge the
> registrations themselves, e.g. by closing the nl80211 socket associated
> with those frames. However, this requires multiple nl80211 sockets to
> be open by the userspace app, and for userspace to be aware of all state
> changes. This is not something that the kernel should rely on.
I tend to agree with that the kernel shouldn't rely on it.
> This commit adds a call to cfg80211_mlme_purge_registrations() to
> forcefully remove any registrations left over prior to switching the
> iftype.
However, I do wonder if we should make this more transactional, and hang
on to them if the type switching fails. We're not notifying userspace
that the registrations have disappeared, so if type switching fails and
it continues to work with the old type rather than throwing its hands up
and quitting or something, it'd make a possibly bigger mess to just
silently have removed them already.
I *think* it should be safe to just move this after the switching
succeeds, since the switching can pretty much only be done at a point
where nothing is happening on the interface anyway, though that might
confuse the driver when the remove happens.
Also, perhaps it'd be better to actually hang on to those registrations
that *are* still possible afterwards? But to not confuse the driver I
guess that might require unregister/re-register to happen, all of which
requires hanging on to the list and going through it after the type
switch completed?
What do you think?
johannes
^ permalink raw reply
* Re: mac80211_hwsim (kernel 4.18+): wmediumd + 2.4Ghz
From: Krishna Chaitanya @ 2019-08-30 8:21 UTC (permalink / raw)
To: Johannes Berg; +Cc: Ramon Fontes, linux-wireless
In-Reply-To: <39d646206446159a2b0a67ee7d8667483ade0733.camel@sipsolutions.net>
On Fri, Aug 30, 2019 at 1:02 PM Johannes Berg <johannes@sipsolutions.net> wrote:
>
> On Fri, 2019-08-30 at 00:35 +0530, Krishna Chaitanya wrote:
> >
> > Is this supposed to work at all? AFAICS, in hwsim channel matching
> > checks are only done in non-mediumd path (no_nl), and wmediumd also
> > doesn't have any checks? So, hostapd responds to all probe requests in all
> > channels. Am I missing something?
>
> Hmm. Interesting observation, I wasn't aware of that.
>
> That certainly explains the situation though - on 2.4 GHz we'd prefer
> using the DS Element, and thus not use the scan result, while on 5 GHz
> we assume that the reported RX frequency is correct (there's no channel
> overlap).
>
> Still doesn't explain why it should work in 4.17 and not in 4.18, there
> aren't a lot of wifi changes there at all.
Yes the git log also doesn't show any changes in this area.
>
> I guess we should fix that in hwsim, anyone esle want to? :-)
I can give it a try to move the channel matching logic to common
code for both nl and no_nl.
^ permalink raw reply
* Re: mac80211_hwsim (kernel 4.18+): wmediumd + 2.4Ghz
From: Johannes Berg @ 2019-08-30 7:32 UTC (permalink / raw)
To: Krishna Chaitanya; +Cc: Ramon Fontes, linux-wireless
In-Reply-To: <CABPxzYLrTC3kS86iyfq+RY=XEgjedu2MWPtn+i+H50jPz3oh3w@mail.gmail.com>
On Fri, 2019-08-30 at 00:35 +0530, Krishna Chaitanya wrote:
>
> Is this supposed to work at all? AFAICS, in hwsim channel matching
> checks are only done in non-mediumd path (no_nl), and wmediumd also
> doesn't have any checks? So, hostapd responds to all probe requests in all
> channels. Am I missing something?
Hmm. Interesting observation, I wasn't aware of that.
That certainly explains the situation though - on 2.4 GHz we'd prefer
using the DS Element, and thus not use the scan result, while on 5 GHz
we assume that the reported RX frequency is correct (there's no channel
overlap).
Still doesn't explain why it should work in 4.17 and not in 4.18, there
aren't a lot of wifi changes there at all.
I guess we should fix that in hwsim, anyone esle want to? :-)
johannes
^ permalink raw reply
* Re: [PATCH] cfg80211: Add new fields to wiphy structure
From: Johannes Berg @ 2019-08-30 7:19 UTC (permalink / raw)
To: Amar Singhal, jouni; +Cc: linux-wireless, jjohnson, rmanohar
In-Reply-To: <1567116559-17419-1-git-send-email-asinghal@codeaurora.org>
On Thu, 2019-08-29 at 15:09 -0700, Amar Singhal wrote:
> A channel is completely defined by (oper_class, channel number) tuple,
> and not just by center frequency. Operating class also tells about the
> bandwidth supported by the channel. Therefore add the operating class and
> channel number to the wiphy structure.
We don't split out the channels that way, so this doesn't seem like the
right approach.
Instead, we list the *frequencies*, and then have flags for the
permitted bandwidths. We already support things like "no-HT40+" and
could possibly extend that to others, if it were _really_ possible,
though in practice those limitations are usually not present in devices,
just in the spec, and we can rely on hostapd/wpa_s to take care of them.
Even if you do have those limitations, this isn't the right way to go
about it, because it'll be very confusing to userspace to see the same
frequency multiple times. It'd also cause a bunch of problems with
scanning (listing the same channel twice) etc.
Since you haven't explained why you want to do this I cannot offer any
further guidance, but this cannot be the right approach.
johannes
^ permalink raw reply
* Re: [PATCH] cfg80211: Add new helper function for channels
From: Johannes Berg @ 2019-08-30 7:16 UTC (permalink / raw)
To: Amar Singhal, jouni; +Cc: linux-wireless, jjohnson, rmanohar
In-Reply-To: <1567115381-7831-1-git-send-email-asinghal@codeaurora.org>
On Thu, 2019-08-29 at 14:49 -0700, Amar Singhal wrote:
> Add new helper function to convert (chan_number, oper_class) pair to
> frequency. Call this function ieee80211_channel_op_class_to_frequency.
> This function would be very useful in the context of 6 GHz channels,
> where channel number is not unique.
Nit: it is unique within 6 GHz, just not within the overall channel
number space, and that was actually already not unique before, it just
didn't matter much to us :-)
I may reword that when I apply it.
> Signed-off-by: Amar Singhal <asinghal@codeaurora.org>
> ---
> include/net/cfg80211.h | 10 ++++++++++
> net/wireless/util.c | 23 +++++++++++++++++++++++
> 2 files changed, 33 insertions(+)
>
> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
> index 6467b60..decafba 100644
> --- a/include/net/cfg80211.h
> +++ b/include/net/cfg80211.h
> @@ -4914,1 +4914,1 @@ static inline void *wdev_priv(struct wireless_dev *wdev)
> int ieee80211_channel_to_frequency(int chan, enum nl80211_band band);
>
> /**
> + * ieee80211_channel_op_class_to_frequency - convert
> + * (channel, operating class) to frequency
That's formatted badly, the short description must fit on one line.
> + if (global_op_class >= 131 && global_op_class <= 135)
> + return (5940 + 5 * chan_num);
> + else if (global_op_class >= 115 && global_op_class <= 130)
> + return (5000 + 5 * chan_num);
> + else if (global_op_class >= 112 && global_op_class <= 113)
> + return (5000 + 5 * chan_num);
> + else if (global_op_class >= 109 && global_op_class <= 110)
> + return (4000 + 5 * chan_num);
> + else if (global_op_class >= 83 && global_op_class <= 84)
> + return (2407 + 5 * chan_num);
> + else if (global_op_class == 81)
> + return (2407 + 5 * chan_num);
> + else if (global_op_class == 82)
> + return (2414 + 5 * chan_num);
> + else if (global_op_class == 180)
> + return (56160 + 5 * chan_num);
I think it would be good to have a list of valid channel numbers for
them as well. I was wondering about 82 for a second there for example,
until I looked up again that it is just for channel 14.
I think this is also missing 83/84 and various other operating classes
for wider channels. Perhaps in those we don't really need to check the
channel numbers precisely, i.e. we could probably treat 81/83/84 all the
same.
But depending on what you feed to the function, it's possible that you
could encounter those other operating classes.
johannes
^ permalink raw reply
* Re: [PATCH v3 8/8] ath10k: enable napi on RX path for sdio
From: Nicolas Boichat @ 2019-08-30 3:19 UTC (permalink / raw)
To: Wen Gong; +Cc: ath10k, open list:NETWORKING DRIVERS (WIRELESS)
In-Reply-To: <1566998177-2658-9-git-send-email-wgong@codeaurora.org>
On Fri, Aug 30, 2019 at 1:50 AM Wen Gong <wgong@codeaurora.org> wrote:
>
> For tcp RX, the quantity of tcp acks to remote is 1/2 of the quantity
> of tcp data from remote, then it will have many small length packets
> on TX path of sdio bus, then it reduce the RX packets's bandwidth of
> tcp.
>
> This patch enable napi on RX path, then the RX packet of tcp will not
> feed to tcp stack immeditely from mac80211 since GRO is enabled by
> default, it will feed to tcp stack after napi complete, if rx bundle
> is enabled, then it will feed to tcp stack one time for each bundle
> of RX. For example, RX bundle size is 32, then tcp stack will receive
> one large length packet, its length is neary 1500*32, then tcp stack
> will send a tcp ack for this large packet, this will reduce the tcp
> acks ratio from 1/2 to 1/32. This results in significant performance
> improvement for tcp RX.
>
> Tcp rx throughout is 240Mbps without this patch, and it arrive 390Mbps
> with this patch. The cpu usage has no obvious difference with and
> without NAPI.
>
> call stack for each RX packet on GRO path:
> (skb length is about 1500 bytes)
> skb_gro_receive ([kernel.kallsyms])
> tcp4_gro_receive ([kernel.kallsyms])
> inet_gro_receive ([kernel.kallsyms])
> dev_gro_receive ([kernel.kallsyms])
> napi_gro_receive ([kernel.kallsyms])
> ieee80211_deliver_skb ([mac80211])
> ieee80211_rx_handlers ([mac80211])
> ieee80211_prepare_and_rx_handle ([mac80211])
> ieee80211_rx_napi ([mac80211])
> ath10k_htt_rx_proc_rx_ind_hl ([ath10k_core])
> ath10k_htt_rx_pktlog_completion_handler ([ath10k_core])
> ath10k_sdio_napi_poll ([ath10k_sdio])
> net_rx_action ([kernel.kallsyms])
> softirqentry_text_start ([kernel.kallsyms])
> do_softirq ([kernel.kallsyms])
>
> call stack for napi complete and send tcp ack from tcp stack:
> (skb length is about 1500*32 bytes)
> _tcp_ack_snd_check ([kernel.kallsyms])
> tcp_v4_do_rcv ([kernel.kallsyms])
> tcp_v4_rcv ([kernel.kallsyms])
> local_deliver_finish ([kernel.kallsyms])
> ip_local_deliver ([kernel.kallsyms])
> ip_rcv_finish ([kernel.kallsyms])
> ip_rcv ([kernel.kallsyms])
> netif_receive_skb_core ([kernel.kallsyms])
> netif_receive_skb_one_core([kernel.kallsyms])
> netif_receive_skb ([kernel.kallsyms])
> netif_receive_skb_internal ([kernel.kallsyms])
> napi_gro_complete ([kernel.kallsyms])
> napi_gro_flush ([kernel.kallsyms])
> napi_complete_done ([kernel.kallsyms])
> ath10k_sdio_napi_poll ([ath10k_sdio])
> net_rx_action ([kernel.kallsyms])
> __softirqentry_text_start ([kernel.kallsyms])
> do_softirq ([kernel.kallsyms])
>
> Tested with QCA6174 SDIO with firmware
> WLAN.RMH.4.4.1-00007-QCARMSWP-1.
>
> Signed-off-by: Wen Gong <wgong@codeaurora.org>
> ---
> v2:no change
> v3:change some code style
> drivers/net/wireless/ath/ath10k/htt.c | 2 ++
> drivers/net/wireless/ath/ath10k/htt.h | 3 +++
> drivers/net/wireless/ath/ath10k/htt_rx.c | 45 ++++++++++++++++++++++++++------
> drivers/net/wireless/ath/ath10k/sdio.c | 33 +++++++++++++++++++++++
> 4 files changed, 75 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath10k/htt.c b/drivers/net/wireless/ath/ath10k/htt.c
> index 127b4e4..f69346f 100644
> --- a/drivers/net/wireless/ath/ath10k/htt.c
> +++ b/drivers/net/wireless/ath/ath10k/htt.c
> @@ -157,6 +157,8 @@ int ath10k_htt_connect(struct ath10k_htt *htt)
>
> htt->eid = conn_resp.eid;
>
> + skb_queue_head_init(&htt->rx_indication_head);
> +
> if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL) {
> ep = &ar->htc.endpoint[htt->eid];
> ath10k_htc_setup_tx_req(ep);
> diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
> index 4851a2e..462a25b 100644
> --- a/drivers/net/wireless/ath/ath10k/htt.h
> +++ b/drivers/net/wireless/ath/ath10k/htt.h
> @@ -1879,6 +1879,8 @@ struct ath10k_htt {
> struct ath10k *ar;
> enum ath10k_htc_ep_id eid;
>
> + struct sk_buff_head rx_indication_head;
> +
> u8 target_version_major;
> u8 target_version_minor;
> struct completion target_version_received;
> @@ -2298,6 +2300,7 @@ int ath10k_htt_tx_mgmt_inc_pending(struct ath10k_htt *htt, bool is_mgmt,
> void ath10k_htt_rx_pktlog_completion_handler(struct ath10k *ar,
> struct sk_buff *skb);
> int ath10k_htt_txrx_compl_task(struct ath10k *ar, int budget);
> +int ath10k_htt_rx_hl_indication(struct ath10k *ar, int budget);
> void ath10k_htt_set_tx_ops(struct ath10k_htt *htt);
> void ath10k_htt_set_rx_ops(struct ath10k_htt *htt);
> #endif
> diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
> index 09825b1..71b4afe 100644
> --- a/drivers/net/wireless/ath/ath10k/htt_rx.c
> +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
> @@ -2263,7 +2263,7 @@ static bool ath10k_htt_rx_proc_rx_ind_hl(struct ath10k_htt *htt,
> if (mpdu_ranges->mpdu_range_status == HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR)
> rx_status->flag |= RX_FLAG_MMIC_ERROR;
>
> - ieee80211_rx_ni(ar->hw, skb);
> + ieee80211_rx_napi(ar->hw, NULL, skb, &ar->napi);
>
> /* We have delivered the skb to the upper layers (mac80211) so we
> * must not free it.
> @@ -3664,14 +3664,12 @@ bool ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
> break;
> }
> case HTT_T2H_MSG_TYPE_RX_IND:
> - if (ar->bus_param.dev_type == ATH10K_DEV_TYPE_HL)
> - return ath10k_htt_rx_proc_rx_ind_hl(htt,
> - &resp->rx_ind_hl,
> - skb,
> - HTT_RX_PN_CHECK,
> - HTT_RX_NON_TKIP_MIC);
> - else
> + if (ar->bus_param.dev_type != ATH10K_DEV_TYPE_HL) {
> ath10k_htt_rx_proc_rx_ind_ll(htt, &resp->rx_ind);
> + } else {
> + skb_queue_tail(&htt->rx_indication_head, skb);
> + return false;
> + }
> break;
> case HTT_T2H_MSG_TYPE_PEER_MAP: {
> struct htt_peer_map_event ev = {
> @@ -3894,6 +3892,37 @@ static int ath10k_htt_rx_deliver_msdu(struct ath10k *ar, int quota, int budget)
> return quota;
> }
>
> +int ath10k_htt_rx_hl_indication(struct ath10k *ar, int budget)
> +{
> + struct htt_resp *resp;
> + struct ath10k_htt *htt = &ar->htt;
> + struct sk_buff *skb;
> + bool release;
> + int quota = 0;
Don't init to 0.
> +
> + for (quota = 0; quota < budget; quota++) {
> + skb = skb_dequeue(&htt->rx_indication_head);
> + if (!skb)
> + break;
> +
> + resp = (struct htt_resp *)skb->data;
> +
> + release = ath10k_htt_rx_proc_rx_ind_hl(htt,
> + &resp->rx_ind_hl,
> + skb,
> + HTT_RX_PN_CHECK,
> + HTT_RX_NON_TKIP_MIC);
> +
> + if (release)
> + dev_kfree_skb_any(skb);
> +
> + ath10k_dbg(ar, ATH10K_DBG_HTT, "rx indication poll pending count:%d\n",
> + skb_queue_len(&htt->rx_indication_head));
> + }
> + return quota;
> +}
> +EXPORT_SYMBOL(ath10k_htt_rx_hl_indication);
> +
> int ath10k_htt_txrx_compl_task(struct ath10k *ar, int budget)
> {
> struct ath10k_htt *htt = &ar->htt;
> diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c
> index c641f1b..23e92ea 100644
> --- a/drivers/net/wireless/ath/ath10k/sdio.c
> +++ b/drivers/net/wireless/ath/ath10k/sdio.c
> @@ -1400,6 +1400,9 @@ static void ath10k_rx_indication_async_work(struct work_struct *work)
> spin_lock_bh(&ar_sdio->wr_async_lock_rx);
> }
>
> + if (test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags))
> + napi_schedule(&ar->napi);
> +
> spin_unlock_bh(&ar_sdio->wr_async_lock_rx);
> }
>
> @@ -1813,6 +1816,8 @@ static int ath10k_sdio_hif_start(struct ath10k *ar)
> struct ath10k_sdio *ar_sdio = ath10k_sdio_priv(ar);
> int ret;
>
> + napi_enable(&ar->napi);
> +
> /* Sleep 20 ms before HIF interrupts are disabled.
> * This will give target plenty of time to process the BMI done
> * request before interrupts are disabled.
> @@ -1951,6 +1956,9 @@ static void ath10k_sdio_hif_stop(struct ath10k *ar)
> }
>
> spin_unlock_bh(&ar_sdio->wr_async_lock);
> +
> + napi_synchronize(&ar->napi);
> + napi_disable(&ar->napi);
> }
>
> #ifdef CONFIG_PM
> @@ -2127,6 +2135,26 @@ static SIMPLE_DEV_PM_OPS(ath10k_sdio_pm_ops, ath10k_sdio_pm_suspend,
>
> #endif /* CONFIG_PM_SLEEP */
>
> +static int ath10k_sdio_napi_poll(struct napi_struct *ctx, int budget)
> +{
> + struct ath10k *ar = container_of(ctx, struct ath10k, napi);
> + int done;
> +
> + done = ath10k_htt_rx_hl_indication(ar, budget);
> + ath10k_dbg(ar, ATH10K_DBG_SDIO, "napi poll: done: %d,budget:%d\n", done, budget);
This is a debug string, but still, please be consistent in spacing:
"napi poll: done: %d, budget: %d\n"
> +
> + if (done < budget)
> + napi_complete_done(ctx, done);
> +
> + return done;
> +}
> +
> +void ath10k_sdio_init_napi(struct ath10k *ar)
> +{
> + netif_napi_add(&ar->napi_dev, &ar->napi, ath10k_sdio_napi_poll,
> + ATH10K_NAPI_BUDGET);
> +}
> +
> static int ath10k_sdio_probe(struct sdio_func *func,
> const struct sdio_device_id *id)
> {
> @@ -2152,6 +2180,8 @@ static int ath10k_sdio_probe(struct sdio_func *func,
> return -ENOMEM;
> }
>
> + ath10k_sdio_init_napi(ar);
> +
> ath10k_dbg(ar, ATH10K_DBG_BOOT,
> "sdio new func %d vendor 0x%x device 0x%x block 0x%x/0x%x\n",
> func->num, func->vendor, func->device,
> @@ -2272,6 +2302,9 @@ static void ath10k_sdio_remove(struct sdio_func *func)
> func->num, func->vendor, func->device);
>
> ath10k_core_unregister(ar);
> +
> + netif_napi_del(&ar->napi);
> +
> ath10k_core_destroy(ar);
>
> flush_workqueue(ar_sdio->workqueue);
> --
> 1.9.1
>
^ permalink raw reply
* Re: [PATCH v3 7/8] ath10k: enable alt data of TX path for sdio
From: Nicolas Boichat @ 2019-08-30 3:18 UTC (permalink / raw)
To: Wen Gong; +Cc: ath10k, open list:NETWORKING DRIVERS (WIRELESS)
In-Reply-To: <1566998177-2658-8-git-send-email-wgong@codeaurora.org>
On Fri, Aug 30, 2019 at 1:39 AM Wen Gong <wgong@codeaurora.org> wrote:
>
> The default credit size is 1792 bytes, but the IP mtu is 1500 bytes,
> then it has about 290 bytes's waste for each data packet on sdio
> transfer path for TX bundle, it will reduce the transmission utilization
> ratio for data packet.
>
> This patch enable the small credit size in firmware, firmware will use
> the new credit size 1556 bytes, it will increase the transmission
> utilization ratio for data packet on TX patch. It results in significant
> performance improvement on TX path.
>
> This patch only effect sdio chip, it will not effect PCI, SNOC etc.
>
> Tested with QCA6174 SDIO with firmware
> WLAN.RMH.4.4.1-00017-QCARMSWP-1.
>
> Signed-off-by: Wen Gong <wgong@codeaurora.org>
> ---
> v2:no change
> v3:change some code style
> drivers/net/wireless/ath/ath10k/core.c | 19 +++++++++++++++++--
> drivers/net/wireless/ath/ath10k/htc.c | 11 +++++++++--
> drivers/net/wireless/ath/ath10k/htc.h | 11 +++++++++--
> 3 files changed, 35 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
> index 9841533..9fd07c7 100644
> --- a/drivers/net/wireless/ath/ath10k/core.c
> +++ b/drivers/net/wireless/ath/ath10k/core.c
> @@ -31,6 +31,7 @@
> static unsigned int ath10k_cryptmode_param;
> static bool uart_print;
> static bool disable_tx_comp = true;
> +static bool alt_data = true;
> static bool skip_otp;
> static bool rawmode;
> static bool fw_diag_log;
> @@ -45,6 +46,15 @@
>
> /* If upper layer need the TX complete status, it can enable tx complete */
> module_param(disable_tx_comp, bool, 0644);
> +
> +/* alt_data is only used for sdio chip, for previous version of firmware, its
> + * alt data size is 1544 which is not enough for native wifi, so it need to
> + * alt_data for the firmware.
> + * If the firmware has changed alt data size to 1556, then it can enable
> + * alt_data for the firmware.
> + * alt_data will not effect PCI, SNOC etc.
> + */
> +module_param(alt_data, bool, 0644);
> module_param(skip_otp, bool, 0644);
> module_param(rawmode, bool, 0644);
> module_param(fw_diag_log, bool, 0644);
> @@ -698,9 +708,14 @@ static void ath10k_init_sdio(struct ath10k *ar, enum ath10k_firmware_mode mode)
> param &= ~HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_SET;
>
> /* Alternate credit size of 1544 as used by SDIO firmware is
> - * not big enough for mac80211 / native wifi frames. disable it
> + * not big enough for mac80211 / native wifi frames. disable it.
> + * If alternate credit size of 1556 as used by SDIO firmware is
> + * big enough for mac80211 / native wifi frames. enable it
> */
> - param &= ~HI_ACS_FLAGS_ALT_DATA_CREDIT_SIZE;
> + if (alt_data && mode == ATH10K_FIRMWARE_MODE_NORMAL)
> + param |= HI_ACS_FLAGS_ALT_DATA_CREDIT_SIZE;
> + else
> + param &= ~HI_ACS_FLAGS_ALT_DATA_CREDIT_SIZE;
>
> if (mode == ATH10K_FIRMWARE_MODE_UTF)
> param &= ~HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_SET;
> diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c
> index 5269168..04298e1 100644
> --- a/drivers/net/wireless/ath/ath10k/htc.c
> +++ b/drivers/net/wireless/ath/ath10k/htc.c
> @@ -940,12 +940,15 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
> */
> if (htc->control_resp_len >=
> sizeof(msg->hdr) + sizeof(msg->ready_ext)) {
> + htc->alt_data_credit_size =
> + __le16_to_cpu(msg->ready_ext.reserved) & 0x0fff;
Please define 0x0fff as a macro. (I believe most other masks are
macros in this driver).
> htc->max_msgs_per_htc_bundle =
> min_t(u8, msg->ready_ext.max_msgs_per_htc_bundle,
> HTC_HOST_MAX_MSG_PER_RX_BUNDLE);
> ath10k_dbg(ar, ATH10K_DBG_HTC,
> - "Extended ready message. RX bundle size: %d\n",
> - htc->max_msgs_per_htc_bundle);
> + "Extended ready message. RX bundle size: %d, alt size:%d\n",
> + htc->max_msgs_per_htc_bundle,
> + htc->alt_data_credit_size);
> }
>
> INIT_WORK(&ar->bundle_tx_work, ath10k_htc_bundle_tx_work);
> @@ -1097,6 +1100,10 @@ int ath10k_htc_connect_service(struct ath10k_htc *htc,
> ep->tx_credits = tx_alloc;
> ep->tx_credit_size = htc->target_credit_size;
>
> + if (conn_req->service_id == ATH10K_HTC_SVC_ID_HTT_DATA_MSG &&
> + htc->alt_data_credit_size != 0)
> + ep->tx_credit_size = htc->alt_data_credit_size;
> +
> /* copy all the callbacks */
> ep->ep_ops = conn_req->ep_ops;
>
> diff --git a/drivers/net/wireless/ath/ath10k/htc.h b/drivers/net/wireless/ath/ath10k/htc.h
> index 7b8e0d0..f3a6ebb 100644
> --- a/drivers/net/wireless/ath/ath10k/htc.h
> +++ b/drivers/net/wireless/ath/ath10k/htc.h
> @@ -141,8 +141,14 @@ struct ath10k_htc_ready_extended {
> struct ath10k_htc_ready base;
> u8 htc_version; /* @enum ath10k_htc_version */
> u8 max_msgs_per_htc_bundle;
> - u8 pad0;
> - u8 pad1;
> + union {
> + __le16 reserved;
> + struct {
> + u8 pad0;
> + u8 pad1;
> + } __packed;
> + } __packed;
> +
> } __packed;
>
> struct ath10k_htc_conn_svc {
> @@ -379,6 +385,7 @@ struct ath10k_htc {
> int total_transmit_credits;
> int target_credit_size;
> u8 max_msgs_per_htc_bundle;
> + int alt_data_credit_size;
> };
>
> int ath10k_htc_init(struct ath10k *ar);
> --
> 1.9.1
>
^ permalink raw reply
* Re: [PATCH v3 3/8] ath10k: change max RX bundle size from 8 to 32 for sdio
From: Nicolas Boichat @ 2019-08-30 3:11 UTC (permalink / raw)
To: Wen Gong; +Cc: ath10k, open list:NETWORKING DRIVERS (WIRELESS)
In-Reply-To: <1566998177-2658-4-git-send-email-wgong@codeaurora.org>
On Fri, Aug 30, 2019 at 1:49 AM Wen Gong <wgong@codeaurora.org> wrote:
>
> The max bundle size support by firmware is 32, change it from 8 to 32
> will help performance. This results in significant performance
> improvement on RX path.
>
> Tested with QCA6174 SDIO with firmware
> WLAN.RMH.4.4.1-00007-QCARMSWP-1.
>
> Signed-off-by: Wen Gong <wgong@codeaurora.org>
> ---
> v2:change macro HTC_GET_BUNDLE_COUNT
> v3:change some code style
> drivers/net/wireless/ath/ath10k/htc.h | 8 +++++++-
> drivers/net/wireless/ath/ath10k/sdio.c | 6 +++---
> drivers/net/wireless/ath/ath10k/sdio.h | 4 ++--
> 3 files changed, 12 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath10k/htc.h b/drivers/net/wireless/ath/ath10k/htc.h
> index f55d3ca..ffda8bf 100644
> --- a/drivers/net/wireless/ath/ath10k/htc.h
> +++ b/drivers/net/wireless/ath/ath10k/htc.h
> @@ -39,7 +39,7 @@
> * 4-byte aligned.
> */
>
> -#define HTC_HOST_MAX_MSG_PER_RX_BUNDLE 8
> +#define HTC_HOST_MAX_MSG_PER_RX_BUNDLE 32
>
> enum ath10k_htc_tx_flags {
> ATH10K_HTC_FLAG_NEED_CREDIT_UPDATE = 0x01,
> @@ -52,6 +52,12 @@ enum ath10k_htc_rx_flags {
> ATH10K_HTC_FLAG_BUNDLE_MASK = 0xF0
> };
>
> +#define BUNDLE_EXTRA_MASK GENMASK(3, 2)
Well, ATH10K_HTC_FLAG_BUNDLE_MASK is defined in a struct, set to a hex value.
This is a macro, set to a GENMASK() value.
I don't care how you do it, but please be consistent.
In this case, please add ATH10K_HTC_FLAG_BUNDLE_EXTRA_MASK GENMASK =
0x0A in the enum above (sorry, I say structure in my previous
comment).
> +
> +#define HTC_GET_BUNDLE_COUNT(flags) \
> + (FIELD_GET(ATH10K_HTC_FLAG_BUNDLE_MASK, (flags)) + \
> + (FIELD_GET(BUNDLE_EXTRA_MASK, (flags)) << 4))
> +
> struct ath10k_htc_hdr {
> u8 eid; /* @enum ath10k_htc_ep_id */
> u8 flags; /* @enum ath10k_htc_tx_flags, ath10k_htc_rx_flags */
> diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c
> index 23c998d..bd808e5 100644
> --- a/drivers/net/wireless/ath/ath10k/sdio.c
> +++ b/drivers/net/wireless/ath/ath10k/sdio.c
> @@ -24,8 +24,8 @@
> #include "trace.h"
> #include "sdio.h"
>
> -#define ATH10K_SDIO_DMA_BUF_SIZE (32 * 1024)
> -#define ATH10K_SDIO_VSG_BUF_SIZE (32 * 1024)
> +#define ATH10K_SDIO_DMA_BUF_SIZE (64 * 1024)
> +#define ATH10K_SDIO_VSG_BUF_SIZE (64 * 1024)
>
> /* inlined helper functions */
>
> @@ -495,7 +495,7 @@ static int ath10k_sdio_mbox_alloc_bundle(struct ath10k *ar,
> {
> int ret, i;
>
> - *bndl_cnt = FIELD_GET(ATH10K_HTC_FLAG_BUNDLE_MASK, htc_hdr->flags);
> + *bndl_cnt = HTC_GET_BUNDLE_COUNT(htc_hdr->flags);
>
> if (*bndl_cnt > HTC_HOST_MAX_MSG_PER_RX_BUNDLE) {
> ath10k_warn(ar,
> diff --git a/drivers/net/wireless/ath/ath10k/sdio.h b/drivers/net/wireless/ath/ath10k/sdio.h
> index 4896eca..3ca76c7 100644
> --- a/drivers/net/wireless/ath/ath10k/sdio.h
> +++ b/drivers/net/wireless/ath/ath10k/sdio.h
> @@ -89,10 +89,10 @@
> * to the maximum value (HTC_HOST_MAX_MSG_PER_RX_BUNDLE).
> *
> * in this case the driver must allocate
> - * (HTC_HOST_MAX_MSG_PER_RX_BUNDLE * HTC_HOST_MAX_MSG_PER_RX_BUNDLE) skb's.
> + * (HTC_HOST_MAX_MSG_PER_RX_BUNDLE * 2) skb's.
> */
> #define ATH10K_SDIO_MAX_RX_MSGS \
> - (HTC_HOST_MAX_MSG_PER_RX_BUNDLE * HTC_HOST_MAX_MSG_PER_RX_BUNDLE)
> + (HTC_HOST_MAX_MSG_PER_RX_BUNDLE * 2)
>
> #define ATH10K_FIFO_TIMEOUT_AND_CHIP_CONTROL 0x00000868u
> #define ATH10K_FIFO_TIMEOUT_AND_CHIP_CONTROL_DISABLE_SLEEP_OFF 0xFFFEFFFF
> --
> 1.9.1
>
^ permalink raw reply
* Re: [PATCH v3 2/8] ath10k: enable RX bundle receive for sdio
From: Nicolas Boichat @ 2019-08-30 3:07 UTC (permalink / raw)
To: Wen Gong; +Cc: ath10k, open list:NETWORKING DRIVERS (WIRELESS)
In-Reply-To: <1566998177-2658-3-git-send-email-wgong@codeaurora.org>
On Thu, Aug 29, 2019 at 11:49 PM Wen Gong <wgong@codeaurora.org> wrote:
>
> From: Alagu Sankar <alagusankar@silex-india.com>
>
> The existing implementation of initiating multiple sdio transfers for
> receive bundling is slowing down the receive speed. Combining the
> transfers using a bundle method would be ideal.
>
> The transmission utilization ratio for sdio bus for small packet is
> slow, because the space and time cost for sdio bus is same for large
> length packet and small length packet. So the speed of data for large
> length packet is higher than small length.
>
> Test result of different length of data:
> data packet(byte) cost time(us) calculated rate(Mbps)
> 256 28 73
> 512 33 124
> 1024 35 234
> 1792 45 318
> 14336 168 682
> 28672 333 688
> 57344 660 695
>
> Tested with QCA6174 SDIO with firmware
> WLAN.RMH.4.4.1-00007-QCARMSWP-1.
>
> Signed-off-by: Alagu Sankar <alagusankar@silex-india.com>
> Signed-off-by: Wen Gong <wgong@codeaurora.org>
> ---
> v2: fix incorrect skb tail of rx bundle in ath10k_sdio_mbox_rx_process_packet
> v3: change some code style
> split fix incorrect skb tail of rx bundle to patch "adjust skb length in ath10k_sdio_mbox_rx_packet"
>
> drivers/net/wireless/ath/ath10k/sdio.c | 106 +++++++++++++++++++++------------
> drivers/net/wireless/ath/ath10k/sdio.h | 7 ++-
> 2 files changed, 74 insertions(+), 39 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c
> index 1127e44..23c998d 100644
> --- a/drivers/net/wireless/ath/ath10k/sdio.c
> +++ b/drivers/net/wireless/ath/ath10k/sdio.c
> @@ -24,6 +24,9 @@
> #include "trace.h"
> #include "sdio.h"
>
> +#define ATH10K_SDIO_DMA_BUF_SIZE (32 * 1024)
> +#define ATH10K_SDIO_VSG_BUF_SIZE (32 * 1024)
> +
> /* inlined helper functions */
>
> static inline int ath10k_sdio_calc_txrx_padded_len(struct ath10k_sdio *ar_sdio,
> @@ -484,11 +487,11 @@ static int ath10k_sdio_mbox_rx_process_packets(struct ath10k *ar,
> return ret;
> }
>
> -static int ath10k_sdio_mbox_alloc_pkt_bundle(struct ath10k *ar,
> - struct ath10k_sdio_rx_data *rx_pkts,
> - struct ath10k_htc_hdr *htc_hdr,
> - size_t full_len, size_t act_len,
> - size_t *bndl_cnt)
> +static int ath10k_sdio_mbox_alloc_bundle(struct ath10k *ar,
> + struct ath10k_sdio_rx_data *rx_pkts,
> + struct ath10k_htc_hdr *htc_hdr,
> + size_t full_len, size_t act_len,
> + size_t *bndl_cnt)
> {
> int ret, i;
>
> @@ -529,6 +532,7 @@ static int ath10k_sdio_mbox_rx_alloc(struct ath10k *ar,
> size_t full_len, act_len;
> bool last_in_bundle;
> int ret, i;
> + int pkt_cnt = 0;
>
> if (n_lookaheads > ATH10K_SDIO_MAX_RX_MSGS) {
> ath10k_warn(ar,
> @@ -572,20 +576,22 @@ static int ath10k_sdio_mbox_rx_alloc(struct ath10k *ar,
> */
> size_t bndl_cnt;
>
> - ret = ath10k_sdio_mbox_alloc_pkt_bundle(ar,
> - &ar_sdio->rx_pkts[i],
> - htc_hdr,
> - full_len,
> - act_len,
> - &bndl_cnt);
> + struct ath10k_sdio_rx_data *rx_pkts =
> + &ar_sdio->rx_pkts[pkt_cnt];
> +
> + ret = ath10k_sdio_mbox_alloc_bundle(ar,
> + rx_pkts,
> + htc_hdr,
> + full_len,
> + act_len,
> + &bndl_cnt);
>
> if (ret) {
> ath10k_warn(ar, "alloc_bundle error %d\n", ret);
> goto err;
> }
>
> - n_lookaheads += bndl_cnt;
> - i += bndl_cnt;
> + pkt_cnt += bndl_cnt;
> /*Next buffer will be the last in the bundle */
> last_in_bundle = true;
> }
> @@ -597,7 +603,7 @@ static int ath10k_sdio_mbox_rx_alloc(struct ath10k *ar,
> if (htc_hdr->flags & ATH10K_HTC_FLAGS_RECV_1MORE_BLOCK)
> full_len += ATH10K_HIF_MBOX_BLOCK_SIZE;
>
> - ret = ath10k_sdio_mbox_alloc_rx_pkt(&ar_sdio->rx_pkts[i],
> + ret = ath10k_sdio_mbox_alloc_rx_pkt(&ar_sdio->rx_pkts[pkt_cnt],
> act_len,
> full_len,
> last_in_bundle,
> @@ -606,9 +612,10 @@ static int ath10k_sdio_mbox_rx_alloc(struct ath10k *ar,
> ath10k_warn(ar, "alloc_rx_pkt error %d\n", ret);
> goto err;
> }
> + pkt_cnt++;
> }
>
> - ar_sdio->n_rx_pkts = i;
> + ar_sdio->n_rx_pkts = pkt_cnt;
>
> return 0;
>
> @@ -622,10 +629,10 @@ static int ath10k_sdio_mbox_rx_alloc(struct ath10k *ar,
> return ret;
> }
>
> -static int ath10k_sdio_mbox_rx_packet(struct ath10k *ar,
> - struct ath10k_sdio_rx_data *pkt)
> +static int ath10k_sdio_mbox_rx_fetch(struct ath10k *ar)
> {
> struct ath10k_sdio *ar_sdio = ath10k_sdio_priv(ar);
> + struct ath10k_sdio_rx_data *pkt = &ar_sdio->rx_pkts[0];
> struct sk_buff *skb = pkt->skb;
> struct ath10k_htc_hdr *htc_hdr;
> int ret;
> @@ -633,46 +640,62 @@ static int ath10k_sdio_mbox_rx_packet(struct ath10k *ar,
> ret = ath10k_sdio_readsb(ar, ar_sdio->mbox_info.htc_addr,
> skb->data, pkt->alloc_len);
>
> - if (!ret) {
> - /* Update actual length. The original length may be incorrect,
> - * as the FW will bundle multiple packets as long as their sizes
> - * fit within the same aligned length (pkt->alloc_len).
> - */
> - htc_hdr = (struct ath10k_htc_hdr *)skb->data;
> - pkt->act_len = le16_to_cpu(htc_hdr->len) + sizeof(*htc_hdr);
> - if (pkt->act_len <= pkt->alloc_len) {
> - skb_put(skb, pkt->act_len);
> - } else {
> - ath10k_warn(ar, "rx packet too large (%zu > %zu)\n",
> - pkt->act_len, pkt->alloc_len);
> - ret = -EMSGSIZE;
> - }
> + if (ret) {
> + ar_sdio->n_rx_pkts = 0;
> + ath10k_sdio_mbox_free_rx_pkt(pkt);
> + return ret;
> }
>
> + htc_hdr = (struct ath10k_htc_hdr *)skb->data;
> + pkt->act_len = le16_to_cpu(htc_hdr->len) + sizeof(*htc_hdr);
> pkt->status = ret;
> + skb_put(skb, pkt->act_len);
>
> return ret;
> }
>
> -static int ath10k_sdio_mbox_rx_fetch(struct ath10k *ar)
> +static int ath10k_sdio_mbox_rx_fetch_bundle(struct ath10k *ar)
> {
> struct ath10k_sdio *ar_sdio = ath10k_sdio_priv(ar);
> + struct ath10k_sdio_rx_data *pkt;
> + struct ath10k_htc_hdr *htc_hdr;
> int ret, i;
> + u32 pkt_offset, virt_pkt_len;
>
> + virt_pkt_len = 0;
> for (i = 0; i < ar_sdio->n_rx_pkts; i++) {
> - ret = ath10k_sdio_mbox_rx_packet(ar,
> - &ar_sdio->rx_pkts[i]);
> + virt_pkt_len += ar_sdio->rx_pkts[i].alloc_len;
> + }
> +
> + if (virt_pkt_len < ATH10K_SDIO_DMA_BUF_SIZE) {
> + ret = ath10k_sdio_readsb(ar, ar_sdio->mbox_info.htc_addr,
> + ar_sdio->vsg_buffer, virt_pkt_len);
> if (ret)
> goto err;
> + } else {
> + ath10k_err(ar, "size exceeding limit %d\n", virt_pkt_len);
Should you set err and goto err here? It seems like you're going to
process garbage if this happens.
> + }
> +
> + pkt_offset = 0;
> + for (i = 0; i < ar_sdio->n_rx_pkts; i++) {
> + pkt = &ar_sdio->rx_pkts[i];
> + htc_hdr = (struct ath10k_htc_hdr *)(ar_sdio->vsg_buffer + pkt_offset);
> + pkt->act_len = le16_to_cpu(htc_hdr->len) + sizeof(*htc_hdr);
> +
> + skb_put_data(pkt->skb, htc_hdr, pkt->act_len);
> + pkt->status = 0;
> + pkt_offset += pkt->alloc_len;
> }
>
> return 0;
>
> err:
> /* Free all packets that was not successfully fetched. */
Well you're freeing everything, now.
> - for (; i < ar_sdio->n_rx_pkts; i++)
> + for (i = 0; i < ar_sdio->n_rx_pkts; i++)
> ath10k_sdio_mbox_free_rx_pkt(&ar_sdio->rx_pkts[i]);
>
> + ar_sdio->n_rx_pkts = 0;
> +
> return ret;
> }
>
> @@ -715,7 +738,10 @@ static int ath10k_sdio_mbox_rxmsg_pending_handler(struct ath10k *ar,
> */
> *done = false;
>
> - ret = ath10k_sdio_mbox_rx_fetch(ar);
> + if (ar_sdio->n_rx_pkts > 1)
> + ret = ath10k_sdio_mbox_rx_fetch_bundle(ar);
> + else
> + ret = ath10k_sdio_mbox_rx_fetch(ar);
>
> /* Process fetched packets. This will potentially update
> * n_lookaheads depending on if the packets contain lookahead
> @@ -1123,7 +1149,7 @@ static int ath10k_sdio_bmi_get_rx_lookahead(struct ath10k *ar)
> MBOX_HOST_INT_STATUS_ADDRESS,
> &rx_word);
> if (ret) {
> - ath10k_warn(ar, "unable to read RX_LOOKAHEAD_VALID: %d\n", ret);
> + ath10k_warn(ar, "unable to read rx_lookahd: %d\n", ret);
> return ret;
> }
>
> @@ -2018,6 +2044,12 @@ static int ath10k_sdio_probe(struct sdio_func *func,
> goto err_core_destroy;
> }
>
> + ar_sdio->vsg_buffer = devm_kmalloc(ar->dev, ATH10K_SDIO_VSG_BUF_SIZE, GFP_KERNEL);
> + if (!ar_sdio->vsg_buffer) {
> + ret = -ENOMEM;
> + goto err_core_destroy;
> + }
> +
> ar_sdio->irq_data.irq_en_reg =
> devm_kzalloc(ar->dev, sizeof(struct ath10k_sdio_irq_enable_regs),
> GFP_KERNEL);
> diff --git a/drivers/net/wireless/ath/ath10k/sdio.h b/drivers/net/wireless/ath/ath10k/sdio.h
> index b8c7ac0..4896eca 100644
> --- a/drivers/net/wireless/ath/ath10k/sdio.h
> +++ b/drivers/net/wireless/ath/ath10k/sdio.h
> @@ -138,8 +138,8 @@ struct ath10k_sdio_irq_proc_regs {
> u8 rx_lookahead_valid;
> u8 host_int_status2;
> u8 gmbox_rx_avail;
> - __le32 rx_lookahead[2];
> - __le32 rx_gmbox_lookahead_alias[2];
> + __le32 rx_lookahead[2 * ATH10K_HIF_MBOX_NUM_MAX];
> + __le32 int_status_enable;
> };
>
> struct ath10k_sdio_irq_enable_regs {
> @@ -196,6 +196,9 @@ struct ath10k_sdio {
> struct ath10k *ar;
> struct ath10k_sdio_irq_data irq_data;
>
> + /* temporary buffer for sdio read */
> + u8 *vsg_buffer;
> +
> /* temporary buffer for BMI requests */
> u8 *bmi_buf;
>
> --
> 1.9.1
>
^ permalink raw reply
* Re: [PATCH v3 1/8] ath10k: adjust skb length in ath10k_sdio_mbox_rx_packet
From: Nicolas Boichat @ 2019-08-30 2:58 UTC (permalink / raw)
To: Wen Gong; +Cc: ath10k, open list:NETWORKING DRIVERS (WIRELESS)
In-Reply-To: <CANMq1KA2oxpObkP1oj2uK=90sZc9DEXbvdgu9P+87+cwJ__wQQ@mail.gmail.com>
On Fri, Aug 30, 2019 at 10:53 AM Nicolas Boichat <drinkcat@chromium.org> wrote:
>
> On Thu, Aug 29, 2019 at 12:18 AM Wen Gong <wgong@codeaurora.org> wrote:
> >
> > When the FW bundles multiple packets, pkt->act_len may be incorrect
> > as it refers to the first packet only (however, the FW will only
> > bundle packets that fit into the same pkt->alloc_len).
> >
> > Before this patch, the skb length would be set (incorrectly) to
> > pkt->act_len in ath10k_sdio_mbox_rx_packet, and then later manually
> > adjusted in ath10k_sdio_mbox_rx_process_packet.
> >
> > The first problem is that ath10k_sdio_mbox_rx_process_packet does not
> > use proper skb_put commands to adjust the length (it directly changes
> > skb->len), so we end up with a mismatch between skb->head + skb->tail
> > and skb->data + skb->len. This is quite serious, and causes corruptions
> > in the TCP stack, as the stack tries to coalesce packets, and relies
> > on skb->tail being correct (that is, skb_tail_pointer must point to
> > the first byte_after_ the data).
> >
> > Instead of re-adjusting the size in ath10k_sdio_mbox_rx_process_packet,
> > this moves the code to ath10k_sdio_mbox_rx_packet, and also add a
> > bounds check, as skb_put would crash the kernel if not enough space is
> > available.
> >
> > Tested with QCA6174 SDIO with firmware
> > WLAN.RMH.4.4.1-00007-QCARMSWP-1.
> >
> > Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
> > Signed-off-by: Wen Gong <wgong@codeaurora.org>
>
> You are not the author of this patch, please reset the author in your
> git tree and resend.
>
> Once you do that, the first line should say:
> From: Nicolas Boichat <drinkcat@chromium.org>
>
> Without this fix:
> NACKed-by: Nicolas Boichat <drinkcat@chromium.org>
>
Also you dropped the Fixes line:
Fixes: 8530b4e7b22bc3b ("ath10k: sdio: set skb len for all rx packets")
> > ---
> > v2:no this patch
> > v2:new added
> > drivers/net/wireless/ath/ath10k/sdio.c | 27 +++++++++++++++++++--------
> > 1 file changed, 19 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c
> > index 8ed4fbd..1127e44 100644
> > --- a/drivers/net/wireless/ath/ath10k/sdio.c
> > +++ b/drivers/net/wireless/ath/ath10k/sdio.c
> > @@ -381,16 +381,11 @@ static int ath10k_sdio_mbox_rx_process_packet(struct ath10k *ar,
> > struct ath10k_htc_hdr *htc_hdr = (struct ath10k_htc_hdr *)skb->data;
> > bool trailer_present = htc_hdr->flags & ATH10K_HTC_FLAG_TRAILER_PRESENT;
> > enum ath10k_htc_ep_id eid;
> > - u16 payload_len;
> > u8 *trailer;
> > int ret;
> >
> > - payload_len = le16_to_cpu(htc_hdr->len);
> > - skb->len = payload_len + sizeof(struct ath10k_htc_hdr);
> > -
> > if (trailer_present) {
> > - trailer = skb->data + sizeof(*htc_hdr) +
> > - payload_len - htc_hdr->trailer_len;
> > + trailer = skb->data + skb->len - htc_hdr->trailer_len;
> >
> > eid = pipe_id_to_eid(htc_hdr->eid);
> >
> > @@ -632,13 +627,29 @@ static int ath10k_sdio_mbox_rx_packet(struct ath10k *ar,
> > {
> > struct ath10k_sdio *ar_sdio = ath10k_sdio_priv(ar);
> > struct sk_buff *skb = pkt->skb;
> > + struct ath10k_htc_hdr *htc_hdr;
> > int ret;
> >
> > ret = ath10k_sdio_readsb(ar, ar_sdio->mbox_info.htc_addr,
> > skb->data, pkt->alloc_len);
> > +
> > + if (!ret) {
> > + /* Update actual length. The original length may be incorrect,
> > + * as the FW will bundle multiple packets as long as their sizes
> > + * fit within the same aligned length (pkt->alloc_len).
> > + */
> > + htc_hdr = (struct ath10k_htc_hdr *)skb->data;
> > + pkt->act_len = le16_to_cpu(htc_hdr->len) + sizeof(*htc_hdr);
> > + if (pkt->act_len <= pkt->alloc_len) {
> > + skb_put(skb, pkt->act_len);
> > + } else {
> > + ath10k_warn(ar, "rx packet too large (%zu > %zu)\n",
> > + pkt->act_len, pkt->alloc_len);
> > + ret = -EMSGSIZE;
> > + }
> > + }
> > +
> > pkt->status = ret;
> > - if (!ret)
> > - skb_put(skb, pkt->act_len);
> >
> > return ret;
> > }
> > --
> > 1.9.1
> >
^ permalink raw reply
* RE: [PATCH] ath10k: add fw coredump for sdio when firmware assert
From: Wen Gong @ 2019-08-30 2:54 UTC (permalink / raw)
To: Wen Gong, Nicolas Boichat, Wen Gong
Cc: Brian Norris, open list:NETWORKING DRIVERS (WIRELESS),
ath10k@lists.infradead.org
In-Reply-To: <8f0f2930e12a4dcabb69c13affe89a31@aptaiexm02f.ap.qualcomm.com>
> -----Original Message-----
> From: ath10k <ath10k-bounces@lists.infradead.org> On Behalf Of Wen Gong
> Sent: Wednesday, August 28, 2019 1:00 PM
> To: Nicolas Boichat <drinkcat@chromium.org>; Wen Gong
> <wgong@codeaurora.org>
> Cc: Brian Norris <briannorris@chromium.org>; open list:NETWORKING
> DRIVERS (WIRELESS) <linux-wireless@vger.kernel.org>;
> ath10k@lists.infradead.org
> Subject: [EXT] RE: [PATCH] ath10k: add fw coredump for sdio when firmware
> assert
Changed and v2 sent, https://patchwork.kernel.org/patch/11122827/
>
>
> _______________________________________________
> ath10k mailing list
> ath10k@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/ath10k
^ permalink raw reply
* Re: [PATCH v3 1/8] ath10k: adjust skb length in ath10k_sdio_mbox_rx_packet
From: Nicolas Boichat @ 2019-08-30 2:53 UTC (permalink / raw)
To: Wen Gong; +Cc: ath10k, open list:NETWORKING DRIVERS (WIRELESS)
In-Reply-To: <1566998177-2658-2-git-send-email-wgong@codeaurora.org>
On Thu, Aug 29, 2019 at 12:18 AM Wen Gong <wgong@codeaurora.org> wrote:
>
> When the FW bundles multiple packets, pkt->act_len may be incorrect
> as it refers to the first packet only (however, the FW will only
> bundle packets that fit into the same pkt->alloc_len).
>
> Before this patch, the skb length would be set (incorrectly) to
> pkt->act_len in ath10k_sdio_mbox_rx_packet, and then later manually
> adjusted in ath10k_sdio_mbox_rx_process_packet.
>
> The first problem is that ath10k_sdio_mbox_rx_process_packet does not
> use proper skb_put commands to adjust the length (it directly changes
> skb->len), so we end up with a mismatch between skb->head + skb->tail
> and skb->data + skb->len. This is quite serious, and causes corruptions
> in the TCP stack, as the stack tries to coalesce packets, and relies
> on skb->tail being correct (that is, skb_tail_pointer must point to
> the first byte_after_ the data).
>
> Instead of re-adjusting the size in ath10k_sdio_mbox_rx_process_packet,
> this moves the code to ath10k_sdio_mbox_rx_packet, and also add a
> bounds check, as skb_put would crash the kernel if not enough space is
> available.
>
> Tested with QCA6174 SDIO with firmware
> WLAN.RMH.4.4.1-00007-QCARMSWP-1.
>
> Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
> Signed-off-by: Wen Gong <wgong@codeaurora.org>
You are not the author of this patch, please reset the author in your
git tree and resend.
Once you do that, the first line should say:
From: Nicolas Boichat <drinkcat@chromium.org>
Without this fix:
NACKed-by: Nicolas Boichat <drinkcat@chromium.org>
> ---
> v2:no this patch
> v2:new added
> drivers/net/wireless/ath/ath10k/sdio.c | 27 +++++++++++++++++++--------
> 1 file changed, 19 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c
> index 8ed4fbd..1127e44 100644
> --- a/drivers/net/wireless/ath/ath10k/sdio.c
> +++ b/drivers/net/wireless/ath/ath10k/sdio.c
> @@ -381,16 +381,11 @@ static int ath10k_sdio_mbox_rx_process_packet(struct ath10k *ar,
> struct ath10k_htc_hdr *htc_hdr = (struct ath10k_htc_hdr *)skb->data;
> bool trailer_present = htc_hdr->flags & ATH10K_HTC_FLAG_TRAILER_PRESENT;
> enum ath10k_htc_ep_id eid;
> - u16 payload_len;
> u8 *trailer;
> int ret;
>
> - payload_len = le16_to_cpu(htc_hdr->len);
> - skb->len = payload_len + sizeof(struct ath10k_htc_hdr);
> -
> if (trailer_present) {
> - trailer = skb->data + sizeof(*htc_hdr) +
> - payload_len - htc_hdr->trailer_len;
> + trailer = skb->data + skb->len - htc_hdr->trailer_len;
>
> eid = pipe_id_to_eid(htc_hdr->eid);
>
> @@ -632,13 +627,29 @@ static int ath10k_sdio_mbox_rx_packet(struct ath10k *ar,
> {
> struct ath10k_sdio *ar_sdio = ath10k_sdio_priv(ar);
> struct sk_buff *skb = pkt->skb;
> + struct ath10k_htc_hdr *htc_hdr;
> int ret;
>
> ret = ath10k_sdio_readsb(ar, ar_sdio->mbox_info.htc_addr,
> skb->data, pkt->alloc_len);
> +
> + if (!ret) {
> + /* Update actual length. The original length may be incorrect,
> + * as the FW will bundle multiple packets as long as their sizes
> + * fit within the same aligned length (pkt->alloc_len).
> + */
> + htc_hdr = (struct ath10k_htc_hdr *)skb->data;
> + pkt->act_len = le16_to_cpu(htc_hdr->len) + sizeof(*htc_hdr);
> + if (pkt->act_len <= pkt->alloc_len) {
> + skb_put(skb, pkt->act_len);
> + } else {
> + ath10k_warn(ar, "rx packet too large (%zu > %zu)\n",
> + pkt->act_len, pkt->alloc_len);
> + ret = -EMSGSIZE;
> + }
> + }
> +
> pkt->status = ret;
> - if (!ret)
> - skb_put(skb, pkt->act_len);
>
> return ret;
> }
> --
> 1.9.1
>
^ permalink raw reply
* RE: [PATCH v2 7/7] ath10k: enable napi on RX path for sdio
From: Wen Gong @ 2019-08-30 2:52 UTC (permalink / raw)
To: Nicolas Boichat, Wen Gong
Cc: open list:NETWORKING DRIVERS (WIRELESS),
ath10k@lists.infradead.org
In-Reply-To: <CANMq1KCQZCOw8kHn2MJfAT9fWoLCmz2jFWqHzd=9QOgZ7MeaXQ@mail.gmail.com>
> -----Original Message-----
> From: ath10k <ath10k-bounces@lists.infradead.org> On Behalf Of Nicolas
> Boichat
> Sent: Wednesday, August 28, 2019 1:40 PM
> To: Wen Gong <wgong@codeaurora.org>
> Cc: open list:NETWORKING DRIVERS (WIRELESS) <linux-
> wireless@vger.kernel.org>; ath10k@lists.infradead.org
> Subject: [EXT] Re: [PATCH v2 7/7] ath10k: enable napi on RX path for sdio
>
Changed and v3 sent, https://patchwork.kernel.org/patch/11122183/
> _______________________________________________
> ath10k mailing list
> ath10k@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/ath10k
^ permalink raw reply
* RE: [PATCH v2 6/7] ath10k: enable alt data of TX path for sdio
From: Wen Gong @ 2019-08-30 2:52 UTC (permalink / raw)
To: Nicolas Boichat, Wen Gong
Cc: open list:NETWORKING DRIVERS (WIRELESS),
ath10k@lists.infradead.org
In-Reply-To: <CANMq1KDJSwyzz2y-yadJPnGijm=G6y0zg1tMZDyacH8a990BOg@mail.gmail.com>
> -----Original Message-----
> From: ath10k <ath10k-bounces@lists.infradead.org> On Behalf Of Nicolas
> Boichat
> Sent: Wednesday, August 28, 2019 1:38 PM
> To: Wen Gong <wgong@codeaurora.org>
> Cc: open list:NETWORKING DRIVERS (WIRELESS) <linux-
> wireless@vger.kernel.org>; ath10k@lists.infradead.org
> Subject: [EXT] Re: [PATCH v2 6/7] ath10k: enable alt data of TX path for sdio
>
Changed and V3 sent, https://patchwork.kernel.org/patch/11122141/
>
> _______________________________________________
> ath10k mailing list
> ath10k@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/ath10k
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox