* Re: [PATCH v2 2/3] mac80211: mesh: improve path resolving time
From: Yeoh Chun-Yeow @ 2016-07-18 16:59 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org
> To improve that, added an 'immediate' flag to be used when the path needs to be resolved.
> Once set, a PREQ frame will be send w/o considering the MinInterval parameter.
Suggest that you try to reduce the mesh_hwmp_preq_min_interval to your
desired value instead of introducing a new patch specific to your use
case.
IEEE 802.11-2012 has defined dot11MeshHWMPpreqMinInterval attribute to
specify the minimum interval of time during which a mesh STA can send
only one Action frame containing a PREQ element. This is to avoid
flooding of broadcast PREQ frame especially when the number of mesh
STA is increased.
---
Chun-Yeow
^ permalink raw reply
* Re: [PATCH v2] cfg80211: Allow differnt beacon interval if driver supports
From: Kalle Valo @ 2016-07-18 16:25 UTC (permalink / raw)
To: Purushottam Kushwaha
Cc: johannes, linux-wireless, jouni, usdutt, ganeshk, mkalikot,
amarnath
In-Reply-To: <1468849985-6881-1-git-send-email-pkushwah@qti.qualcomm.com>
Purushottam Kushwaha <pkushwah@qti.qualcomm.com> writes:
> Driver may allow support for different beacon interval on virtual interfaces.
> Allow if such support is advertised by driver. This adds new ext_feature as
> NL80211_EXT_FEATURE_DIFF_BEACON_INTERVAL.
>
> Signed-off-by: Purushottam Kushwaha <pkushwah@qti.qualcomm.com>
A typo in the title: "differnt"
--
Kalle Valo
^ permalink raw reply
* [PATCH v2] cfg80211: Allow differnt beacon interval if driver supports
From: Purushottam Kushwaha @ 2016-07-18 13:53 UTC (permalink / raw)
To: johannes
Cc: linux-wireless, jouni, usdutt, ganeshk, mkalikot, amarnath,
pkushwah
Driver may allow support for different beacon interval on virtual interfaces.
Allow if such support is advertised by driver. This adds new ext_feature as
NL80211_EXT_FEATURE_DIFF_BEACON_INTERVAL.
Signed-off-by: Purushottam Kushwaha <pkushwah@qti.qualcomm.com>
---
include/uapi/linux/nl80211.h | 3 +++
net/wireless/util.c | 4 ++++
2 files changed, 7 insertions(+)
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 2206941..a910d0e 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -4551,6 +4551,8 @@ enum nl80211_feature_flags {
* (if available).
* @NL80211_EXT_FEATURE_SET_SCAN_DWELL: This driver supports configuration of
* channel dwell time.
+ * @NL80211_EXT_FEATURE_DIFF_BEACON_INTERVAL: This driver supports different
+ * beacon interval on virtual interfaces.
*
* @NUM_NL80211_EXT_FEATURES: number of extended features.
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -4562,6 +4564,7 @@ enum nl80211_ext_feature_index {
NL80211_EXT_FEATURE_SCAN_START_TIME,
NL80211_EXT_FEATURE_BSS_PARENT_TSF,
NL80211_EXT_FEATURE_SET_SCAN_DWELL,
+ NL80211_EXT_FEATURE_DIFF_BEACON_INTERVAL,
/* add new features before the definition below */
NUM_NL80211_EXT_FEATURES,
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 2443ee3..65eeb23 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1560,6 +1560,10 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
if (!beacon_int)
return -EINVAL;
+ if (wiphy_ext_feature_isset(&rdev->wiphy,
+ NL80211_EXT_FEATURE_DIFF_BEACON_INTERVAL))
+ return 0;
+
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
if (!wdev->beacon_interval)
continue;
--
1.9.1
^ permalink raw reply related
* Re: [PATCH 3/3] mac80211: mesh: fixed HT ies in beacon template
From: Bob Copeland @ 2016-07-18 13:38 UTC (permalink / raw)
To: Yaniv Machani
Cc: linux-kernel, Meirav Kama, Johannes Berg, David S. Miller,
linux-wireless, netdev
In-Reply-To: <20160713114542.24937-1-yanivma@ti.com>
On Wed, Jul 13, 2016 at 02:45:40PM +0300, Yaniv Machani wrote:
> The HT capab info field inside the HT capab IE of the mesh beacon
> is incorrect (in the case of 20MHz channel width).
> To fix this driver will check configuration from cfg and
> will build it accordingly.
> + /* determine capability flags */
> + cap = sband->ht_cap.cap;
> +
> + /* if channel width is 20MHz - configure HT capab accordingly*/
> + if (sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20) {
> + cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
> + cap &= ~IEEE80211_HT_CAP_DSSSCCK40;
> + }
Is it required that HT capability match the HT operation in this case?
> diff --git a/net/mac80211/util.c b/net/mac80211/util.c
> index 42bf0b6..5375a82 100644
> --- a/net/mac80211/util.c
> +++ b/net/mac80211/util.c
> @@ -2349,10 +2349,7 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap,
> ht_oper->operation_mode = cpu_to_le16(prot_mode);
> ht_oper->stbc_param = 0x0000;
>
> - /* It seems that Basic MCS set and Supported MCS set
> - are identical for the first 10 bytes */
> memset(&ht_oper->basic_set, 0, 16);
> - memcpy(&ht_oper->basic_set, &ht_cap->mcs, 10);
This change doesn't look right (basic mcs set will be all zeroes) but
then, neither does the original code. Basic MCS set for a mesh STA should
be the mandatory MCSes according to 9.7.4.
--
Bob Copeland %% http://bobcopeland.com/
^ permalink raw reply
* [PATCH] bcma: allow enabling serial flash support on non-MIPS SoCs
From: Rafał Miłecki @ 2016-07-18 10:34 UTC (permalink / raw)
To: Kalle Valo, linux-wireless; +Cc: Rafał Miłecki, open list
So far we had only MIPS devices with serial flash connected to the SoC's
ChipCommon. ARM devices got a separated SPI controller and weere using
standard SPI drivers.
This has changed with the wireless SoC BCM47189B0. It's ARM based but
has serial flash attached just like older devices. This allows using
existing driver with these devices.
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
drivers/bcma/Kconfig | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig
index efdc2ae..b5c48a8 100644
--- a/drivers/bcma/Kconfig
+++ b/drivers/bcma/Kconfig
@@ -76,9 +76,16 @@ config BCMA_PFLASH
default y
config BCMA_SFLASH
- bool
- depends on BCMA_DRIVER_MIPS
+ bool "ChipCommon-attached serial flash support"
+ depends on BCMA_HOST_SOC
default y
+ help
+ Some cheap devices have serial flash connected to the ChipCommon
+ instead of independent SPI controller. It requires using a separated
+ driver that implements ChipCommon specific interface communication.
+
+ Enabling this symbol will let bcma recognize serial flash and register
+ it as platform device.
config BCMA_NFLASH
bool
--
1.8.4.5
^ permalink raw reply related
* Re: [PATCH 2/2 v4] wlcore: Add support for get_expected_throughput opcode
From: Kalle Valo @ 2016-07-18 8:43 UTC (permalink / raw)
To: Maxim Altshul
Cc: linux-kernel, Eliad Peller, Arik Nemtsov, Yaniv Machani,
linux-wireless
In-Reply-To: <20160711142251.30443-2-maxim.altshul@ti.com>
Maxim Altshul <maxim.altshul@ti.com> writes:
> Adding this opcode, allows the TI wireless driver,
> to report throughput directly from FW to mac80211.
>
> This is used mainly for mesh metric calculation.
>
> Signed-off-by: Maxim Altshul <maxim.altshul@ti.com>
[...]
> +static u32 wlcore_op_get_expected_throughput(struct ieee80211_sta *sta)
> +{
> + struct wl1271_station *wl_sta = (struct wl1271_station *)sta->drv_priv;
> + struct wl1271 *wl = wl_sta->wl;
> + u8 hlid = wl_sta->hlid;
> +
> + /* return in units of Kbps */
> + return (wl->links[hlid].fw_rate_mbps * 1000);
The indentation looks wrong, but I can fix it before I apply the patch.
--
Kalle Valo
^ permalink raw reply
* Re: [linux-sunxi] Re: [PATCH 1/4] brcmfmac: Add brcm,nvram_file_name dt property
From: Arend Van Spriel @ 2016-07-18 7:51 UTC (permalink / raw)
To: Rob Herring, Arnd Bergmann
Cc: Jonas Gorski, Hans de Goede, Kalle Valo, Priit Laes,
John W . Linville, Arend van Spriel, Maxime Ripard, Chen-Yu Tsai,
linux-wireless@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, devicetree, linux-sunxi
In-Reply-To: <20160717214502.GA11498@rob-hp-laptop>
On 17-7-2016 23:45, Rob Herring wrote:
> On Thu, Jul 07, 2016 at 10:46:28AM +0200, Arnd Bergmann wrote:
>> On Wednesday, July 6, 2016 9:19:41 PM CEST Arend Van Spriel wrote:
>>> On 6-7-2016 15:42, Arnd Bergmann wrote:
>>>> On Wednesday, July 6, 2016 10:08:55 AM CEST Arend Van Spriel wrote:
>>>>> On Tue, Jul 5, 2016 at 3:43 PM, Arnd Bergmann <arnd@arndb.de> wrote:
>>>> All existing uses of the model property in arch/arm/boot/dts and most of
>>>> the ones in arch/powerpc/boot/dts are against the intended usage in
>>>> one way or another, but adding different kind of incorrect usage won't
>>>> improve that.
>>>>
>>>> The only way I can see the model property being used correctly would
>>>> be to have it match the first entry in the compatible property, but
>>>> that is completely redundant, so we tend to omit it, except for the
>>>> root node in which it is required. For the root node however, the
>>>> historic practice that has crept in on ARM is to put something completely
>>>> different in there, which is a human-readable description of the
>>>> machine rather than something we can use as a unique indentifier.
>>>>
>>>> I'd just consider the "model" property burned, and not use it for anything
>>>> that doesn't already use it, just like we handle "device_type": a few
>>>> things require it, nothing else should use it.
>>>
>>> If that is the agreed approach in devicetree arena I am fine with it. I
>>> have been unaware of this and just looked at the suggestion from Jonas
>>> seeing a solution to the problem at hand.
>>
>> I don't think it has been discussed or decided before as the question
>> has not come up, so for now this is my personal view. Maybe one of
>> the devicetree maintainers can comment on this.
>
> Back from vacation and getting caught up.
>
> I agree with Arnd here. In my view model is the OEM branding on the
> device, compatible is the h/w. If you have different firmware related
> files, that goes beyond OEM branding.
Thanks, Rob
We are talking about hardware variants here. So using the model property
is off the table.
Regards,
Arend
^ permalink raw reply
* Re: [RFC] rfkill: Add new ACPI device for Realtek serial BT
From: Kalle Valo @ 2016-07-18 7:18 UTC (permalink / raw)
To: Larry Finger; +Cc: devel, linux-wireless
In-Reply-To: <1468609696-8828-1-git-send-email-Larry.Finger@lwfinger.net>
Larry Finger <Larry.Finger@lwfinger.net> writes:
> The Realtek RTL8723BS chips, which are connected via SDIO, also contain
> a serial Bluetooth device. In order for BT to work, the device must be
> added to the acpi_device_id table.
>
> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
> ---
>
> I have no idea if this device should be added here, or if the device could
> be added to some structure supplied at device startup. If anyone has any
> suggestions, please let me know.
>
> Thanks,
>
> Larry
> ---
> net/rfkill/rfkill-gpio.c | 1 +
> 1 file changed, 1 insertion(+)
BTW Johannes maintains rfkill, not me.
--
Kalle Valo
^ permalink raw reply
* Further question about MAC80211
From: Joan Josep Aleixendri @ 2016-07-18 6:23 UTC (permalink / raw)
To: linux-wireless
Hello there!
I'd like to thank you for your time and all the information you gave me
last monday; I'm still reading and studying it!
The main goal of our project is to dinamically control the troughtput of
each virtual interface (ViF) depending on how good the connection is
between 2 stations and depending on the others ViF throughtputs our
station (STA structure or local) may have instantiated.
To do that we estimate the airtime of the packet that's about to be send
and depending on the channel usage we decide if we let the packet flow
or if we should enqueue or even drop it!
The problems begin when we enqueue a packet that has the txpending flag
set (it's been in the AC queue once) and our algorithm decides to
enqueue it again or drop the packet. The tx_pending tasklet begins to
loop the same packet on tx_frags (stopping the tasklet for some time is
not a slution either...). The results of enqueueing is connection lost
or a huge delay on some packets.
If we drop any packet in tx_frags() mac80211 goes crazy and may
instantly drop connection and destroy the vif.
Is there any more projects I should check out that drops or enqueue
packets on mac80211 when it's not supposed to be enqueuing?
Thanks again for your precious time!
Joan Josep Aleixendri
^ permalink raw reply
* Re: [linux-sunxi] Re: [PATCH 1/4] brcmfmac: Add brcm,nvram_file_name dt property
From: Rob Herring @ 2016-07-17 21:45 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Arend Van Spriel, Jonas Gorski, Hans de Goede, Kalle Valo,
Priit Laes, John W . Linville, Arend van Spriel, Maxime Ripard,
Chen-Yu Tsai, linux-wireless@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, devicetree, linux-sunxi
In-Reply-To: <3996482.D5xdKXDiGl@wuerfel>
On Thu, Jul 07, 2016 at 10:46:28AM +0200, Arnd Bergmann wrote:
> On Wednesday, July 6, 2016 9:19:41 PM CEST Arend Van Spriel wrote:
> > On 6-7-2016 15:42, Arnd Bergmann wrote:
> > > On Wednesday, July 6, 2016 10:08:55 AM CEST Arend Van Spriel wrote:
> > >> On Tue, Jul 5, 2016 at 3:43 PM, Arnd Bergmann <arnd@arndb.de> wrote:
> > > All existing uses of the model property in arch/arm/boot/dts and most of
> > > the ones in arch/powerpc/boot/dts are against the intended usage in
> > > one way or another, but adding different kind of incorrect usage won't
> > > improve that.
> > >
> > > The only way I can see the model property being used correctly would
> > > be to have it match the first entry in the compatible property, but
> > > that is completely redundant, so we tend to omit it, except for the
> > > root node in which it is required. For the root node however, the
> > > historic practice that has crept in on ARM is to put something completely
> > > different in there, which is a human-readable description of the
> > > machine rather than something we can use as a unique indentifier.
> > >
> > > I'd just consider the "model" property burned, and not use it for anything
> > > that doesn't already use it, just like we handle "device_type": a few
> > > things require it, nothing else should use it.
> >
> > If that is the agreed approach in devicetree arena I am fine with it. I
> > have been unaware of this and just looked at the suggestion from Jonas
> > seeing a solution to the problem at hand.
>
> I don't think it has been discussed or decided before as the question
> has not come up, so for now this is my personal view. Maybe one of
> the devicetree maintainers can comment on this.
Back from vacation and getting caught up.
I agree with Arnd here. In my view model is the OEM branding on the
device, compatible is the h/w. If you have different firmware related
files, that goes beyond OEM branding.
Rob
^ permalink raw reply
* Re: [PATCH] ath9k: fix GPIO mask for AR9462 and AR9565
From: Stefan Lippers-Hollmann @ 2016-07-17 21:05 UTC (permalink / raw)
To: miaoqing; +Cc: kvalo, linux-wireless, ath9k-devel, sudipm.mukherjee
In-Reply-To: <1464932817-30988-1-git-send-email-miaoqing@codeaurora.org>
Hi
On 2016-06-03, miaoqing@codeaurora.org wrote:
> From: Miaoqing Pan <miaoqing@codeaurora.org>
>
> The incorrect GPIO mask cause kernel warning, when AR9462 access GPIO11.
> Also fix the mask for AR9565.
[...]
I think I'm seeing a very similar issue on AR5008/ AR5416+AR2133 and
4.7-rc7 (mainline v4.7-rc7-92-g47ef4ad, to be exact).
[ 4.958874] ath9k 0000:02:02.0: enabling device (0000 -> 0002)
[...]
[ 5.401086] ------------[ cut here ]------------
[ 5.401093] WARNING: CPU: 1 PID: 1159 at /build/linux-aptosid-4.7~rc7/drivers/net/wireless/ath/ath9k/hw.c:2776 ath9k_hw_gpio_get+0x148/0x1a0 [ath9k_hw]
[ 5.401116] Modules linked in: iTCO_wdt gpio_ich iTCO_vendor_support evdev intel_rapl x86_pkg_temp_thermal intel_powerclamp coretemp ir_lirc_codec lirc_dev kvm_intel kvm irqbypass crct10dif_pclmul crc32_pclmul rtl2832_sdr videobuf2_vmalloc videobuf2_memops videobuf2_v4l2 videobuf2_core videodev ghash_clmulni_intel fc0013 rtl2832 i2c_mux regmap_i2c sha256_ssse3 sha256_generic drbg ansi_cprng rc_medion_x10_digitainer dvb_usb_rtl28xxu dvb_usb_v2 dvb_usb_dw2102(+) dvb_usb aesni_intel dvb_core aes_x86_64 lrw ati_remote media gf128mul glue_helper ablk_helper cryptd intel_cstate intel_rapl_perf snd_hda_codec_hdmi(+) i915 snd_hda_codec_realtek snd_hda_codec_generic pcspkr serio_raw i2c_i801 ath9k(+) ath9k_common video ath9k_hw i2c_algo_bit drm_kms_helper ath snd_hda_intel drm snd_hda_codec mac80211 snd_hda_core
[ 5.401135] snd_hwdep snd_pcm cfg80211 i2c_core intel_gtt rfkill snd_timer syscopyarea lpc_ich sysfillrect snd sg sysimgblt mfd_core mei_me soundcore fb_sys_fops mei nuvoton_cir floppy(+) rc_core button w83627ehf hwmon_vid parport_pc ppdev lp parport autofs4 ext4 crc16 jbd2 mbcache hid_generic usbhid hid dm_mod sd_mod sr_mod cdrom ohci_pci crc32c_intel psmouse r8169 ahci libahci libata scsi_mod xhci_pci xhci_hcd ohci_hcd e100 mii ehci_pci ehci_hcd usbcore usb_common e1000e ptp pps_core fjes
[ 5.401137] CPU: 1 PID: 1159 Comm: systemd-udevd Not tainted 4.7.0-rc7-aptosid-amd64 #1 aptosid 4.7~rc7-1~git92.slh.3
[ 5.401138] Hardware name: /DH67CL, BIOS BLH6710H.86A.0160.2012.1204.1156 12/04/2012
[ 5.401140] 0000000000000286 00000000f912d633 ffffffff81290fd3 0000000000000000
[ 5.401141] 0000000000000000 ffffffff81063fd4 ffff88040c6dc018 0000000000000000
[ 5.401143] 0000000000000002 0000000000000000 0000000000000100 ffff88040c6dc018
[ 5.401143] Call Trace:
[ 5.401148] [<ffffffff81290fd3>] ? dump_stack+0x5c/0x79
[ 5.401150] [<ffffffff81063fd4>] ? __warn+0xb4/0xd0
[ 5.401153] [<ffffffffa0668fb8>] ? ath9k_hw_gpio_get+0x148/0x1a0 [ath9k_hw]
[ 5.401156] [<ffffffffa0669653>] ? ath9k_hw_fill_cap_info+0x163/0x830 [ath9k_hw]
[ 5.401159] [<ffffffffa066a384>] ? ath9k_hw_init+0x664/0xb10 [ath9k_hw]
[ 5.401167] [<ffffffffa06fa7df>] ? ath9k_init_device+0x4df/0xe00 [ath9k]
[ 5.401170] [<ffffffff810b1e51>] ? request_threaded_irq+0xf1/0x1a0
[ 5.401176] [<ffffffffa070a259>] ? ath_pci_probe+0x1c9/0x370 [ath9k]
[ 5.401178] [<ffffffff812dad6a>] ? local_pci_probe+0x3a/0x90
[ 5.401179] [<ffffffff812dbccf>] ? pci_match_device+0xcf/0xf0
[ 5.401180] [<ffffffff812dc08b>] ? pci_device_probe+0xfb/0x140
[ 5.401183] [<ffffffff813b7dcd>] ? driver_probe_device+0x1ed/0x2b0
[ 5.401184] [<ffffffff813b7f1f>] ? __driver_attach+0x8f/0xa0
[ 5.401185] [<ffffffff813b7e90>] ? driver_probe_device+0x2b0/0x2b0
[ 5.401186] [<ffffffff813b5e12>] ? bus_for_each_dev+0x62/0xb0
[ 5.401188] [<ffffffff813b71ca>] ? bus_add_driver+0x19a/0x210
[ 5.401189] [<ffffffffa0718000>] ? 0xffffffffa0718000
[ 5.401190] [<ffffffff813b85b2>] ? driver_register+0x52/0xc0
[ 5.401195] [<ffffffffa0718005>] ? ath9k_init+0x5/0x34 [ath9k]
[ 5.401197] [<ffffffff81002147>] ? do_one_initcall+0x47/0x180
[ 5.401199] [<ffffffff8111b0a8>] ? do_init_module+0x51/0x1b9
[ 5.401201] [<ffffffff810d6e37>] ? load_module+0x1f77/0x23a0
[ 5.401202] [<ffffffff810d4330>] ? __symbol_put+0x80/0x80
[ 5.401205] [<ffffffff812277ac>] ? security_capable+0x3c/0x50
[ 5.401207] [<ffffffff810d7462>] ? SYSC_finit_module+0xc2/0xd0
[ 5.401210] [<ffffffff8153cd72>] ? entry_SYSCALL_64_fastpath+0x1a/0xa4
[ 5.401211] ---[ end trace ac762697fb0d9f1d ]---
[ 5.401211] ------------[ cut here ]------------
[ 5.401214] WARNING: CPU: 1 PID: 1159 at /build/linux-aptosid-4.7~rc7/drivers/net/wireless/ath/ath9k/hw.c:2796 ath9k_hw_gpio_get+0xb4/0x1a0 [ath9k_hw]
[ 5.401234] Modules linked in: iTCO_wdt gpio_ich iTCO_vendor_support evdev intel_rapl x86_pkg_temp_thermal intel_powerclamp coretemp ir_lirc_codec lirc_dev kvm_intel kvm irqbypass crct10dif_pclmul crc32_pclmul rtl2832_sdr videobuf2_vmalloc videobuf2_memops videobuf2_v4l2 videobuf2_core videodev ghash_clmulni_intel fc0013 rtl2832 i2c_mux regmap_i2c sha256_ssse3 sha256_generic drbg ansi_cprng rc_medion_x10_digitainer dvb_usb_rtl28xxu dvb_usb_v2 dvb_usb_dw2102(+) dvb_usb aesni_intel dvb_core aes_x86_64 lrw ati_remote media gf128mul glue_helper ablk_helper cryptd intel_cstate intel_rapl_perf snd_hda_codec_hdmi(+) i915 snd_hda_codec_realtek snd_hda_codec_generic pcspkr serio_raw i2c_i801 ath9k(+) ath9k_common video ath9k_hw i2c_algo_bit drm_kms_helper ath snd_hda_intel drm snd_hda_codec mac80211 snd_hda_core
[ 5.401254] snd_hwdep snd_pcm cfg80211 i2c_core intel_gtt rfkill snd_timer syscopyarea lpc_ich sysfillrect snd sg sysimgblt mfd_core mei_me soundcore fb_sys_fops mei nuvoton_cir floppy(+) rc_core button w83627ehf hwmon_vid parport_pc ppdev lp parport autofs4 ext4 crc16 jbd2 mbcache hid_generic usbhid hid dm_mod sd_mod sr_mod cdrom ohci_pci crc32c_intel psmouse r8169 ahci libahci libata scsi_mod xhci_pci xhci_hcd ohci_hcd e100 mii ehci_pci ehci_hcd usbcore usb_common e1000e ptp pps_core fjes
[ 5.401255] CPU: 1 PID: 1159 Comm: systemd-udevd Tainted: G W 4.7.0-rc7-aptosid-amd64 #1 aptosid 4.7~rc7-1~git92.slh.3
[ 5.401256] Hardware name: /DH67CL, BIOS BLH6710H.86A.0160.2012.1204.1156 12/04/2012
[ 5.401257] 0000000000000286 00000000f912d633 ffffffff81290fd3 0000000000000000
[ 5.401258] 0000000000000000 ffffffff81063fd4 ffff88040c6dc018 0000000000000000
[ 5.401260] 0000000000000002 0000000000000000 0000000000000100 ffff88040c6dc018
[ 5.401260] Call Trace:
[ 5.401262] [<ffffffff81290fd3>] ? dump_stack+0x5c/0x79
[ 5.401263] [<ffffffff81063fd4>] ? __warn+0xb4/0xd0
[ 5.401266] [<ffffffffa0668f24>] ? ath9k_hw_gpio_get+0xb4/0x1a0 [ath9k_hw]
[ 5.401268] [<ffffffffa0669653>] ? ath9k_hw_fill_cap_info+0x163/0x830 [ath9k_hw]
[ 5.401271] [<ffffffffa066a384>] ? ath9k_hw_init+0x664/0xb10 [ath9k_hw]
[ 5.401275] [<ffffffffa06fa7df>] ? ath9k_init_device+0x4df/0xe00 [ath9k]
[ 5.401277] [<ffffffff810b1e51>] ? request_threaded_irq+0xf1/0x1a0
[ 5.401282] [<ffffffffa070a259>] ? ath_pci_probe+0x1c9/0x370 [ath9k]
[ 5.401283] [<ffffffff812dad6a>] ? local_pci_probe+0x3a/0x90
[ 5.401284] [<ffffffff812dbccf>] ? pci_match_device+0xcf/0xf0
[ 5.401285] [<ffffffff812dc08b>] ? pci_device_probe+0xfb/0x140
[ 5.401287] [<ffffffff813b7dcd>] ? driver_probe_device+0x1ed/0x2b0
[ 5.401288] [<ffffffff813b7f1f>] ? __driver_attach+0x8f/0xa0
[ 5.401289] [<ffffffff813b7e90>] ? driver_probe_device+0x2b0/0x2b0
[ 5.401290] [<ffffffff813b5e12>] ? bus_for_each_dev+0x62/0xb0
[ 5.401291] [<ffffffff813b71ca>] ? bus_add_driver+0x19a/0x210
[ 5.401292] [<ffffffffa0718000>] ? 0xffffffffa0718000
[ 5.401293] [<ffffffff813b85b2>] ? driver_register+0x52/0xc0
[ 5.401297] [<ffffffffa0718005>] ? ath9k_init+0x5/0x34 [ath9k]
[ 5.401298] [<ffffffff81002147>] ? do_one_initcall+0x47/0x180
[ 5.401300] [<ffffffff8111b0a8>] ? do_init_module+0x51/0x1b9
[ 5.401301] [<ffffffff810d6e37>] ? load_module+0x1f77/0x23a0
[ 5.401303] [<ffffffff810d4330>] ? __symbol_put+0x80/0x80
[ 5.401304] [<ffffffff812277ac>] ? security_capable+0x3c/0x50
[ 5.401306] [<ffffffff810d7462>] ? SYSC_finit_module+0xc2/0xd0
[ 5.401307] [<ffffffff8153cd72>] ? entry_SYSCALL_64_fastpath+0x1a/0xa4
[ 5.401308] ---[ end trace ac762697fb0d9f1e ]---
[ 5.403236] ath: EEPROM regdomain: 0x809c
[ 5.403236] ath: EEPROM indicates we should expect a country code
[ 5.403237] ath: doing EEPROM country->regdmn map search
[ 5.403237] ath: country maps to regdmn code: 0x52
[ 5.403238] ath: Country alpha2 being used: CN
[ 5.403238] ath: Regpair used: 0x52
[...]
[ 5.411361] ieee80211 phy0: Selected rate control algorithm 'minstrel_ht'
[ 5.411655] ieee80211 phy0: Atheros AR5416 MAC/BB Rev:2 AR2133 RF Rev:81 mem=0xffffc90002aa0000, irq=18
[ 5.414043] ath9k 0000:02:02.0 wlp2s2: renamed from wlan0
02:02.0 Network controller [0280]: Qualcomm Atheros AR5416 Wireless Network Adapter [AR5008 802.11(a)bgn] [168c:0023] (rev 01)
Subsystem: Qualcomm Atheros AR5416 Wireless Network Adapter [AR5008 802.11(a)bgn] [168c:3071]
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz+ UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 168, Cache Line Size: 64 bytes
Interrupt: pin A routed to IRQ 18
Region 0: Memory at fe100000 (32-bit, non-prefetchable) [size=64K]
Capabilities: [40] #80 [0000]
Kernel driver in use: ath9k
Kernel modules: ath9k
Bisecting leads me to:
$ git bisect log
git bisect start 'drivers/net/wireless/ath/'
# good: [2dcd0af568b0cf583645c8a317dd12e344b1c72a] Linux 4.6
git bisect good 2dcd0af568b0cf583645c8a317dd12e344b1c72a
# bad: [47ef4ad2684d380dd6d596140fb79395115c3950] Merge tag 'for-linus-20160715' of git://git.infradead.org/linux-mtd
git bisect bad 47ef4ad2684d380dd6d596140fb79395115c3950
# bad: [b131129d96575479e2447d134cb1797cf430b3a4] ath10k: fix calibration init sequence of qca99x0
git bisect bad b131129d96575479e2447d134cb1797cf430b3a4
# good: [27ae9cd258a84ce7259afbee38dbe7841e723a68] ath9k: enable manual peak cal for all ar9300 chips
git bisect good 27ae9cd258a84ce7259afbee38dbe7841e723a68
# bad: [9d71d47eed20f34620e54e29bcc90f959d5873b8] ath10k: fix tx hang
git bisect bad 9d71d47eed20f34620e54e29bcc90f959d5873b8
# bad: [c8770bcf5cefa8cbfae21c07c4fe3428f5a9d42a] ath9k: Allow platform override BTCoex pin
git bisect bad c8770bcf5cefa8cbfae21c07c4fe3428f5a9d42a
# good: [c8c91b02a8ddb802259b712245ee97f9c3067a7f] ath9k_htc: fix up indents with spaces
git bisect good c8c91b02a8ddb802259b712245ee97f9c3067a7f
# bad: [b2d70d4944c1789bc64376ad97a811f37e230c87] ath9k: make GPIO API to support both of WMAC and SOC
git bisect bad b2d70d4944c1789bc64376ad97a811f37e230c87
Reverting this, and the other patches depending on it, fixes the
problem for me:
e024111f6946f45cf1559a8c6fd48d2d0f696d07 Revert "ath9k: fix GPIO mask for AR9462 and AR9565"
db2221901fbded787daed153281ed875de489692 Revert "ath9k: free GPIO resource for SOC GPIOs"
c7212b7136ba69efb9785df68b669381cb893920 Revert "ath9k: fix BTCoex configuration for SOC chips"
dfcf02cd2998e2240b2bc7b4f4412578b8070bdb Revert "ath9k: fix BTCoex access invalid registers for SOC chips"
668ae0a3e48ac6811f431915b466514bf167e2f4 Revert "ath9k: add bits definition of BTCoex MODE2/3 for SOC chips"
c8770bcf5cefa8cbfae21c07c4fe3428f5a9d42a Revert "ath9k: Allow platform override BTCoex pin"
79d4db1214a0c7b1818aaf64d0606b17ff1acea7 Revert "ath9k: cleanup led_pin initial"
b2d70d4944c1789bc64376ad97a811f37e230c87 Revert "ath9k: make GPIO API to support both of WMAC and SOC"
a01ab81b09c55025365c1de1345b941a18e05529 Revert "ath9k: define correct GPIO numbers and bits mask"
AR9285 (168c:002b) is fine either way.
Regards
Stefan Lippers-Hollmann
^ permalink raw reply
* [PATCH] cfg80211: fix missing break in NL8211_CHAN_WIDTH_80P80 case
From: Colin King @ 2016-07-17 18:55 UTC (permalink / raw)
To: Johannes Berg, David S . Miller, linux-wireless, netdev; +Cc: linux-kernel
From: Colin Ian King <colin.king@canonical.com>
The switch on chandef->width is missing a break on the
NL8211_CHAN_WIDTH_80P80 case; currently we get a WARN_ON when
center_freq2 is non-zero because of the missing break.
Signed-off-by: Colin Ian King <colin.king@canonical.com>
---
net/wireless/chan.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index b0e11b6..0f50622 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -513,6 +513,7 @@ static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy,
r = cfg80211_get_chans_dfs_available(wiphy,
chandef->center_freq2,
width);
+ break;
default:
WARN_ON(chandef->center_freq2);
break;
--
2.8.1
^ permalink raw reply related
* [PATCH v5] wlcore: spi: add wl18xx support
From: Reizer, Eyal @ 2016-07-17 6:36 UTC (permalink / raw)
To: Kalle Valo, Rob Herring
Cc: linux-wireless@vger.kernel.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
linux-spi@vger.kernel.org
In-Reply-To: <8665E2433BC68541A24DFFCA87B70F5B36156367@DFRE01.ent.ti.com>
Add support for using with both wl12xx and wl18xx.
- all wilink family needs special init command for entering wspi mode.
extra clock cycles should be sent after the spi init command while the
cs pin is high.
- Use inverted chip select for sending a dummy 4 bytes command that
completes the init stage.
Signed-off-by: Eyal Reizer <eyalr@ti.com>
Acked-by: Rob Herring <robh@kernel.org>
---
v1->v2:update device tree bindings configuration
v2->v3:revert from manual gpio manipulation. use inverted chip select
instead for sending the extra init cycle which, achieves the same hardware
purpose.
update device tree bindings docucmentation accordingly
v3->v4: Remove redundant data form binding documentation and fix chip
select number mismatch in wl1271 example
v4->v5: Rebase on top of head of wireless-drivers-next
.../bindings/net/wireless/ti,wlcore,spi.txt | 41 +++++--
drivers/net/wireless/ti/wlcore/spi.c | 123 ++++++++++++++++++---
2 files changed, 137 insertions(+), 27 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt b/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt
index 9180724..8f9ced0 100644
--- a/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt
+++ b/Documentation/devicetree/bindings/net/wireless/ti,wlcore,spi.txt
@@ -1,19 +1,30 @@
-* Texas Instruments wl1271 wireless lan controller
+* Texas Instruments wl12xx/wl18xx wireless lan controller
-The wl1271 chip can be connected via SPI or via SDIO. This
+The wl12xx/wl18xx chips can be connected via SPI or via SDIO. This
document describes the binding for the SPI connected chip.
Required properties:
-- compatible : Should be "ti,wl1271"
+- compatible : Should be one of the following:
+ * "ti,wl1271"
+ * "ti,wl1273"
+ * "ti,wl1281"
+ * "ti,wl1283"
+ * "ti,wl1801"
+ * "ti,wl1805"
+ * "ti,wl1807"
+ * "ti,wl1831"
+ * "ti,wl1835"
+ * "ti,wl1837"
- reg : Chip select address of device
- spi-max-frequency : Maximum SPI clocking speed of device in Hz
-- ref-clock-frequency : Reference clock frequency
- interrupt-parent, interrupts :
Should contain parameters for 1 interrupt line.
Interrupt parameters: parent, line number, type.
-- vwlan-supply : Point the node of the regulator that powers/enable the wl1271 chip
+- vwlan-supply : Point the node of the regulator that powers/enable the
+ wl12xx/wl18xx chip
Optional properties:
+- ref-clock-frequency : Reference clock frequency (should be set for
+wl12xx)
- clock-xtal : boolean, clock is generated from XTAL
- Please consult Documentation/devicetree/bindings/spi/spi-bus.txt
@@ -21,16 +32,28 @@ Optional properties:
Examples:
+For wl12xx family:
&spi1 {
- wl1271@1 {
+ wlcore: wlcore@1 {
compatible = "ti,wl1271";
-
reg = <1>;
spi-max-frequency = <48000000>;
- clock-xtal;
- ref-clock-frequency = <38400000>;
interrupt-parent = <&gpio3>;
interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
vwlan-supply = <&vwlan_fixed>;
+ clock-xtal;
+ ref-clock-frequency = <38400000>;
+ };
+};
+
+For wl18xx family:
+&spi0 {
+ wlcore: wlcore@0 {
+ compatible = "ti,wl1835";
+ reg = <0>;
+ spi-max-frequency = <48000000>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <27 IRQ_TYPE_EDGE_RISING>;
+ vwlan-supply = <&vwlan_fixed>;
};
};
diff --git a/drivers/net/wireless/ti/wlcore/spi.c b/drivers/net/wireless/ti/wlcore/spi.c
index cea9443..73fbcf1 100644
--- a/drivers/net/wireless/ti/wlcore/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -70,16 +70,30 @@
#define WSPI_MAX_CHUNK_SIZE 4092
/*
- * only support SPI for 12xx - this code should be reworked when 18xx
- * support is introduced
+ * wl18xx driver aggregation buffer size is (13 * PAGE_SIZE) compared
+ to
+ * (4 * PAGE_SIZE) for wl12xx, so use the larger buffer needed for
+ wl18xx
*/
-#define SPI_AGGR_BUFFER_SIZE (4 * PAGE_SIZE)
+#define SPI_AGGR_BUFFER_SIZE (13 * PAGE_SIZE)
/* Maximum number of SPI write chunks */ #define WSPI_MAX_NUM_OF_CHUNKS \
((SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE) + 1)
+struct wilink_familiy_data {
+ char name[8];
+};
+
+const struct wilink_familiy_data *wilink_data;
+
+static const struct wilink_familiy_data wl18xx_data = {
+ .name = "wl18xx",
+};
+
+static const struct wilink_familiy_data wl12xx_data = {
+ .name = "wl12xx",
+};
+
struct wl12xx_spi_glue {
struct device *dev;
struct platform_device *core;
@@ -119,6 +133,7 @@ static void wl12xx_spi_init(struct device *child)
struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
struct spi_transfer t;
struct spi_message m;
+ struct spi_device *spi = to_spi_device(glue->dev);
u8 *cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
if (!cmd) {
@@ -151,6 +166,7 @@ static void wl12xx_spi_init(struct device *child)
cmd[6] |= WSPI_INIT_CMD_EN_FIXEDBUSY;
cmd[7] = crc7_be(0, cmd+2, WSPI_INIT_CMD_CRC_LEN) | WSPI_INIT_CMD_END;
+
/*
* The above is the logical order; it must actually be stored
* in the buffer byte-swapped.
@@ -163,6 +179,28 @@ static void wl12xx_spi_init(struct device *child)
spi_message_add_tail(&t, &m);
spi_sync(to_spi_device(glue->dev), &m);
+
+ /* Send extra clocks with inverted CS (high). this is required
+ * by the wilink family in order to successfully enter WSPI mode.
+ */
+ spi->mode ^= SPI_CS_HIGH;
+ memset(&m, 0, sizeof(m));
+ spi_message_init(&m);
+
+ cmd[0] = 0xff;
+ cmd[1] = 0xff;
+ cmd[2] = 0xff;
+ cmd[3] = 0xff;
+ __swab32s((u32 *)cmd);
+
+ t.tx_buf = cmd;
+ t.len = 4;
+ spi_message_add_tail(&t, &m);
+
+ spi_sync(to_spi_device(glue->dev), &m);
+
+ /* Restore chip select configration to normal */
+ spi->mode ^= SPI_CS_HIGH;
kfree(cmd);
}
@@ -270,22 +308,25 @@ static int __must_check wl12xx_spi_raw_read(struct device *child, int addr,
return 0;
}
-static int __must_check wl12xx_spi_raw_write(struct device *child, int addr,
- void *buf, size_t len, bool fixed)
+static int __wl12xx_spi_raw_write(struct device *child, int addr,
+ void *buf, size_t len, bool fixed)
{
struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
- /* SPI write buffers - 2 for each chunk */
- struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS];
+ struct spi_transfer *t;
struct spi_message m;
u32 commands[WSPI_MAX_NUM_OF_CHUNKS]; /* 1 command per chunk */
u32 *cmd;
u32 chunk_len;
int i;
+ /* SPI write buffers - 2 for each chunk */
+ t = kzalloc(sizeof(*t) * 2 * WSPI_MAX_NUM_OF_CHUNKS, GFP_KERNEL);
+ if (!t)
+ return -ENOMEM;
+
WARN_ON(len > SPI_AGGR_BUFFER_SIZE);
spi_message_init(&m);
- memset(t, 0, sizeof(t));
cmd = &commands[0];
i = 0;
@@ -318,9 +359,26 @@ static int __must_check wl12xx_spi_raw_write(struct device *child, int addr,
spi_sync(to_spi_device(glue->dev), &m);
+ kfree(t);
return 0;
}
+static int __must_check wl12xx_spi_raw_write(struct device *child, int addr,
+ void *buf, size_t len, bool
+fixed) {
+ int ret;
+
+ /* The ELP wakeup write may fail the first time due to internal
+ * hardware latency. It is safer to send the wakeup command twice to
+ * avoid unexpected failures.
+ */
+ if (addr == HW_ACCESS_ELP_CTRL_REG)
+ ret = __wl12xx_spi_raw_write(child, addr, buf, len, fixed);
+ ret = __wl12xx_spi_raw_write(child, addr, buf, len, fixed);
+
+ return ret;
+}
+
/**
* wl12xx_spi_set_power - power on/off the wl12xx unit
* @child: wl12xx device handle.
@@ -349,17 +407,38 @@ static int wl12xx_spi_set_power(struct device *child, bool enable)
return ret;
}
+/**
+ * wl12xx_spi_set_block_size
+ *
+ * This function is not needed for spi mode, but need to be present.
+ * Without it defined the wlcore fallback to use the wrong packet
+ * allignment on tx.
+ */
+static void wl12xx_spi_set_block_size(struct device *child,
+ unsigned int blksz) { }
+
static struct wl1271_if_operations spi_ops = {
.read = wl12xx_spi_raw_read,
.write = wl12xx_spi_raw_write,
.reset = wl12xx_spi_reset,
.init = wl12xx_spi_init,
.power = wl12xx_spi_set_power,
- .set_block_size = NULL,
+ .set_block_size = wl12xx_spi_set_block_size,
};
static const struct of_device_id wlcore_spi_of_match_table[] = {
- { .compatible = "ti,wl1271" },
+ { .compatible = "ti,wl1271", .data = &wl12xx_data},
+ { .compatible = "ti,wl1273", .data = &wl12xx_data},
+ { .compatible = "ti,wl1281", .data = &wl12xx_data},
+ { .compatible = "ti,wl1283", .data = &wl12xx_data},
+ { .compatible = "ti,wl1801", .data = &wl18xx_data},
+ { .compatible = "ti,wl1805", .data = &wl18xx_data},
+ { .compatible = "ti,wl1807", .data = &wl18xx_data},
+ { .compatible = "ti,wl1831", .data = &wl18xx_data},
+ { .compatible = "ti,wl1835", .data = &wl18xx_data},
+ { .compatible = "ti,wl1837", .data = &wl18xx_data},
{ }
};
MODULE_DEVICE_TABLE(of, wlcore_spi_of_match_table); @@ -376,17 +455,24 @@ static int wlcore_probe_of(struct spi_device *spi, struct wl12xx_spi_glue *glue, {
struct device_node *dt_node = spi->dev.of_node;
int ret;
+ const struct of_device_id *of_id;
+
+ of_id = of_match_node(wlcore_spi_of_match_table, dt_node);
+ if (!of_id)
+ return -ENODEV;
+
+ wilink_data = of_id->data;
+ dev_info(&spi->dev, "selected chip familiy is %s\n",
+ wilink_data->name);
if (of_find_property(dt_node, "clock-xtal", NULL))
pdev_data->ref_clock_xtal = true;
- ret = of_property_read_u32(dt_node, "ref-clock-frequency",
- &pdev_data->ref_clock_freq);
- if (ret) {
- dev_err(glue->dev,
- "can't get reference clock frequency (%d)\n", ret);
- return ret;
- }
+ /* optional clock frequency params */
+ of_property_read_u32(dt_node, "ref-clock-frequency",
+ &pdev_data->ref_clock_freq);
+ of_property_read_u32(dt_node, "tcxo-clock-frequency",
+ &pdev_data->tcxo_clock_freq);
return 0;
}
@@ -437,7 +523,8 @@ static int wl1271_probe(struct spi_device *spi)
return ret;
}
- glue->core = platform_device_alloc("wl12xx", PLATFORM_DEVID_AUTO);
+ glue->core = platform_device_alloc(wilink_data->name,
+ PLATFORM_DEVID_AUTO);
if (!glue->core) {
dev_err(glue->dev, "can't allocate platform_device\n");
return -ENOMEM;
--
2.7.4
^ permalink raw reply related
* RE: [PATCH RESEND] iwlwifi, Do not implement thermal zone unless ucode is loaded
From: Grumbach, Emmanuel @ 2016-07-17 6:13 UTC (permalink / raw)
To: Prarit Bhargava, Stanislaw Gruszka
Cc: linux-kernel@vger.kernel.org, linuxwifi, Coelho, Luciano,
Berg, Johannes, kvalo@codeaurora.org, Ivgi, Chaya Rachel,
netdev@vger.kernel.org, Sharon, Sara,
linux-wireless@vger.kernel.org
In-Reply-To: <5788D397.9030904@redhat.com>
> On 07/15/2016 07:25 AM, Stanislaw Gruszka wrote:
> > On Thu, Jul 14, 2016 at 09:44:22AM +0000, Grumbach, Emmanuel wrote:
> >>> If I understad correctly this error happen 100% of the time, not
> >>> only during init. Hence seems there is an issue here, i.e. cur_ucode
> >>> is not marked correctly as IWL_UCODE_REGULAR or
> iwl_mvm_get_temp()
> >>> fail 100% of the time (iwl_mvm_is_tt_in_fw() incorrecly return true on
> Prarit device ? ).
> >>
> >> Cur_ucode will not be IWL_UCODE_REGULAR until you load the firmware
> >> which will happen upon ifup.
> >
> > Then creating thermal_device on ifup looks more reasonable to me.
> > Otherwise we can create device that can be non-functional virtually
> > forever, i.e. when soft RFKILL is enabled. However I admit that
> > creating thermal_device when HW is detected has some advantages too.
>
> That's my plan right now. Unfortunately something else in the kernel seems
> recently broken and is preventing me from testing. I will get back to this
> early next week.
>
But we already said that this won't work since you may have the device enabled upon boot and then disabled. So unless you unregister the thermal zone subsystem upon wifi disable, you won't solve the problem. Kalle and Luca already refused that solution.
I glanced (again) at the thermal zone API and since it allows to return an int, the subsystem itself should handle the failures and / or the userspace problems. The API itself is awful, it has no documentation whatsoever, even not variable names, but only types... You can't really blame the subsystem users to assume that a method that can return an int can't fail where the out values is passed by a pointer. Of course, you have to guess that this is the expected behavior, since you don't have any hint about the meaning of the parameters.
I think that the right place to "fix" this problem is to fix the subsystem. This way, you will fix it for iwlwifi and for any (future) other users that may fall into the trap opened by the API itself.
^ permalink raw reply
* [PATCH 3/3 v6] mac80211: Refactor ieee80211_iface_work
From: Alex Briskin @ 2016-07-16 18:19 UTC (permalink / raw)
To: linux-wireless, johannes; +Cc: Alex Briskin
In-Reply-To: <1468693140-19483-1-git-send-email-br.shurik@gmail.com>
Added ieee80211_iface_work_handle_vif_type function. Moved the code that
handles sdata->vif.type from ieee80211_iface_work to the function.
Signed-off-by: Alex Briskin <br.shurik@gmail.com>
---
net/mac80211/iface.c | 44 ++++++++++++++++++++++++--------------------
1 file changed, 24 insertions(+), 20 deletions(-)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index c185801..f8f7363 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1323,6 +1323,27 @@ static int ieee80211_iface_work_handle_frame_control(struct sk_buff *skb,
return 0;
}
+static void ieee80211_iface_work_handle_vif_type(struct sk_buff *skb,
+ struct ieee80211_sub_if_data *sdata)
+{
+ switch (sdata->vif.type) {
+ case NL80211_IFTYPE_STATION:
+ ieee80211_sta_rx_queued_mgmt(sdata, skb);
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ ieee80211_ibss_rx_queued_mgmt(sdata, skb);
+ break;
+ case NL80211_IFTYPE_MESH_POINT:
+ if (!ieee80211_vif_is_mesh(&sdata->vif))
+ break;
+ ieee80211_mesh_rx_queued_mgmt(sdata, skb);
+ break;
+ default:
+ WARN(1, "frame for unexpected interface type");
+ break;
+ }
+}
+
static void ieee80211_iface_work(struct work_struct *work)
{
struct ieee80211_sub_if_data *sdata =
@@ -1341,28 +1362,11 @@ static void ieee80211_iface_work(struct work_struct *work)
/* first process frames */
while ((skb = skb_dequeue(&sdata->skb_queue))) {
- if (!ieee80211_iface_work_handle_pkt_type(skb, sdata)) {
- goto free_skb;
- } else if (!ieee80211_iface_work_handle_frame_control(skb, sdata)) {
- goto free_skb;
- } else switch (sdata->vif.type) {
- case NL80211_IFTYPE_STATION:
- ieee80211_sta_rx_queued_mgmt(sdata, skb);
- break;
- case NL80211_IFTYPE_ADHOC:
- ieee80211_ibss_rx_queued_mgmt(sdata, skb);
- break;
- case NL80211_IFTYPE_MESH_POINT:
- if (!ieee80211_vif_is_mesh(&sdata->vif))
- break;
- ieee80211_mesh_rx_queued_mgmt(sdata, skb);
- break;
- default:
- WARN(1, "frame for unexpected interface type");
- break;
+ if (ieee80211_iface_work_handle_pkt_type(skb, sdata) &&
+ ieee80211_iface_work_handle_frame_control(skb, sdata)) {
+ ieee80211_iface_work_handle_vif_type(skb, sdata);
}
-free_skb:
kfree_skb(skb);
}
--
2.7.4
^ permalink raw reply related
* [PATCH 2/3 v6] mac80211: Refactor ieee80211_iface_work
From: Alex Briskin @ 2016-07-16 18:18 UTC (permalink / raw)
To: linux-wireless, johannes; +Cc: Alex Briskin
In-Reply-To: <1468693140-19483-1-git-send-email-br.shurik@gmail.com>
Refactored ieee80211_iface_work_handle_pkt_type - if else if replaced by
switch case.
Added ieee80211_iface_work_handle_frame_control.
Moved the code that looks in skb->data (ieee80211_mgmt/ieee80211_hdr) at
frame_control member(field) from ieee80211_iface_work to the function.
Signed-off-by: Alex Briskin <br.shurik@gmail.com>
---
net/mac80211/iface.c | 165 ++++++++++++++++++++++++++++-----------------------
1 file changed, 90 insertions(+), 75 deletions(-)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 0fc973a..c185801 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1207,13 +1207,16 @@ static int ieee80211_iface_work_handle_pkt_type(struct sk_buff *skb,
struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
- if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_START) {
+ switch (skb->pkt_type) {
+ case IEEE80211_SDATA_QUEUE_AGG_START:
ra_tid = (void *)&skb->cb;
ieee80211_start_tx_ba_cb(&sdata->vif, ra_tid->ra, ra_tid->tid);
- } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_STOP) {
+ break;
+ case IEEE80211_SDATA_QUEUE_AGG_STOP:
ra_tid = (void *)&skb->cb;
ieee80211_stop_tx_ba_cb(&sdata->vif, ra_tid->ra, ra_tid->tid);
- } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_START) {
+ break;
+ case IEEE80211_SDATA_QUEUE_RX_AGG_START:
rx_agg = (void *)&skb->cb;
mutex_lock(&local->sta_mtx);
sta = sta_info_get_bss(sdata, rx_agg->addr);
@@ -1223,7 +1226,8 @@ static int ieee80211_iface_work_handle_pkt_type(struct sk_buff *skb,
IEEE80211_MAX_AMPDU_BUF,
false, true);
mutex_unlock(&local->sta_mtx);
- } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_STOP) {
+ break;
+ case IEEE80211_SDATA_QUEUE_RX_AGG_STOP:
rx_agg = (void *)&skb->cb;
mutex_lock(&local->sta_mtx);
sta = sta_info_get_bss(sdata, rx_agg->addr);
@@ -1233,20 +1237,98 @@ static int ieee80211_iface_work_handle_pkt_type(struct sk_buff *skb,
WLAN_BACK_RECIPIENT, 0,
false);
mutex_unlock(&local->sta_mtx);
- } else {
+ break;
+ default:
return -EINVAL;
}
/*will return 0 if pkt_type found and handled */
return 0;
}
+static int ieee80211_iface_work_handle_frame_control(struct sk_buff *skb,
+ struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_local *local = sdata->local;
+ struct sta_info *sta;
+ struct ieee80211_mgmt *mgmt = (void *)skb->data;
+
+ if (ieee80211_is_action(mgmt->frame_control) &&
+ mgmt->u.action.category == WLAN_CATEGORY_BACK) {
+ int len = skb->len;
+
+ mutex_lock(&local->sta_mtx);
+ sta = sta_info_get_bss(sdata, mgmt->sa);
+ if (sta) {
+ switch (mgmt->u.action.u.addba_req.action_code) {
+ case WLAN_ACTION_ADDBA_REQ:
+ ieee80211_process_addba_request(local, sta,
+ mgmt, len);
+ break;
+ case WLAN_ACTION_ADDBA_RESP:
+ ieee80211_process_addba_resp(local, sta,
+ mgmt, len);
+ break;
+ case WLAN_ACTION_DELBA:
+ ieee80211_process_delba(sdata, sta, mgmt, len);
+ break;
+ default:
+ WARN_ON(1);
+ break;
+ }
+ }
+ mutex_unlock(&local->sta_mtx);
+ } else if (ieee80211_is_action(mgmt->frame_control) &&
+ mgmt->u.action.category == WLAN_CATEGORY_VHT) {
+ switch (mgmt->u.action.u.vht_group_notif.action_code) {
+ case WLAN_VHT_ACTION_GROUPID_MGMT:
+ ieee80211_process_mu_groups(sdata, mgmt);
+ break;
+ default:
+ WARN_ON(1);
+ break;
+ }
+ } else if (ieee80211_is_data_qos(mgmt->frame_control)) {
+ struct ieee80211_hdr *hdr = (void *)mgmt;
+ /*
+ * So the frame isn't mgmt, but frame_control
+ * is at the right place anyway, of course, so
+ * the if statement is correct.
+ *
+ * Warn if we have other data frame types here,
+ * they must not get here.
+ */
+ WARN_ON(hdr->frame_control &
+ cpu_to_le16(IEEE80211_STYPE_NULLFUNC));
+ WARN_ON(!(hdr->seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG)));
+ /*
+ * This was a fragment of a frame, received while
+ * a block-ack session was active. That cannot be
+ * right, so terminate the session.
+ */
+ mutex_lock(&local->sta_mtx);
+ sta = sta_info_get_bss(sdata, mgmt->sa);
+ if (sta) {
+ u16 tid = *ieee80211_get_qos_ctl(hdr) &
+ IEEE80211_QOS_CTL_TID_MASK;
+
+ __ieee80211_stop_rx_ba_session(sta, tid,
+ WLAN_BACK_RECIPIENT,
+ WLAN_REASON_QSTA_REQUIRE_SETUP,
+ true);
+ }
+ mutex_unlock(&local->sta_mtx);
+ } else {
+ return -EINVAL;
+ }
+ return 0;
+}
+
static void ieee80211_iface_work(struct work_struct *work)
{
struct ieee80211_sub_if_data *sdata =
container_of(work, struct ieee80211_sub_if_data, work);
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb;
- struct sta_info *sta;
if (!ieee80211_sdata_running(sdata))
return;
@@ -1259,77 +1341,10 @@ static void ieee80211_iface_work(struct work_struct *work)
/* first process frames */
while ((skb = skb_dequeue(&sdata->skb_queue))) {
- struct ieee80211_mgmt *mgmt = (void *)skb->data;
-
if (!ieee80211_iface_work_handle_pkt_type(skb, sdata)) {
goto free_skb;
- } else if (ieee80211_is_action(mgmt->frame_control) &&
- mgmt->u.action.category == WLAN_CATEGORY_BACK) {
- int len = skb->len;
-
- mutex_lock(&local->sta_mtx);
- sta = sta_info_get_bss(sdata, mgmt->sa);
- if (sta) {
- switch (mgmt->u.action.u.addba_req.action_code) {
- case WLAN_ACTION_ADDBA_REQ:
- ieee80211_process_addba_request(
- local, sta, mgmt, len);
- break;
- case WLAN_ACTION_ADDBA_RESP:
- ieee80211_process_addba_resp(local, sta,
- mgmt, len);
- break;
- case WLAN_ACTION_DELBA:
- ieee80211_process_delba(sdata, sta,
- mgmt, len);
- break;
- default:
- WARN_ON(1);
- break;
- }
- }
- mutex_unlock(&local->sta_mtx);
- } else if (ieee80211_is_action(mgmt->frame_control) &&
- mgmt->u.action.category == WLAN_CATEGORY_VHT) {
- switch (mgmt->u.action.u.vht_group_notif.action_code) {
- case WLAN_VHT_ACTION_GROUPID_MGMT:
- ieee80211_process_mu_groups(sdata, mgmt);
- break;
- default:
- WARN_ON(1);
- break;
- }
- } else if (ieee80211_is_data_qos(mgmt->frame_control)) {
- struct ieee80211_hdr *hdr = (void *)mgmt;
- /*
- * So the frame isn't mgmt, but frame_control
- * is at the right place anyway, of course, so
- * the if statement is correct.
- *
- * Warn if we have other data frame types here,
- * they must not get here.
- */
- WARN_ON(hdr->frame_control &
- cpu_to_le16(IEEE80211_STYPE_NULLFUNC));
- WARN_ON(!(hdr->seq_ctrl &
- cpu_to_le16(IEEE80211_SCTL_FRAG)));
- /*
- * This was a fragment of a frame, received while
- * a block-ack session was active. That cannot be
- * right, so terminate the session.
- */
- mutex_lock(&local->sta_mtx);
- sta = sta_info_get_bss(sdata, mgmt->sa);
- if (sta) {
- u16 tid = *ieee80211_get_qos_ctl(hdr) &
- IEEE80211_QOS_CTL_TID_MASK;
-
- __ieee80211_stop_rx_ba_session(
- sta, tid, WLAN_BACK_RECIPIENT,
- WLAN_REASON_QSTA_REQUIRE_SETUP,
- true);
- }
- mutex_unlock(&local->sta_mtx);
+ } else if (!ieee80211_iface_work_handle_frame_control(skb, sdata)) {
+ goto free_skb;
} else switch (sdata->vif.type) {
case NL80211_IFTYPE_STATION:
ieee80211_sta_rx_queued_mgmt(sdata, skb);
--
2.7.4
^ permalink raw reply related
* [PATCH 1/3 v6] mac80211: Refactor ieee80211_iface_work
From: Alex Briskin @ 2016-07-16 18:18 UTC (permalink / raw)
To: linux-wireless, johannes; +Cc: Alex Briskin
Added ieee80211_iface_work_handle_pkt_type function. Moved part of the
code that checks skb->pkt_type from ieee80211_iface_work to
ieee80211_iface_work_handle_pkt_type.
Signed-off-by: Alex Briskin <br.shurik@gmail.com>
---
net/mac80211/iface.c | 75 +++++++++++++++++++++++++++++++---------------------
1 file changed, 45 insertions(+), 30 deletions(-)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index c59af3e..0fc973a 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1198,6 +1198,48 @@ static void ieee80211_if_setup(struct net_device *dev)
dev->destructor = ieee80211_if_free;
}
+static int ieee80211_iface_work_handle_pkt_type(struct sk_buff *skb,
+ struct ieee80211_sub_if_data
+ *sdata)
+{
+ struct ieee80211_ra_tid *ra_tid;
+ struct ieee80211_rx_agg *rx_agg;
+ struct ieee80211_local *local = sdata->local;
+ struct sta_info *sta;
+
+ if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_START) {
+ ra_tid = (void *)&skb->cb;
+ ieee80211_start_tx_ba_cb(&sdata->vif, ra_tid->ra, ra_tid->tid);
+ } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_STOP) {
+ ra_tid = (void *)&skb->cb;
+ ieee80211_stop_tx_ba_cb(&sdata->vif, ra_tid->ra, ra_tid->tid);
+ } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_START) {
+ rx_agg = (void *)&skb->cb;
+ mutex_lock(&local->sta_mtx);
+ sta = sta_info_get_bss(sdata, rx_agg->addr);
+ if (sta)
+ __ieee80211_start_rx_ba_session(sta,
+ 0, 0, 0, 1, rx_agg->tid,
+ IEEE80211_MAX_AMPDU_BUF,
+ false, true);
+ mutex_unlock(&local->sta_mtx);
+ } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_STOP) {
+ rx_agg = (void *)&skb->cb;
+ mutex_lock(&local->sta_mtx);
+ sta = sta_info_get_bss(sdata, rx_agg->addr);
+ if (sta)
+ __ieee80211_stop_rx_ba_session(sta,
+ rx_agg->tid,
+ WLAN_BACK_RECIPIENT, 0,
+ false);
+ mutex_unlock(&local->sta_mtx);
+ } else {
+ return -EINVAL;
+ }
+ /*will return 0 if pkt_type found and handled */
+ return 0;
+}
+
static void ieee80211_iface_work(struct work_struct *work)
{
struct ieee80211_sub_if_data *sdata =
@@ -1205,8 +1247,6 @@ static void ieee80211_iface_work(struct work_struct *work)
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb;
struct sta_info *sta;
- struct ieee80211_ra_tid *ra_tid;
- struct ieee80211_rx_agg *rx_agg;
if (!ieee80211_sdata_running(sdata))
return;
@@ -1221,34 +1261,8 @@ static void ieee80211_iface_work(struct work_struct *work)
while ((skb = skb_dequeue(&sdata->skb_queue))) {
struct ieee80211_mgmt *mgmt = (void *)skb->data;
- if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_START) {
- ra_tid = (void *)&skb->cb;
- ieee80211_start_tx_ba_cb(&sdata->vif, ra_tid->ra,
- ra_tid->tid);
- } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_STOP) {
- ra_tid = (void *)&skb->cb;
- ieee80211_stop_tx_ba_cb(&sdata->vif, ra_tid->ra,
- ra_tid->tid);
- } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_START) {
- rx_agg = (void *)&skb->cb;
- mutex_lock(&local->sta_mtx);
- sta = sta_info_get_bss(sdata, rx_agg->addr);
- if (sta)
- __ieee80211_start_rx_ba_session(sta,
- 0, 0, 0, 1, rx_agg->tid,
- IEEE80211_MAX_AMPDU_BUF,
- false, true);
- mutex_unlock(&local->sta_mtx);
- } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_STOP) {
- rx_agg = (void *)&skb->cb;
- mutex_lock(&local->sta_mtx);
- sta = sta_info_get_bss(sdata, rx_agg->addr);
- if (sta)
- __ieee80211_stop_rx_ba_session(sta,
- rx_agg->tid,
- WLAN_BACK_RECIPIENT, 0,
- false);
- mutex_unlock(&local->sta_mtx);
+ if (!ieee80211_iface_work_handle_pkt_type(skb, sdata)) {
+ goto free_skb;
} else if (ieee80211_is_action(mgmt->frame_control) &&
mgmt->u.action.category == WLAN_CATEGORY_BACK) {
int len = skb->len;
@@ -1333,6 +1347,7 @@ static void ieee80211_iface_work(struct work_struct *work)
break;
}
+free_skb:
kfree_skb(skb);
}
--
2.7.4
^ permalink raw reply related
* [PATCH 3/3 v5] mac80211: Refactor ieee80211_iface_work
From: Alex Briskin @ 2016-07-16 17:21 UTC (permalink / raw)
To: linux-wireless, johannes; +Cc: Alex Briskin
In-Reply-To: <1468689687-18943-1-git-send-email-br.shurik@gmail.com>
Added ieee80211_iface_work_handle_vif_type function. Moved the code that
handles sdata->vif.type from ieee80211_iface_work to the function.
Signed-off-by: Alex Briskin <br.shurik@gmail.com>
---
net/mac80211/iface.c | 44 ++++++++++++++++++++++++--------------------
1 file changed, 24 insertions(+), 20 deletions(-)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index c185801..3643430 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1323,6 +1323,27 @@ static int ieee80211_iface_work_handle_frame_control(struct sk_buff *skb,
return 0;
}
+static void ieee80211_iface_work_handle_vif_type(struct sk_buff *skb,
+ struct ieee80211_sub_if_data *sdata)
+{
+ switch (sdata->vif.type) {
+ case NL80211_IFTYPE_STATION:
+ ieee80211_sta_rx_queued_mgmt(sdata, skb);
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ ieee80211_ibss_rx_queued_mgmt(sdata, skb);
+ break;
+ case NL80211_IFTYPE_MESH_POINT:
+ if (!ieee80211_vif_is_mesh(&sdata->vif))
+ break;
+ ieee80211_mesh_rx_queued_mgmt(sdata, skb);
+ break;
+ default:
+ WARN(1, "frame for unexpected interface type");
+ break;
+ }
+}
+
static void ieee80211_iface_work(struct work_struct *work)
{
struct ieee80211_sub_if_data *sdata =
@@ -1341,28 +1362,11 @@ static void ieee80211_iface_work(struct work_struct *work)
/* first process frames */
while ((skb = skb_dequeue(&sdata->skb_queue))) {
- if (!ieee80211_iface_work_handle_pkt_type(skb, sdata)) {
- goto free_skb;
- } else if (!ieee80211_iface_work_handle_frame_control(skb, sdata)) {
- goto free_skb;
- } else switch (sdata->vif.type) {
- case NL80211_IFTYPE_STATION:
- ieee80211_sta_rx_queued_mgmt(sdata, skb);
- break;
- case NL80211_IFTYPE_ADHOC:
- ieee80211_ibss_rx_queued_mgmt(sdata, skb);
- break;
- case NL80211_IFTYPE_MESH_POINT:
- if (!ieee80211_vif_is_mesh(&sdata->vif))
- break;
- ieee80211_mesh_rx_queued_mgmt(sdata, skb);
- break;
- default:
- WARN(1, "frame for unexpected interface type");
- break;
+ if (ieee80211_iface_work_handle_pkt_type(skb, sdata) ||
+ ieee80211_iface_work_handle_frame_control(skb, sdata)) {
+ ieee80211_iface_work_handle_vif_type(skb, sdata);
}
-free_skb:
kfree_skb(skb);
}
--
2.7.4
^ permalink raw reply related
* [PATCH 2/3 v5] mac80211: Refactor ieee80211_iface_work
From: Alex Briskin @ 2016-07-16 17:21 UTC (permalink / raw)
To: linux-wireless, johannes; +Cc: Alex Briskin
In-Reply-To: <1468689687-18943-1-git-send-email-br.shurik@gmail.com>
Refactored ieee80211_iface_work_handle_pkt_type - if else if replaced by
switch case.
Added ieee80211_iface_work_handle_frame_control.
Moved the code that looks in skb->data (ieee80211_mgmt/ieee80211_hdr) at
frame_control member(field) from ieee80211_iface_work to the function.
Signed-off-by: Alex Briskin <br.shurik@gmail.com>
---
net/mac80211/iface.c | 165 ++++++++++++++++++++++++++++-----------------------
1 file changed, 90 insertions(+), 75 deletions(-)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 0fc973a..c185801 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1207,13 +1207,16 @@ static int ieee80211_iface_work_handle_pkt_type(struct sk_buff *skb,
struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
- if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_START) {
+ switch (skb->pkt_type) {
+ case IEEE80211_SDATA_QUEUE_AGG_START:
ra_tid = (void *)&skb->cb;
ieee80211_start_tx_ba_cb(&sdata->vif, ra_tid->ra, ra_tid->tid);
- } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_STOP) {
+ break;
+ case IEEE80211_SDATA_QUEUE_AGG_STOP:
ra_tid = (void *)&skb->cb;
ieee80211_stop_tx_ba_cb(&sdata->vif, ra_tid->ra, ra_tid->tid);
- } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_START) {
+ break;
+ case IEEE80211_SDATA_QUEUE_RX_AGG_START:
rx_agg = (void *)&skb->cb;
mutex_lock(&local->sta_mtx);
sta = sta_info_get_bss(sdata, rx_agg->addr);
@@ -1223,7 +1226,8 @@ static int ieee80211_iface_work_handle_pkt_type(struct sk_buff *skb,
IEEE80211_MAX_AMPDU_BUF,
false, true);
mutex_unlock(&local->sta_mtx);
- } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_STOP) {
+ break;
+ case IEEE80211_SDATA_QUEUE_RX_AGG_STOP:
rx_agg = (void *)&skb->cb;
mutex_lock(&local->sta_mtx);
sta = sta_info_get_bss(sdata, rx_agg->addr);
@@ -1233,20 +1237,98 @@ static int ieee80211_iface_work_handle_pkt_type(struct sk_buff *skb,
WLAN_BACK_RECIPIENT, 0,
false);
mutex_unlock(&local->sta_mtx);
- } else {
+ break;
+ default:
return -EINVAL;
}
/*will return 0 if pkt_type found and handled */
return 0;
}
+static int ieee80211_iface_work_handle_frame_control(struct sk_buff *skb,
+ struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_local *local = sdata->local;
+ struct sta_info *sta;
+ struct ieee80211_mgmt *mgmt = (void *)skb->data;
+
+ if (ieee80211_is_action(mgmt->frame_control) &&
+ mgmt->u.action.category == WLAN_CATEGORY_BACK) {
+ int len = skb->len;
+
+ mutex_lock(&local->sta_mtx);
+ sta = sta_info_get_bss(sdata, mgmt->sa);
+ if (sta) {
+ switch (mgmt->u.action.u.addba_req.action_code) {
+ case WLAN_ACTION_ADDBA_REQ:
+ ieee80211_process_addba_request(local, sta,
+ mgmt, len);
+ break;
+ case WLAN_ACTION_ADDBA_RESP:
+ ieee80211_process_addba_resp(local, sta,
+ mgmt, len);
+ break;
+ case WLAN_ACTION_DELBA:
+ ieee80211_process_delba(sdata, sta, mgmt, len);
+ break;
+ default:
+ WARN_ON(1);
+ break;
+ }
+ }
+ mutex_unlock(&local->sta_mtx);
+ } else if (ieee80211_is_action(mgmt->frame_control) &&
+ mgmt->u.action.category == WLAN_CATEGORY_VHT) {
+ switch (mgmt->u.action.u.vht_group_notif.action_code) {
+ case WLAN_VHT_ACTION_GROUPID_MGMT:
+ ieee80211_process_mu_groups(sdata, mgmt);
+ break;
+ default:
+ WARN_ON(1);
+ break;
+ }
+ } else if (ieee80211_is_data_qos(mgmt->frame_control)) {
+ struct ieee80211_hdr *hdr = (void *)mgmt;
+ /*
+ * So the frame isn't mgmt, but frame_control
+ * is at the right place anyway, of course, so
+ * the if statement is correct.
+ *
+ * Warn if we have other data frame types here,
+ * they must not get here.
+ */
+ WARN_ON(hdr->frame_control &
+ cpu_to_le16(IEEE80211_STYPE_NULLFUNC));
+ WARN_ON(!(hdr->seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG)));
+ /*
+ * This was a fragment of a frame, received while
+ * a block-ack session was active. That cannot be
+ * right, so terminate the session.
+ */
+ mutex_lock(&local->sta_mtx);
+ sta = sta_info_get_bss(sdata, mgmt->sa);
+ if (sta) {
+ u16 tid = *ieee80211_get_qos_ctl(hdr) &
+ IEEE80211_QOS_CTL_TID_MASK;
+
+ __ieee80211_stop_rx_ba_session(sta, tid,
+ WLAN_BACK_RECIPIENT,
+ WLAN_REASON_QSTA_REQUIRE_SETUP,
+ true);
+ }
+ mutex_unlock(&local->sta_mtx);
+ } else {
+ return -EINVAL;
+ }
+ return 0;
+}
+
static void ieee80211_iface_work(struct work_struct *work)
{
struct ieee80211_sub_if_data *sdata =
container_of(work, struct ieee80211_sub_if_data, work);
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb;
- struct sta_info *sta;
if (!ieee80211_sdata_running(sdata))
return;
@@ -1259,77 +1341,10 @@ static void ieee80211_iface_work(struct work_struct *work)
/* first process frames */
while ((skb = skb_dequeue(&sdata->skb_queue))) {
- struct ieee80211_mgmt *mgmt = (void *)skb->data;
-
if (!ieee80211_iface_work_handle_pkt_type(skb, sdata)) {
goto free_skb;
- } else if (ieee80211_is_action(mgmt->frame_control) &&
- mgmt->u.action.category == WLAN_CATEGORY_BACK) {
- int len = skb->len;
-
- mutex_lock(&local->sta_mtx);
- sta = sta_info_get_bss(sdata, mgmt->sa);
- if (sta) {
- switch (mgmt->u.action.u.addba_req.action_code) {
- case WLAN_ACTION_ADDBA_REQ:
- ieee80211_process_addba_request(
- local, sta, mgmt, len);
- break;
- case WLAN_ACTION_ADDBA_RESP:
- ieee80211_process_addba_resp(local, sta,
- mgmt, len);
- break;
- case WLAN_ACTION_DELBA:
- ieee80211_process_delba(sdata, sta,
- mgmt, len);
- break;
- default:
- WARN_ON(1);
- break;
- }
- }
- mutex_unlock(&local->sta_mtx);
- } else if (ieee80211_is_action(mgmt->frame_control) &&
- mgmt->u.action.category == WLAN_CATEGORY_VHT) {
- switch (mgmt->u.action.u.vht_group_notif.action_code) {
- case WLAN_VHT_ACTION_GROUPID_MGMT:
- ieee80211_process_mu_groups(sdata, mgmt);
- break;
- default:
- WARN_ON(1);
- break;
- }
- } else if (ieee80211_is_data_qos(mgmt->frame_control)) {
- struct ieee80211_hdr *hdr = (void *)mgmt;
- /*
- * So the frame isn't mgmt, but frame_control
- * is at the right place anyway, of course, so
- * the if statement is correct.
- *
- * Warn if we have other data frame types here,
- * they must not get here.
- */
- WARN_ON(hdr->frame_control &
- cpu_to_le16(IEEE80211_STYPE_NULLFUNC));
- WARN_ON(!(hdr->seq_ctrl &
- cpu_to_le16(IEEE80211_SCTL_FRAG)));
- /*
- * This was a fragment of a frame, received while
- * a block-ack session was active. That cannot be
- * right, so terminate the session.
- */
- mutex_lock(&local->sta_mtx);
- sta = sta_info_get_bss(sdata, mgmt->sa);
- if (sta) {
- u16 tid = *ieee80211_get_qos_ctl(hdr) &
- IEEE80211_QOS_CTL_TID_MASK;
-
- __ieee80211_stop_rx_ba_session(
- sta, tid, WLAN_BACK_RECIPIENT,
- WLAN_REASON_QSTA_REQUIRE_SETUP,
- true);
- }
- mutex_unlock(&local->sta_mtx);
+ } else if (!ieee80211_iface_work_handle_frame_control(skb, sdata)) {
+ goto free_skb;
} else switch (sdata->vif.type) {
case NL80211_IFTYPE_STATION:
ieee80211_sta_rx_queued_mgmt(sdata, skb);
--
2.7.4
^ permalink raw reply related
* [PATCH 1/3 v5] mac80211: Refactor ieee80211_iface_work
From: Alex Briskin @ 2016-07-16 17:21 UTC (permalink / raw)
To: linux-wireless, johannes; +Cc: Alex Briskin
Added ieee80211_iface_work_handle_pkt_type function. Moved part of the
code that checks skb->pkt_type from ieee80211_iface_work to
ieee80211_iface_work_handle_pkt_type.
Signed-off-by: Alex Briskin <br.shurik@gmail.com>
---
net/mac80211/iface.c | 75 +++++++++++++++++++++++++++++++---------------------
1 file changed, 45 insertions(+), 30 deletions(-)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index c59af3e..0fc973a 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1198,6 +1198,48 @@ static void ieee80211_if_setup(struct net_device *dev)
dev->destructor = ieee80211_if_free;
}
+static int ieee80211_iface_work_handle_pkt_type(struct sk_buff *skb,
+ struct ieee80211_sub_if_data
+ *sdata)
+{
+ struct ieee80211_ra_tid *ra_tid;
+ struct ieee80211_rx_agg *rx_agg;
+ struct ieee80211_local *local = sdata->local;
+ struct sta_info *sta;
+
+ if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_START) {
+ ra_tid = (void *)&skb->cb;
+ ieee80211_start_tx_ba_cb(&sdata->vif, ra_tid->ra, ra_tid->tid);
+ } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_STOP) {
+ ra_tid = (void *)&skb->cb;
+ ieee80211_stop_tx_ba_cb(&sdata->vif, ra_tid->ra, ra_tid->tid);
+ } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_START) {
+ rx_agg = (void *)&skb->cb;
+ mutex_lock(&local->sta_mtx);
+ sta = sta_info_get_bss(sdata, rx_agg->addr);
+ if (sta)
+ __ieee80211_start_rx_ba_session(sta,
+ 0, 0, 0, 1, rx_agg->tid,
+ IEEE80211_MAX_AMPDU_BUF,
+ false, true);
+ mutex_unlock(&local->sta_mtx);
+ } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_STOP) {
+ rx_agg = (void *)&skb->cb;
+ mutex_lock(&local->sta_mtx);
+ sta = sta_info_get_bss(sdata, rx_agg->addr);
+ if (sta)
+ __ieee80211_stop_rx_ba_session(sta,
+ rx_agg->tid,
+ WLAN_BACK_RECIPIENT, 0,
+ false);
+ mutex_unlock(&local->sta_mtx);
+ } else {
+ return -EINVAL;
+ }
+ /*will return 0 if pkt_type found and handled */
+ return 0;
+}
+
static void ieee80211_iface_work(struct work_struct *work)
{
struct ieee80211_sub_if_data *sdata =
@@ -1205,8 +1247,6 @@ static void ieee80211_iface_work(struct work_struct *work)
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb;
struct sta_info *sta;
- struct ieee80211_ra_tid *ra_tid;
- struct ieee80211_rx_agg *rx_agg;
if (!ieee80211_sdata_running(sdata))
return;
@@ -1221,34 +1261,8 @@ static void ieee80211_iface_work(struct work_struct *work)
while ((skb = skb_dequeue(&sdata->skb_queue))) {
struct ieee80211_mgmt *mgmt = (void *)skb->data;
- if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_START) {
- ra_tid = (void *)&skb->cb;
- ieee80211_start_tx_ba_cb(&sdata->vif, ra_tid->ra,
- ra_tid->tid);
- } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_STOP) {
- ra_tid = (void *)&skb->cb;
- ieee80211_stop_tx_ba_cb(&sdata->vif, ra_tid->ra,
- ra_tid->tid);
- } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_START) {
- rx_agg = (void *)&skb->cb;
- mutex_lock(&local->sta_mtx);
- sta = sta_info_get_bss(sdata, rx_agg->addr);
- if (sta)
- __ieee80211_start_rx_ba_session(sta,
- 0, 0, 0, 1, rx_agg->tid,
- IEEE80211_MAX_AMPDU_BUF,
- false, true);
- mutex_unlock(&local->sta_mtx);
- } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_STOP) {
- rx_agg = (void *)&skb->cb;
- mutex_lock(&local->sta_mtx);
- sta = sta_info_get_bss(sdata, rx_agg->addr);
- if (sta)
- __ieee80211_stop_rx_ba_session(sta,
- rx_agg->tid,
- WLAN_BACK_RECIPIENT, 0,
- false);
- mutex_unlock(&local->sta_mtx);
+ if (!ieee80211_iface_work_handle_pkt_type(skb, sdata)) {
+ goto free_skb;
} else if (ieee80211_is_action(mgmt->frame_control) &&
mgmt->u.action.category == WLAN_CATEGORY_BACK) {
int len = skb->len;
@@ -1333,6 +1347,7 @@ static void ieee80211_iface_work(struct work_struct *work)
break;
}
+free_skb:
kfree_skb(skb);
}
--
2.7.4
^ permalink raw reply related
* [PATCH 3/3 v4] mac80211: Refactor ieee80211_iface_work
From: Alex Briskin @ 2016-07-16 17:06 UTC (permalink / raw)
To: linux-wireless, johannes; +Cc: Alex Briskin
In-Reply-To: <1468688771-18508-1-git-send-email-br.shurik@gmail.com>
Added ieee80211_iface_work_handle_vif_type function. Moved the code that
handles sdata->vif.type from ieee80211_iface_work to the function.
Signed-off-by: Alex Briskin <br.shurik@gmail.com>
---
net/mac80211/iface.c | 44 ++++++++++++++++++++++++--------------------
1 file changed, 24 insertions(+), 20 deletions(-)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index c185801..e82f80d 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1323,6 +1323,27 @@ static int ieee80211_iface_work_handle_frame_control(struct sk_buff *skb,
return 0;
}
+static void ieee80211_iface_work_handle_vif_type(struct sk_buff *skb,
+ struct ieee80211_sub_if_data *sdata)
+{
+ switch (sdata->vif.type) {
+ case NL80211_IFTYPE_STATION:
+ ieee80211_sta_rx_queued_mgmt(sdata, skb);
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ ieee80211_ibss_rx_queued_mgmt(sdata, skb);
+ break;
+ case NL80211_IFTYPE_MESH_POINT:
+ if (!ieee80211_vif_is_mesh(&sdata->vif))
+ break;
+ ieee80211_mesh_rx_queued_mgmt(sdata, skb);
+ break;
+ default:
+ WARN(1, "frame for unexpected interface type");
+ break;
+ }
+}
+
static void ieee80211_iface_work(struct work_struct *work)
{
struct ieee80211_sub_if_data *sdata =
@@ -1341,28 +1362,11 @@ static void ieee80211_iface_work(struct work_struct *work)
/* first process frames */
while ((skb = skb_dequeue(&sdata->skb_queue))) {
- if (!ieee80211_iface_work_handle_pkt_type(skb, sdata)) {
- goto free_skb;
- } else if (!ieee80211_iface_work_handle_frame_control(skb, sdata)) {
- goto free_skb;
- } else switch (sdata->vif.type) {
- case NL80211_IFTYPE_STATION:
- ieee80211_sta_rx_queued_mgmt(sdata, skb);
- break;
- case NL80211_IFTYPE_ADHOC:
- ieee80211_ibss_rx_queued_mgmt(sdata, skb);
- break;
- case NL80211_IFTYPE_MESH_POINT:
- if (!ieee80211_vif_is_mesh(&sdata->vif))
- break;
- ieee80211_mesh_rx_queued_mgmt(sdata, skb);
- break;
- default:
- WARN(1, "frame for unexpected interface type");
- break;
+ if (!ieee80211_iface_work_handle_pkt_type(skb, sdata) &&
+ !ieee80211_iface_work_handle_frame_control(skb, sdata)) {
+ ieee80211_iface_work_handle_vif_type(skb, sdata);
}
-free_skb:
kfree_skb(skb);
}
--
2.7.4
^ permalink raw reply related
* [PATCH 2/3 v4] mac80211: Refactor ieee80211_iface_work
From: Alex Briskin @ 2016-07-16 17:06 UTC (permalink / raw)
To: linux-wireless, johannes; +Cc: Alex Briskin
In-Reply-To: <1468688771-18508-1-git-send-email-br.shurik@gmail.com>
Refactored ieee80211_iface_work_handle_pkt_type - if else if replaced by
switch case.
Added ieee80211_iface_work_handle_frame_control.
Moved the code that looks in skb->data (ieee80211_mgmt/ieee80211_hdr) at
frame_control member(field) from ieee80211_iface_work to the function.
Signed-off-by: Alex Briskin <br.shurik@gmail.com>
---
net/mac80211/iface.c | 165 ++++++++++++++++++++++++++++-----------------------
1 file changed, 90 insertions(+), 75 deletions(-)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 0fc973a..c185801 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1207,13 +1207,16 @@ static int ieee80211_iface_work_handle_pkt_type(struct sk_buff *skb,
struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
- if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_START) {
+ switch (skb->pkt_type) {
+ case IEEE80211_SDATA_QUEUE_AGG_START:
ra_tid = (void *)&skb->cb;
ieee80211_start_tx_ba_cb(&sdata->vif, ra_tid->ra, ra_tid->tid);
- } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_STOP) {
+ break;
+ case IEEE80211_SDATA_QUEUE_AGG_STOP:
ra_tid = (void *)&skb->cb;
ieee80211_stop_tx_ba_cb(&sdata->vif, ra_tid->ra, ra_tid->tid);
- } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_START) {
+ break;
+ case IEEE80211_SDATA_QUEUE_RX_AGG_START:
rx_agg = (void *)&skb->cb;
mutex_lock(&local->sta_mtx);
sta = sta_info_get_bss(sdata, rx_agg->addr);
@@ -1223,7 +1226,8 @@ static int ieee80211_iface_work_handle_pkt_type(struct sk_buff *skb,
IEEE80211_MAX_AMPDU_BUF,
false, true);
mutex_unlock(&local->sta_mtx);
- } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_STOP) {
+ break;
+ case IEEE80211_SDATA_QUEUE_RX_AGG_STOP:
rx_agg = (void *)&skb->cb;
mutex_lock(&local->sta_mtx);
sta = sta_info_get_bss(sdata, rx_agg->addr);
@@ -1233,20 +1237,98 @@ static int ieee80211_iface_work_handle_pkt_type(struct sk_buff *skb,
WLAN_BACK_RECIPIENT, 0,
false);
mutex_unlock(&local->sta_mtx);
- } else {
+ break;
+ default:
return -EINVAL;
}
/*will return 0 if pkt_type found and handled */
return 0;
}
+static int ieee80211_iface_work_handle_frame_control(struct sk_buff *skb,
+ struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_local *local = sdata->local;
+ struct sta_info *sta;
+ struct ieee80211_mgmt *mgmt = (void *)skb->data;
+
+ if (ieee80211_is_action(mgmt->frame_control) &&
+ mgmt->u.action.category == WLAN_CATEGORY_BACK) {
+ int len = skb->len;
+
+ mutex_lock(&local->sta_mtx);
+ sta = sta_info_get_bss(sdata, mgmt->sa);
+ if (sta) {
+ switch (mgmt->u.action.u.addba_req.action_code) {
+ case WLAN_ACTION_ADDBA_REQ:
+ ieee80211_process_addba_request(local, sta,
+ mgmt, len);
+ break;
+ case WLAN_ACTION_ADDBA_RESP:
+ ieee80211_process_addba_resp(local, sta,
+ mgmt, len);
+ break;
+ case WLAN_ACTION_DELBA:
+ ieee80211_process_delba(sdata, sta, mgmt, len);
+ break;
+ default:
+ WARN_ON(1);
+ break;
+ }
+ }
+ mutex_unlock(&local->sta_mtx);
+ } else if (ieee80211_is_action(mgmt->frame_control) &&
+ mgmt->u.action.category == WLAN_CATEGORY_VHT) {
+ switch (mgmt->u.action.u.vht_group_notif.action_code) {
+ case WLAN_VHT_ACTION_GROUPID_MGMT:
+ ieee80211_process_mu_groups(sdata, mgmt);
+ break;
+ default:
+ WARN_ON(1);
+ break;
+ }
+ } else if (ieee80211_is_data_qos(mgmt->frame_control)) {
+ struct ieee80211_hdr *hdr = (void *)mgmt;
+ /*
+ * So the frame isn't mgmt, but frame_control
+ * is at the right place anyway, of course, so
+ * the if statement is correct.
+ *
+ * Warn if we have other data frame types here,
+ * they must not get here.
+ */
+ WARN_ON(hdr->frame_control &
+ cpu_to_le16(IEEE80211_STYPE_NULLFUNC));
+ WARN_ON(!(hdr->seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG)));
+ /*
+ * This was a fragment of a frame, received while
+ * a block-ack session was active. That cannot be
+ * right, so terminate the session.
+ */
+ mutex_lock(&local->sta_mtx);
+ sta = sta_info_get_bss(sdata, mgmt->sa);
+ if (sta) {
+ u16 tid = *ieee80211_get_qos_ctl(hdr) &
+ IEEE80211_QOS_CTL_TID_MASK;
+
+ __ieee80211_stop_rx_ba_session(sta, tid,
+ WLAN_BACK_RECIPIENT,
+ WLAN_REASON_QSTA_REQUIRE_SETUP,
+ true);
+ }
+ mutex_unlock(&local->sta_mtx);
+ } else {
+ return -EINVAL;
+ }
+ return 0;
+}
+
static void ieee80211_iface_work(struct work_struct *work)
{
struct ieee80211_sub_if_data *sdata =
container_of(work, struct ieee80211_sub_if_data, work);
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb;
- struct sta_info *sta;
if (!ieee80211_sdata_running(sdata))
return;
@@ -1259,77 +1341,10 @@ static void ieee80211_iface_work(struct work_struct *work)
/* first process frames */
while ((skb = skb_dequeue(&sdata->skb_queue))) {
- struct ieee80211_mgmt *mgmt = (void *)skb->data;
-
if (!ieee80211_iface_work_handle_pkt_type(skb, sdata)) {
goto free_skb;
- } else if (ieee80211_is_action(mgmt->frame_control) &&
- mgmt->u.action.category == WLAN_CATEGORY_BACK) {
- int len = skb->len;
-
- mutex_lock(&local->sta_mtx);
- sta = sta_info_get_bss(sdata, mgmt->sa);
- if (sta) {
- switch (mgmt->u.action.u.addba_req.action_code) {
- case WLAN_ACTION_ADDBA_REQ:
- ieee80211_process_addba_request(
- local, sta, mgmt, len);
- break;
- case WLAN_ACTION_ADDBA_RESP:
- ieee80211_process_addba_resp(local, sta,
- mgmt, len);
- break;
- case WLAN_ACTION_DELBA:
- ieee80211_process_delba(sdata, sta,
- mgmt, len);
- break;
- default:
- WARN_ON(1);
- break;
- }
- }
- mutex_unlock(&local->sta_mtx);
- } else if (ieee80211_is_action(mgmt->frame_control) &&
- mgmt->u.action.category == WLAN_CATEGORY_VHT) {
- switch (mgmt->u.action.u.vht_group_notif.action_code) {
- case WLAN_VHT_ACTION_GROUPID_MGMT:
- ieee80211_process_mu_groups(sdata, mgmt);
- break;
- default:
- WARN_ON(1);
- break;
- }
- } else if (ieee80211_is_data_qos(mgmt->frame_control)) {
- struct ieee80211_hdr *hdr = (void *)mgmt;
- /*
- * So the frame isn't mgmt, but frame_control
- * is at the right place anyway, of course, so
- * the if statement is correct.
- *
- * Warn if we have other data frame types here,
- * they must not get here.
- */
- WARN_ON(hdr->frame_control &
- cpu_to_le16(IEEE80211_STYPE_NULLFUNC));
- WARN_ON(!(hdr->seq_ctrl &
- cpu_to_le16(IEEE80211_SCTL_FRAG)));
- /*
- * This was a fragment of a frame, received while
- * a block-ack session was active. That cannot be
- * right, so terminate the session.
- */
- mutex_lock(&local->sta_mtx);
- sta = sta_info_get_bss(sdata, mgmt->sa);
- if (sta) {
- u16 tid = *ieee80211_get_qos_ctl(hdr) &
- IEEE80211_QOS_CTL_TID_MASK;
-
- __ieee80211_stop_rx_ba_session(
- sta, tid, WLAN_BACK_RECIPIENT,
- WLAN_REASON_QSTA_REQUIRE_SETUP,
- true);
- }
- mutex_unlock(&local->sta_mtx);
+ } else if (!ieee80211_iface_work_handle_frame_control(skb, sdata)) {
+ goto free_skb;
} else switch (sdata->vif.type) {
case NL80211_IFTYPE_STATION:
ieee80211_sta_rx_queued_mgmt(sdata, skb);
--
2.7.4
^ permalink raw reply related
* [PATCH 1/3 v4] mac80211: Refactor ieee80211_iface_work
From: Alex Briskin @ 2016-07-16 17:06 UTC (permalink / raw)
To: linux-wireless, johannes; +Cc: Alex Briskin
Added ieee80211_iface_work_handle_pkt_type function. Moved part of the
code that checks skb->pkt_type from ieee80211_iface_work to
ieee80211_iface_work_handle_pkt_type.
Signed-off-by: Alex Briskin <br.shurik@gmail.com>
---
net/mac80211/iface.c | 75 +++++++++++++++++++++++++++++++---------------------
1 file changed, 45 insertions(+), 30 deletions(-)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index c59af3e..0fc973a 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1198,6 +1198,48 @@ static void ieee80211_if_setup(struct net_device *dev)
dev->destructor = ieee80211_if_free;
}
+static int ieee80211_iface_work_handle_pkt_type(struct sk_buff *skb,
+ struct ieee80211_sub_if_data
+ *sdata)
+{
+ struct ieee80211_ra_tid *ra_tid;
+ struct ieee80211_rx_agg *rx_agg;
+ struct ieee80211_local *local = sdata->local;
+ struct sta_info *sta;
+
+ if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_START) {
+ ra_tid = (void *)&skb->cb;
+ ieee80211_start_tx_ba_cb(&sdata->vif, ra_tid->ra, ra_tid->tid);
+ } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_STOP) {
+ ra_tid = (void *)&skb->cb;
+ ieee80211_stop_tx_ba_cb(&sdata->vif, ra_tid->ra, ra_tid->tid);
+ } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_START) {
+ rx_agg = (void *)&skb->cb;
+ mutex_lock(&local->sta_mtx);
+ sta = sta_info_get_bss(sdata, rx_agg->addr);
+ if (sta)
+ __ieee80211_start_rx_ba_session(sta,
+ 0, 0, 0, 1, rx_agg->tid,
+ IEEE80211_MAX_AMPDU_BUF,
+ false, true);
+ mutex_unlock(&local->sta_mtx);
+ } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_STOP) {
+ rx_agg = (void *)&skb->cb;
+ mutex_lock(&local->sta_mtx);
+ sta = sta_info_get_bss(sdata, rx_agg->addr);
+ if (sta)
+ __ieee80211_stop_rx_ba_session(sta,
+ rx_agg->tid,
+ WLAN_BACK_RECIPIENT, 0,
+ false);
+ mutex_unlock(&local->sta_mtx);
+ } else {
+ return -EINVAL;
+ }
+ /*will return 0 if pkt_type found and handled */
+ return 0;
+}
+
static void ieee80211_iface_work(struct work_struct *work)
{
struct ieee80211_sub_if_data *sdata =
@@ -1205,8 +1247,6 @@ static void ieee80211_iface_work(struct work_struct *work)
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb;
struct sta_info *sta;
- struct ieee80211_ra_tid *ra_tid;
- struct ieee80211_rx_agg *rx_agg;
if (!ieee80211_sdata_running(sdata))
return;
@@ -1221,34 +1261,8 @@ static void ieee80211_iface_work(struct work_struct *work)
while ((skb = skb_dequeue(&sdata->skb_queue))) {
struct ieee80211_mgmt *mgmt = (void *)skb->data;
- if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_START) {
- ra_tid = (void *)&skb->cb;
- ieee80211_start_tx_ba_cb(&sdata->vif, ra_tid->ra,
- ra_tid->tid);
- } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_STOP) {
- ra_tid = (void *)&skb->cb;
- ieee80211_stop_tx_ba_cb(&sdata->vif, ra_tid->ra,
- ra_tid->tid);
- } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_START) {
- rx_agg = (void *)&skb->cb;
- mutex_lock(&local->sta_mtx);
- sta = sta_info_get_bss(sdata, rx_agg->addr);
- if (sta)
- __ieee80211_start_rx_ba_session(sta,
- 0, 0, 0, 1, rx_agg->tid,
- IEEE80211_MAX_AMPDU_BUF,
- false, true);
- mutex_unlock(&local->sta_mtx);
- } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_STOP) {
- rx_agg = (void *)&skb->cb;
- mutex_lock(&local->sta_mtx);
- sta = sta_info_get_bss(sdata, rx_agg->addr);
- if (sta)
- __ieee80211_stop_rx_ba_session(sta,
- rx_agg->tid,
- WLAN_BACK_RECIPIENT, 0,
- false);
- mutex_unlock(&local->sta_mtx);
+ if (!ieee80211_iface_work_handle_pkt_type(skb, sdata)) {
+ goto free_skb;
} else if (ieee80211_is_action(mgmt->frame_control) &&
mgmt->u.action.category == WLAN_CATEGORY_BACK) {
int len = skb->len;
@@ -1333,6 +1347,7 @@ static void ieee80211_iface_work(struct work_struct *work)
break;
}
+free_skb:
kfree_skb(skb);
}
--
2.7.4
^ permalink raw reply related
* [PATCH 3/3 v3] mac80211: Refactor ieee80211_iface_work
From: Alex Briskin @ 2016-07-16 15:10 UTC (permalink / raw)
To: linux-wireless, johannes; +Cc: Alex Briskin
In-Reply-To: <1468681838-16601-1-git-send-email-br.shurik@gmail.com>
Added ieee80211_iface_work_handle_vif_type function. Moved the code that
handles sdata->vif.type from ieee80211_iface_work to the function.
Signed-off-by: Alex Briskin <br.shurik@gmail.com>
---
net/mac80211/iface.c | 44 ++++++++++++++++++++++++--------------------
1 file changed, 24 insertions(+), 20 deletions(-)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index c185801..e82f80d 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1323,6 +1323,27 @@ static int ieee80211_iface_work_handle_frame_control(struct sk_buff *skb,
return 0;
}
+static void ieee80211_iface_work_handle_vif_type(struct sk_buff *skb,
+ struct ieee80211_sub_if_data *sdata)
+{
+ switch (sdata->vif.type) {
+ case NL80211_IFTYPE_STATION:
+ ieee80211_sta_rx_queued_mgmt(sdata, skb);
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ ieee80211_ibss_rx_queued_mgmt(sdata, skb);
+ break;
+ case NL80211_IFTYPE_MESH_POINT:
+ if (!ieee80211_vif_is_mesh(&sdata->vif))
+ break;
+ ieee80211_mesh_rx_queued_mgmt(sdata, skb);
+ break;
+ default:
+ WARN(1, "frame for unexpected interface type");
+ break;
+ }
+}
+
static void ieee80211_iface_work(struct work_struct *work)
{
struct ieee80211_sub_if_data *sdata =
@@ -1341,28 +1362,11 @@ static void ieee80211_iface_work(struct work_struct *work)
/* first process frames */
while ((skb = skb_dequeue(&sdata->skb_queue))) {
- if (!ieee80211_iface_work_handle_pkt_type(skb, sdata)) {
- goto free_skb;
- } else if (!ieee80211_iface_work_handle_frame_control(skb, sdata)) {
- goto free_skb;
- } else switch (sdata->vif.type) {
- case NL80211_IFTYPE_STATION:
- ieee80211_sta_rx_queued_mgmt(sdata, skb);
- break;
- case NL80211_IFTYPE_ADHOC:
- ieee80211_ibss_rx_queued_mgmt(sdata, skb);
- break;
- case NL80211_IFTYPE_MESH_POINT:
- if (!ieee80211_vif_is_mesh(&sdata->vif))
- break;
- ieee80211_mesh_rx_queued_mgmt(sdata, skb);
- break;
- default:
- WARN(1, "frame for unexpected interface type");
- break;
+ if (!ieee80211_iface_work_handle_pkt_type(skb, sdata) &&
+ !ieee80211_iface_work_handle_frame_control(skb, sdata)) {
+ ieee80211_iface_work_handle_vif_type(skb, sdata);
}
-free_skb:
kfree_skb(skb);
}
--
2.7.4
^ permalink raw reply related
* [PATCH 2/3 v3] mac80211: Refactor ieee80211_iface_work
From: Alex Briskin @ 2016-07-16 15:10 UTC (permalink / raw)
To: linux-wireless, johannes; +Cc: Alex Briskin
In-Reply-To: <1468681838-16601-1-git-send-email-br.shurik@gmail.com>
Refactored ieee80211_iface_work_handle_pkt_type - if else if replaced by
switch case.
Added ieee80211_iface_work_handle_frame_control.
Moved the code that looks in skb->data (ieee80211_mgmt/ieee80211_hdr) at
frame_control member(field) from ieee80211_iface_work to the function.
Signed-off-by: Alex Briskin <br.shurik@gmail.com>
---
net/mac80211/iface.c | 165 ++++++++++++++++++++++++++++-----------------------
1 file changed, 90 insertions(+), 75 deletions(-)
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 0fc973a..c185801 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1207,13 +1207,16 @@ static int ieee80211_iface_work_handle_pkt_type(struct sk_buff *skb,
struct ieee80211_local *local = sdata->local;
struct sta_info *sta;
- if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_START) {
+ switch (skb->pkt_type) {
+ case IEEE80211_SDATA_QUEUE_AGG_START:
ra_tid = (void *)&skb->cb;
ieee80211_start_tx_ba_cb(&sdata->vif, ra_tid->ra, ra_tid->tid);
- } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_STOP) {
+ break;
+ case IEEE80211_SDATA_QUEUE_AGG_STOP:
ra_tid = (void *)&skb->cb;
ieee80211_stop_tx_ba_cb(&sdata->vif, ra_tid->ra, ra_tid->tid);
- } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_START) {
+ break;
+ case IEEE80211_SDATA_QUEUE_RX_AGG_START:
rx_agg = (void *)&skb->cb;
mutex_lock(&local->sta_mtx);
sta = sta_info_get_bss(sdata, rx_agg->addr);
@@ -1223,7 +1226,8 @@ static int ieee80211_iface_work_handle_pkt_type(struct sk_buff *skb,
IEEE80211_MAX_AMPDU_BUF,
false, true);
mutex_unlock(&local->sta_mtx);
- } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_STOP) {
+ break;
+ case IEEE80211_SDATA_QUEUE_RX_AGG_STOP:
rx_agg = (void *)&skb->cb;
mutex_lock(&local->sta_mtx);
sta = sta_info_get_bss(sdata, rx_agg->addr);
@@ -1233,20 +1237,98 @@ static int ieee80211_iface_work_handle_pkt_type(struct sk_buff *skb,
WLAN_BACK_RECIPIENT, 0,
false);
mutex_unlock(&local->sta_mtx);
- } else {
+ break;
+ default:
return -EINVAL;
}
/*will return 0 if pkt_type found and handled */
return 0;
}
+static int ieee80211_iface_work_handle_frame_control(struct sk_buff *skb,
+ struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_local *local = sdata->local;
+ struct sta_info *sta;
+ struct ieee80211_mgmt *mgmt = (void *)skb->data;
+
+ if (ieee80211_is_action(mgmt->frame_control) &&
+ mgmt->u.action.category == WLAN_CATEGORY_BACK) {
+ int len = skb->len;
+
+ mutex_lock(&local->sta_mtx);
+ sta = sta_info_get_bss(sdata, mgmt->sa);
+ if (sta) {
+ switch (mgmt->u.action.u.addba_req.action_code) {
+ case WLAN_ACTION_ADDBA_REQ:
+ ieee80211_process_addba_request(local, sta,
+ mgmt, len);
+ break;
+ case WLAN_ACTION_ADDBA_RESP:
+ ieee80211_process_addba_resp(local, sta,
+ mgmt, len);
+ break;
+ case WLAN_ACTION_DELBA:
+ ieee80211_process_delba(sdata, sta, mgmt, len);
+ break;
+ default:
+ WARN_ON(1);
+ break;
+ }
+ }
+ mutex_unlock(&local->sta_mtx);
+ } else if (ieee80211_is_action(mgmt->frame_control) &&
+ mgmt->u.action.category == WLAN_CATEGORY_VHT) {
+ switch (mgmt->u.action.u.vht_group_notif.action_code) {
+ case WLAN_VHT_ACTION_GROUPID_MGMT:
+ ieee80211_process_mu_groups(sdata, mgmt);
+ break;
+ default:
+ WARN_ON(1);
+ break;
+ }
+ } else if (ieee80211_is_data_qos(mgmt->frame_control)) {
+ struct ieee80211_hdr *hdr = (void *)mgmt;
+ /*
+ * So the frame isn't mgmt, but frame_control
+ * is at the right place anyway, of course, so
+ * the if statement is correct.
+ *
+ * Warn if we have other data frame types here,
+ * they must not get here.
+ */
+ WARN_ON(hdr->frame_control &
+ cpu_to_le16(IEEE80211_STYPE_NULLFUNC));
+ WARN_ON(!(hdr->seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG)));
+ /*
+ * This was a fragment of a frame, received while
+ * a block-ack session was active. That cannot be
+ * right, so terminate the session.
+ */
+ mutex_lock(&local->sta_mtx);
+ sta = sta_info_get_bss(sdata, mgmt->sa);
+ if (sta) {
+ u16 tid = *ieee80211_get_qos_ctl(hdr) &
+ IEEE80211_QOS_CTL_TID_MASK;
+
+ __ieee80211_stop_rx_ba_session(sta, tid,
+ WLAN_BACK_RECIPIENT,
+ WLAN_REASON_QSTA_REQUIRE_SETUP,
+ true);
+ }
+ mutex_unlock(&local->sta_mtx);
+ } else {
+ return -EINVAL;
+ }
+ return 0;
+}
+
static void ieee80211_iface_work(struct work_struct *work)
{
struct ieee80211_sub_if_data *sdata =
container_of(work, struct ieee80211_sub_if_data, work);
struct ieee80211_local *local = sdata->local;
struct sk_buff *skb;
- struct sta_info *sta;
if (!ieee80211_sdata_running(sdata))
return;
@@ -1259,77 +1341,10 @@ static void ieee80211_iface_work(struct work_struct *work)
/* first process frames */
while ((skb = skb_dequeue(&sdata->skb_queue))) {
- struct ieee80211_mgmt *mgmt = (void *)skb->data;
-
if (!ieee80211_iface_work_handle_pkt_type(skb, sdata)) {
goto free_skb;
- } else if (ieee80211_is_action(mgmt->frame_control) &&
- mgmt->u.action.category == WLAN_CATEGORY_BACK) {
- int len = skb->len;
-
- mutex_lock(&local->sta_mtx);
- sta = sta_info_get_bss(sdata, mgmt->sa);
- if (sta) {
- switch (mgmt->u.action.u.addba_req.action_code) {
- case WLAN_ACTION_ADDBA_REQ:
- ieee80211_process_addba_request(
- local, sta, mgmt, len);
- break;
- case WLAN_ACTION_ADDBA_RESP:
- ieee80211_process_addba_resp(local, sta,
- mgmt, len);
- break;
- case WLAN_ACTION_DELBA:
- ieee80211_process_delba(sdata, sta,
- mgmt, len);
- break;
- default:
- WARN_ON(1);
- break;
- }
- }
- mutex_unlock(&local->sta_mtx);
- } else if (ieee80211_is_action(mgmt->frame_control) &&
- mgmt->u.action.category == WLAN_CATEGORY_VHT) {
- switch (mgmt->u.action.u.vht_group_notif.action_code) {
- case WLAN_VHT_ACTION_GROUPID_MGMT:
- ieee80211_process_mu_groups(sdata, mgmt);
- break;
- default:
- WARN_ON(1);
- break;
- }
- } else if (ieee80211_is_data_qos(mgmt->frame_control)) {
- struct ieee80211_hdr *hdr = (void *)mgmt;
- /*
- * So the frame isn't mgmt, but frame_control
- * is at the right place anyway, of course, so
- * the if statement is correct.
- *
- * Warn if we have other data frame types here,
- * they must not get here.
- */
- WARN_ON(hdr->frame_control &
- cpu_to_le16(IEEE80211_STYPE_NULLFUNC));
- WARN_ON(!(hdr->seq_ctrl &
- cpu_to_le16(IEEE80211_SCTL_FRAG)));
- /*
- * This was a fragment of a frame, received while
- * a block-ack session was active. That cannot be
- * right, so terminate the session.
- */
- mutex_lock(&local->sta_mtx);
- sta = sta_info_get_bss(sdata, mgmt->sa);
- if (sta) {
- u16 tid = *ieee80211_get_qos_ctl(hdr) &
- IEEE80211_QOS_CTL_TID_MASK;
-
- __ieee80211_stop_rx_ba_session(
- sta, tid, WLAN_BACK_RECIPIENT,
- WLAN_REASON_QSTA_REQUIRE_SETUP,
- true);
- }
- mutex_unlock(&local->sta_mtx);
+ } else if (!ieee80211_iface_work_handle_frame_control(skb, sdata)) {
+ goto free_skb;
} else switch (sdata->vif.type) {
case NL80211_IFTYPE_STATION:
ieee80211_sta_rx_queued_mgmt(sdata, skb);
--
2.7.4
^ 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