* Re: wireless workshop coming soon :-)
From: Johannes Berg @ 2019-03-15 9:21 UTC (permalink / raw)
To: Kevin Hayes, Toke Høiland-Jørgensen, Kirtika Ruchandani
Cc: linux-wireless
In-Reply-To: <1d87a40795765be3ce9a485381c2867b143f26e1.camel@sipsolutions.net>
On Fri, 2019-03-15 at 10:20 +0100, Johannes Berg wrote:
> On Sun, 2019-03-10 at 20:21 -0700, Kevin Hayes wrote:
> > [resending after html mode got nacked..]
> >
> > Hi Johannes/Toke,
> > It would be fine with Kan and me to push the airtime fairness
> > discussion to later, to accomodate Toke.
> > Workshop fairness in action. :)
>
> :)
> Yes, I know we need to do that. Unfortunately I haven't had a chance to
> really build up a time-based agenda.
>
> Let's see. We have track 4 all day on Wednesday, overlaps are:
>
> | track 1 | track 2 | track 3
> 8:30 - 10:30 | TCP | XDP tut | IoT / U-LPWA
> 10:50 - 11:50 | TCP | Kubrnts | FRR
> 11:50 - 12:20 | netlink | QUIC | FRR dataplane
> 13:20 - 14:20 | netlink | QUIC | -
> 14:40 - 16:10 | TC | NF | -
> 16:30 - 18:00 | hw offl | preempt | -
>
> So the overlaps I know about are the XDP Tutorial (Toke) and netlink
> (partially at least, myself).
>
> Any others?
>
> Clearly Toke needs to be at the full XDP Tutorial, I think I can live
> with just doing the first part of the netlink workshop, according to
> their (tentative) agenda.
>
> As far as I'm concerned, we need Toke for the eBPF/XDP wifi topic, and
> clearly for all the topics related to TXQs, which includes at least part
> of HE/11ax. Toke, is there anything else you have a strong interest in?
>
>
> So tentatively, I'd say you can do w/o me for the FQ/airtime fairness
> stuff (right Toke, Kalle?) and talk about that at 11:50?
>
>
>
> Just randomly dropping the other stuff, I get:
>
> (T = no Toke, J = no Johannes)
>
> 8:30 - 9:00 T intro / CRDA deprecation / other regulatory topics?
> 9:00 - 9:30 T CSI reporting / vendor command/event handling updates
> 9:30 - 10:00 T nl80211 APIs - non-public features, NAN deprecation
> 10:00 - 10:30 T nl80211 APIs cont'd - Android
> 10:50 - 11:20 eBPF integration / XDP support for wifi
> 11:20 - 11:50 (buffer)
> 11:50 - 12:20 J rtw88 / grill Kalle (be)fore lunch ;-)
> 13:20 - 13:50 Kevin/Kan chromiumOS fairness review, bufferbloat plans
> 13:50 - 14:20 fq_codel / airtime fairness stack integration
> 14:40 - 15:10 HE/11ax status, timeline, testing, future work
> 15:10 - 15:40 HE/11ax TXQ AP-side (is anyone doing something here?)
> 15:40 - 16:10 release discussions (iw, wpa_s, ...)
> 16:30 - 17:00 security issue handling w/ backports
> 17:00 - 17:30 (buffer)
> 17:30 - 18:00
Oh, I have another idea - radiotap TLV format discussion, if anyone
cares?
johannes
^ permalink raw reply
* Re: [PATCH v2] fq: fix fq_tin tx bytes overflow
From: Johannes Berg @ 2019-03-15 9:38 UTC (permalink / raw)
To: Yibo Zhao, ath10k; +Cc: linux-wireless, Toke Høiland-Jørgensen
In-Reply-To: <1552446505-15444-1-git-send-email-yiboz@codeaurora.org>
On Wed, 2019-03-13 at 11:08 +0800, Yibo Zhao wrote:
> Currently, we are using u32 for tx_bytes in fq_tin.
> If the throughput stays more than 1.2Gbps, tx_bytes
> statistics overflow in about 1 min.
>
> In order to allow us to trace the tx_bytes statistics
> for longer time in high throughput, change its type
> from u32 to u64.
Hmm. 64-bit values are kinda expensive on 32-bit architectures. How
badly do you need this? I mean ... worst case you just have to capture
every 30 seconds or so if you're doing really high throughput with HE or
something?
johannes
^ permalink raw reply
* Re: preparing for 802.11ah channels
From: Johannes Berg @ 2019-03-15 9:47 UTC (permalink / raw)
To: thomas pedersen, linux-wireless
In-Reply-To: <CABWD38man7mGiConmvmK0V=35P9zV7uvhVoY-8eSQQeO9W2+Qw@mail.gmail.com>
On Sat, 2019-02-16 at 15:45 -0800, thomas pedersen wrote:
> Hello,
>
> I'm working on defining new channels for S1G PHYs in mac80211. These
> are in the 900MHz range and center frequency for the 1MHz channels are
> on a half MHz, while the existing channel definitions are in units of
> MHz.
Yay... :)
> In order to support the new channels we could change the internal
> center frequency units to KHz and extend the nl80211 API so
> NL80211_FREQUENCY_ATTR_FREQ and NL80211_ATTR_WIPHY_FREQ get _KHZ
> variants while renaming the original attributes to _MHZ to reflect the
> units.
The nl80211 API seems straightforward, yeah.
> From looking at the code it looks like this should be fairly
> straightforward, if involving a lot of changes since the driver
> declarations would have to change too. Am I missing something
> obviously wrong, or does this sound reasonable?
I'm not sure I agree about all the driver changes being straightforward.
In theory yes, but ... ;-)
I guess you'd define a new band (NL80211_BAND_S1G or something?), so
perhaps there's a way we can get away with doing it only on that band?
OTOH, I guess if you change center_freq1 to center_freq1_khz or
something then you compile-fail everywhere ...
johanne
^ permalink raw reply
* Re: [PATCH v2] net: brcm80211: fix missing checks for kmemdup
From: Arend Van Spriel @ 2019-03-15 9:50 UTC (permalink / raw)
To: Kangjie Lu
Cc: pakki001, Franky Lin, Hante Meuleman, Chi-Hsien Lin, Wright Feng,
Kalle Valo, David S. Miller, Rafał Miłecki,
Stefan Wahren, Chung-Hsien Hsu, linux-wireless,
brcm80211-dev-list.pdl, brcm80211-dev-list, netdev, linux-kernel
In-Reply-To: <20190312043929.727-1-kjlu@umn.edu>
On 3/12/2019 5:39 AM, Kangjie Lu wrote:
> In case kmemdup fails, the fix sets conn_info->req_ie_len to zero
> to avoid buffer overflows.
Hi Kangjie,
See comment below. Also for v3 change prefix 'net:brcm80211:' to
'brcmfmac:' instead.
> Signed-off-by: Kangjie Lu <kjlu@umn.edu>
> ---
> drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
> index e92f6351bd22..5d9a3c35fef5 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
> @@ -5464,6 +5464,8 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
> conn_info->req_ie =
> kmemdup(cfg->extra_buf, conn_info->req_ie_len,
> GFP_KERNEL);
> + if (!conn_info->req_ie)
> + conn_info->req_ie_len = 0;
good.
> } else {
> conn_info->req_ie_len = 0;
> conn_info->req_ie = NULL;
> @@ -5480,6 +5482,8 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
> conn_info->resp_ie =
> kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
> GFP_KERNEL);
> + if (!conn_info->resp_ie)
> + conn_info->req_ie_len = 0;
bad! I think you took my comment too literal. Here it should set
conn_info->resp_ie_len to zero.
Regards,
Arend
> } else {
> conn_info->resp_ie_len = 0;
> conn_info->resp_ie = NULL;
>
^ permalink raw reply
* [PATCH] mac80211: rework locking for txq scheduling / airtime fairness
From: Felix Fietkau @ 2019-03-15 10:03 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, Toke Høiland-Jørgensen
Holding the lock around the entire duration of tx scheduling can create
some nasty lock contention, especially when processing airtime information
from the tx status or the rx path.
Improve locking by only holding the active_txq_lock for lookups / scheduling
list modifications.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
include/net/mac80211.h | 49 ++++++++++++++++--------------------------
net/mac80211/tx.c | 44 ++++++++++++++-----------------------
2 files changed, 35 insertions(+), 58 deletions(-)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 3771625b7a9d..0de0aba580eb 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -6269,8 +6269,6 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
* @hw: pointer as obtained from ieee80211_alloc_hw()
* @ac: AC number to return packets from.
*
- * Should only be called between calls to ieee80211_txq_schedule_start()
- * and ieee80211_txq_schedule_end().
* Returns the next txq if successful, %NULL if no queue is eligible. If a txq
* is returned, it should be returned with ieee80211_return_txq() after the
* driver has finished scheduling it.
@@ -6278,51 +6276,42 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac);
/**
- * ieee80211_return_txq - return a TXQ previously acquired by ieee80211_next_txq()
- *
- * @hw: pointer as obtained from ieee80211_alloc_hw()
- * @txq: pointer obtained from station or virtual interface
- *
- * Should only be called between calls to ieee80211_txq_schedule_start()
- * and ieee80211_txq_schedule_end().
- */
-void ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq);
-
-/**
- * ieee80211_txq_schedule_start - acquire locks for safe scheduling of an AC
+ * ieee80211_txq_schedule_start - start new scheduling round for TXQs
*
* @hw: pointer as obtained from ieee80211_alloc_hw()
* @ac: AC number to acquire locks for
*
- * Acquire locks needed to schedule TXQs from the given AC. Should be called
- * before ieee80211_next_txq() or ieee80211_return_txq().
+ * Should be called before ieee80211_next_txq() or ieee80211_return_txq().
+ * The driver must not call multiple TXQ scheduling rounds concurrently.
*/
-void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac)
- __acquires(txq_lock);
+void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac);
+
+/* (deprecated) */
+static inline void ieee80211_txq_schedule_end(struct ieee80211_hw *hw, u8 ac)
+{
+}
/**
- * ieee80211_txq_schedule_end - release locks for safe scheduling of an AC
+ * ieee80211_schedule_txq - schedule a TXQ for transmission
*
* @hw: pointer as obtained from ieee80211_alloc_hw()
- * @ac: AC number to acquire locks for
+ * @txq: pointer obtained from station or virtual interface
*
- * Release locks previously acquired by ieee80211_txq_schedule_end().
+ * Schedules a TXQ for transmission if it is not already scheduled.
*/
-void ieee80211_txq_schedule_end(struct ieee80211_hw *hw, u8 ac)
- __releases(txq_lock);
+void ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq);
/**
- * ieee80211_schedule_txq - schedule a TXQ for transmission
+ * ieee80211_return_txq - return a TXQ previously acquired by ieee80211_next_txq()
*
* @hw: pointer as obtained from ieee80211_alloc_hw()
* @txq: pointer obtained from station or virtual interface
- *
- * Schedules a TXQ for transmission if it is not already scheduled. Takes a
- * lock, which means it must *not* be called between
- * ieee80211_txq_schedule_start() and ieee80211_txq_schedule_end()
*/
-void ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
- __acquires(txq_lock) __releases(txq_lock);
+static inline void
+ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
+{
+ ieee80211_schedule_txq(hw, txq);
+}
/**
* ieee80211_txq_may_transmit - check whether TXQ is allowed to transmit
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index ca23abbf5c0b..51cc37802439 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -3653,16 +3653,17 @@ EXPORT_SYMBOL(ieee80211_tx_dequeue);
struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac)
{
struct ieee80211_local *local = hw_to_local(hw);
+ struct ieee80211_txq *ret = NULL;
struct txq_info *txqi = NULL;
- lockdep_assert_held(&local->active_txq_lock[ac]);
+ spin_lock_bh(&local->active_txq_lock[ac]);
begin:
txqi = list_first_entry_or_null(&local->active_txqs[ac],
struct txq_info,
schedule_order);
if (!txqi)
- return NULL;
+ goto out;
if (txqi->txq.sta) {
struct sta_info *sta = container_of(txqi->txq.sta,
@@ -3679,21 +3680,25 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac)
if (txqi->schedule_round == local->schedule_round[ac])
- return NULL;
+ goto out;
list_del_init(&txqi->schedule_order);
txqi->schedule_round = local->schedule_round[ac];
- return &txqi->txq;
+ ret = &txqi->txq;
+
+out:
+ spin_unlock_bh(&local->active_txq_lock[ac]);
+ return ret;
}
EXPORT_SYMBOL(ieee80211_next_txq);
-void ieee80211_return_txq(struct ieee80211_hw *hw,
- struct ieee80211_txq *txq)
+void ieee80211_schedule_txq(struct ieee80211_hw *hw,
+ struct ieee80211_txq *txq)
{
struct ieee80211_local *local = hw_to_local(hw);
struct txq_info *txqi = to_txq_info(txq);
- lockdep_assert_held(&local->active_txq_lock[txq->ac]);
+ spin_lock_bh(&local->active_txq_lock[txq->ac]);
if (list_empty(&txqi->schedule_order) &&
(!skb_queue_empty(&txqi->frags) || txqi->tin.backlog_packets)) {
@@ -3713,17 +3718,7 @@ void ieee80211_return_txq(struct ieee80211_hw *hw,
list_add_tail(&txqi->schedule_order,
&local->active_txqs[txq->ac]);
}
-}
-EXPORT_SYMBOL(ieee80211_return_txq);
-void ieee80211_schedule_txq(struct ieee80211_hw *hw,
- struct ieee80211_txq *txq)
- __acquires(txq_lock) __releases(txq_lock)
-{
- struct ieee80211_local *local = hw_to_local(hw);
-
- spin_lock_bh(&local->active_txq_lock[txq->ac]);
- ieee80211_return_txq(hw, txq);
spin_unlock_bh(&local->active_txq_lock[txq->ac]);
}
EXPORT_SYMBOL(ieee80211_schedule_txq);
@@ -3736,7 +3731,7 @@ bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
struct sta_info *sta;
u8 ac = txq->ac;
- lockdep_assert_held(&local->active_txq_lock[ac]);
+ spin_lock_bh(&local->active_txq_lock[ac]);
if (!txqi->txq.sta)
goto out;
@@ -3766,34 +3761,27 @@ bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
sta->airtime[ac].deficit += sta->airtime_weight;
list_move_tail(&txqi->schedule_order, &local->active_txqs[ac]);
+ spin_unlock_bh(&local->active_txq_lock[ac]);
return false;
out:
if (!list_empty(&txqi->schedule_order))
list_del_init(&txqi->schedule_order);
+ spin_unlock_bh(&local->active_txq_lock[ac]);
return true;
}
EXPORT_SYMBOL(ieee80211_txq_may_transmit);
void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac)
- __acquires(txq_lock)
{
struct ieee80211_local *local = hw_to_local(hw);
spin_lock_bh(&local->active_txq_lock[ac]);
local->schedule_round[ac]++;
-}
-EXPORT_SYMBOL(ieee80211_txq_schedule_start);
-
-void ieee80211_txq_schedule_end(struct ieee80211_hw *hw, u8 ac)
- __releases(txq_lock)
-{
- struct ieee80211_local *local = hw_to_local(hw);
-
spin_unlock_bh(&local->active_txq_lock[ac]);
}
-EXPORT_SYMBOL(ieee80211_txq_schedule_end);
+EXPORT_SYMBOL(ieee80211_txq_schedule_start);
void __ieee80211_subif_start_xmit(struct sk_buff *skb,
struct net_device *dev,
--
2.17.0
^ permalink raw reply related
* Re: [PATCH] mac80211: rework locking for txq scheduling / airtime fairness
From: Toke Høiland-Jørgensen @ 2019-03-15 13:04 UTC (permalink / raw)
To: Felix Fietkau, linux-wireless; +Cc: johannes
In-Reply-To: <20190315100335.91445-1-nbd@nbd.name>
Felix Fietkau <nbd@nbd.name> writes:
> Holding the lock around the entire duration of tx scheduling can create
> some nasty lock contention, especially when processing airtime information
> from the tx status or the rx path.
> Improve locking by only holding the active_txq_lock for lookups / scheduling
> list modifications.
>
> Signed-off-by: Felix Fietkau <nbd@nbd.name>
Acked-by: Toke Høiland-Jørgensen <toke@redhat.com>
> include/net/mac80211.h | 49 ++++++++++++++++--------------------------
> net/mac80211/tx.c | 44 ++++++++++++++-----------------------
> 2 files changed, 35 insertions(+), 58 deletions(-)
>
> diff --git a/include/net/mac80211.h b/include/net/mac80211.h
> index 3771625b7a9d..0de0aba580eb 100644
> --- a/include/net/mac80211.h
> +++ b/include/net/mac80211.h
[ ... ]
> -void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac)
> - __acquires(txq_lock);
> +void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac);
> +
> +/* (deprecated) */
> +static inline void ieee80211_txq_schedule_end(struct ieee80211_hw *hw, u8 ac)
> +{
> +}
I figure I'll post a cleanup of this as part of my reworked schedule
change patch; since I'll be messing around with these bits anyway...
-Toke
^ permalink raw reply
* Re: wireless workshop coming soon :-)
From: Toke Høiland-Jørgensen @ 2019-03-15 13:06 UTC (permalink / raw)
To: Johannes Berg, Kevin Hayes, Kirtika Ruchandani; +Cc: linux-wireless
In-Reply-To: <1d87a40795765be3ce9a485381c2867b143f26e1.camel@sipsolutions.net>
Johannes Berg <johannes@sipsolutions.net> writes:
> On Sun, 2019-03-10 at 20:21 -0700, Kevin Hayes wrote:
>> [resending after html mode got nacked..]
>>
>> Hi Johannes/Toke,
>> It would be fine with Kan and me to push the airtime fairness
>> discussion to later, to accomodate Toke.
>> Workshop fairness in action. :)
>
> :)
> Yes, I know we need to do that. Unfortunately I haven't had a chance to
> really build up a time-based agenda.
>
> Let's see. We have track 4 all day on Wednesday, overlaps are:
>
> | track 1 | track 2 | track 3
> 8:30 - 10:30 | TCP | XDP tut | IoT / U-LPWA
> 10:50 - 11:50 | TCP | Kubrnts | FRR
> 11:50 - 12:20 | netlink | QUIC | FRR dataplane
> 13:20 - 14:20 | netlink | QUIC | -
> 14:40 - 16:10 | TC | NF | -
> 16:30 - 18:00 | hw offl | preempt | -
>
> So the overlaps I know about are the XDP Tutorial (Toke) and netlink
> (partially at least, myself).
>
> Any others?
>
> Clearly Toke needs to be at the full XDP Tutorial, I think I can live
> with just doing the first part of the netlink workshop, according to
> their (tentative) agenda.
>
> As far as I'm concerned, we need Toke for the eBPF/XDP wifi topic, and
> clearly for all the topics related to TXQs, which includes at least part
> of HE/11ax. Toke, is there anything else you have a strong interest in?
>
>
> So tentatively, I'd say you can do w/o me for the FQ/airtime fairness
> stuff (right Toke, Kalle?) and talk about that at 11:50?
>
>
>
> Just randomly dropping the other stuff, I get:
>
> (T = no Toke, J = no Johannes)
>
> 8:30 - 9:00 T intro / CRDA deprecation / other regulatory topics?
> 9:00 - 9:30 T CSI reporting / vendor command/event handling updates
> 9:30 - 10:00 T nl80211 APIs - non-public features, NAN deprecation
> 10:00 - 10:30 T nl80211 APIs cont'd - Android
> 10:50 - 11:20 eBPF integration / XDP support for wifi
> 11:20 - 11:50 (buffer)
> 11:50 - 12:20 J rtw88 / grill Kalle (be)fore lunch ;-)
> 13:20 - 13:50 Kevin/Kan chromiumOS fairness review, bufferbloat plans
> 13:50 - 14:20 fq_codel / airtime fairness stack integration
> 14:40 - 15:10 HE/11ax status, timeline, testing, future work
> 15:10 - 15:40 HE/11ax TXQ AP-side (is anyone doing something here?)
> 15:40 - 16:10 release discussions (iw, wpa_s, ...)
> 16:30 - 17:00 security issue handling w/ backports
> 17:00 - 17:30 (buffer)
> 17:30 - 18:00
>
> WDYT?
SGTM :)
-Toke
^ permalink raw reply
* [PATCH 03/11] nl80211: copy the length of dst of src in nl80211_notify_radar_detection()
From: Luca Coelho @ 2019-03-15 15:38 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Luca Coelho
In-Reply-To: <20190315153907.16192-1-luca@coelho.fi>
From: Luca Coelho <luciano.coelho@intel.com>
It is generally safer to copy the length of the destination instead of
the length of the source, because if the sizes don't match, it's
usually better to leak some data from the source than to write data
out of bounds in the destination.
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
net/wireless/nl80211.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 25a9e3b5c154..239be0e2f9e1 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -8061,7 +8061,7 @@ static int nl80211_notify_radar_detection(struct sk_buff *skb,
cfg80211_sched_dfs_chan_update(rdev);
- memcpy(&rdev->radar_chandef, &chandef, sizeof(chandef));
+ memcpy(&rdev->radar_chandef, &chandef, sizeof(rdev->radar_chandef));
/* Propagate this notification to other radios as well */
queue_work(cfg80211_wq, &rdev->propagate_radar_detect_wk);
--
2.20.1
^ permalink raw reply related
* [PATCH 00/11] cfg80211/mac80211 patches from our internal tree 2019-03-15
From: Luca Coelho @ 2019-03-15 15:38 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Luca Coelho
From: Luca Coelho <luciano.coelho@intel.com>
Hi,
Some patches with mac80211 and cfg80211 changes from our internal
tree.
Please review, though you have already reviewed most if not all of
them ;)
Cheers,
Luca.
Andrei Otcheretianski (1):
mac80211: Increase MAX_MSG_LEN
Avraham Stern (1):
mac80211_hwsim: set p2p device interface support indication
Ilan Peer (1):
cfg80211: Handle WMM rules in regulatory domain intersection
Liad Kaufman (1):
ieee80211: update HE IEs to D4.0 spec
Luca Coelho (1):
nl80211: copy the length of dst of src in
nl80211_notify_radar_detection()
Sara Sharon (5):
cfg80211: don't skip multi-bssid index element
cfg80211: support non-inheritance element
mac80211: support non-inheritance element
cfg80211: support profile split between elements
mac80211: support profile split between elements
Shaul Triebitz (1):
nl80211: increase NL80211_MAX_SUPP_REG_RULES
drivers/net/wireless/mac80211_hwsim.c | 2 +
include/linux/ieee80211.h | 14 ++-
include/net/cfg80211.h | 22 ++++
include/uapi/linux/nl80211.h | 4 +-
net/mac80211/ieee80211_i.h | 1 -
net/mac80211/trace_msg.h | 7 +-
net/mac80211/util.c | 162 +++++++++++++++---------
net/wireless/nl80211.c | 2 +-
net/wireless/reg.c | 39 ++++++
net/wireless/scan.c | 173 ++++++++++++++++++++++++--
10 files changed, 345 insertions(+), 81 deletions(-)
--
2.20.1
^ permalink raw reply
* [PATCH 04/11] cfg80211: Handle WMM rules in regulatory domain intersection
From: Luca Coelho @ 2019-03-15 15:39 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Ilan Peer, Luca Coelho
In-Reply-To: <20190315153907.16192-1-luca@coelho.fi>
From: Ilan Peer <ilan.peer@intel.com>
The support added for regulatory WMM rules did not handle
the case of regulatory domain intersections. Fix it.
Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Fixes: 230ebaa189af ("cfg80211: read wmm rules from regulatory database")
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
net/wireless/reg.c | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 2f1bf91eb226..0ba778f371cb 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1309,6 +1309,16 @@ reg_intersect_dfs_region(const enum nl80211_dfs_regions dfs_region1,
return dfs_region1;
}
+static void reg_wmm_rules_intersect(const struct ieee80211_wmm_ac *wmm_ac1,
+ const struct ieee80211_wmm_ac *wmm_ac2,
+ struct ieee80211_wmm_ac *intersect)
+{
+ intersect->cw_min = max_t(u16, wmm_ac1->cw_min, wmm_ac2->cw_min);
+ intersect->cw_max = max_t(u16, wmm_ac1->cw_max, wmm_ac2->cw_max);
+ intersect->cot = min_t(u16, wmm_ac1->cot, wmm_ac2->cot);
+ intersect->aifsn = max_t(u8, wmm_ac1->aifsn, wmm_ac2->aifsn);
+}
+
/*
* Helper for regdom_intersect(), this does the real
* mathematical intersection fun
@@ -1323,6 +1333,8 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1,
struct ieee80211_freq_range *freq_range;
const struct ieee80211_power_rule *power_rule1, *power_rule2;
struct ieee80211_power_rule *power_rule;
+ const struct ieee80211_wmm_rule *wmm_rule1, *wmm_rule2;
+ struct ieee80211_wmm_rule *wmm_rule;
u32 freq_diff, max_bandwidth1, max_bandwidth2;
freq_range1 = &rule1->freq_range;
@@ -1333,6 +1345,10 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1,
power_rule2 = &rule2->power_rule;
power_rule = &intersected_rule->power_rule;
+ wmm_rule1 = &rule1->wmm_rule;
+ wmm_rule2 = &rule2->wmm_rule;
+ wmm_rule = &intersected_rule->wmm_rule;
+
freq_range->start_freq_khz = max(freq_range1->start_freq_khz,
freq_range2->start_freq_khz);
freq_range->end_freq_khz = min(freq_range1->end_freq_khz,
@@ -1376,6 +1392,29 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1,
intersected_rule->dfs_cac_ms = max(rule1->dfs_cac_ms,
rule2->dfs_cac_ms);
+ if (rule1->has_wmm && rule2->has_wmm) {
+ u8 ac;
+
+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
+ reg_wmm_rules_intersect(&wmm_rule1->client[ac],
+ &wmm_rule2->client[ac],
+ &wmm_rule->client[ac]);
+ reg_wmm_rules_intersect(&wmm_rule1->ap[ac],
+ &wmm_rule2->ap[ac],
+ &wmm_rule->ap[ac]);
+ }
+
+ intersected_rule->has_wmm = true;
+ } else if (rule1->has_wmm) {
+ *wmm_rule = *wmm_rule1;
+ intersected_rule->has_wmm = true;
+ } else if (rule2->has_wmm) {
+ *wmm_rule = *wmm_rule2;
+ intersected_rule->has_wmm = true;
+ } else {
+ intersected_rule->has_wmm = false;
+ }
+
if (!is_valid_reg_rule(intersected_rule))
return -EINVAL;
--
2.20.1
^ permalink raw reply related
* [PATCH 02/11] nl80211: increase NL80211_MAX_SUPP_REG_RULES
From: Luca Coelho @ 2019-03-15 15:38 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Shaul Triebitz, Luca Coelho
In-Reply-To: <20190315153907.16192-1-luca@coelho.fi>
From: Shaul Triebitz <shaul.triebitz@intel.com>
The iwlwifi driver creates one rule per channel, thus it needs more
rules than normal. To solve this, increase NL80211_MAX_SUPP_REG_RULES
so iwlwifi can also fit UHB (ultra high band) channels.
Signed-off-by: Shaul Triebitz <shaul.triebitz@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
include/uapi/linux/nl80211.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index dd4f86ee286e..f04f407b14c5 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -11,7 +11,7 @@
* Copyright 2008 Jouni Malinen <jouni.malinen@atheros.com>
* Copyright 2008 Colin McCabe <colin@cozybit.com>
* Copyright 2015-2017 Intel Deutschland GmbH
- * Copyright (C) 2018 Intel Corporation
+ * Copyright (C) 2018-2019 Intel Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -2802,7 +2802,7 @@ enum nl80211_attrs {
#define NL80211_MAX_SUPP_RATES 32
#define NL80211_MAX_SUPP_HT_RATES 77
-#define NL80211_MAX_SUPP_REG_RULES 64
+#define NL80211_MAX_SUPP_REG_RULES 128
#define NL80211_TKIP_DATA_OFFSET_ENCR_KEY 0
#define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY 16
#define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24
--
2.20.1
^ permalink raw reply related
* [PATCH 01/11] mac80211: Increase MAX_MSG_LEN
From: Luca Coelho @ 2019-03-15 15:38 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Andrei Otcheretianski, Luca Coelho
In-Reply-To: <20190315153907.16192-1-luca@coelho.fi>
From: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Looks that 100 chars isn't enough for messages, as we keep getting
warnings popping from different places due to message shortening.
Instead of trying to shorten the prints, just increase the buffer size.
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
net/mac80211/trace_msg.h | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/net/mac80211/trace_msg.h b/net/mac80211/trace_msg.h
index 366b9e6f043e..40141df09f25 100644
--- a/net/mac80211/trace_msg.h
+++ b/net/mac80211/trace_msg.h
@@ -1,4 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Portions of this file
+ * Copyright (C) 2019 Intel Corporation
+ */
+
#ifdef CONFIG_MAC80211_MESSAGE_TRACING
#if !defined(__MAC80211_MSG_DRIVER_TRACE) || defined(TRACE_HEADER_MULTI_READ)
@@ -11,7 +16,7 @@
#undef TRACE_SYSTEM
#define TRACE_SYSTEM mac80211_msg
-#define MAX_MSG_LEN 100
+#define MAX_MSG_LEN 120
DECLARE_EVENT_CLASS(mac80211_msg_event,
TP_PROTO(struct va_format *vaf),
--
2.20.1
^ permalink raw reply related
* [PATCH 05/11] mac80211_hwsim: set p2p device interface support indication
From: Luca Coelho @ 2019-03-15 15:39 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Avraham Stern, Luca Coelho
In-Reply-To: <20190315153907.16192-1-luca@coelho.fi>
From: Avraham Stern <avraham.stern@intel.com>
P2P device interface type was not indicated in the supported
interface types even when hwsim was configured with p2p device
support. Fix it.
Signed-off-by: Avraham Stern <avraham.stern@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
drivers/net/wireless/mac80211_hwsim.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 0838af04d681..d79f3ee2a741 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -3894,6 +3894,8 @@ static int __init init_mac80211_hwsim(void)
param.p2p_device = support_p2p_device;
param.use_chanctx = channels > 1;
param.iftypes = HWSIM_IFTYPE_SUPPORT_MASK;
+ if (param.p2p_device)
+ param.iftypes |= BIT(NL80211_IFTYPE_P2P_DEVICE);
err = mac80211_hwsim_new_radio(NULL, ¶m);
if (err < 0)
--
2.20.1
^ permalink raw reply related
* [PATCH 06/11] cfg80211: don't skip multi-bssid index element
From: Luca Coelho @ 2019-03-15 15:39 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Sara Sharon, Luca Coelho
In-Reply-To: <20190315153907.16192-1-luca@coelho.fi>
From: Sara Sharon <sara.sharon@intel.com>
When creating the IEs for the nontransmitted BSS, the index
element is skipped. However, we need to get DTIM values from
it, so don't skip it.
Signed-off-by: Sara Sharon <sara.sharon@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
net/wireless/scan.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 287518c6caa4..49f700a1460b 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -269,8 +269,7 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
tmp_new = sub_copy;
while (tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) {
if (!(tmp_new[0] == WLAN_EID_NON_TX_BSSID_CAP ||
- tmp_new[0] == WLAN_EID_SSID ||
- tmp_new[0] == WLAN_EID_MULTI_BSSID_IDX)) {
+ tmp_new[0] == WLAN_EID_SSID)) {
memcpy(pos, tmp_new, tmp_new[1] + 2);
pos += tmp_new[1] + 2;
}
--
2.20.1
^ permalink raw reply related
* [PATCH 07/11] cfg80211: support non-inheritance element
From: Luca Coelho @ 2019-03-15 15:39 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Sara Sharon, Luca Coelho
In-Reply-To: <20190315153907.16192-1-luca@coelho.fi>
From: Sara Sharon <sara.sharon@intel.com>
Subelement profile may specify element IDs it doesn't inherit
from the management frame. Support it.
Signed-off-by: Sara Sharon <sara.sharon@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
include/linux/ieee80211.h | 1 +
include/net/cfg80211.h | 8 +++++
net/wireless/scan.c | 61 ++++++++++++++++++++++++++++++++++++++-
3 files changed, 69 insertions(+), 1 deletion(-)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 48703ec60d06..522881f31938 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -2487,6 +2487,7 @@ enum ieee80211_eid_ext {
WLAN_EID_EXT_HE_MU_EDCA = 38,
WLAN_EID_EXT_MAX_CHANNEL_SWITCH_TIME = 52,
WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION = 55,
+ WLAN_EID_EXT_NON_INHERITANCE = 56,
};
/* Action category code */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index bb307a11ee63..cd47b7085f59 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5491,6 +5491,14 @@ static inline void cfg80211_gen_new_bssid(const u8 *bssid, u8 max_bssid,
u64_to_ether_addr(new_bssid_u64, new_bssid);
}
+/**
+ * cfg80211_is_element_inherited - returns if element ID should be inherited
+ * @element: element to check
+ * @non_inherit_element: non inheritance element
+ */
+bool cfg80211_is_element_inherited(const struct element *element,
+ const struct element *non_inherit_element);
+
/**
* enum cfg80211_bss_frame_type - frame type that the BSS data came from
* @CFG80211_BSS_FTYPE_UNKNOWN: driver doesn't know whether the data is
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 49f700a1460b..bda9114ded77 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -179,12 +179,63 @@ static bool __cfg80211_unlink_bss(struct cfg80211_registered_device *rdev,
return true;
}
+bool cfg80211_is_element_inherited(const struct element *elem,
+ const struct element *non_inherit_elem)
+{
+ u8 id_len, ext_id_len, i, loop_len, id;
+ const u8 *list;
+
+ if (elem->id == WLAN_EID_MULTIPLE_BSSID)
+ return false;
+
+ if (!non_inherit_elem || non_inherit_elem->datalen < 2)
+ return true;
+
+ /*
+ * non inheritance element format is:
+ * ext ID (56) | IDs list len | list | extension IDs list len | list
+ * Both lists are optional. Both lengths are mandatory.
+ * This means valid length is:
+ * elem_len = 1 (extension ID) + 2 (list len fields) + list lengths
+ */
+ id_len = non_inherit_elem->data[1];
+ if (non_inherit_elem->datalen < 3 + id_len)
+ return true;
+
+ ext_id_len = non_inherit_elem->data[2 + id_len];
+ if (non_inherit_elem->datalen < 3 + id_len + ext_id_len)
+ return true;
+
+ if (elem->id == WLAN_EID_EXTENSION) {
+ if (!ext_id_len)
+ return true;
+ loop_len = ext_id_len;
+ list = &non_inherit_elem->data[3 + id_len];
+ id = elem->data[0];
+ } else {
+ if (!id_len)
+ return true;
+ loop_len = id_len;
+ list = &non_inherit_elem->data[2];
+ id = elem->id;
+ }
+
+ for (i = 0; i < loop_len; i++) {
+ if (list[i] == id)
+ return false;
+ }
+
+ return true;
+}
+EXPORT_SYMBOL(cfg80211_is_element_inherited);
+
static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
const u8 *subelement, size_t subie_len,
u8 *new_ie, gfp_t gfp)
{
u8 *pos, *tmp;
const u8 *tmp_old, *tmp_new;
+ const struct element *non_inherit_elem;
u8 *sub_copy;
/* copy subelement as we need to change its content to
@@ -204,6 +255,11 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
pos += (tmp_new[1] + 2);
}
+ /* get non inheritance list if exists */
+ non_inherit_elem =
+ cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
+ sub_copy, subie_len);
+
/* go through IEs in ie (skip SSID) and subelement,
* merge them into new_ie
*/
@@ -224,8 +280,11 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
subie_len);
if (!tmp) {
+ const struct element *old_elem = (void *)tmp_old;
+
/* ie in old ie but not in subelement */
- if (tmp_old[0] != WLAN_EID_MULTIPLE_BSSID) {
+ if (cfg80211_is_element_inherited(old_elem,
+ non_inherit_elem)) {
memcpy(pos, tmp_old, tmp_old[1] + 2);
pos += tmp_old[1] + 2;
}
--
2.20.1
^ permalink raw reply related
* [PATCH 09/11] cfg80211: support profile split between elements
From: Luca Coelho @ 2019-03-15 15:39 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Sara Sharon, Luca Coelho
In-Reply-To: <20190315153907.16192-1-luca@coelho.fi>
From: Sara Sharon <sara.sharon@intel.com>
Since an element is limited to 255 octets, a profile may be split
split to several elements. Support the split as defined in the 11ax
draft 3. Detect legacy split and print a net-rate limited warning,
since there is no ROI in supporting this probably non-existent
split.
Signed-off-by: Sara Sharon <sara.sharon@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
include/net/cfg80211.h | 14 ++++++
net/wireless/scan.c | 109 ++++++++++++++++++++++++++++++++++++++---
2 files changed, 117 insertions(+), 6 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index cd47b7085f59..f192c65fe9b4 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5499,6 +5499,20 @@ static inline void cfg80211_gen_new_bssid(const u8 *bssid, u8 max_bssid,
bool cfg80211_is_element_inherited(const struct element *element,
const struct element *non_inherit_element);
+/**
+ * cfg80211_merge_profile - merges a MBSSID profile if it is split between IEs
+ * @ie: ies
+ * @ielen: length of IEs
+ * @mbssid_elem: current MBSSID element
+ * @sub_elem: current MBSSID subelement (profile)
+ * @merged_ie: location of the merged profile
+ * @max_copy_len: max merged profile length
+ */
+size_t cfg80211_merge_profile(const u8 *ie, size_t ielen,
+ const struct element *mbssid_elem,
+ const struct element *sub_elem,
+ u8 **merged_ie, size_t max_copy_len);
+
/**
* enum cfg80211_bss_frame_type - frame type that the BSS data came from
* @CFG80211_BSS_FTYPE_UNKNOWN: driver doesn't know whether the data is
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index bda9114ded77..878c867f3f7d 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -1456,6 +1456,78 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy,
return &res->pub;
}
+static const struct element
+*cfg80211_get_profile_continuation(const u8 *ie, size_t ielen,
+ const struct element *mbssid_elem,
+ const struct element *sub_elem)
+{
+ const u8 *mbssid_end = mbssid_elem->data + mbssid_elem->datalen;
+ const struct element *next_mbssid;
+ const struct element *next_sub;
+
+ next_mbssid = cfg80211_find_elem(WLAN_EID_MULTIPLE_BSSID,
+ mbssid_end,
+ ielen - (mbssid_end - ie));
+
+ /*
+ * If is is not the last subelement in current MBSSID IE or there isn't
+ * a next MBSSID IE - profile is complete.
+ */
+ if ((sub_elem->data + sub_elem->datalen < mbssid_end - 1) ||
+ !next_mbssid)
+ return NULL;
+
+ /* For any length error, just return NULL */
+
+ if (next_mbssid->datalen < 4)
+ return NULL;
+
+ next_sub = (void *)&next_mbssid->data[1];
+
+ if (next_mbssid->data + next_mbssid->datalen <
+ next_sub->data + next_sub->datalen)
+ return NULL;
+
+ if (next_sub->id != 0 || next_sub->datalen < 2)
+ return NULL;
+
+ /*
+ * Check if the first element in the next sub element is a start
+ * of a new profile
+ */
+ return next_sub->data[0] == WLAN_EID_NON_TX_BSSID_CAP ?
+ NULL : next_mbssid;
+}
+
+size_t cfg80211_merge_profile(const u8 *ie, size_t ielen,
+ const struct element *mbssid_elem,
+ const struct element *sub_elem,
+ u8 **merged_ie, size_t max_copy_len)
+{
+ size_t copied_len = sub_elem->datalen;
+ const struct element *next_mbssid;
+
+ if (sub_elem->datalen > max_copy_len)
+ return 0;
+
+ memcpy(*merged_ie, sub_elem->data, sub_elem->datalen);
+
+ while ((next_mbssid = cfg80211_get_profile_continuation(ie, ielen,
+ mbssid_elem,
+ sub_elem))) {
+ const struct element *next_sub = (void *)&next_mbssid->data[1];
+
+ if (copied_len + next_sub->datalen > max_copy_len)
+ break;
+ memcpy(*merged_ie + copied_len, next_sub->data,
+ next_sub->datalen);
+ copied_len += next_sub->datalen;
+ }
+
+ return copied_len;
+}
+EXPORT_SYMBOL(cfg80211_merge_profile);
+
static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
struct cfg80211_inform_bss *data,
enum cfg80211_bss_frame_type ftype,
@@ -1469,7 +1541,8 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
const struct element *elem, *sub;
size_t new_ie_len;
u8 new_bssid[ETH_ALEN];
- u8 *new_ie;
+ u8 *new_ie, *profile;
+ u64 seen_indices = 0;
u16 capability;
struct cfg80211_bss *bss;
@@ -1487,10 +1560,16 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
if (!new_ie)
return;
+ profile = kmalloc(ielen, gfp);
+ if (!profile)
+ goto out;
+
for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, ie, ielen) {
if (elem->datalen < 4)
continue;
for_each_element(sub, elem->data + 1, elem->datalen - 1) {
+ u8 profile_len;
+
if (sub->id != 0 || sub->datalen < 4) {
/* not a valid BSS profile */
continue;
@@ -1505,16 +1584,31 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
continue;
}
+ memset(profile, 0, ielen);
+ profile_len = cfg80211_merge_profile(ie, ielen,
+ elem,
+ sub,
+ &profile,
+ ielen);
+
/* found a Nontransmitted BSSID Profile */
mbssid_index_ie = cfg80211_find_ie
(WLAN_EID_MULTI_BSSID_IDX,
- sub->data, sub->datalen);
+ profile, profile_len);
if (!mbssid_index_ie || mbssid_index_ie[1] < 1 ||
- mbssid_index_ie[2] == 0) {
+ mbssid_index_ie[2] == 0 ||
+ mbssid_index_ie[2] > 46) {
/* No valid Multiple BSSID-Index element */
continue;
}
+ if (seen_indices & BIT(mbssid_index_ie[2]))
+ /* We don't support legacy split of a profile */
+ net_dbg_ratelimited("Partial info for BSSID index %d\n",
+ mbssid_index_ie[2]);
+
+ seen_indices |= BIT(mbssid_index_ie[2]);
+
non_tx_data->bssid_index = mbssid_index_ie[2];
non_tx_data->max_bssid_indicator = elem->data[0];
@@ -1523,13 +1617,14 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
non_tx_data->bssid_index,
new_bssid);
memset(new_ie, 0, IEEE80211_MAX_DATA_LEN);
- new_ie_len = cfg80211_gen_new_ie(ie, ielen, sub->data,
- sub->datalen, new_ie,
+ new_ie_len = cfg80211_gen_new_ie(ie, ielen,
+ profile,
+ profile_len, new_ie,
gfp);
if (!new_ie_len)
continue;
- capability = get_unaligned_le16(sub->data + 2);
+ capability = get_unaligned_le16(profile + 2);
bss = cfg80211_inform_single_bss_data(wiphy, data,
ftype,
new_bssid, tsf,
@@ -1545,7 +1640,9 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
}
}
+out:
kfree(new_ie);
+ kfree(profile);
}
struct cfg80211_bss *
--
2.20.1
^ permalink raw reply related
* [PATCH 08/11] mac80211: support non-inheritance element
From: Luca Coelho @ 2019-03-15 15:39 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Sara Sharon, Luca Coelho
In-Reply-To: <20190315153907.16192-1-luca@coelho.fi>
From: Sara Sharon <sara.sharon@intel.com>
Subelement profile may specify element IDs it doesn't inherit
from the management frame. Support it.
Signed-off-by: Sara Sharon <sara.sharon@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
net/mac80211/util.c | 134 +++++++++++++++++++++++++-------------------
1 file changed, 77 insertions(+), 57 deletions(-)
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 4c1655972565..08197afdb7b3 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -894,10 +894,10 @@ EXPORT_SYMBOL(ieee80211_queue_delayed_work);
static u32
_ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
struct ieee802_11_elems *elems,
- u64 filter, u32 crc, u8 *transmitter_bssid,
- u8 *bss_bssid)
+ u64 filter, u32 crc,
+ const struct element *check_inherit)
{
- const struct element *elem, *sub;
+ const struct element *elem;
bool calc_crc = filter != 0;
DECLARE_BITMAP(seen_elems, 256);
const u8 *ie;
@@ -910,6 +910,11 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
u8 elen = elem->datalen;
const u8 *pos = elem->data;
+ if (check_inherit &&
+ !cfg80211_is_element_inherited(elem,
+ check_inherit))
+ continue;
+
switch (id) {
case WLAN_EID_SSID:
case WLAN_EID_SUPP_RATES:
@@ -1208,57 +1213,6 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
if (elen >= sizeof(*elems->max_idle_period_ie))
elems->max_idle_period_ie = (void *)pos;
break;
- case WLAN_EID_MULTIPLE_BSSID:
- if (!bss_bssid || !transmitter_bssid || elen < 4)
- break;
-
- elems->max_bssid_indicator = pos[0];
-
- for_each_element(sub, pos + 1, elen - 1) {
- u8 sub_len = sub->datalen;
- u8 new_bssid[ETH_ALEN];
- const u8 *index;
-
- /*
- * we only expect the "non-transmitted BSSID
- * profile" subelement (subelement id 0)
- */
- if (sub->id != 0 || sub->datalen < 4) {
- /* not a valid BSS profile */
- continue;
- }
-
- if (sub->data[0] != WLAN_EID_NON_TX_BSSID_CAP ||
- sub->data[1] != 2) {
- /* The first element of the
- * Nontransmitted BSSID Profile is not
- * the Nontransmitted BSSID Capability
- * element.
- */
- continue;
- }
-
- /* found a Nontransmitted BSSID Profile */
- index = cfg80211_find_ie(WLAN_EID_MULTI_BSSID_IDX,
- sub->data, sub_len);
- if (!index || index[1] < 1 || index[2] == 0) {
- /* Invalid MBSSID Index element */
- continue;
- }
-
- cfg80211_gen_new_bssid(transmitter_bssid,
- pos[0],
- index[2],
- new_bssid);
- if (ether_addr_equal(new_bssid, bss_bssid)) {
- elems->nontransmitted_bssid_profile =
- (void *)sub;
- elems->bssid_index_len = index[1];
- elems->bssid_index = (void *)&index[2];
- break;
- }
- }
- break;
case WLAN_EID_EXTENSION:
if (pos[0] == WLAN_EID_EXT_HE_MU_EDCA &&
elen >= (sizeof(*elems->mu_edca_param_set) + 1)) {
@@ -1300,25 +1254,91 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
return crc;
}
+static void ieee802_11_find_bssid_profile(const u8 *start, size_t len,
+ struct ieee802_11_elems *elems,
+ u8 *transmitter_bssid,
+ u8 *bss_bssid)
+{
+ const struct element *elem, *sub;
+
+ if (!bss_bssid || !transmitter_bssid)
+ return;
+
+ for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, start, len) {
+ if (elem->datalen < 2)
+ continue;
+
+ for_each_element(sub, elem->data + 1, elem->datalen - 1) {
+ u8 new_bssid[ETH_ALEN];
+ const u8 *index;
+
+ if (sub->id != 0 || sub->datalen < 4) {
+ /* not a valid BSS profile */
+ continue;
+ }
+
+ if (sub->data[0] != WLAN_EID_NON_TX_BSSID_CAP ||
+ sub->data[1] != 2) {
+ /* The first element of the
+ * Nontransmitted BSSID Profile is not
+ * the Nontransmitted BSSID Capability
+ * element.
+ */
+ continue;
+ }
+
+ /* found a Nontransmitted BSSID Profile */
+ index = cfg80211_find_ie(WLAN_EID_MULTI_BSSID_IDX,
+ sub->data, sub->datalen);
+ if (!index || index[1] < 1 || index[2] == 0) {
+ /* Invalid MBSSID Index element */
+ continue;
+ }
+
+ cfg80211_gen_new_bssid(transmitter_bssid,
+ elem->data[0],
+ index[2],
+ new_bssid);
+ if (ether_addr_equal(new_bssid, bss_bssid)) {
+ elems->nontransmitted_bssid_profile =
+ elem->data;
+ elems->bssid_index_len = index[1];
+ elems->bssid_index = (void *)&index[2];
+ break;
+ }
+ }
+ }
+}
+
u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
struct ieee802_11_elems *elems,
u64 filter, u32 crc, u8 *transmitter_bssid,
u8 *bss_bssid)
{
+ const struct element *non_inherit = NULL;
+
memset(elems, 0, sizeof(*elems));
elems->ie_start = start;
elems->total_len = len;
+ ieee802_11_find_bssid_profile(start, len, elems, transmitter_bssid,
+ bss_bssid);
+
+ if (elems->nontransmitted_bssid_profile)
+ non_inherit =
+ cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
+ &elems->nontransmitted_bssid_profile[2],
+ elems->nontransmitted_bssid_profile[1]);
+
crc = _ieee802_11_parse_elems_crc(start, len, action, elems, filter,
- crc, transmitter_bssid, bss_bssid);
+ crc, non_inherit);
/* Override with nontransmitted profile, if found */
if (transmitter_bssid && elems->nontransmitted_bssid_profile) {
const u8 *profile = elems->nontransmitted_bssid_profile;
_ieee802_11_parse_elems_crc(&profile[2], profile[1],
- action, elems, 0, 0,
- transmitter_bssid, bss_bssid);
+ action, elems, 0, 0, NULL);
}
if (elems->tim && !elems->parse_error) {
--
2.20.1
^ permalink raw reply related
* [PATCH 10/11] mac80211: support profile split between elements
From: Luca Coelho @ 2019-03-15 15:39 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Sara Sharon, Luca Coelho
In-Reply-To: <20190315153907.16192-1-luca@coelho.fi>
From: Sara Sharon <sara.sharon@intel.com>
Since an element is limited to 255 octets, a profile may be split
split to several elements. Support the split as defined in the 11ax
draft 3.
Signed-off-by: Sara Sharon <sara.sharon@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
net/mac80211/ieee80211_i.h | 1 -
net/mac80211/util.c | 56 +++++++++++++++++++++++++-------------
2 files changed, 37 insertions(+), 20 deletions(-)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index e170f986d226..c5708f8a7401 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1505,7 +1505,6 @@ struct ieee802_11_elems {
const struct ieee80211_bss_max_idle_period_ie *max_idle_period_ie;
const struct ieee80211_multiple_bssid_configuration *mbssid_config_ie;
const struct ieee80211_bssid_index *bssid_index;
- const u8 *nontransmitted_bssid_profile;
u8 max_bssid_indicator;
u8 dtim_count;
u8 dtim_period;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 08197afdb7b3..99dd58454592 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1254,15 +1254,18 @@ _ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
return crc;
}
-static void ieee802_11_find_bssid_profile(const u8 *start, size_t len,
- struct ieee802_11_elems *elems,
- u8 *transmitter_bssid,
- u8 *bss_bssid)
+static size_t ieee802_11_find_bssid_profile(const u8 *start, size_t len,
+ struct ieee802_11_elems *elems,
+ u8 *transmitter_bssid,
+ u8 *bss_bssid,
+ u8 **nontransmitted_profile)
{
const struct element *elem, *sub;
+ size_t profile_len = 0;
+ bool found = false;
if (!bss_bssid || !transmitter_bssid)
- return;
+ return profile_len;
for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, start, len) {
if (elem->datalen < 2)
@@ -1287,9 +1290,17 @@ static void ieee802_11_find_bssid_profile(const u8 *start, size_t len,
continue;
}
+ memset(*nontransmitted_profile, 0, len);
+ profile_len = cfg80211_merge_profile(start, len,
+ elem,
+ sub,
+ nontransmitted_profile,
+ len);
+
/* found a Nontransmitted BSSID Profile */
index = cfg80211_find_ie(WLAN_EID_MULTI_BSSID_IDX,
- sub->data, sub->datalen);
+ *nontransmitted_profile,
+ profile_len);
if (!index || index[1] < 1 || index[2] == 0) {
/* Invalid MBSSID Index element */
continue;
@@ -1300,14 +1311,15 @@ static void ieee802_11_find_bssid_profile(const u8 *start, size_t len,
index[2],
new_bssid);
if (ether_addr_equal(new_bssid, bss_bssid)) {
- elems->nontransmitted_bssid_profile =
- elem->data;
+ found = true;
elems->bssid_index_len = index[1];
elems->bssid_index = (void *)&index[2];
break;
}
}
}
+
+ return found ? profile_len : 0;
}
u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
@@ -1316,30 +1328,34 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
u8 *bss_bssid)
{
const struct element *non_inherit = NULL;
+ u8 *nontransmitted_profile;
+ int nontransmitted_profile_len = 0;
memset(elems, 0, sizeof(*elems));
elems->ie_start = start;
elems->total_len = len;
- ieee802_11_find_bssid_profile(start, len, elems, transmitter_bssid,
- bss_bssid);
-
- if (elems->nontransmitted_bssid_profile)
+ nontransmitted_profile = kmalloc(len, GFP_ATOMIC);
+ if (nontransmitted_profile) {
+ nontransmitted_profile_len =
+ ieee802_11_find_bssid_profile(start, len, elems,
+ transmitter_bssid,
+ bss_bssid,
+ &nontransmitted_profile);
non_inherit =
cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
- &elems->nontransmitted_bssid_profile[2],
- elems->nontransmitted_bssid_profile[1]);
+ nontransmitted_profile,
+ nontransmitted_profile_len);
+ }
crc = _ieee802_11_parse_elems_crc(start, len, action, elems, filter,
crc, non_inherit);
/* Override with nontransmitted profile, if found */
- if (transmitter_bssid && elems->nontransmitted_bssid_profile) {
- const u8 *profile = elems->nontransmitted_bssid_profile;
-
- _ieee802_11_parse_elems_crc(&profile[2], profile[1],
+ if (nontransmitted_profile_len)
+ _ieee802_11_parse_elems_crc(nontransmitted_profile,
+ nontransmitted_profile_len,
action, elems, 0, 0, NULL);
- }
if (elems->tim && !elems->parse_error) {
const struct ieee80211_tim_ie *tim_ie = elems->tim;
@@ -1359,6 +1375,8 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
offsetofend(struct ieee80211_bssid_index, dtim_count))
elems->dtim_count = elems->bssid_index->dtim_count;
+ kfree(nontransmitted_profile);
+
return crc;
}
--
2.20.1
^ permalink raw reply related
* [PATCH 11/11] ieee80211: update HE IEs to D4.0 spec
From: Luca Coelho @ 2019-03-15 15:39 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Liad Kaufman, Luca Coelho
In-Reply-To: <20190315153907.16192-1-luca@coelho.fi>
From: Liad Kaufman <liad.kaufman@intel.com>
Update the out-dated comments as well, and have them point to
the correct sections in the D4.0 spec.
Signed-off-by: Liad Kaufman <liad.kaufman@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
include/linux/ieee80211.h | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 522881f31938..61f0a316c6ac 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1557,7 +1557,7 @@ struct ieee80211_vht_operation {
* struct ieee80211_he_cap_elem - HE capabilities element
*
* This structure is the "HE capabilities element" fixed fields as
- * described in P802.11ax_D3.0 section 9.4.2.237.2 and 9.4.2.237.3
+ * described in P802.11ax_D4.0 section 9.4.2.242.2 and 9.4.2.242.3
*/
struct ieee80211_he_cap_elem {
u8 mac_cap_info[6];
@@ -1619,12 +1619,12 @@ struct ieee80211_he_mcs_nss_supp {
* struct ieee80211_he_operation - HE capabilities element
*
* This structure is the "HE operation element" fields as
- * described in P802.11ax_D3.0 section 9.4.2.238
+ * described in P802.11ax_D4.0 section 9.4.2.243
*/
struct ieee80211_he_operation {
__le32 he_oper_params;
__le16 he_mcs_nss_set;
- /* Optional 0,1,3 or 4 bytes: depends on @he_oper_params */
+ /* Optional 0,1,3,4,5,7 or 8 bytes: depends on @he_oper_params */
u8 optional[0];
} __packed;
@@ -1632,7 +1632,7 @@ struct ieee80211_he_operation {
* struct ieee80211_he_mu_edca_param_ac_rec - MU AC Parameter Record field
*
* This structure is the "MU AC Parameter Record" fields as
- * described in P802.11ax_D2.0 section 9.4.2.240
+ * described in P802.11ax_D4.0 section 9.4.2.245
*/
struct ieee80211_he_mu_edca_param_ac_rec {
u8 aifsn;
@@ -1644,7 +1644,7 @@ struct ieee80211_he_mu_edca_param_ac_rec {
* struct ieee80211_mu_edca_param_set - MU EDCA Parameter Set element
*
* This structure is the "MU EDCA Parameter Set element" fields as
- * described in P802.11ax_D2.0 section 9.4.2.240
+ * described in P802.11ax_D4.0 section 9.4.2.245
*/
struct ieee80211_mu_edca_param_set {
u8 mu_qos_info;
@@ -2026,6 +2026,7 @@ ieee80211_he_ppe_size(u8 ppe_thres_hdr, const u8 *phy_cap_info)
#define IEEE80211_HE_OPERATION_VHT_OPER_INFO 0x00004000
#define IEEE80211_HE_OPERATION_CO_HOSTED_BSS 0x00008000
#define IEEE80211_HE_OPERATION_ER_SU_DISABLE 0x00010000
+#define IEEE80211_HE_OPERATION_6GHZ_OP_INFO 0x00020000
#define IEEE80211_HE_OPERATION_BSS_COLOR_MASK 0x3f000000
#define IEEE80211_HE_OPERATION_BSS_COLOR_OFFSET 24
#define IEEE80211_HE_OPERATION_PARTIAL_BSS_COLOR 0x40000000
@@ -2056,6 +2057,8 @@ ieee80211_he_oper_size(const u8 *he_oper_ie)
oper_len += 3;
if (he_oper_params & IEEE80211_HE_OPERATION_CO_HOSTED_BSS)
oper_len++;
+ if (he_oper_params & IEEE80211_HE_OPERATION_6GHZ_OP_INFO)
+ oper_len += 4;
/* Add the first byte (extension ID) to the total length */
oper_len++;
--
2.20.1
^ permalink raw reply related
* [PATCH 00/16] iwlwifi: updates intended for v5.1 2019-03-15
From: Luca Coelho @ 2019-03-15 16:36 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless, Luca Coelho
From: Luca Coelho <luciano.coelho@intel.com>
Hi,
Here's the second set of patches intended for v5.2. It's the usual
development, new features, cleanups and bugfixes.
The changes are:
* Continued work and bugfixes for the new debugging infra;
* Support for some new FW API versions;
* Some work to support new hardware;
* General bugfixes;
* Other cleanups;
As usual, I'm pushing this to a pending branch, for kbuild bot, and
will send a pull-request later.
Please review.
Cheers,
Luca.
Ilan Peer (1):
iwlwifi: mvm: Support new format of SCAN_OFFLOAD_PROFILES_QUERY_RSP
Johannes Berg (2):
iwlwifi: mvm: enable HT/VHT IBSS
iwlwifi: pcie: switch to correct RBD/CD layout for 22560
Luca Coelho (2):
mac80211_hwsim: make copying of ciphers safer by checking the length
iwlwifi: remove unnecessary goto out in iwl_parse_nvm_mcc_info()
Mordechay Goodstein (1):
iwlwifi: mvm: set max amsdu for TLC offload
Shahar S Matityahu (5):
iwlwifi: dbg: use dump mask for tx command dumping length
iwlwifi: mvm: use dump worker during restart instead of sync dump
iwlwifi: dbg: add DRAM monitor support for AX210 device family
iwlwifi: dbg_ini: separate between ini and legacy dump flows
iwlwifi: dbg_ini: align to FW api version 1
Shaul Triebitz (4):
iwlwifi: mvm: be more forgiving if num of channels is too big
iwlwifi: add support for 6-7 GHz channels
iwlwifi: support new NVM response API
iwlwifi: for AX210 device support radio GF4
YueHaibing (1):
iwlwifi: Use struct_size() in kzalloc
.../net/wireless/intel/iwlwifi/cfg/22000.c | 9 +
.../wireless/intel/iwlwifi/fw/api/dbg-tlv.h | 177 ++++++++++------
.../wireless/intel/iwlwifi/fw/api/nvm-reg.h | 39 +++-
.../net/wireless/intel/iwlwifi/fw/api/rx.h | 67 +------
.../net/wireless/intel/iwlwifi/fw/api/scan.h | 54 ++++-
drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 189 ++++++++++--------
drivers/net/wireless/intel/iwlwifi/fw/dbg.h | 17 +-
.../wireless/intel/iwlwifi/fw/error-dump.h | 6 +-
drivers/net/wireless/intel/iwlwifi/fw/file.h | 7 +
.../net/wireless/intel/iwlwifi/fw/runtime.h | 1 +
.../net/wireless/intel/iwlwifi/iwl-config.h | 5 +-
drivers/net/wireless/intel/iwlwifi/iwl-csr.h | 5 +-
.../net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | 10 +-
.../wireless/intel/iwlwifi/iwl-nvm-parse.c | 139 +++++++------
drivers/net/wireless/intel/iwlwifi/iwl-prph.h | 6 +
.../net/wireless/intel/iwlwifi/iwl-trans.h | 1 -
drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 90 +++++++--
.../net/wireless/intel/iwlwifi/mvm/debugfs.c | 2 +-
.../net/wireless/intel/iwlwifi/mvm/mac80211.c | 12 +-
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h | 13 --
drivers/net/wireless/intel/iwlwifi/mvm/ops.c | 2 +
.../net/wireless/intel/iwlwifi/mvm/rs-fw.c | 44 +++-
drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 25 ++-
.../wireless/intel/iwlwifi/pcie/internal.h | 30 +--
drivers/net/wireless/intel/iwlwifi/pcie/rx.c | 13 +-
.../net/wireless/intel/iwlwifi/pcie/trans.c | 38 +++-
drivers/net/wireless/mac80211_hwsim.c | 12 +-
27 files changed, 628 insertions(+), 385 deletions(-)
--
2.20.1
^ permalink raw reply
* [PATCH 01/16] iwlwifi: mvm: enable HT/VHT IBSS
From: Luca Coelho @ 2019-03-15 16:36 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless, Johannes Berg, Luca Coelho
In-Reply-To: <20190315163634.17315-1-luca@coelho.fi>
From: Johannes Berg <johannes.berg@intel.com>
For some reason we never enabled it, but it appears to work fine.
Enable it now.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index fd989c43df2a..dc4bff74c89c 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -598,6 +598,9 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
BIT(NL80211_IFTYPE_ADHOC);
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
+ wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
+ hw->wiphy->features |= NL80211_FEATURE_HT_IBSS;
+
hw->wiphy->regulatory_flags |= REGULATORY_ENABLE_RELAX_NO_IR;
if (iwl_mvm_is_lar_supported(mvm))
hw->wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED;
--
2.20.1
^ permalink raw reply related
* [PATCH 02/16] iwlwifi: mvm: be more forgiving if num of channels is too big
From: Luca Coelho @ 2019-03-15 16:36 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless, Shaul Triebitz, Luca Coelho
In-Reply-To: <20190315163634.17315-1-luca@coelho.fi>
From: Shaul Triebitz <shaul.triebitz@intel.com>
If number of channels in the driver is greater than
number of scan channels given by firmware TLV, do not
fail scan config, but adjust to firmware's number of channels.
This is helpful for supporting in driver new channels before
it being supported by firmware scan.
Signed-off-by: Shaul Triebitz <shaul.triebitz@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
drivers/net/wireless/intel/iwlwifi/mvm/scan.c | 25 +++++++++++--------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
index 78694bc38e76..d9ddf9ff6428 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
@@ -1082,21 +1082,23 @@ static void iwl_mvm_fill_scan_dwell(struct iwl_mvm *mvm,
dwell->extended = IWL_SCAN_DWELL_EXTENDED;
}
-static void iwl_mvm_fill_channels(struct iwl_mvm *mvm, u8 *channels)
+static void iwl_mvm_fill_channels(struct iwl_mvm *mvm, u8 *channels,
+ u32 max_channels)
{
struct ieee80211_supported_band *band;
int i, j = 0;
band = &mvm->nvm_data->bands[NL80211_BAND_2GHZ];
- for (i = 0; i < band->n_channels; i++, j++)
+ for (i = 0; i < band->n_channels && j < max_channels; i++, j++)
channels[j] = band->channels[i].hw_value;
band = &mvm->nvm_data->bands[NL80211_BAND_5GHZ];
- for (i = 0; i < band->n_channels; i++, j++)
+ for (i = 0; i < band->n_channels && j < max_channels; i++, j++)
channels[j] = band->channels[i].hw_value;
}
static void iwl_mvm_fill_scan_config_v1(struct iwl_mvm *mvm, void *config,
- u32 flags, u8 channel_flags)
+ u32 flags, u8 channel_flags,
+ u32 max_channels)
{
enum iwl_mvm_scan_type type = iwl_mvm_get_scan_type(mvm, NULL);
struct iwl_scan_config_v1 *cfg = config;
@@ -1115,11 +1117,12 @@ static void iwl_mvm_fill_scan_config_v1(struct iwl_mvm *mvm, void *config,
cfg->bcast_sta_id = mvm->aux_sta.sta_id;
cfg->channel_flags = channel_flags;
- iwl_mvm_fill_channels(mvm, cfg->channel_array);
+ iwl_mvm_fill_channels(mvm, cfg->channel_array, max_channels);
}
static void iwl_mvm_fill_scan_config(struct iwl_mvm *mvm, void *config,
- u32 flags, u8 channel_flags)
+ u32 flags, u8 channel_flags,
+ u32 max_channels)
{
struct iwl_scan_config *cfg = config;
@@ -1162,7 +1165,7 @@ static void iwl_mvm_fill_scan_config(struct iwl_mvm *mvm, void *config,
cfg->bcast_sta_id = mvm->aux_sta.sta_id;
cfg->channel_flags = channel_flags;
- iwl_mvm_fill_channels(mvm, cfg->channel_array);
+ iwl_mvm_fill_channels(mvm, cfg->channel_array, max_channels);
}
int iwl_mvm_config_scan(struct iwl_mvm *mvm)
@@ -1181,7 +1184,7 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm)
u8 channel_flags;
if (WARN_ON(num_channels > mvm->fw->ucode_capa.n_scan_channels))
- return -ENOBUFS;
+ num_channels = mvm->fw->ucode_capa.n_scan_channels;
if (iwl_mvm_is_cdb_supported(mvm)) {
type = iwl_mvm_get_scan_type_band(mvm, NULL,
@@ -1234,9 +1237,11 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm)
flags |= (iwl_mvm_is_scan_fragmented(hb_type)) ?
SCAN_CONFIG_FLAG_SET_LMAC2_FRAGMENTED :
SCAN_CONFIG_FLAG_CLEAR_LMAC2_FRAGMENTED;
- iwl_mvm_fill_scan_config(mvm, cfg, flags, channel_flags);
+ iwl_mvm_fill_scan_config(mvm, cfg, flags, channel_flags,
+ num_channels);
} else {
- iwl_mvm_fill_scan_config_v1(mvm, cfg, flags, channel_flags);
+ iwl_mvm_fill_scan_config_v1(mvm, cfg, flags, channel_flags,
+ num_channels);
}
cmd.data[0] = cfg;
--
2.20.1
^ permalink raw reply related
* [PATCH 03/16] iwlwifi: add support for 6-7 GHz channels
From: Luca Coelho @ 2019-03-15 16:36 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless, Shaul Triebitz, Luca Coelho
In-Reply-To: <20190315163634.17315-1-luca@coelho.fi>
From: Shaul Triebitz <shaul.triebitz@intel.com>
Add UHB (ultra high band) channels and use 16 bit variables
to fit the new channels.
Signed-off-by: Shaul Triebitz <shaul.triebitz@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
.../net/wireless/intel/iwlwifi/cfg/22000.c | 2 +
.../net/wireless/intel/iwlwifi/iwl-config.h | 4 +-
.../wireless/intel/iwlwifi/iwl-nvm-parse.c | 74 +++++++++++--------
3 files changed, 49 insertions(+), 31 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
index fdc56f821b5a..dd781232c8a8 100644
--- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
+++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c
@@ -427,12 +427,14 @@ const struct iwl_cfg iwlax210_2ax_cfg_so_hr_a0 = {
const struct iwl_cfg iwlax210_2ax_cfg_so_gf_a0 = {
.name = "Intel(R) Wi-Fi 7 AX211 160MHz",
.fw_name_pre = IWL_22000_SO_A_GF_A_FW_PRE,
+ .uhb_supported = true,
IWL_DEVICE_AX210,
};
const struct iwl_cfg iwlax210_2ax_cfg_ty_gf_a0 = {
.name = "Intel(R) Wi-Fi 7 AX210 160MHz",
.fw_name_pre = IWL_22000_TY_A_GF_A_FW_PRE,
+ .uhb_supported = true,
IWL_DEVICE_AX210,
};
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-config.h b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
index f5f87773667b..a68481d16f1f 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-config.h
@@ -383,6 +383,7 @@ struct iwl_csr_params {
* @bisr_workaround: BISR hardware workaround (for 22260 series devices)
* @min_txq_size: minimum number of slots required in a TX queue
* @umac_prph_offset: offset to add to UMAC periphery address
+ * @uhb_supported: ultra high band channels supported
*
* We enable the driver to be backward compatible wrt. hardware features.
* API differences in uCode shouldn't be handled here but through TLVs
@@ -433,7 +434,8 @@ struct iwl_cfg {
gen2:1,
cdb:1,
dbgc_supported:1,
- bisr_workaround:1;
+ bisr_workaround:1,
+ uhb_supported:1;
u8 valid_tx_ant;
u8 valid_rx_ant;
u8 non_shared_ant;
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index 87d6de7efdd2..a20ac68f4ba3 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -130,7 +130,7 @@ enum nvm_sku_bits {
/*
* These are the channel numbers in the order that they are stored in the NVM
*/
-static const u8 iwl_nvm_channels[] = {
+static const u16 iwl_nvm_channels[] = {
/* 2.4 GHz */
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
/* 5 GHz */
@@ -139,7 +139,7 @@ static const u8 iwl_nvm_channels[] = {
149, 153, 157, 161, 165
};
-static const u8 iwl_ext_nvm_channels[] = {
+static const u16 iwl_ext_nvm_channels[] = {
/* 2.4 GHz */
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
/* 5 GHz */
@@ -148,14 +148,27 @@ static const u8 iwl_ext_nvm_channels[] = {
149, 153, 157, 161, 165, 169, 173, 177, 181
};
+static const u16 iwl_uhb_nvm_channels[] = {
+ /* 2.4 GHz */
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ /* 5 GHz */
+ 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92,
+ 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
+ 149, 153, 157, 161, 165, 169, 173, 177, 181,
+ /* 6-7 GHz */
+ 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, 233, 237, 241,
+ 245, 249, 253, 257, 261, 265, 269, 273, 277, 281, 285, 289, 293, 297,
+ 301, 305, 309, 313, 317, 321, 325, 329, 333, 337, 341, 345, 349, 353,
+ 357, 361, 365, 369, 373, 377, 381, 385, 389, 393, 397, 401, 405, 409,
+ 413, 417, 421
+};
+
#define IWL_NVM_NUM_CHANNELS ARRAY_SIZE(iwl_nvm_channels)
#define IWL_NVM_NUM_CHANNELS_EXT ARRAY_SIZE(iwl_ext_nvm_channels)
+#define IWL_NVM_NUM_CHANNELS_UHB ARRAY_SIZE(iwl_uhb_nvm_channels)
#define NUM_2GHZ_CHANNELS 14
-#define NUM_2GHZ_CHANNELS_EXT 14
#define FIRST_2GHZ_HT_MINUS 5
#define LAST_2GHZ_HT_PLUS 9
-#define LAST_5GHZ_HT 165
-#define LAST_5GHZ_HT_FAMILY_8000 181
#define N_HW_ADDR_MASK 0xF
/* rate data (static) */
@@ -247,17 +260,13 @@ static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz,
u16 nvm_flags, const struct iwl_cfg *cfg)
{
u32 flags = IEEE80211_CHAN_NO_HT40;
- u32 last_5ghz_ht = LAST_5GHZ_HT;
-
- if (cfg->nvm_type == IWL_NVM_EXT)
- last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000;
if (!is_5ghz && (nvm_flags & NVM_CHANNEL_40MHZ)) {
if (ch_num <= LAST_2GHZ_HT_PLUS)
flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
if (ch_num >= FIRST_2GHZ_HT_MINUS)
flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
- } else if (ch_num <= last_5ghz_ht && (nvm_flags & NVM_CHANNEL_40MHZ)) {
+ } else if (nvm_flags & NVM_CHANNEL_40MHZ) {
if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
else
@@ -299,17 +308,18 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
int n_channels = 0;
struct ieee80211_channel *channel;
u16 ch_flags;
- int num_of_ch, num_2ghz_channels;
- const u8 *nvm_chan;
+ int num_of_ch, num_2ghz_channels = NUM_2GHZ_CHANNELS;
+ const u16 *nvm_chan;
- if (cfg->nvm_type != IWL_NVM_EXT) {
- num_of_ch = IWL_NVM_NUM_CHANNELS;
- nvm_chan = &iwl_nvm_channels[0];
- num_2ghz_channels = NUM_2GHZ_CHANNELS;
- } else {
+ if (cfg->uhb_supported) {
+ num_of_ch = IWL_NVM_NUM_CHANNELS_UHB;
+ nvm_chan = iwl_uhb_nvm_channels;
+ } else if (cfg->nvm_type == IWL_NVM_EXT) {
num_of_ch = IWL_NVM_NUM_CHANNELS_EXT;
- nvm_chan = &iwl_ext_nvm_channels[0];
- num_2ghz_channels = NUM_2GHZ_CHANNELS_EXT;
+ nvm_chan = iwl_ext_nvm_channels;
+ } else {
+ num_of_ch = IWL_NVM_NUM_CHANNELS;
+ nvm_chan = iwl_nvm_channels;
}
for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
@@ -1013,15 +1023,11 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
}
IWL_EXPORT_SYMBOL(iwl_parse_nvm_data);
-static u32 iwl_nvm_get_regdom_bw_flags(const u8 *nvm_chan,
+static u32 iwl_nvm_get_regdom_bw_flags(const u16 *nvm_chan,
int ch_idx, u16 nvm_flags,
const struct iwl_cfg *cfg)
{
u32 flags = NL80211_RRF_NO_HT40;
- u32 last_5ghz_ht = LAST_5GHZ_HT;
-
- if (cfg->nvm_type == IWL_NVM_EXT)
- last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000;
if (ch_idx < NUM_2GHZ_CHANNELS &&
(nvm_flags & NVM_CHANNEL_40MHZ)) {
@@ -1029,8 +1035,7 @@ static u32 iwl_nvm_get_regdom_bw_flags(const u8 *nvm_chan,
flags &= ~NL80211_RRF_NO_HT40PLUS;
if (nvm_chan[ch_idx] >= FIRST_2GHZ_HT_MINUS)
flags &= ~NL80211_RRF_NO_HT40MINUS;
- } else if (nvm_chan[ch_idx] <= last_5ghz_ht &&
- (nvm_flags & NVM_CHANNEL_40MHZ)) {
+ } else if (nvm_flags & NVM_CHANNEL_40MHZ) {
if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
flags &= ~NL80211_RRF_NO_HT40PLUS;
else
@@ -1074,8 +1079,7 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
int ch_idx;
u16 ch_flags;
u32 reg_rule_flags, prev_reg_rule_flags = 0;
- const u8 *nvm_chan = cfg->nvm_type == IWL_NVM_EXT ?
- iwl_ext_nvm_channels : iwl_nvm_channels;
+ const u16 *nvm_chan;
struct ieee80211_regdomain *regd, *copy_rd;
int size_of_regd, regd_to_copy;
struct ieee80211_reg_rule *rule;
@@ -1084,8 +1088,18 @@ iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
int center_freq, prev_center_freq = 0;
int valid_rules = 0;
bool new_rule;
- int max_num_ch = cfg->nvm_type == IWL_NVM_EXT ?
- IWL_NVM_NUM_CHANNELS_EXT : IWL_NVM_NUM_CHANNELS;
+ int max_num_ch;
+
+ if (cfg->uhb_supported) {
+ max_num_ch = IWL_NVM_NUM_CHANNELS_UHB;
+ nvm_chan = iwl_uhb_nvm_channels;
+ } else if (cfg->nvm_type == IWL_NVM_EXT) {
+ max_num_ch = IWL_NVM_NUM_CHANNELS_EXT;
+ nvm_chan = iwl_ext_nvm_channels;
+ } else {
+ max_num_ch = IWL_NVM_NUM_CHANNELS;
+ nvm_chan = iwl_nvm_channels;
+ }
if (WARN_ON(num_of_ch > max_num_ch))
num_of_ch = max_num_ch;
--
2.20.1
^ permalink raw reply related
* [PATCH 04/16] iwlwifi: support new NVM response API
From: Luca Coelho @ 2019-03-15 16:36 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless, Shaul Triebitz, Luca Coelho
In-Reply-To: <20190315163634.17315-1-luca@coelho.fi>
From: Shaul Triebitz <shaul.triebitz@intel.com>
Support REGULATORY_NVM_GET_INFO_RSP_API_S_VER_4.
This API adds the new 6-7GHz channels.
Signed-off-by: Shaul Triebitz <shaul.triebitz@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
.../wireless/intel/iwlwifi/fw/api/nvm-reg.h | 39 +++++++++++++---
drivers/net/wireless/intel/iwlwifi/fw/file.h | 3 ++
.../wireless/intel/iwlwifi/iwl-nvm-parse.c | 46 +++++++++++++------
3 files changed, 69 insertions(+), 19 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
index 93b392f0c6a4..97b49843e318 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
@@ -8,7 +8,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
- * Copyright (C) 2018 Intel Corporation
+ * Copyright(C) 2018 - 2019 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
* Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
* Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
* Copyright(c) 2016 - 2017 Intel Deutschland GmbH
- * Copyright (C) 2018 Intel Corporation
+ * Copyright(C) 2018 - 2019 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -233,7 +233,8 @@ struct iwl_nvm_get_info_phy {
__le32 rx_chains;
} __packed; /* REGULATORY_NVM_GET_INFO_PHY_SKU_SECTION_S_VER_1 */
-#define IWL_NUM_CHANNELS (51)
+#define IWL_NUM_CHANNELS_V1 51
+#define IWL_NUM_CHANNELS 110
/**
* struct iwl_nvm_get_info_regulatory - regulatory information
@@ -241,12 +242,38 @@ struct iwl_nvm_get_info_phy {
* @channel_profile: regulatory data of this channel
* @reserved: reserved
*/
-struct iwl_nvm_get_info_regulatory {
+struct iwl_nvm_get_info_regulatory_v1 {
__le32 lar_enabled;
- __le16 channel_profile[IWL_NUM_CHANNELS];
+ __le16 channel_profile[IWL_NUM_CHANNELS_V1];
__le16 reserved;
} __packed; /* REGULATORY_NVM_GET_INFO_REGULATORY_S_VER_1 */
+/**
+ * struct iwl_nvm_get_info_regulatory - regulatory information
+ * @lar_enabled: is LAR enabled
+ * @n_channels: number of valid channels in the array
+ * @channel_profile: regulatory data of this channel
+ */
+struct iwl_nvm_get_info_regulatory {
+ __le32 lar_enabled;
+ __le32 n_channels;
+ __le32 channel_profile[IWL_NUM_CHANNELS];
+} __packed; /* REGULATORY_NVM_GET_INFO_REGULATORY_S_VER_2 */
+
+/**
+ * struct iwl_nvm_get_info_rsp_v3 - response to get NVM data
+ * @general: general NVM data
+ * @mac_sku: data relating to MAC sku
+ * @phy_sku: data relating to PHY sku
+ * @regulatory: regulatory data
+ */
+struct iwl_nvm_get_info_rsp_v3 {
+ struct iwl_nvm_get_info_general general;
+ struct iwl_nvm_get_info_sku mac_sku;
+ struct iwl_nvm_get_info_phy phy_sku;
+ struct iwl_nvm_get_info_regulatory_v1 regulatory;
+} __packed; /* REGULATORY_NVM_GET_INFO_RSP_API_S_VER_3 */
+
/**
* struct iwl_nvm_get_info_rsp - response to get NVM data
* @general: general NVM data
@@ -259,7 +286,7 @@ struct iwl_nvm_get_info_rsp {
struct iwl_nvm_get_info_sku mac_sku;
struct iwl_nvm_get_info_phy phy_sku;
struct iwl_nvm_get_info_regulatory regulatory;
-} __packed; /* REGULATORY_NVM_GET_INFO_RSP_API_S_VER_3 */
+} __packed; /* REGULATORY_NVM_GET_INFO_RSP_API_S_VER_4 */
/**
* struct iwl_nvm_access_complete_cmd - NVM_ACCESS commands are completed
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h
index 04ad6b96a28b..3f26dee1b29c 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
@@ -272,6 +272,8 @@ typedef unsigned int __bitwise iwl_ucode_tlv_api_t;
* version of the beacon notification.
* @IWL_UCODE_TLV_API_BEACON_FILTER_V4: This ucode supports v4 of
* BEACON_FILTER_CONFIG_API_S_VER_4.
+ * @IWL_UCODE_TLV_API_REGULATORY_NVM_INFO: This ucode supports v4 of
+ * REGULATORY_NVM_GET_INFO_RSP_API_S.
* @IWL_UCODE_TLV_API_FTM_NEW_RANGE_REQ: This ucode supports v7 of
* LOCATION_RANGE_REQ_CMD_API_S and v6 of LOCATION_RANGE_RESP_NTFY_API_S.
*
@@ -300,6 +302,7 @@ enum iwl_ucode_tlv_api {
IWL_UCODE_TLV_API_REDUCE_TX_POWER = (__force iwl_ucode_tlv_api_t)45,
IWL_UCODE_TLV_API_SHORT_BEACON_NOTIF = (__force iwl_ucode_tlv_api_t)46,
IWL_UCODE_TLV_API_BEACON_FILTER_V4 = (__force iwl_ucode_tlv_api_t)47,
+ IWL_UCODE_TLV_API_REGULATORY_NVM_INFO = (__force iwl_ucode_tlv_api_t)48,
IWL_UCODE_TLV_API_FTM_NEW_RANGE_REQ = (__force iwl_ucode_tlv_api_t)49,
NUM_IWL_UCODE_TLV_API
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
index a20ac68f4ba3..1408c89242a7 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
@@ -226,7 +226,7 @@ enum iwl_nvm_channel_flags {
};
static inline void iwl_nvm_print_channel_flags(struct device *dev, u32 level,
- int chan, u16 flags)
+ int chan, u32 flags)
{
#define CHECK_AND_PRINT_I(x) \
((flags & NVM_CHANNEL_##x) ? " " #x : "")
@@ -257,7 +257,7 @@ static inline void iwl_nvm_print_channel_flags(struct device *dev, u32 level,
}
static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz,
- u16 nvm_flags, const struct iwl_cfg *cfg)
+ u32 nvm_flags, const struct iwl_cfg *cfg)
{
u32 flags = IEEE80211_CHAN_NO_HT40;
@@ -301,13 +301,13 @@ static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz,
static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
struct iwl_nvm_data *data,
- const __le16 * const nvm_ch_flags,
- u32 sbands_flags)
+ const void * const nvm_ch_flags,
+ u32 sbands_flags, bool v4)
{
int ch_idx;
int n_channels = 0;
struct ieee80211_channel *channel;
- u16 ch_flags;
+ u32 ch_flags;
int num_of_ch, num_2ghz_channels = NUM_2GHZ_CHANNELS;
const u16 *nvm_chan;
@@ -325,7 +325,12 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
bool is_5ghz = (ch_idx >= num_2ghz_channels);
- ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
+ if (v4)
+ ch_flags =
+ __le32_to_cpup((__le32 *)nvm_ch_flags + ch_idx);
+ else
+ ch_flags =
+ __le16_to_cpup((__le16 *)nvm_ch_flags + ch_idx);
if (is_5ghz && !data->sku_cap_band_52ghz_enable)
continue;
@@ -671,15 +676,15 @@ static void iwl_init_he_hw_capab(struct ieee80211_supported_band *sband,
static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
struct iwl_nvm_data *data,
- const __le16 *nvm_ch_flags, u8 tx_chains,
- u8 rx_chains, u32 sbands_flags)
+ const void *nvm_ch_flags, u8 tx_chains,
+ u8 rx_chains, u32 sbands_flags, bool v4)
{
int n_channels;
int n_used = 0;
struct ieee80211_supported_band *sband;
n_channels = iwl_init_channel_map(dev, cfg, data, nvm_ch_flags,
- sbands_flags);
+ sbands_flags, v4);
sband = &data->bands[NL80211_BAND_2GHZ];
sband->band = NL80211_BAND_2GHZ;
sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS];
@@ -1016,7 +1021,7 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
sbands_flags |= IWL_NVM_SBANDS_FLAGS_NO_WIDE_IN_5GHZ;
iwl_init_sbands(dev, cfg, data, ch_section, tx_chains, rx_chains,
- sbands_flags);
+ sbands_flags, false);
data->calib_version = 255;
return data;
@@ -1407,7 +1412,6 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans,
const struct iwl_fw *fw)
{
struct iwl_nvm_get_info cmd = {};
- struct iwl_nvm_get_info_rsp *rsp;
struct iwl_nvm_data *nvm;
struct iwl_host_cmd hcmd = {
.flags = CMD_WANT_SKB | CMD_SEND_IN_RFKILL,
@@ -1422,12 +1426,24 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans,
bool empty_otp;
u32 mac_flags;
u32 sbands_flags = 0;
+ /*
+ * All the values in iwl_nvm_get_info_rsp v4 are the same as
+ * in v3, except for the channel profile part of the
+ * regulatory. So we can just access the new struct, with the
+ * exception of the latter.
+ */
+ struct iwl_nvm_get_info_rsp *rsp;
+ struct iwl_nvm_get_info_rsp_v3 *rsp_v3;
+ bool v4 = fw_has_api(&fw->ucode_capa,
+ IWL_UCODE_TLV_API_REGULATORY_NVM_INFO);
+ size_t rsp_size = v4 ? sizeof(*rsp) : sizeof(*rsp_v3);
+ void *channel_profile;
ret = iwl_trans_send_cmd(trans, &hcmd);
if (ret)
return ERR_PTR(ret);
- if (WARN(iwl_rx_packet_payload_len(hcmd.resp_pkt) != sizeof(*rsp),
+ if (WARN(iwl_rx_packet_payload_len(hcmd.resp_pkt) != rsp_size,
"Invalid payload len in NVM response from FW %d",
iwl_rx_packet_payload_len(hcmd.resp_pkt))) {
ret = -EINVAL;
@@ -1489,11 +1505,15 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans,
sbands_flags |= IWL_NVM_SBANDS_FLAGS_LAR;
}
+ rsp_v3 = (void *)rsp;
+ channel_profile = v4 ? (void *)rsp->regulatory.channel_profile :
+ (void *)rsp_v3->regulatory.channel_profile;
+
iwl_init_sbands(trans->dev, trans->cfg, nvm,
rsp->regulatory.channel_profile,
nvm->valid_tx_ant & fw->valid_tx_ant,
nvm->valid_rx_ant & fw->valid_rx_ant,
- sbands_flags);
+ sbands_flags, v4);
iwl_free_resp(&hcmd);
return nvm;
--
2.20.1
^ permalink raw reply related
* [PATCH 06/16] mac80211_hwsim: make copying of ciphers safer by checking the length
From: Luca Coelho @ 2019-03-15 16:36 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless, Luca Coelho
In-Reply-To: <20190315163634.17315-1-luca@coelho.fi>
From: Luca Coelho <luciano.coelho@intel.com>
Make sure the length of the ciphers we are copying never exceeds the
space we have for storing them. There is no risk of overcopying at
the moment, because we check n_params before, but this makes this
function safer in case someone changes something in the future.
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
---
drivers/net/wireless/mac80211_hwsim.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 0838af04d681..809a75357113 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -3,7 +3,7 @@
* Copyright (c) 2008, Jouni Malinen <j@w1.fi>
* Copyright (c) 2011, Javier Lopez <jlopex@gmail.com>
* Copyright (c) 2016 - 2017 Intel Deutschland GmbH
- * Copyright (C) 2018 Intel Corporation
+ * Copyright (C) 2018 - 2019 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -2776,10 +2776,14 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
hw->wiphy->n_iface_combinations = 1;
if (param->ciphers) {
- memcpy(data->ciphers, param->ciphers,
- param->n_ciphers * sizeof(u32));
+ int ciphers_len = param->n_ciphers * sizeof(data->ciphers[0]);
+
+ if (WARN_ON_ONCE(ciphers_len > sizeof(data->ciphers)))
+ ciphers_len = sizeof(data->ciphers);
+
+ memcpy(data->ciphers, param->ciphers, ciphers_len);
hw->wiphy->cipher_suites = data->ciphers;
- hw->wiphy->n_cipher_suites = param->n_ciphers;
+ hw->wiphy->n_cipher_suites = ciphers_len / sizeof(data->ciphers[0]);
}
INIT_DELAYED_WORK(&data->roc_start, hw_roc_start);
--
2.20.1
^ permalink raw reply related
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