summaryrefslogtreecommitdiff
path: root/net/mac80211/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r--net/mac80211/util.c80
1 files changed, 34 insertions, 46 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index dc0b74443c8d..dec6e16b8c7d 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -6,7 +6,7 @@
* Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2024 Intel Corporation
+ * Copyright (C) 2018-2025 Intel Corporation
*
* utilities for mac80211
*/
@@ -437,8 +437,6 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
{
struct ieee80211_local *local = hw_to_local(hw);
- trace_wake_queue(local, queue, reason);
-
if (WARN_ON(queue >= hw->queues))
return;
@@ -456,6 +454,9 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
if (local->q_stop_reasons[queue][reason] == 0)
__clear_bit(reason, &local->queue_stop_reasons[queue]);
+ trace_wake_queue(local, queue, reason,
+ local->q_stop_reasons[queue][reason]);
+
if (local->queue_stop_reasons[queue] != 0)
/* someone still has this queue stopped */
return;
@@ -502,8 +503,6 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
{
struct ieee80211_local *local = hw_to_local(hw);
- trace_stop_queue(local, queue, reason);
-
if (WARN_ON(queue >= hw->queues))
return;
@@ -512,6 +511,9 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
else
local->q_stop_reasons[queue][reason]++;
+ trace_stop_queue(local, queue, reason,
+ local->q_stop_reasons[queue][reason]);
+
set_bit(reason, &local->queue_stop_reasons[queue]);
}
@@ -685,7 +687,7 @@ void __ieee80211_flush_queues(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
unsigned int queues, bool drop)
{
- if (!local->ops->flush)
+ if (!local->ops->flush && !drop)
return;
/*
@@ -712,7 +714,8 @@ void __ieee80211_flush_queues(struct ieee80211_local *local,
}
}
- drv_flush(local, sdata, queues, drop);
+ if (local->ops->flush)
+ drv_flush(local, sdata, queues, drop);
ieee80211_wake_queues_by_reason(&local->hw, queues,
IEEE80211_QUEUE_STOP_REASON_FLUSH,
@@ -2153,7 +2156,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
wake_up:
- if (local->monitors == local->open_count && local->monitors > 0)
+ if (local->virt_monitors > 0 &&
+ local->virt_monitors == local->open_count)
ieee80211_add_virtual_monitor(local);
/*
@@ -2190,8 +2194,10 @@ int ieee80211_reconfig(struct ieee80211_local *local)
ieee80211_reconfig_roc(local);
/* Requeue all works */
- list_for_each_entry(sdata, &local->interfaces, list)
- wiphy_work_queue(local->hw.wiphy, &sdata->work);
+ list_for_each_entry(sdata, &local->interfaces, list) {
+ if (ieee80211_sdata_running(sdata))
+ wiphy_work_queue(local->hw.wiphy, &sdata->work);
+ }
}
ieee80211_wake_queues_by_reason(hw, IEEE80211_MAX_QUEUE_MAP,
@@ -2748,6 +2754,7 @@ u8 *ieee80211_ie_build_he_oper(u8 *pos, const struct cfg80211_chan_def *chandef)
{
struct ieee80211_he_operation *he_oper;
struct ieee80211_he_6ghz_oper *he_6ghz_op;
+ struct cfg80211_chan_def he_chandef;
u32 he_oper_params;
u8 ie_len = 1 + sizeof(struct ieee80211_he_operation);
@@ -2779,27 +2786,33 @@ u8 *ieee80211_ie_build_he_oper(u8 *pos, const struct cfg80211_chan_def *chandef)
if (chandef->chan->band != NL80211_BAND_6GHZ)
goto out;
+ cfg80211_chandef_create(&he_chandef, chandef->chan, NL80211_CHAN_NO_HT);
+ he_chandef.center_freq1 = chandef->center_freq1;
+ he_chandef.center_freq2 = chandef->center_freq2;
+ he_chandef.width = chandef->width;
+
/* TODO add VHT operational */
he_6ghz_op = (struct ieee80211_he_6ghz_oper *)pos;
he_6ghz_op->minrate = 6; /* 6 Mbps */
he_6ghz_op->primary =
- ieee80211_frequency_to_channel(chandef->chan->center_freq);
+ ieee80211_frequency_to_channel(he_chandef.chan->center_freq);
he_6ghz_op->ccfs0 =
- ieee80211_frequency_to_channel(chandef->center_freq1);
- if (chandef->center_freq2)
+ ieee80211_frequency_to_channel(he_chandef.center_freq1);
+ if (he_chandef.center_freq2)
he_6ghz_op->ccfs1 =
- ieee80211_frequency_to_channel(chandef->center_freq2);
+ ieee80211_frequency_to_channel(he_chandef.center_freq2);
else
he_6ghz_op->ccfs1 = 0;
- switch (chandef->width) {
+ switch (he_chandef.width) {
case NL80211_CHAN_WIDTH_320:
- /*
- * TODO: mesh operation is not defined over 6GHz 320 MHz
- * channels.
+ /* Downgrade EHT 320 MHz BW to 160 MHz for HE and set new
+ * center_freq1
*/
- WARN_ON(1);
- break;
+ ieee80211_chandef_downgrade(&he_chandef, NULL);
+ he_6ghz_op->ccfs0 =
+ ieee80211_frequency_to_channel(he_chandef.center_freq1);
+ fallthrough;
case NL80211_CHAN_WIDTH_160:
/* Convert 160 MHz channel width to new style as interop
* workaround.
@@ -2807,7 +2820,7 @@ u8 *ieee80211_ie_build_he_oper(u8 *pos, const struct cfg80211_chan_def *chandef)
he_6ghz_op->control =
IEEE80211_HE_6GHZ_OPER_CTRL_CHANWIDTH_160MHZ;
he_6ghz_op->ccfs1 = he_6ghz_op->ccfs0;
- if (chandef->chan->center_freq < chandef->center_freq1)
+ if (he_chandef.chan->center_freq < he_chandef.center_freq1)
he_6ghz_op->ccfs0 -= 8;
else
he_6ghz_op->ccfs0 += 8;
@@ -3647,31 +3660,6 @@ again:
WARN_ON_ONCE(!cfg80211_chandef_valid(c));
}
-/*
- * Returns true if smps_mode_new is strictly more restrictive than
- * smps_mode_old.
- */
-bool ieee80211_smps_is_restrictive(enum ieee80211_smps_mode smps_mode_old,
- enum ieee80211_smps_mode smps_mode_new)
-{
- if (WARN_ON_ONCE(smps_mode_old == IEEE80211_SMPS_AUTOMATIC ||
- smps_mode_new == IEEE80211_SMPS_AUTOMATIC))
- return false;
-
- switch (smps_mode_old) {
- case IEEE80211_SMPS_STATIC:
- return false;
- case IEEE80211_SMPS_DYNAMIC:
- return smps_mode_new == IEEE80211_SMPS_STATIC;
- case IEEE80211_SMPS_OFF:
- return smps_mode_new != IEEE80211_SMPS_OFF;
- default:
- WARN_ON(1);
- }
-
- return false;
-}
-
int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
struct cfg80211_csa_settings *csa_settings)
{