* 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: wireless workshop coming soon :-)
From: Johannes Berg @ 2019-03-15 9:20 UTC (permalink / raw)
To: Kevin Hayes, Toke Høiland-Jørgensen, Kirtika Ruchandani
Cc: linux-wireless
In-Reply-To: <CAPJUEh3s-Bs6dKrDG54Q1Wu2+1+kwMvTDxJxxEAVBanLA0=FYA@mail.gmail.com>
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?
johannes
^ permalink raw reply
* Re: [PATCH v8 01/14] rtw88: main files
From: Johannes Berg @ 2019-03-15 8:28 UTC (permalink / raw)
To: yhchuang, kvalo
Cc: linux-wireless, gregkh, sgruszka, pkshih, tehuang, briannorris,
Larry.Finger
In-Reply-To: <1552450443-351-2-git-send-email-yhchuang@realtek.com>
On Wed, 2019-03-13 at 12:13 +0800, yhchuang@realtek.com wrote:
>
> +static int rtw_ops_config(struct ieee80211_hw *hw, u32 changed)
> +{
> + struct rtw_dev *rtwdev = hw->priv;
> + int ret = 0;
> +
> + mutex_lock(&rtwdev->mutex);
> +
> + if (changed & IEEE80211_CONF_CHANGE_IDLE) {
> + if (hw->conf.flags & IEEE80211_CONF_IDLE) {
> + rtw_enter_ips(rtwdev);
> + } else {
> + ret = rtw_leave_ips(rtwdev);
> + if (ret) {
> + rtw_err(rtwdev, "failed to leave idle state\n");
> + goto out;
> + }
> + }
> + }
> +
> + if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
> + rtw_set_channel(rtwdev);
It's clearly your decision, but you're probably better off supporting
the modern channel context APIs, even if (at this time) you only support
a single channel.
The settings and methods here that apply to the "whole hardware" are
mostly obsolete as far as mac80211 is concerned.
Now, I also don't recommend you change that now, and it's clearly not a
requirement for an in-tree driver, but something to think about.
> +static int rtw_ops_add_interface(struct ieee80211_hw *hw,
> + struct ieee80211_vif *vif)
> +{
> + struct rtw_dev *rtwdev = hw->priv;
> + struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
> + enum rtw_net_type net_type;
> + u32 config = 0;
> + u8 port = 0;
> +
> + rtwvif->port = port;
> + rtwvif->vif = vif;
> + rtwvif->stats.tx_unicast = 0;
> + rtwvif->stats.rx_unicast = 0;
> + rtwvif->stats.tx_cnt = 0;
> + rtwvif->stats.rx_cnt = 0;
> + rtwvif->in_lps = false;
> + rtwvif->conf = &rtw_vif_port[port];
That's a bit weird, port is always 0. But I guess it's some kind of
preparation for future multi-interface changes (and then you probably
want the channel contexts too?)
> + rtw_info(rtwdev, "start vif %pM on port %d\n", vif->addr, rtwvif->port);
I'm not convinced that warrants an "info" level trace, but YMMV.
> + rtw_info(rtwdev, "stop vif %pM on port %d\n", vif->addr, rtwvif->port);
dito
> +static int rtw_ops_sta_add(struct ieee80211_hw *hw,
> + struct ieee80211_vif *vif,
> + struct ieee80211_sta *sta)
Also, here, I'd consider using sta-state API, it tells you more. Here
it's even less important though since from mac80211's POV it's exactly
the same (it only ever calls sta_state) but the driver with
sta_add/sta_remove gets a filtered view thereof.
> +{
> + struct rtw_dev *rtwdev = hw->priv;
> + struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
> + int ret = 0;
> +
> + mutex_lock(&rtwdev->mutex);
> +
> + si->mac_id = rtw_acquire_macid(rtwdev);
I note you don't handle any kinds of firmware restart scenarios here. I
guess eventually you'd want to?
> +static void rtw_watch_dog_work(struct work_struct *work)
Hm, is that really a "watchdog" in the usual sense?
It seems more like some sort of "periodic work" like the LPS stuff
below, or whatever the PHY dynamic thing is - but not a "watchdog" in
the sense of checking that things are still OK?
Anyway, just a nit about semantics.
(I was looking for FW restart handling here or so)
> + /* power on MAC before firmware downloaded */
> + ret = rtw_mac_power_on(rtwdev);
> + if (ret) {
> + rtw_err(rtwdev, "failed to power on mac\n");
> + goto err;
> + }
> +
> + wait_for_completion(&fw->completion);
Maybe I'm misreading the code, but does this every do anything? It
looked like you only get here after the callback.
> + ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->watch_dog_work,
> + RTW_WATCH_DOG_DELAY_TIME);
Consider using at least round_jiffies_relative() - this is expensive
from a power consumption POV already and doesn't look like it needs
perfect timing.
> +static int rtw_chip_efuse_enable(struct rtw_dev *rtwdev)
> +{
> + struct rtw_fw_state *fw = &rtwdev->fw;
> + int ret;
> +
> + ret = rtw_hci_setup(rtwdev);
> + if (ret) {
> + rtw_err(rtwdev, "failed to setup hci\n");
> + goto err;
> + }
> +
> + ret = rtw_mac_power_on(rtwdev);
> + if (ret) {
> + rtw_err(rtwdev, "failed to power on mac\n");
> + goto err;
> + }
> +
> + rtw_write8(rtwdev, REG_C2HEVT, C2H_HW_FEATURE_DUMP);
> +
> + wait_for_completion(&fw->completion);
same here?
It sort of looked like you don't even need the completion, but I may not
be understanding the full flow.
Typically the flow would be
probe -> load firmware -> firmware callback -> continue work
but I haven't checked in detail if it's different here. If it is though,
why should it be? You can't really do anything without firmware?
> +++ b/drivers/net/wireless/realtek/rtw88/main.h
This file is a bit confusing. On the one hand, you have things like:
> +#define RTW_WATCH_DOG_DELAY_TIME round_jiffies_relative(HZ * 2)
(ohh. you did use round_jiffies_relative!)
> +extern unsigned int rtw_debug_mask;
> +extern const struct ieee80211_ops rtw_ops;
> +extern struct rtw_chip_info rtw8822b_hw_spec;
> +extern struct rtw_chip_info rtw8822c_hw_spec;
This which are very clearly driver specific.
On the other hand you have:
> +enum rtw_bandwidth {
> + RTW_CHANNEL_WIDTH_20 = 0,
> + RTW_CHANNEL_WIDTH_40 = 1,
> + RTW_CHANNEL_WIDTH_80 = 2,
> + RTW_CHANNEL_WIDTH_160 = 3,
> + RTW_CHANNEL_WIDTH_80_80 = 4,
> + RTW_CHANNEL_WIDTH_5 = 5,
> + RTW_CHANNEL_WIDTH_10 = 6,
> +};
> +
> +enum rtw_net_type {
> + RTW_NET_NO_LINK = 0,
> + RTW_NET_AD_HOC = 1,
> + RTW_NET_MGD_LINKED = 2,
> + RTW_NET_AP_MODE = 3,
> +};
> +
> +enum rtw_rf_type {
> + RF_1T1R = 0,
> + RF_1T2R = 1,
> + RF_2T2R = 2,
> + RF_2T3R = 3,
> + RF_2T4R = 4,
> + RF_3T3R = 5,
> + RF_3T4R = 6,
> + RF_4T4R = 7,
> + RF_TYPE_MAX,
> +};
And lots of other things like that which look like some kind of device
API (firmware, hardware, OTP, ...)
IMHO it'd be cleaner to separate that into different files.
Again, for example:
> +enum rtw_regulatory_domains {
> + RTW_REGD_FCC = 0,
> + RTW_REGD_MKK = 1,
> + RTW_REGD_ETSI = 2,
> + RTW_REGD_WW = 3,
> +
> + RTW_REGD_MAX
> +};
Must be hardware API otherwise you wouldn't really care about the exact
values, I guess?
> +enum rtw_flags {
> + RTW_FLAG_RUNNING,
> + RTW_FLAG_FW_RUNNING,
> + RTW_FLAG_SCANNING,
> + RTW_FLAG_INACTIVE_PS,
> + RTW_FLAG_LEISURE_PS,
> + RTW_FLAG_DIG_DISABLE,
> +
> + NUM_OF_RTW_FLAGS,
> +};
Where this is clearly pure driver but everything is completely
intermingled.
It's not a huge problem, but ...
> +/* the power index is represented by differences, which cck-1s & ht40-1s are
> + * the base values, so for 1s's differences, there are only ht20 & ofdm
> + */
> +struct rtw_2g_1s_pwr_idx_diff {
> +#ifdef __LITTLE_ENDIAN
> + s8 ofdm:4;
> + s8 bw20:4;
> +#else
> + s8 bw20:4;
> + s8 ofdm:4;
> +#endif
> +} __packed;
Again, clearly something with the device, otherwise you wouldn't go to
the effort of doing correct-endian-bitfields :-)
(Which I wouldn't really recommend anyway ... but that's another story)
> +#define rtw_iterate_vifs(rtwdev, iterator, data) \
> + ieee80211_iterate_active_interfaces(rtwdev->hw, \
> + IEEE80211_IFACE_ITER_NORMAL, iterator, data)
> +#define rtw_iterate_vifs_atomic(rtwdev, iterator, data) \
> + ieee80211_iterate_active_interfaces_atomic(rtwdev->hw, \
> + IEEE80211_IFACE_ITER_NORMAL, iterator, data)
> +#define rtw_iterate_stas_atomic(rtwdev, iterator, data) \
> + ieee80211_iterate_stations_atomic(rtwdev->hw, iterator, data)
Why not make those inlines?
> +static inline u8 *get_hdr_bssid(struct ieee80211_hdr *hdr)
> +{
> + __le16 fc = hdr->frame_control;
> + u8 *bssid;
> +
> + if (ieee80211_has_tods(fc))
> + bssid = hdr->addr1;
> + else if (ieee80211_has_fromds(fc))
> + bssid = hdr->addr2;
> + else
> + bssid = hdr->addr3;
> +
> + return bssid;
> +}
This is kinda incomplete, perhaps we should export ieee80211_get_bssid()
instead?
Anyway, none of that really seems like blocking issues.
joahnnes
^ permalink raw reply
* Re: [PATCH] net: ath: fix missing checks for bmi reads and writes
From: Kalle Valo @ 2019-03-15 5:24 UTC (permalink / raw)
To: Kangjie Lu
Cc: pakki001, David S. Miller, ath10k, linux-wireless, netdev,
linux-kernel
In-Reply-To: <20190315051903.10664-1-kjlu@umn.edu>
Kangjie Lu <kjlu@umn.edu> writes:
> ath10k_bmi_write32 and ath10k_bmi_read32 can fail. The fix
> checks their statuses to avoid potential undefined behaviors.
>
> Signed-off-by: Kangjie Lu <kjlu@umn.edu>
The title prefix should be "ath10k: ", I'll fix that.
--
Kalle Valo
^ permalink raw reply
* [PATCH] net: ath: fix missing checks for bmi reads and writes
From: Kangjie Lu @ 2019-03-15 5:19 UTC (permalink / raw)
To: kjlu
Cc: pakki001, Kalle Valo, David S. Miller, ath10k, linux-wireless,
netdev, linux-kernel
ath10k_bmi_write32 and ath10k_bmi_read32 can fail. The fix
checks their statuses to avoid potential undefined behaviors.
Signed-off-by: Kangjie Lu <kjlu@umn.edu>
---
drivers/net/wireless/ath/ath10k/core.c | 40 ++++++++++++++++++++------
1 file changed, 31 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 835b8de92d55..1bb586f0040e 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -629,13 +629,20 @@ static void ath10k_send_suspend_complete(struct ath10k *ar)
complete(&ar->target_suspend);
}
-static void ath10k_init_sdio(struct ath10k *ar)
+static int ath10k_init_sdio(struct ath10k *ar)
{
+ int ret;
u32 param = 0;
- ath10k_bmi_write32(ar, hi_mbox_io_block_sz, 256);
- ath10k_bmi_write32(ar, hi_mbox_isr_yield_limit, 99);
- ath10k_bmi_read32(ar, hi_acs_flags, ¶m);
+ ret = ath10k_bmi_write32(ar, hi_mbox_io_block_sz, 256);
+ if (ret)
+ return ret;
+ ret = ath10k_bmi_write32(ar, hi_mbox_isr_yield_limit, 99);
+ if (ret)
+ return ret;
+ ret = ath10k_bmi_read32(ar, hi_acs_flags, ¶m);
+ if (ret)
+ return ret;
/* Data transfer is not initiated, when reduced Tx completion
* is used for SDIO. disable it until fixed
@@ -647,14 +654,22 @@ static void ath10k_init_sdio(struct ath10k *ar)
*/
param &= ~HI_ACS_FLAGS_ALT_DATA_CREDIT_SIZE;
param |= HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_SET;
- ath10k_bmi_write32(ar, hi_acs_flags, param);
+ ret = ath10k_bmi_write32(ar, hi_acs_flags, param);
+ if (ret)
+ return ret;
/* Explicitly set fwlog prints to zero as target may turn it on
* based on scratch registers.
*/
- ath10k_bmi_read32(ar, hi_option_flag, ¶m);
+ ret = ath10k_bmi_read32(ar, hi_option_flag, ¶m);
+ if (ret)
+ return ret;
param |= HI_OPTION_DISABLE_DBGLOG;
- ath10k_bmi_write32(ar, hi_option_flag, param);
+ ret = ath10k_bmi_write32(ar, hi_option_flag, param);
+ if (ret)
+ return ret;
+
+ return 0;
}
static int ath10k_init_configure_target(struct ath10k *ar)
@@ -2500,8 +2515,15 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
if (status)
goto err;
- if (ar->hif.bus == ATH10K_BUS_SDIO)
- ath10k_init_sdio(ar);
+ if (ar->hif.bus == ATH10K_BUS_SDIO) {
+ status = ath10k_init_sdio(ar);
+ if (status) {
+ ath10k_err(ar,
+ "could not init HTC (%d)\n",
+ status);
+ goto err;
+ }
+ }
}
ar->htc.htc_ops.target_send_suspend_complete =
--
2.17.1
^ permalink raw reply related
* Re: [PATCH v5 03/18] wlcore: simplify/fix/optimize reg_ch_conf_pending operations
From: Fenghua Yu @ 2019-03-14 23:16 UTC (permalink / raw)
To: Kalle Valo
Cc: Thomas Gleixner, Ingo Molnar, H Peter Anvin, Dave Hansen,
Paolo Bonzini, Ashok Raj, Peter Zijlstra, Xiaoyao Li,
Michael Chan, Ravi V Shankar, linux-kernel, x86, linux-wireless,
netdev, kvm
In-Reply-To: <87a7hxzjda.fsf@purkki.adurom.net>
Hi, Valo,
On Thu, Mar 14, 2019 at 03:16:33PM +0200, Kalle Valo wrote:
> Fenghua Yu <fenghua.yu@intel.com> writes:
>
> > From: Paolo Bonzini <pbonzini@redhat.com>
> >
> > Bitmaps are defined on unsigned longs, so the usage of u32[2] in the
> > wlcore driver is incorrect. As noted by Peter Zijlstra, casting arrays
> > to a bitmap is incorrect for big-endian architectures.
> >
> > When looking at it I observed that:
> >
> > - operations on reg_ch_conf_pending is always under the wl_lock mutex,
> > so set_bit is overkill
> >
> > - the only case where reg_ch_conf_pending is accessed a u32 at a time is
> > unnecessary too.
> >
> > This patch cleans up everything in this area, and changes tmp_ch_bitmap
> > to have the proper alignment.
> >
> > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> > Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
>
> [...]
>
> > int wlcore_cmd_regdomain_config_locked(struct wl1271 *wl)
> > {
> > struct wl12xx_cmd_regdomain_dfs_config *cmd = NULL;
> > int ret = 0, i, b, ch_bit_idx;
> > - u32 tmp_ch_bitmap[2];
> > + u32 tmp_ch_bitmap[2] __aligned(sizeof(unsigned long));
> > struct wiphy *wiphy = wl->hw->wiphy;
> > struct ieee80211_supported_band *band;
> > bool timeout = false;
>
> [...]
>
> > @@ -1754,8 +1751,8 @@ int wlcore_cmd_regdomain_config_locked(struct wl1271 *wl)
> > goto out;
> > }
> >
> > - cmd->ch_bit_map1 = cpu_to_le32(tmp_ch_bitmap[0]);
> > - cmd->ch_bit_map2 = cpu_to_le32(tmp_ch_bitmap[1]);
> > + cmd->ch_bit_map1 = tmp_ch_bitmap[0];
> > + cmd->ch_bit_map2 = tmp_ch_bitmap[1];
>
> Will sparse still be happy? AFAICS you are now assigning u32 to __le32:
>
> struct wl12xx_cmd_regdomain_dfs_config {
> struct wl1271_cmd_header header;
>
> __le32 ch_bit_map1;
> __le32 ch_bit_map2;
Discussion between Peter and Paolo (https://lkml.org/lkml/2019/3/4/521)
may answer your question.
(Sorry I didn't send to you v4 patch set)
>
> Also this doesn't depend on anything else from this patchset, right? So
> I could apply this directly?
You are right. This patch doesn't rely on other patches from this patchset.
This patch just fixes a split lock issue. You could apply this directly
without other patches.
Thanks.
-Fenghua
^ permalink raw reply
* Re: [RFC] mac80211: rework locking for txq scheduling / airtime fairness
From: Toke Høiland-Jørgensen @ 2019-03-14 22:17 UTC (permalink / raw)
To: Felix Fietkau, linux-wireless; +Cc: johannes
In-Reply-To: <50e3ab54-4e8c-171c-28f0-7e3ad5a02c99@nbd.name>
Felix Fietkau <nbd@nbd.name> writes:
> On 2019-03-13 23:55, Toke Høiland-Jørgensen wrote:
>> 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.
>>
>> Right, I can see how that could become an issue at higher loads than
>> what I tested with :)
> I stumbled onto this when I was doing perf runs with mt76 (before even
> adding support for this API) and I noticed that a visible amount of lock
> contention was caused by mac80211 tx calls being blocked by mt76 tx
> scheduling.
> I wanted to fix these issues by switching to the mac80211 txq scheduling
> API, but when reading the code I noticed that using this API had the
> very same issue I was trying to fix. That's why I made this patch :)
Ah, I see. Well I applaud you making fixing this and switching over mt76
your solution :)
>>> Improve locking by only holding the active_txq_lock for lookups /
>>> scheduling list modifications.
>>
>> So the (potential) issue I see with this modification is that it
>> requires the driver to ensure that it will not interleave two different
>> scheduling rounds for the same acno. I.e., another call to
>> schedule_start() will reset the round counter and something needs to
>> guarantee that this doesn't happen until the driver has actually
>> finished the previous round.
>>
>> I am not sure to what extent this would *actually* be a problem. For
>> ath9k, for instance, there's already the in-driver chan_lock (although
>> the call to ieee80211_txq_schedule_start() would then have to be moved
>> into the section covered by that lock). But it does introduce an
>> implicit dependency in the API, which should at least be documented.
> With ath9k it's also protected by the per-txq lock.
Ah, right, that was just moved not removed entirely. Great!
> With ath10k it's protected by having scheduling calls come from the NAPI
> poll function.
Cool.
>> If memory serves, avoiding this implicit dependency was the original
>> reason I had for adding the full lock around everything. I can't think
>> of any other reason right now, but if I do think of something I'll be
>> sure to let you know :)
> I'll change the patch to make this more explicit and resubmit.
> Thanks for your comments.
Sounds good!
-Toke
^ permalink raw reply
* Re: [RFC] mac80211: rework locking for txq scheduling / airtime fairness
From: Felix Fietkau @ 2019-03-14 17:23 UTC (permalink / raw)
To: Toke Høiland-Jørgensen, linux-wireless; +Cc: johannes
In-Reply-To: <87va0mz8nu.fsf@toke.dk>
On 2019-03-13 23:55, Toke Høiland-Jørgensen wrote:
> 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.
>
> Right, I can see how that could become an issue at higher loads than
> what I tested with :)
I stumbled onto this when I was doing perf runs with mt76 (before even
adding support for this API) and I noticed that a visible amount of lock
contention was caused by mac80211 tx calls being blocked by mt76 tx
scheduling.
I wanted to fix these issues by switching to the mac80211 txq scheduling
API, but when reading the code I noticed that using this API had the
very same issue I was trying to fix. That's why I made this patch :)
>> Improve locking by only holding the active_txq_lock for lookups /
>> scheduling list modifications.
>
> So the (potential) issue I see with this modification is that it
> requires the driver to ensure that it will not interleave two different
> scheduling rounds for the same acno. I.e., another call to
> schedule_start() will reset the round counter and something needs to
> guarantee that this doesn't happen until the driver has actually
> finished the previous round.
>
> I am not sure to what extent this would *actually* be a problem. For
> ath9k, for instance, there's already the in-driver chan_lock (although
> the call to ieee80211_txq_schedule_start() would then have to be moved
> into the section covered by that lock). But it does introduce an
> implicit dependency in the API, which should at least be documented.
With ath9k it's also protected by the per-txq lock.
With ath10k it's protected by having scheduling calls come from the NAPI
poll function.
> If memory serves, avoiding this implicit dependency was the original
> reason I had for adding the full lock around everything. I can't think
> of any other reason right now, but if I do think of something I'll be
> sure to let you know :)
I'll change the patch to make this more explicit and resubmit.
Thanks for your comments.
- Felix
^ permalink raw reply
* Re: [PATCH 2/2] ath9k: drop redundant code in ar9003_hw_set_channel
From: Kalle Valo @ 2019-03-14 15:52 UTC (permalink / raw)
To: Tom Psyborg; +Cc: linux-wireless
In-Reply-To: <CAKR_QV+Ogamn1uZxkOCAiNrPQ4PrMmqb-mMcuhY74MGS44An5w@mail.gmail.com>
Tom Psyborg <pozega.tomislav@gmail.com> writes:
> Done.
Thanks. I see v2 now:
https://patchwork.kernel.org/project/linux-wireless/list/?series=91659
--
Kalle Valo
^ permalink raw reply
* [PATCH] mt76: move mac_work in mt76_dev
From: Lorenzo Bianconi @ 2019-03-14 14:57 UTC (permalink / raw)
To: nbd; +Cc: linux-wireless, lorenzo.bianconi, sgruszka
In-Reply-To: <cover.1552575244.git.lorenzo@kernel.org>
Move mac_work delayed work in mt76_dev data structure since
it is used by all drivers and it will be reused adding mac work to
mt7615
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 2 ++
drivers/net/wireless/mediatek/mt76/mt7603/init.c | 2 +-
drivers/net/wireless/mediatek/mt76/mt7603/mac.c | 8 +++++---
drivers/net/wireless/mediatek/mt76/mt7603/main.c | 10 +++++-----
drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h | 1 -
drivers/net/wireless/mediatek/mt76/mt76x0/pci.c | 4 ++--
drivers/net/wireless/mediatek/mt76/mt76x0/usb.c | 4 ++--
drivers/net/wireless/mediatek/mt76/mt76x02.h | 1 -
drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 8 +++++---
drivers/net/wireless/mediatek/mt76/mt76x02_util.c | 2 +-
drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c | 2 +-
drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c | 2 +-
drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c | 2 +-
drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c | 2 +-
14 files changed, 27 insertions(+), 23 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index edff44f32c8e..46bde2f55fce 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -455,6 +455,8 @@ struct mt76_dev {
const struct mt76_queue_ops *queue_ops;
int tx_dma_idx[4];
+ struct delayed_work mac_work;
+
wait_queue_head_t tx_wait;
struct sk_buff_head status_list;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/init.c b/drivers/net/wireless/mediatek/mt76/mt7603/init.c
index d54dda67d036..ce1685d44888 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/init.c
@@ -510,7 +510,7 @@ int mt7603_register_device(struct mt7603_dev *dev)
bus_ops->rmw = mt7603_rmw;
dev->mt76.bus = bus_ops;
- INIT_DELAYED_WORK(&dev->mac_work, mt7603_mac_work);
+ INIT_DELAYED_WORK(&dev->mt76.mac_work, mt7603_mac_work);
tasklet_init(&dev->pre_tbtt_tasklet, mt7603_pre_tbtt_tasklet,
(unsigned long)dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
index 5f800467c628..d15d8316a108 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
@@ -1691,10 +1691,12 @@ mt7603_false_cca_check(struct mt7603_dev *dev)
void mt7603_mac_work(struct work_struct *work)
{
- struct mt7603_dev *dev = container_of(work, struct mt7603_dev,
- mac_work.work);
+ struct mt7603_dev *dev;
bool reset = false;
+ dev = (struct mt7603_dev *)container_of(work, struct mt76_dev,
+ mac_work.work);
+
mt76_tx_status_check(&dev->mt76, NULL, false);
mutex_lock(&dev->mt76.mutex);
@@ -1745,6 +1747,6 @@ void mt7603_mac_work(struct work_struct *work)
if (reset)
mt7603_mac_watchdog_reset(dev);
- ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mac_work,
+ ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
msecs_to_jiffies(MT7603_WATCHDOG_TIME));
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/main.c b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
index 7849528db134..4ab020d955e0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
@@ -16,7 +16,7 @@ mt7603_start(struct ieee80211_hw *hw)
mt7603_mac_start(dev);
dev->survey_time = ktime_get_boottime();
set_bit(MT76_STATE_RUNNING, &dev->mt76.state);
- mt7603_mac_work(&dev->mac_work.work);
+ mt7603_mac_work(&dev->mt76.mac_work.work);
return 0;
}
@@ -27,7 +27,7 @@ mt7603_stop(struct ieee80211_hw *hw)
struct mt7603_dev *dev = hw->priv;
clear_bit(MT76_STATE_RUNNING, &dev->mt76.state);
- cancel_delayed_work_sync(&dev->mac_work);
+ cancel_delayed_work_sync(&dev->mt76.mac_work);
mt7603_mac_stop(dev);
}
@@ -132,7 +132,7 @@ mt7603_set_channel(struct mt7603_dev *dev, struct cfg80211_chan_def *def)
u8 bw = MT_BW_20;
bool failed = false;
- cancel_delayed_work_sync(&dev->mac_work);
+ cancel_delayed_work_sync(&dev->mt76.mac_work);
mutex_lock(&dev->mt76.mutex);
set_bit(MT76_RESET, &dev->mt76.state);
@@ -171,7 +171,7 @@ mt7603_set_channel(struct mt7603_dev *dev, struct cfg80211_chan_def *def)
mt76_txq_schedule_all(&dev->mt76);
- ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mac_work,
+ ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
MT7603_WATCHDOG_TIME);
/* reset channel stats */
@@ -189,7 +189,7 @@ mt7603_set_channel(struct mt7603_dev *dev, struct cfg80211_chan_def *def)
mutex_unlock(&dev->mt76.mutex);
if (failed)
- mt7603_mac_work(&dev->mac_work.work);
+ mt7603_mac_work(&dev->mt76.mac_work.work);
return ret;
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
index f414ff2a5279..2c937c4a3105 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
@@ -144,7 +144,6 @@ struct mt7603_dev {
unsigned int reset_cause[__RESET_CAUSE_MAX];
- struct delayed_work mac_work;
struct tasklet_struct tx_tasklet;
struct tasklet_struct pre_tbtt_tasklet;
};
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
index e07a62246db7..b934a974df32 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
@@ -29,7 +29,7 @@ static int mt76x0e_start(struct ieee80211_hw *hw)
mt76x02_mac_start(dev);
mt76x0_phy_calibrate(dev, true);
- ieee80211_queue_delayed_work(dev->mt76.hw, &dev->mac_work,
+ ieee80211_queue_delayed_work(dev->mt76.hw, &dev->mt76.mac_work,
MT_MAC_WORK_INTERVAL);
ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work,
MT_CALIBRATE_INTERVAL);
@@ -43,7 +43,7 @@ static int mt76x0e_start(struct ieee80211_hw *hw)
static void mt76x0e_stop_hw(struct mt76x02_dev *dev)
{
cancel_delayed_work_sync(&dev->cal_work);
- cancel_delayed_work_sync(&dev->mac_work);
+ cancel_delayed_work_sync(&dev->mt76.mac_work);
if (!mt76_poll(dev, MT_WPDMA_GLO_CFG, MT_WPDMA_GLO_CFG_TX_DMA_BUSY,
0, 1000))
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
index 91718647da02..17be27c9cc94 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
@@ -85,7 +85,7 @@ static void mt76x0u_mac_stop(struct mt76x02_dev *dev)
{
clear_bit(MT76_STATE_RUNNING, &dev->mt76.state);
cancel_delayed_work_sync(&dev->cal_work);
- cancel_delayed_work_sync(&dev->mac_work);
+ cancel_delayed_work_sync(&dev->mt76.mac_work);
mt76u_stop_stat_wk(&dev->mt76);
if (test_bit(MT76_REMOVED, &dev->mt76.state))
@@ -116,7 +116,7 @@ static int mt76x0u_start(struct ieee80211_hw *hw)
goto out;
mt76x0_phy_calibrate(dev, true);
- ieee80211_queue_delayed_work(dev->mt76.hw, &dev->mac_work,
+ ieee80211_queue_delayed_work(dev->mt76.hw, &dev->mt76.mac_work,
MT_MAC_WORK_INTERVAL);
ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work,
MT_CALIBRATE_INTERVAL);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index cb5792b41d2d..8e17fbb6fd04 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -85,7 +85,6 @@ struct mt76x02_dev {
struct tasklet_struct tx_tasklet;
struct tasklet_struct pre_tbtt_tasklet;
struct delayed_work cal_work;
- struct delayed_work mac_work;
struct delayed_work wdt_work;
u32 aggr_stats[32];
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index df6930a94f74..5fad3ad0f33a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -1018,10 +1018,12 @@ static void mt76x02_edcca_check(struct mt76x02_dev *dev)
void mt76x02_mac_work(struct work_struct *work)
{
- struct mt76x02_dev *dev = container_of(work, struct mt76x02_dev,
- mac_work.work);
+ struct mt76x02_dev *dev;
int i, idx;
+ dev = (struct mt76x02_dev *)container_of(work, struct mt76_dev,
+ mac_work.work);
+
mutex_lock(&dev->mt76.mutex);
mt76x02_update_channel(&dev->mt76);
@@ -1042,7 +1044,7 @@ void mt76x02_mac_work(struct work_struct *work)
mt76_tx_status_check(&dev->mt76, NULL, false);
- ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mac_work,
+ ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
MT_MAC_WORK_INTERVAL);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index 81d65319d3ea..33fc215c29f7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -132,7 +132,7 @@ void mt76x02_init_device(struct mt76x02_dev *dev)
struct ieee80211_hw *hw = mt76_hw(dev);
struct wiphy *wiphy = hw->wiphy;
- INIT_DELAYED_WORK(&dev->mac_work, mt76x02_mac_work);
+ INIT_DELAYED_WORK(&dev->mt76.mac_work, mt76x02_mac_work);
hw->queues = 4;
hw->max_rates = 1;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
index d3927a13e92e..9661e9ba734d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_init.c
@@ -291,7 +291,7 @@ static int mt76x2_init_hardware(struct mt76x02_dev *dev)
void mt76x2_stop_hardware(struct mt76x02_dev *dev)
{
cancel_delayed_work_sync(&dev->cal_work);
- cancel_delayed_work_sync(&dev->mac_work);
+ cancel_delayed_work_sync(&dev->mt76.mac_work);
cancel_delayed_work_sync(&dev->wdt_work);
mt76x02_mcu_set_radio_state(dev, false);
mt76x2_mac_stop(dev, false);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
index 878ce92405ed..ef42743364e4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci_main.c
@@ -32,7 +32,7 @@ mt76x2_start(struct ieee80211_hw *hw)
if (ret)
goto out;
- ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mac_work,
+ ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
MT_MAC_WORK_INTERVAL);
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->wdt_work,
MT_WATCHDOG_TIME);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
index 1da90e58d942..4bfd958b4334 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_init.c
@@ -246,7 +246,7 @@ void mt76x2u_stop_hw(struct mt76x02_dev *dev)
{
mt76u_stop_stat_wk(&dev->mt76);
cancel_delayed_work_sync(&dev->cal_work);
- cancel_delayed_work_sync(&dev->mac_work);
+ cancel_delayed_work_sync(&dev->mt76.mac_work);
mt76x2u_mac_stop(dev);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
index 2ac78e4dc41a..5f746c8df906 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
@@ -27,7 +27,7 @@ static int mt76x2u_start(struct ieee80211_hw *hw)
if (ret)
goto out;
- ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mac_work,
+ ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
MT_MAC_WORK_INTERVAL);
set_bit(MT76_STATE_RUNNING, &dev->mt76.state);
--
2.20.1
^ permalink raw reply related
* [PATCH] rt2x00: code-style fix in rt2800usb.c
From: Tomislav Požega @ 2019-03-14 14:19 UTC (permalink / raw)
To: linux-wireless; +Cc: kvalo
Remove space leftovers.
Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
---
drivers/net/wireless/ralink/rt2x00/rt2800usb.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
index 19eabf1..091a607 100644
--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c
@@ -562,13 +562,13 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
* stripped it from the frame. Signal this to mac80211.
*/
rxdesc->flags |= RX_FLAG_MMIC_STRIPPED;
-
+
if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS) {
rxdesc->flags |= RX_FLAG_DECRYPTED;
} else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC) {
/*
* In order to check the Michael Mic, the packet must have
- * been decrypted. Mac80211 doesnt check the MMIC failure
+ * been decrypted. Mac80211 doesnt check the MMIC failure
* flag to initiate MMIC countermeasures if the decoded flag
* has not been set.
*/
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH 2/2] rt2x00: enable experimental MFP with HW crypt
From: Stanislaw Gruszka @ 2019-03-14 14:13 UTC (permalink / raw)
To: Tom Psyborg; +Cc: linux-wireless, kvalo, daniel
In-Reply-To: <CAKR_QV+=i_Sp26zCkTC9cAHrhVLq4w0FoxLVmD-T3wFyd-ruEQ@mail.gmail.com>
On Thu, Mar 14, 2019 at 03:02:14PM +0100, Tom Psyborg wrote:
> On 13/03/2019, Stanislaw Gruszka <sgruszka@redhat.com> wrote:
>
> >
> > There should be no difference between enabling MFP with nohwcrypt and
> > without nohwcrypt,
>
> well there is.
Perhaps then you could provide explanation why there is difference ?
> do you still want me to resend this with MFP enabled
> unconditionally for all chips?
Yes, but first lets clarify things.
Stanislaw
^ permalink raw reply
* Re: [PATCH 2/2] ath9k: drop redundant code in ar9003_hw_set_channel
From: Tom Psyborg @ 2019-03-14 14:10 UTC (permalink / raw)
To: Kalle Valo; +Cc: linux-wireless
In-Reply-To: <87zhpxzit5.fsf@codeaurora.org>
Done.
^ permalink raw reply
* [PATCH v2 2/2] ath9k: drop redundant code in ar9003_hw_set_channel
From: Tomislav Požega @ 2019-03-14 14:07 UTC (permalink / raw)
To: linux-wireless; +Cc: kvalo
In-Reply-To: <1552572470-2656-1-git-send-email-pozega.tomislav@gmail.com>
AR9330, AR9485, AR9531, AR9550, AR9561 and AR9565 all use same
channel set register configuration which allows for small code
size reduction.
Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
---
drivers/net/wireless/ath/ath9k/ar9003_phy.c | 24 +++---------------------
1 files changed, 3 insertions(+), 21 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 98c5f52..daf30f9 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -157,7 +157,9 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
freq = centers.synth_center;
if (freq < 4800) { /* 2 GHz, fractional mode */
- if (AR_SREV_9330(ah)) {
+ if (AR_SREV_9330(ah) || AR_SREV_9485(ah) ||
+ AR_SREV_9531(ah) || AR_SREV_9550(ah) ||
+ AR_SREV_9561(ah) || AR_SREV_9565(ah)) {
if (ah->is_clk_25mhz)
div = 75;
else
@@ -166,16 +168,6 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
channelSel = (freq * 4) / div;
chan_frac = (((freq * 4) % div) * 0x20000) / div;
channelSel = (channelSel << 17) | chan_frac;
- } else if (AR_SREV_9485(ah) || AR_SREV_9565(ah)) {
- /*
- * freq_ref = 40 / (refdiva >> amoderefsel);
- * where refdiva=1 and amoderefsel=0
- * ndiv = ((chan_mhz * 4) / 3) / freq_ref;
- * chansel = int(ndiv), chanfrac = (ndiv - chansel) * 0x20000
- */
- channelSel = (freq * 4) / 120;
- chan_frac = (((freq * 4) % 120) * 0x20000) / 120;
- channelSel = (channelSel << 17) | chan_frac;
} else if (AR_SREV_9340(ah)) {
if (ah->is_clk_25mhz) {
channelSel = (freq * 2) / 75;
@@ -184,16 +176,6 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
} else {
channelSel = CHANSEL_2G(freq) >> 1;
}
- } else if (AR_SREV_9550(ah) || AR_SREV_9531(ah) ||
- AR_SREV_9561(ah)) {
- if (ah->is_clk_25mhz)
- div = 75;
- else
- div = 120;
-
- channelSel = (freq * 4) / div;
- chan_frac = (((freq * 4) % div) * 0x20000) / div;
- channelSel = (channelSel << 17) | chan_frac;
} else {
channelSel = CHANSEL_2G(freq);
}
--
1.7.0.4
^ permalink raw reply related
* [PATCH v2 1/2] ath: drop duplicated define
From: Tomislav Požega @ 2019-03-14 14:07 UTC (permalink / raw)
To: linux-wireless; +Cc: kvalo
Remove duplicate NO_CTL that is just 2 lines below.
Signed-off-by: Tomislav Požega <pozega.tomislav@gmail.com>
---
drivers/net/wireless/ath/regd.h | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/ath/regd.h b/drivers/net/wireless/ath/regd.h
index 75ddaef..8d5a16b 100644
--- a/drivers/net/wireless/ath/regd.h
+++ b/drivers/net/wireless/ath/regd.h
@@ -28,7 +28,6 @@ enum ctl_group {
CTL_ETSI = 0x30,
};
-#define NO_CTL 0xff
#define SD_NO_CTL 0xE0
#define NO_CTL 0xff
#define CTL_11A 0
--
1.7.0.4
^ permalink raw reply related
* Re: [PATCH 2/2] rt2x00: enable experimental MFP with HW crypt
From: Tom Psyborg @ 2019-03-14 14:02 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: linux-wireless, kvalo, daniel
In-Reply-To: <20190313155028.GB5302@redhat.com>
On 13/03/2019, Stanislaw Gruszka <sgruszka@redhat.com> wrote:
>
> There should be no difference between enabling MFP with nohwcrypt and
> without nohwcrypt,
well there is. do you still want me to resend this with MFP enabled
unconditionally for all chips?
^ permalink raw reply
* [PATCH v2 4/4] mt76: introduce mt76_tx_info data structure
From: Lorenzo Bianconi @ 2019-03-14 13:54 UTC (permalink / raw)
To: nbd; +Cc: ryder.lee, roychl666, linux-wireless, lorenzo.bianconi
In-Reply-To: <cover.1552570806.git.lorenzo@kernel.org>
Add mt76_tx_info as auxiliary data structure to pass values
to tx_prepare_skb pointer. This is a preliminary patch to add
support for new chipsets (e.g. mt7615)
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/dma.c | 29 ++++++++++---------
drivers/net/wireless/mediatek/mt76/mt76.h | 9 +++++-
.../net/wireless/mediatek/mt76/mt7603/mac.c | 2 +-
.../wireless/mediatek/mt76/mt7603/mt7603.h | 2 +-
drivers/net/wireless/mediatek/mt76/mt76x02.h | 2 +-
.../net/wireless/mediatek/mt76/mt76x02_txrx.c | 8 ++---
.../net/wireless/mediatek/mt76/mt76x02_usb.h | 2 +-
.../wireless/mediatek/mt76/mt76x02_usb_core.c | 2 +-
8 files changed, 32 insertions(+), 24 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index a3edaca05fa8..7b8a998103d7 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -284,13 +284,12 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
struct ieee80211_sta *sta)
{
struct mt76_queue *q = dev->q_tx[qid].q;
+ struct mt76_tx_info tx_info = {};
+ int len, n = 0, ret = -ENOMEM;
struct mt76_queue_entry e;
struct mt76_txwi_cache *t;
- struct mt76_queue_buf buf[32];
- int len, n = 0, ret = -ENOMEM;
struct sk_buff *iter;
dma_addr_t addr;
- u32 tx_info = 0;
t = mt76_get_txwi(dev);
if (!t) {
@@ -307,13 +306,13 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
if (dma_mapping_error(dev->dev, addr))
goto free;
- buf[n].addr = t->dma_addr;
- buf[n++].len = dev->drv->txwi_size;
- buf[n].addr = addr;
- buf[n++].len = len;
+ tx_info.buf[n].addr = t->dma_addr;
+ tx_info.buf[n++].len = dev->drv->txwi_size;
+ tx_info.buf[n].addr = addr;
+ tx_info.buf[n++].len = len;
skb_walk_frags(skb, iter) {
- if (n == ARRAY_SIZE(buf))
+ if (n == ARRAY_SIZE(tx_info.buf))
goto unmap;
addr = dma_map_single(dev->dev, iter->data, iter->len,
@@ -321,9 +320,10 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
if (dma_mapping_error(dev->dev, addr))
goto unmap;
- buf[n].addr = addr;
- buf[n++].len = iter->len;
+ tx_info.buf[n].addr = addr;
+ tx_info.buf[n++].len = iter->len;
}
+ tx_info.nbuf = n;
dma_sync_single_for_cpu(dev->dev, t->dma_addr, sizeof(t->txwi),
DMA_TO_DEVICE);
@@ -334,17 +334,18 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
if (ret < 0)
goto unmap;
- if (q->queued + (n + 1) / 2 >= q->ndesc - 1) {
+ if (q->queued + (tx_info.nbuf + 1) / 2 >= q->ndesc - 1) {
ret = -ENOMEM;
goto unmap;
}
- return mt76_dma_add_buf(dev, q, buf, n, tx_info, skb, t);
+ return mt76_dma_add_buf(dev, q, tx_info.buf, tx_info.nbuf,
+ tx_info.info, skb, t);
unmap:
for (n--; n > 0; n--)
- dma_unmap_single(dev->dev, buf[n].addr, buf[n].len,
- DMA_TO_DEVICE);
+ dma_unmap_single(dev->dev, tx_info.buf[n].addr,
+ tx_info.buf[n].len, DMA_TO_DEVICE);
free:
e.skb = skb;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 48d3c03e46a7..edff44f32c8e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -83,6 +83,12 @@ struct mt76_queue_buf {
int len;
};
+struct mt76_tx_info {
+ struct mt76_queue_buf buf[32];
+ int nbuf;
+ u32 info;
+};
+
struct mt76u_buf {
struct mt76_dev *dev;
struct urb *urb;
@@ -296,7 +302,8 @@ struct mt76_driver_ops {
int (*tx_prepare_skb)(struct mt76_dev *dev, void *txwi_ptr,
struct sk_buff *skb, enum mt76_txq_id qid,
struct mt76_wcid *wcid,
- struct ieee80211_sta *sta, u32 *tx_info);
+ struct ieee80211_sta *sta,
+ struct mt76_tx_info *tx_info);
void (*tx_complete_skb)(struct mt76_dev *dev, enum mt76_txq_id qid,
struct mt76_queue_entry *e);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
index 1ff4c10b291c..5f800467c628 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
@@ -939,7 +939,7 @@ mt7603_mac_write_txwi(struct mt7603_dev *dev, __le32 *txwi,
int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
struct sk_buff *skb, enum mt76_txq_id qid,
struct mt76_wcid *wcid, struct ieee80211_sta *sta,
- u32 *tx_info)
+ struct mt76_tx_info *tx_info)
{
struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
struct mt7603_sta *msta = container_of(wcid, struct mt7603_sta, wcid);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
index 8bd00b97066a..f414ff2a5279 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
@@ -225,7 +225,7 @@ void mt7603_filter_tx(struct mt7603_dev *dev, int idx, bool abort);
int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
struct sk_buff *skb, enum mt76_txq_id qid,
struct mt76_wcid *wcid, struct ieee80211_sta *sta,
- u32 *tx_info);
+ struct mt76_tx_info *tx_info);
void mt7603_tx_complete_skb(struct mt76_dev *mdev, enum mt76_txq_id qid,
struct mt76_queue_entry *e);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index 53ec8103a268..cb5792b41d2d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -174,7 +174,7 @@ void mt76x02_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi,
struct sk_buff *skb, enum mt76_txq_id qid,
struct mt76_wcid *wcid, struct ieee80211_sta *sta,
- u32 *tx_info);
+ struct mt76_tx_info *tx_info);
void mt76x02_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
const u8 *mac);
void mt76x02_sw_scan_complete(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
index 708f2c65d3fd..dd7d04b9b8db 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
@@ -149,7 +149,7 @@ EXPORT_SYMBOL_GPL(mt76x02_tx_status_data);
int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
struct sk_buff *skb, enum mt76_txq_id qid,
struct mt76_wcid *wcid, struct ieee80211_sta *sta,
- u32 *tx_info)
+ struct mt76_tx_info *tx_info)
{
struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
@@ -169,11 +169,11 @@ int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
if (pid >= MT_PACKET_ID_FIRST)
qsel = MT_QSEL_MGMT;
- *tx_info = FIELD_PREP(MT_TXD_INFO_QSEL, qsel) |
- MT_TXD_INFO_80211;
+ tx_info->info = FIELD_PREP(MT_TXD_INFO_QSEL, qsel) |
+ MT_TXD_INFO_80211;
if (!wcid || wcid->hw_key_idx == 0xff || wcid->sw_iv)
- *tx_info |= MT_TXD_INFO_WIV;
+ tx_info->info |= MT_TXD_INFO_WIV;
return 0;
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h b/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h
index 98e647c8c7c7..8f98cc6ce094 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h
@@ -28,7 +28,7 @@ int mt76x02u_skb_dma_info(struct sk_buff *skb, int port, u32 flags);
int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
struct sk_buff *skb, enum mt76_txq_id qid,
struct mt76_wcid *wcid, struct ieee80211_sta *sta,
- u32 *tx_info);
+ struct mt76_tx_info *tx_info);
void mt76x02u_tx_complete_skb(struct mt76_dev *mdev, enum mt76_txq_id qid,
struct mt76_queue_entry *e);
#endif /* __MT76x02_USB_H */
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
index 6c3fc4cea283..394dfe5b4a2e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
@@ -74,7 +74,7 @@ int mt76x02u_skb_dma_info(struct sk_buff *skb, int port, u32 flags)
int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
struct sk_buff *skb, enum mt76_txq_id qid,
struct mt76_wcid *wcid, struct ieee80211_sta *sta,
- u32 *tx_info)
+ struct mt76_tx_info *tx_info)
{
struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
int pid, len = skb->len, ep = q2ep(mdev->q_tx[qid].q->hw_idx);
--
2.20.1
^ permalink raw reply related
* [PATCH v2 3/4] mt76: move skb dma mapping before running tx_prepare_skb
From: Lorenzo Bianconi @ 2019-03-14 13:54 UTC (permalink / raw)
To: nbd; +Cc: ryder.lee, roychl666, linux-wireless, lorenzo.bianconi
In-Reply-To: <cover.1552570806.git.lorenzo@kernel.org>
Move skb dma mapping before configuring txwi since new chipsets (mt7615)
will need skb dma addresses in order to properly configure txwi
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/dma.c | 33 +++++++++++-------------
1 file changed, 15 insertions(+), 18 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index 33725b839983..a3edaca05fa8 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -287,11 +287,10 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
struct mt76_queue_entry e;
struct mt76_txwi_cache *t;
struct mt76_queue_buf buf[32];
+ int len, n = 0, ret = -ENOMEM;
struct sk_buff *iter;
dma_addr_t addr;
- int len;
u32 tx_info = 0;
- int n, ret;
t = mt76_get_txwi(dev);
if (!t) {
@@ -303,23 +302,11 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
if (dev->drv->tx_aligned4_skbs)
mt76_insert_hdr_pad(skb);
- dma_sync_single_for_cpu(dev->dev, t->dma_addr, sizeof(t->txwi),
- DMA_TO_DEVICE);
- ret = dev->drv->tx_prepare_skb(dev, &t->txwi, skb, qid, wcid, sta,
- &tx_info);
- dma_sync_single_for_device(dev->dev, t->dma_addr, sizeof(t->txwi),
- DMA_TO_DEVICE);
- if (ret < 0)
- goto free;
-
- len = skb->len - skb->data_len;
+ len = skb_headlen(skb);
addr = dma_map_single(dev->dev, skb->data, len, DMA_TO_DEVICE);
- if (dma_mapping_error(dev->dev, addr)) {
- ret = -ENOMEM;
+ if (dma_mapping_error(dev->dev, addr))
goto free;
- }
- n = 0;
buf[n].addr = t->dma_addr;
buf[n++].len = dev->drv->txwi_size;
buf[n].addr = addr;
@@ -338,13 +325,23 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
buf[n++].len = iter->len;
}
- if (q->queued + (n + 1) / 2 >= q->ndesc - 1)
+ dma_sync_single_for_cpu(dev->dev, t->dma_addr, sizeof(t->txwi),
+ DMA_TO_DEVICE);
+ ret = dev->drv->tx_prepare_skb(dev, &t->txwi, skb, qid, wcid, sta,
+ &tx_info);
+ dma_sync_single_for_device(dev->dev, t->dma_addr, sizeof(t->txwi),
+ DMA_TO_DEVICE);
+ if (ret < 0)
goto unmap;
+ if (q->queued + (n + 1) / 2 >= q->ndesc - 1) {
+ ret = -ENOMEM;
+ goto unmap;
+ }
+
return mt76_dma_add_buf(dev, q, buf, n, tx_info, skb, t);
unmap:
- ret = -ENOMEM;
for (n--; n > 0; n--)
dma_unmap_single(dev->dev, buf[n].addr, buf[n].len,
DMA_TO_DEVICE);
--
2.20.1
^ permalink raw reply related
* [PATCH v2 2/4] mt76: mmio: move mt76_insert_hdr_pad in mt76_dma_tx_queue_skb
From: Lorenzo Bianconi @ 2019-03-14 13:54 UTC (permalink / raw)
To: nbd; +Cc: ryder.lee, roychl666, linux-wireless, lorenzo.bianconi
In-Reply-To: <cover.1552570806.git.lorenzo@kernel.org>
Introduce tx_aligned4_skbs in mt76_driver_ops and move
mt76_insert_hdr_pad in mt76_dma_tx_queue_skb. This is a preliminary
patch in order to unify tx dma mapping for mt76x02 and new chipsets
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/dma.c | 3 +++
drivers/net/wireless/mediatek/mt76/mt76.h | 1 +
drivers/net/wireless/mediatek/mt76/mt76x0/pci.c | 1 +
drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c | 10 +++++-----
drivers/net/wireless/mediatek/mt76/mt76x2/pci.c | 1 +
5 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index fb1cc575e83f..33725b839983 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -300,6 +300,9 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
}
skb->prev = skb->next = NULL;
+ if (dev->drv->tx_aligned4_skbs)
+ mt76_insert_hdr_pad(skb);
+
dma_sync_single_for_cpu(dev->dev, t->dma_addr, sizeof(t->txwi),
DMA_TO_DEVICE);
ret = dev->drv->tx_prepare_skb(dev, &t->txwi, skb, qid, wcid, sta,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index c8ab74ae243e..48d3c03e46a7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -288,6 +288,7 @@ struct mt76_hw_cap {
};
struct mt76_driver_ops {
+ bool tx_aligned4_skbs;
u16 txwi_size;
void (*update_survey)(struct mt76_dev *dev);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
index f302162036d0..e07a62246db7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
@@ -164,6 +164,7 @@ mt76x0e_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct mt76_driver_ops drv_ops = {
.txwi_size = sizeof(struct mt76x02_txwi),
+ .tx_aligned4_skbs = true,
.update_survey = mt76x02_update_channel,
.tx_prepare_skb = mt76x02_tx_prepare_skb,
.tx_complete_skb = mt76x02_tx_complete_skb,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
index 0a3a3605c151..708f2c65d3fd 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
@@ -152,20 +152,20 @@ int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
u32 *tx_info)
{
struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct mt76x02_txwi *txwi = txwi_ptr;
- int qsel = MT_QSEL_EDCA;
- int pid;
+ int hdrlen, len, pid, qsel = MT_QSEL_EDCA;
if (qid == MT_TXQ_PSD && wcid && wcid->idx < 128)
mt76x02_mac_wcid_set_drop(dev, wcid->idx, false);
- mt76x02_mac_write_txwi(dev, txwi, skb, wcid, sta, skb->len);
+ hdrlen = ieee80211_hdrlen(hdr->frame_control);
+ len = skb->len - (hdrlen & 2);
+ mt76x02_mac_write_txwi(dev, txwi, skb, wcid, sta, len);
pid = mt76_tx_status_skb_add(mdev, wcid, skb);
txwi->pktid = pid;
- mt76_insert_hdr_pad(skb);
-
if (pid >= MT_PACKET_ID_FIRST)
qsel = MT_QSEL_MGMT;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c
index 6274655e1f7e..4747f782417a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c
@@ -32,6 +32,7 @@ mt76pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct mt76_driver_ops drv_ops = {
.txwi_size = sizeof(struct mt76x02_txwi),
+ .tx_aligned4_skbs = true,
.update_survey = mt76x02_update_channel,
.tx_prepare_skb = mt76x02_tx_prepare_skb,
.tx_complete_skb = mt76x02_tx_complete_skb,
--
2.20.1
^ permalink raw reply related
* [PATCH v2 1/4] mt76: move mt76x02_insert_hdr_pad in mt76-core module
From: Lorenzo Bianconi @ 2019-03-14 13:54 UTC (permalink / raw)
To: nbd; +Cc: ryder.lee, roychl666, linux-wireless, lorenzo.bianconi
In-Reply-To: <cover.1552570806.git.lorenzo@kernel.org>
Move mt76x02_insert_hdr_pad in m76-core and rename it in
mt76_insert_hdr_pad in order to be used in mt76_dma_tx_queue_skb.
This is a preliminary patch in order to properly support tx dma
mapping for new chipsets (e.g. mt7615)
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 14 ++++++++++++++
drivers/net/wireless/mediatek/mt76/mt76x02.h | 1 -
.../net/wireless/mediatek/mt76/mt76x02_txrx.c | 5 +----
.../wireless/mediatek/mt76/mt76x02_usb_core.c | 2 +-
.../net/wireless/mediatek/mt76/mt76x02_util.c | 16 ----------------
5 files changed, 16 insertions(+), 22 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 57136073e1fa..c8ab74ae243e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -653,6 +653,20 @@ static inline struct mt76_tx_cb *mt76_tx_skb_cb(struct sk_buff *skb)
return ((void *) IEEE80211_SKB_CB(skb)->status.status_driver_data);
}
+static inline void mt76_insert_hdr_pad(struct sk_buff *skb)
+{
+ int len = ieee80211_get_hdrlen_from_skb(skb);
+
+ if (len % 4 == 0)
+ return;
+
+ skb_push(skb, 2);
+ memmove(skb->data, skb->data + 2, len);
+
+ skb->data[len] = 0;
+ skb->data[len + 1] = 0;
+}
+
void mt76_rx(struct mt76_dev *dev, enum mt76_rxq_id q, struct sk_buff *skb);
void mt76_tx(struct mt76_dev *dev, struct ieee80211_sta *sta,
struct mt76_wcid *wcid, struct sk_buff *skb);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index 392b96fcb520..53ec8103a268 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -163,7 +163,6 @@ void mt76x02_set_tx_ackto(struct mt76x02_dev *dev);
void mt76x02_set_coverage_class(struct ieee80211_hw *hw,
s16 coverage_class);
int mt76x02_set_rts_threshold(struct ieee80211_hw *hw, u32 val);
-int mt76x02_insert_hdr_pad(struct sk_buff *skb);
void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len);
bool mt76x02_tx_status_data(struct mt76_dev *mdev, u8 *update);
void mt76x02_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
index ce9ace11339d..0a3a3605c151 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
@@ -155,7 +155,6 @@ int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
struct mt76x02_txwi *txwi = txwi_ptr;
int qsel = MT_QSEL_EDCA;
int pid;
- int ret;
if (qid == MT_TXQ_PSD && wcid && wcid->idx < 128)
mt76x02_mac_wcid_set_drop(dev, wcid->idx, false);
@@ -165,9 +164,7 @@ int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
pid = mt76_tx_status_skb_add(mdev, wcid, skb);
txwi->pktid = pid;
- ret = mt76x02_insert_hdr_pad(skb);
- if (ret < 0)
- return ret;
+ mt76_insert_hdr_pad(skb);
if (pid >= MT_PACKET_ID_FIRST)
qsel = MT_QSEL_MGMT;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
index 8ab63255ba6f..6c3fc4cea283 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
@@ -82,7 +82,7 @@ int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
enum mt76_qsel qsel;
u32 flags;
- mt76x02_insert_hdr_pad(skb);
+ mt76_insert_hdr_pad(skb);
txwi = (struct mt76x02_txwi *)(skb->data - sizeof(struct mt76x02_txwi));
mt76x02_mac_write_txwi(dev, txwi, skb, wcid, sta, len);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index b14a55737829..81d65319d3ea 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -566,22 +566,6 @@ void mt76x02_sta_rate_tbl_update(struct ieee80211_hw *hw,
}
EXPORT_SYMBOL_GPL(mt76x02_sta_rate_tbl_update);
-int mt76x02_insert_hdr_pad(struct sk_buff *skb)
-{
- int len = ieee80211_get_hdrlen_from_skb(skb);
-
- if (len % 4 == 0)
- return 0;
-
- skb_push(skb, 2);
- memmove(skb->data, skb->data + 2, len);
-
- skb->data[len] = 0;
- skb->data[len + 1] = 0;
- return 2;
-}
-EXPORT_SYMBOL_GPL(mt76x02_insert_hdr_pad);
-
void mt76x02_remove_hdr_pad(struct sk_buff *skb, int len)
{
int hdrlen;
--
2.20.1
^ permalink raw reply related
* [PATCH v2 0/4] move skb mapping before configuring txwi
From: Lorenzo Bianconi @ 2019-03-14 13:54 UTC (permalink / raw)
To: nbd; +Cc: ryder.lee, roychl666, linux-wireless, lorenzo.bianconi
Move skb dma mapping before configuring txwi since new chipsets
(e.g. mt7615) will need dma addresses to properly configure txwi.
Introduce temporary tx_aligned4_skbs variable in order to tell mt76 layer
if it is necessary to align the 802.11 header (it will be removed as soon
as mac80211 will take care of it)
Changes since v1:
- move queue depth check after tx_prepare_skb pointer
- make mt76_inser_hdr_pad() return void
Lorenzo Bianconi (4):
mt76: move mt76x02_insert_hdr_pad in mt76-core module
mt76: mmio: move mt76_insert_hdr_pad in mt76_dma_tx_queue_skb
mt76: move skb dma mapping before running tx_prepare_skb
mt76: introduce mt76_tx_info data structure
drivers/net/wireless/mediatek/mt76/dma.c | 59 ++++++++++---------
drivers/net/wireless/mediatek/mt76/mt76.h | 24 +++++++-
.../net/wireless/mediatek/mt76/mt7603/mac.c | 2 +-
.../wireless/mediatek/mt76/mt7603/mt7603.h | 2 +-
.../net/wireless/mediatek/mt76/mt76x0/pci.c | 1 +
drivers/net/wireless/mediatek/mt76/mt76x02.h | 3 +-
.../net/wireless/mediatek/mt76/mt76x02_txrx.c | 21 +++----
.../net/wireless/mediatek/mt76/mt76x02_usb.h | 2 +-
.../wireless/mediatek/mt76/mt76x02_usb_core.c | 4 +-
.../net/wireless/mediatek/mt76/mt76x02_util.c | 16 -----
.../net/wireless/mediatek/mt76/mt76x2/pci.c | 1 +
11 files changed, 70 insertions(+), 65 deletions(-)
--
2.20.1
^ permalink raw reply
* Re: [RFC] mt76: add 3dBm for reporting txpower also for 1x1
From: Stanislaw Gruszka @ 2019-03-14 13:50 UTC (permalink / raw)
To: Felix Fietkau; +Cc: linux-wireless, Lorenzo Bianconi
In-Reply-To: <795dd253-53db-d837-4da6-6016a096cdc7@nbd.name>
On Wed, Mar 13, 2019 at 02:38:01PM +0100, Felix Fietkau wrote:
> On 2019-03-13 14:34, Stanislaw Gruszka wrote:
> > It's not clear for my why we should add 3dBm for 2x2 devices
> > and not for 1x1. 3dBm looks rater like minimal txpower and
> > hardware transmit at 3dBm + dev->txpower_cur / 2 .
> >
> > With the change reported txpower value are closer to regulatory
> > values, but honestly I have no idea what should be reported.
> >
> > Perhaps also some better comment should be added.
> >
> > Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
> The reason why we add 3dBm is because using two chains to transmit in
> the worst case (from regulatory point of view) doubles the transmit
> power (= +3dBm). There's no reason to do the same for 1x1.
Do we calculate and show correct txpower for mt76x0 then?
I have mt76x0u 50:3e:aa:a6:5d:32 and iwlmvm 1c:1b:b5:23:cf:58
devices on one laptop at the same location connected to AP.
RSSI values of both stations are quite similar:
Station 50:3e:aa:a6:5d:32 (on wlan0)
inactive time: 4971 ms
rx bytes: 11383
rx packets: 97
tx bytes: 2764
tx packets: 17
tx retries: 3
tx failed: 1
signal: -55 [-65, -55] dBm
signal avg: -57 [-65, -57] dBm
tx bitrate: 65.0 MBit/s MCS 6 short GI
rx bitrate: 6.0 MBit/s
authorized: yes
authenticated: yes
preamble: long
WMM/WME: yes
MFP: no
TDLS peer: no
Station 1c:1b:b5:23:cf:58 (on wlan0)
inactive time: 24261 ms
rx bytes: 11320
rx packets: 121
tx bytes: 2274
tx packets: 11
tx retries: 0
tx failed: 1
signal: -52 [-60, -52] dBm
signal avg: -54 [-59, -55] dBm
tx bitrate: 6.5 MBit/s MCS 0
rx bitrate: 6.0 MBit/s
authorized: yes
authenticated: yes
preamble: long
WMM/WME: yes
MFP: no
TDLS peer: no
On laptop txpower showed by iw for mt76x0u is 17 dBm , for iwlmvm
is 22 dBm (this is value from mac80211, iwlwifi does not implement
.get_txpower() callback).
I do not consider this as big issue though, but can confuse some users.
Apparently confuses me.
Stanislaw
^ permalink raw reply
* Re: [PATCH 2/2] ath9k: drop redundant code in ar9003_hw_set_channel
From: Kalle Valo @ 2019-03-14 13:28 UTC (permalink / raw)
To: Tom Psyborg; +Cc: linux-wireless
In-Reply-To: <CAKR_QVL+4f4Y8Edj_tVeDefa0YMJM6N5mrBnXUF6MnxEJ98=gQ@mail.gmail.com>
Tom Psyborg <pozega.tomislav@gmail.com> writes:
> locales problems during some system upgrades. can you fix it without
> resending?
There's actually a bigger problem, I cannot find your patches from
patchwork:
https://patchwork.kernel.org/project/linux-wireless/list/
Maybe patchwork dropped them because of the charset problem? Anyway, you
have to resend so that I see the patches in patchwork.
--
Kalle Valo
^ permalink raw reply
* Re: [PATCH v5 03/18] wlcore: simplify/fix/optimize reg_ch_conf_pending operations
From: Kalle Valo @ 2019-03-14 13:16 UTC (permalink / raw)
To: Fenghua Yu
Cc: Thomas Gleixner, Ingo Molnar, H Peter Anvin, Dave Hansen,
Paolo Bonzini, Ashok Raj, Peter Zijlstra, Xiaoyao Li ,
Michael Chan, Ravi V Shankar, linux-kernel, x86, linux-wireless,
netdev, kvm
In-Reply-To: <1552431636-31511-4-git-send-email-fenghua.yu@intel.com>
Fenghua Yu <fenghua.yu@intel.com> writes:
> From: Paolo Bonzini <pbonzini@redhat.com>
>
> Bitmaps are defined on unsigned longs, so the usage of u32[2] in the
> wlcore driver is incorrect. As noted by Peter Zijlstra, casting arrays
> to a bitmap is incorrect for big-endian architectures.
>
> When looking at it I observed that:
>
> - operations on reg_ch_conf_pending is always under the wl_lock mutex,
> so set_bit is overkill
>
> - the only case where reg_ch_conf_pending is accessed a u32 at a time is
> unnecessary too.
>
> This patch cleans up everything in this area, and changes tmp_ch_bitmap
> to have the proper alignment.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
[...]
> int wlcore_cmd_regdomain_config_locked(struct wl1271 *wl)
> {
> struct wl12xx_cmd_regdomain_dfs_config *cmd = NULL;
> int ret = 0, i, b, ch_bit_idx;
> - u32 tmp_ch_bitmap[2];
> + u32 tmp_ch_bitmap[2] __aligned(sizeof(unsigned long));
> struct wiphy *wiphy = wl->hw->wiphy;
> struct ieee80211_supported_band *band;
> bool timeout = false;
[...]
> @@ -1754,8 +1751,8 @@ int wlcore_cmd_regdomain_config_locked(struct wl1271 *wl)
> goto out;
> }
>
> - cmd->ch_bit_map1 = cpu_to_le32(tmp_ch_bitmap[0]);
> - cmd->ch_bit_map2 = cpu_to_le32(tmp_ch_bitmap[1]);
> + cmd->ch_bit_map1 = tmp_ch_bitmap[0];
> + cmd->ch_bit_map2 = tmp_ch_bitmap[1];
Will sparse still be happy? AFAICS you are now assigning u32 to __le32:
struct wl12xx_cmd_regdomain_dfs_config {
struct wl1271_cmd_header header;
__le32 ch_bit_map1;
__le32 ch_bit_map2;
Also this doesn't depend on anything else from this patchset, right? So
I could apply this directly?
--
Kalle Valo
^ permalink raw reply
* Re: wil6210 firmware version
From: Robert Marko @ 2019-03-14 10:05 UTC (permalink / raw)
To: merez; +Cc: linux-wireless, wil6210, linux-wireless-owner
In-Reply-To: <0aabbc6e74fefa8bd5a094dc84b1f87c@codeaurora.org>
Biggest thing would be Channel 4 support as it is supported by driver
but requires FW support also.
But I would also like 20 station limit instead of 8.
Cheers
Robert Marko
On Thu, 14 Mar 2019 at 11:03, <merez@codeaurora.org> wrote:
>
> On 2019-03-14 11:07, Robert Marko wrote:
> > Hi,
> > I am working on OpenWrt support for device using wil6210 card.
> > I am using firmware and board file provided in linux-firmware for its
> > development but it appears tha most of newer features that driver
> > enables are firmware dependant and version 5.2 in linux-firmware is
> > too old to expose those.
> >
> > Is there any chance of QCA pushing updated version to linux-firmware?
> >
> > Thanks
> > Robert Marko
>
> Is there any specific feature you are interested in?
>
> --
> Maya Erez
> Qualcomm Israel, Inc. on behalf of Qualcomm Innovation Center, Inc.
> The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a
> Linux Foundation Collaborative Project
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox