While leaving an IBSS in ieee80211_ibss_disconnect() mac80211 flushes
stations, turns the carrier off and immediately tells the driver to
leave as well. While there may be synchronize_net() in station flush
and in this code later, packets can still be transmitted due to
cross-CPU race conditions after carrier off is set.
Therefore, it's possible for a race to happen where a TX to the
driver occurs while or after telling it to leave the IBSS. This can
be confusing to drivers, and in the case of iwlwifi leads to an
attempt to use invalid queues.
Move netif_carrier_off() to occur before sta_info_flush() during
IBSS disconnect, and add synchronize_net() if flushing didn't,
so that the synchronize_net() always happens between turning the
carrier off and telling the driver, avoiding this race.
Signed-off-by: Pagadala Yesu Anjaneyulu <pagadala.yesu.anjaneyulu@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260706223751.da1ce439cc93.If5cf482f87ab98ce66dd48724e24c81fed236d3f@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
When IBSS peer capabilities change, rates_updated is set to true in
ieee80211_update_sta_info(), but rx_nss is never recalculated.
For peers with HT/VHT, this leaves rx_nss at 0 instead of the
correct value, causing drivers to use incorrect rate scaling
parameters.
The root cause is that the commit below moved NSS initialisation
out of rate_control_rate_init() into explicit call sites, but
missing the rates_updated path in ieee80211_update_sta_info().
Fix this by calling ieee80211_sta_init_nss_bw_capa() before
rate_control_rate_init() when peer capabilities are updated,
consistent with the other IBSS call sites added by that commit.
Fixes: e5ad38a9b2 ("wifi: mac80211: clean up STA NSS handling")
Signed-off-by: Shahar Tzarfati <shahar.tzarfati@intel.com>
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260706222724.422adfd57b71.I5a47f65c5e38a221712f5203e5c8040304b382b5@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Currently, the initial STA bandwidth is set during each
parsing of HT/VHT/... elements to the station capabilities,
multiple times, in a confusing way that's not very good in
the case of NAN stations either.
For now, keep the NULL chandef pointer and all that, but
clean up the initial handling of NSS/BW capabilities and
then apply the VHT operation mode on top of that. This
clarifies the code and the client code now also handles
the bandwidth change from Operating Mode Notification in
association response.
The HT code is completely unnecessary now, since the VHT
(soon to be renamed) function will be called and handles
HT as well.
Reviewed-by: Miriam Rachel Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260415144514.a4d88eb27a8d.Id7a316e75e7e3dce2023d987e6939060f5286378@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Move ieee80211_sta_init_nss() from VHT code to station code,
and disentangle it from rate control. This way, it becomes
clearer when 'rx_nss' is set up.
While doing this, fix the client side code to set up
link_sta->op_mode_nss instead of link_sta->pub->rx_nss for
the opmode element in association response, and remove the
(now wrong) comment about handling that in the function.
type=cleanup
ticket=none
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Reviewed-on: https://gerritwcs.ir.intel.com/c/iwlwifi-stack-dev/+/273695
Tested-by: iil_jenkins iil_jenkins <EC.GER.UNIX.IIL.JENKINS@INTEL.COM>
tested: iil_jenkins iil_jenkins <EC.GER.UNIX.IIL.JENKINS@INTEL.COM>
Reviewed-by: Miriam Rachel Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260415144514.bef3d07beeb6.I97fb93ccc1b366110ab23de58fcd73676cdd85d6@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
In NAN, we have one set of (HT, VHT, HE) capabilities for all bands,
which means that we will need to process those capabilities without a
given sband.
To prepare for that, remove the sband argument from
ieee80211_ht_cap_ie_to_sta_ht_cap and ieee80211_he_cap_ie_to_sta_he_cap
and pass our own capabilities instead.
For ieee80211_vht_cap_ie_to_sta_vht_cap, make the sband argument
optional, since it is also used to check if there is at least one channel
that supports 80 MHz.
(Note that this check doesn't make much sense, but this can be handled in
a different patch.)
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260320141504.e42ef1f0eabb.If994d6346f00219437e22043e7bf2395b827b34a@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
The action code actually serves to identify the type of action
frame, so it really isn't part of the per-type structure. Pull
it out and have it in the general action frame format.
In theory, whether or not the action code is present in this
way is up to each category, but all categories that are defined
right now all have that value.
While at it, and since this change requires changing all users,
remove the 'u' and make it an anonymous union in this case, so
that all code using this changes.
Change IEEE80211_MIN_ACTION_SIZE to take an argument which says
how much of the frame is needed, e.g. category, action_code or
the specific frame type that's defined in the union. Again this
also ensures that all code is updated.
In some cases, fix bugs where the SKB length was checked after
having accessed beyond the checked length, in particular in FTM
code, e.g. ieee80211_is_ftm().
Link: https://patch.msgid.link/20260226183607.67e71846b59e.I9a24328e3ffcaae179466a935f1c3345029f9961@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This will be needed for UHR operation parsing, and we
already pass whether or not the frame is an action
frame, replace that by the full type. Note this fixes
a few cases where 'false' was erroneously passed (mesh
and TDLS) and removes ieee802_11_parse_elems_crc() as
it's unused.
Link: https://patch.msgid.link/20251105160810.a476d20a6e01.Ie659535f9357f2f9a3c73f8c059ccfc96bf93b54@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Currently, in supporting API's to fill sinfo structure from sta
structure, is mapped to fill the fields from sta->deflink. However,
for multi-link (ML) station, sinfo structure should be filled from
corresponding link_id.
Therefore, add link_id as an additional argument in supporting API's
for filling sinfo structure correctly. Link_id is set to -1 for non-ML
station and corresponding link_id for ML stations. In supporting API's
for filling sinfo structure, check for link_id, if link_id < 0, fill
the sinfo structure from sta->deflink, otherwise fill from
sta->link[link_id].
Current, changes are done at the deflink level i.e, pass -1 as link_id.
Actual link_id will be added in subsequent patches to support
station statistics for MLO.
Signed-off-by: Sarika Sharma <quic_sarishar@quicinc.com>
Link: https://patch.msgid.link/20250528054420.3050133-2-quic_sarishar@quicinc.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Move this API to the canonical timer_*() namespace.
[ tglx: Redone against pre rc1 ]
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/all/aB2X0jCKQO56WdMt@gmail.com
timer_delete[_sync]() replaces del_timer[_sync](). Convert the whole tree
over and remove the historical wrapper inlines.
Conversion was done with coccinelle plus manual fixups where necessary.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Mark that we left the IBSS before actually leaving (which
requires calling the driver). Otherwise, it's possible to
have the driver do some work flushing etc. while leaving,
and then get into the work trying to join again while all
data is being destroyed.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20250102161730.81a6c12b304c.I8484f768371e128152a84aa164854cca9ec1066b@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
We disable the carrier, but that doesn't immediately take
effect, and as such a concurrent transmit can go into the
driver while drv_leave_ibss() is happening and confuse it.
Synchronize to avoid that.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20250102161730.83b58167e80e.I538751fbe1b4302d20f6ed80afb024bca6a2dbf5@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
In order to update the right link information, call the update
rate_control_rate_update() with the right link_sta, and then
pass that through to the driver's sta_rc_update() method. The
software rate control still doesn't support it, but that'll be
skipped by not having a rate control ref.
Since it now operates on a link sta, rename the driver method.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20241007144851.5851b6b5fd41.Ibdf50d96afa4b761dd9b9dfd54a1147e77a75329@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Andrei previously fixed an issue in the client where the NSS
for links other than the primary/assoc/deflink isn't set. The
same issue appears to exist on the AP side, because there's
only a call to rate_control_rate_init() for the deflink, and
not any other links.
Rework the code a bit to do rate_control_rate_init() for links,
even if it really doesn't work with software rate control yet,
it does other things as well.
Also add rate_control_rate_init_all_links() to actually do it
properly when moving to ASSOC state in cfg80211.
Change the explicit call to ieee80211_sta_init_nss() to instead
be rate_control_rate_init() now in the client code, but also
add a call to rate_control_rate_init() when a link is added in
AP mode and the STA is already associated.
This should fix the NSS initialization issue, and perhaps pave
the way for actual software rate scaling a bit, in case anyone
cares in the future, but that of course needs a lot more than
just the init call.
We still need to fix the rate control _update_ as well, and the
sta_rc_update() driver method especially, but that will be in a
different patch.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20241007144851.c693274a908f.I0376da02e9f5a30eaa1b5d0d01371ff09506d453@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Public action extended channel switch announcement (ECSA)
frames cannot be protected well, the spec is unclear about
what should happen in the presence of stations that can
receive protected dual and stations that cannot.
Mitigate these issues by not treating public action frames
as the absolute truth, only treat them as a hint to stop
transmitting (quiet mode), and do the remainder of the CSA
handling only when receiving the next beacon (or protected
action frame) that contains the CSA; or, if it doesn't,
simply stop being quiet and continue operating normally.
This limits the exposure to malicious ECSA public action
frames, since they cannot cause a disconnect now, only a
short interruption in traffic.
Reviewed-by: Miriam Rachel Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20240612143037.ec7ccc45903e.Ife17d55c7ecbf98060f9c52889f3c8ba48798970@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Collect the CSA data in ieee80211_link_data_managed and
ieee80211_link_data into a csa sub-struct to clean up a
bit and make adding new things more obvious.
Reviewed-by: Miriam Rachel Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240506215543.29f954b1f576.I9a683a9647c33d4dd3011aade6677982428c1082@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Whenever sta_flush() function is invoked, all STAs present in that
interface are flushed. In case of MLO, it is desirable to only flush such
STAs that are at least using a given link id as one of their links.
Add support for this by making change in the __sta_info_flush API argument
to accept a link ID. And then, only if the STA is using the given link as
one of its links, it would be flushed.
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
Link: https://msgid.link/20240205162952.1697646-3-quic_adisi@quicinc.com
[reword commit message, in particular this isn't about "active" links]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
For channel contexts, mac80211 currently uses the cfg80211
chandef struct (control channel, center freq(s), width) to
define towards drivers and internally how these behave. In
fact, there are _two_ such structs used, where the min_def
can reduce bandwidth according to the stations connected.
Unfortunately, with EHT this is longer be sufficient, at
least not for all hardware. EHT requires that non-AP STAs
that are connected to an AP with a lower bandwidth than it
(the AP) advertises (e.g. 160 MHz STA connected to 320 MHz
AP) still be able to receive downlink OFDMA and respond to
trigger frames for uplink OFDMA that specify the position
and bandwidth for the non-AP STA relative to the channel
the AP is using. Therefore, they need to be aware of this,
and at least for some hardware (e.g. Intel) this awareness
is in the hardware. As a result, use of the "same" channel
may need to be split over two channel contexts where they
differ by the AP being used.
As a first step, introduce a concept of a channel request
('chanreq') for each interface, to control the context it
requests. This step does nothing but reorganise the code,
so that later the AP's chandef can be added to the request
in order to handle the EHT case described above.
Link: https://msgid.link/20240129194108.2e88e48bd2e9.I4256183debe975c5ed71621611206fdbb69ba330@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Rewrite the station-side connection handling. The connection
flags (IEEE80211_DISABLE_*) are rather confusing, and they're
not always maintained well. Additionally, for wider-bandwidth
OFDMA support we need to know the precise bandwidth of the AP,
which is currently somewhat difficult.
Rewrite this to have a 'mode' (S1G/legacy/HT/...) and a limit
on the bandwidth. This is not entirely clean because some of
those modes aren't completely sequenced (as this assumes in
some places), e.g. VHT doesn't exist on 2.4 GHz, but HE does.
However, it still simplifies things and gives us a good idea
what we're operating as, so we can parse elements accordingly
etc.
This leaves a FIXME for puncturing, this is addressed in a
later patch.
Reviewed-by: Ilan Peer <ilan.peer@intel.com>
Reviewed-by: Miriam Rachel Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240129194108.9451722c0110.I3e61f4cfe9da89008e1854160093c76a1e69dc2a@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Resolve several conflicts, mostly between changes/fixes in
wireless and the locking rework in wireless-next. One of
the conflicts actually shows a bug in wireless that we'll
want to fix separately.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Cisco AP module 9115 with FW 17.3 has a bug and sends a too
large maximum MPDU length in the association response
(indicating 12k) that it cannot actually process.
Work around that by taking the minimum between what's in the
association response and the BSS elements (from beacon or
probe response).
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230918140607.d1966a9a532e.I090225babb7cd4d1081ee9acd40e7de7e41c15ae@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
We really cannot even get into this as we can't have
a BSS with a 5/10 MHz (scan) width, and therefore all
the code handling shifted rates cannot happen. Remove
it all, since it's broken anyway, at least with MLO.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
There really isn't any support for scanning at different
channel widths than 20 MHz since there's no way to set it.
Remove this support for now, if somebody wants to maintain
this whole thing later we can revisit how it should work.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Since we're now protecting everything with the wiphy mutex
(and were really using it for almost everything before),
there's no longer any real reason to have a separate wdev
mutex. It may feel better, but really has no value.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
We now hold the wiphy mutex everywhere that we use or
needed the iflist_mtx, so we don't need this mutex any
more in mac80211. However, drivers may also iterate,
and in some cases (e.g. mt76) do so from high-priority
contexts. Thus, keep the mutex around but remove its
usage in mac80211 apart from those driver-visible parts
that are still needed.
Most of this change was done automatically with spatch,
with the parts that are still needed as described above
reverted manually.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
We now hold the wiphy mutex everywhere that we use or
needed the local->mtx, so we don't need this mutex any
more. Remove it.
Most of this change was done automatically with spatch.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
We now hold the wiphy mutex everywhere that we use or
needed the chanctx_mtx, so we don't need this mutex any
more. Remove it.
Most of this change was done automatically with spatch.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
We now hold the wiphy mutex everywhere that we use or
needed the sta_mtx, so we don't need this mutex any
more. Remove it.
Most of this change was done automatically with spatch.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
We'll need this later to convert other works that might
be cancelled from here, so convert this one first.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
When we create a station with a non-default link, then
we should have a link address, and we definitely need
to insert it into the link hash table on insertion.
Split the API into with and without link creation and
if it has a link, insert the link into the link hash
table on sta_info_insert().
Fixes: ba6ddab94f ("wifi: mac80211: maintain link-sta hash table")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
The flag here is currently per interface, but the way we
set and clear it means it should be per link, so change
it.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
When parsing a frame containing a multi-BSSID element, we
need to know both the transmitted and non-transmitted BSSID
so we can parse it correctly.
Unfortunately, in quite a number of cases, we got this wrong
and were passing the wrong BSSID or useless information:
* the mgmt->bssid from a frame is only the transmitted
BSSID if the frame is a beacon
* passing just one of the parameters as non-NULL isn't
useful and ignored
In those case where we need to parse for a specific BSS we
always have a BSS structure pointer, representing the BSS
we need, whether transmitted or not. Thus, pass that pointer
to the parsing function instead of the two BSSIDs.
Also fix two bugs:
* we need to re-parse all the elements for the other BSS
when iterating the non-transmitted BSSes in scan
* we need to parse for the correct BSS when setting up
the channel data in client code
Fixes: 78ac51f815 ("mac80211: support multi-bssid")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Separate out the connection downgrade flags from the ifmgd->flags
and put them into the link information instead. While at it, make
them a separate sparse type so we don't get confused about where
they belong and have static checking on correct handling.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Since links can be added and removed dynamically, we need to
somehow protect the sdata->link[] and vif->link_conf[] array
pointers from disappearing when accessing them without locks.
RCU-ify the pointers to achieve this, which requires quite a
bit of rework.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
We need to be able to access these in a race-free way under
traffic while adding/removing them, so RCU-ify the pointers.
This requires passing a link_sta to a lot of functions so
we don't have to do the RCU handling everywhere.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Add the necessary infrastructure, including a new driver
method, to add/remove links to/from a station. To do this,
refactor the link alloc/free a bit, splitting that so we
can do it without linking them, to handle failures better.
Note that a station entry must be created representing an
MLD or a non-MLD STA, it cannot change between the two.
When representing an MLD, the 'deflink' is used for the
first link, which might be removed later, in which case
the memory isn't reused.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>